diff --git a/boot/boot.asm b/boot/boot.asm index 975cacb..8413bab 100644 --- a/boot/boot.asm +++ b/boot/boot.asm @@ -27,6 +27,9 @@ ; ; ; $Log$ +; Revision 1.5 2001/11/13 23:36:45 bartoldeman +; Kernel 2025a final changes. +; ; Revision 1.4 2001/04/29 17:34:39 bartoldeman ; A new SYS.COM/config.sys single stepping/console output/misc fixes. ; @@ -274,10 +277,7 @@ real_start: cli mov di, bp mov cx, 0x0100 rep movsw - push es - mov bx, cont - push bx - retf + jmp word 0x1FE0:cont cont: mov ds, ax mov ss, ax @@ -455,15 +455,15 @@ boot_success: call print ; prints text after call to this function. -print: pop si ; this is the first character +print_1char: xor bx, bx ; video page 0 mov ah, 0x0E ; else print it -print1: lodsb ; get token - cmp al, 0 ; end of string? - je print2 ; if so, exit int 0x10 ; via TTY mode - jmp short print1 ; until done -print2: push si ; stack up return address +print: pop si ; this is the first character +print1: lodsb ; get token + push si ; stack up potential return address + cmp al, 0 ; end of string? + jne print_1char ; until done ret ; and jump to it diff --git a/boot/boot32.asm b/boot/boot32.asm index 8c4b249..51973f0 100644 --- a/boot/boot32.asm +++ b/boot/boot32.asm @@ -92,10 +92,7 @@ real_start: cld mov di, bp mov cx, 0x0100 rep movsw ; move boot code to the 0x1FE0:0x0000 - push es - mov bx, cont - push bx - retf + jmp word 0x1FE0:cont cont: mov ds, ax mov ss, ax @@ -269,15 +266,15 @@ c3: ; prints text after call to this function. -print: pop si ; this is the first character +print_1char: xor bx, bx ; video page 0 mov ah, 0x0E ; else print it -print1: lodsb ; get token - cmp al, bl ; end of string? (al == bl == 0) - je print2 ; if so, exit int 0x10 ; via TTY mode - jmp short print1 ; until done -print2: push si ; stack up return address +print: pop si ; this is the first character +print1: lodsb ; get token + push si ; stack up potential return address + cmp al, 0 ; end of string? + jne print_1char ; until done ret ; and jump to it diff --git a/boot/makefile b/boot/makefile index f5dad31..0aa3740 100644 --- a/boot/makefile +++ b/boot/makefile @@ -5,6 +5,9 @@ # # $Log$ +# Revision 1.2 2001/11/13 23:36:45 bartoldeman +# Kernel 2025a final changes. +# # Revision 1.1 2001/11/04 20:10:15 bartoldeman # Added new makefile names, utils sources, kconfig.h # @@ -53,7 +56,7 @@ #Initial revision. # -!include "..\config.mak" +!include "..\mkfiles\generic.mak" production: b_fat12.bin b_fat16.bin b_fat32.bin @@ -67,9 +70,9 @@ b_fat32.bin: boot32.asm $(NASM) boot32.asm -ob_fat32.bin clobber: clean - $(RM) b_fat12.bin b_fat16.bin b_fat32.bin status.me + -$(RM) b_fat12.bin b_fat16.bin b_fat32.bin status.me clean: - $(RM) *.lst *.map *.bak *.obj + -$(RM) *.lst *.map *.bak *.obj diff --git a/build.bat b/build.bat index b58a944..ed546bf 100644 --- a/build.bat +++ b/build.bat @@ -5,6 +5,9 @@ :- $Id$ :- $Log$ +:- Revision 1.7 2001/11/13 23:36:43 bartoldeman +:- Kernel 2025a final changes. +:- :- Revision 1.6 2001/11/04 19:47:37 bartoldeman :- kernel 2025a changes: see history.txt :- @@ -52,18 +55,34 @@ set XERROR= -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 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 +@if not \%1 == \-r goto norebuild + call clobber :norebuild call config.bat +call getmake.bat -set XERROR= +@if not \%XLINK% == \ goto link_set + +@if \%COMPILER% == \TC2 set XLINK=%TC2_BASE%\tlink /m/c +@if \%COMPILER% == \TURBOCPP set XLINK=%TP1_BASE%\bin\tlink /m/c +@if \%COMPILER% == \TC3 set XLINK=%TC3_BASE%\bin\tlink /m/c +@if \%COMPILER% == \BC5 set XLINK=%BC5_BASE%\bin\tlink /m/c +@if \%COMPILER% == \WATCOM goto watcom_problem +@if \%COMPILER% == \MSCL8 set XLINK=%MS_BASE%\link /ONERROR:NOEXE /ma /nologo +goto link_set + +:watcom_problem +@echo you MUST set XLINK for Watcom in config.bat as WLINK is not suitable +goto end + +:link_set + +@set XERROR= :********************************************************************** :* DONE with preferences - following is command line handling @@ -150,3 +169,10 @@ set XERROR=1 @set COMPILER= @set XCPU= @set XFAT= +@set XLINK= +@set TC2_BASE= +@set TP1_BASE= +@set TC3_BASE= +@set BC5_BASE= +@set MS_BASE= + diff --git a/buildall.bat b/buildall.bat index bb9c2b1..5353548 100644 --- a/buildall.bat +++ b/buildall.bat @@ -20,7 +20,8 @@ set onerror=if not \%XERROR% == \ goto daswarwohlnix :***** some MSCL kernels call config.bat -if not \%SKIPMS% == \ goto no_ms + +if \%MS_BASE% == \ goto no_ms call build -r msc 386 fat16 %ONERROR% call build -r msc 186 fat16 @@ -33,11 +34,11 @@ call build -r msc 186 fat32 %ONERROR% call build -r msc 86 fat32 %ONERROR% -no_ms: -SET SKIPMS= +:no_ms :***** some TC 2.01 kernels +if \%TC2_BASE% == \ goto no_tc call build -r tc 186 fat16 %ONERROR% call build -r tc 86 fat16 @@ -46,7 +47,7 @@ call build -r tc 186 fat32 %ONERROR% call build -r tc 86 fat32 %ONERROR% - +:no_tc :wc @@ -56,10 +57,12 @@ call build -r tc 86 fat32 :- this is definitively only for fun - now :- hope, this gets better :- +if \%WATCOM% == \ goto no_wc call build -r wc 386 fat32 call build -r wc 386 fat16 call build -r wc 86 fat32 call build -r wc 86 fat16 +:no_wc :- the watcom executables will currently NOT RUN @del bin\kwc*.sys >nul diff --git a/clean.bat b/clean.bat index f7fe99a..b5df82e 100644 --- a/clean.bat +++ b/clean.bat @@ -5,6 +5,9 @@ rem batch file to clean everything rem $Id$ rem $Log$ +rem Revision 1.6 2001/11/13 23:36:43 bartoldeman +rem Kernel 2025a final changes. +rem rem Revision 1.5 2001/11/04 19:47:37 bartoldeman rem kernel 2025a changes: see history.txt rem @@ -38,20 +41,15 @@ rem Clean up rem if not exist config.bat goto noconfigbat -if not exist config.mak goto noconfigmak goto start :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 - :start -@set COMPILER=tc2 call config.bat +call getmake.bat cd utils %MAKE% clean diff --git a/clobber.bat b/clobber.bat index 96d3230..e431272 100644 --- a/clobber.bat +++ b/clobber.bat @@ -4,6 +4,9 @@ rem batch file to clobber everything rem $Id$ rem $Log$ +rem Revision 1.6 2001/11/13 23:36:43 bartoldeman +rem Kernel 2025a final changes. +rem rem Revision 1.5 2001/11/04 19:47:37 bartoldeman rem kernel 2025a changes: see history.txt rem @@ -31,20 +34,15 @@ rem Initial include rem if not exist config.bat goto noconfigbat -if not exist config.mak goto noconfigmak goto start :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 - :start -set COMPILER=tc2 call config.bat +call getmake.bat cd utils %MAKE% clobber @@ -75,4 +73,4 @@ del status.me :end set MAKE= -set COMPILER= \ No newline at end of file +set COMPILER= diff --git a/config.b b/config.b index d9a230d..0b086a2 100644 --- a/config.b +++ b/config.b @@ -1,23 +1,152 @@ -rem ********************************************************************** -rem - define your MAKE type here, pick one of them -rem ********************************************************************** +:- +:- batch file that is included in all other batch files for configuration +:- -set MAKE=c:\tc201\make -rem set MAKE=c:\watcom\binw\wmake /ms -rem set MAKE=c:\msvc\bin\nmake /nologo +:-**************************************************************** +:- NOTICE! You must edit and rename this file to CONFIG.BAT! * +:-**************************************************************** -rem ********************************************************************** -rem - define your COMPILER type here, pick one of them -rem ********************************************************************** +:-********************************************************************* +:- determine your compiler settings +:- +:- you have to +:- search for XNASM - and set the path for NASM +:- search for COMPILER - and set your compiler +:- search for ??_BASE - and set the path to your compiler +:- +:-********************************************************************* +:-********************************************************************** +:-- define where to find NASM - remember - it should not be protected +:- mode DJGPP version if you're using Windows NT/2k/XP to compile +:- also: DJGPP-nasm crashes when using protected mode Borland's make +:-********************************************************************** + +set XNASM=c:\bin\nasm16 + +:********************************************************************** +:- define your COMPILER type here, pick one of them +:********************************************************************** + +:- Turbo C 2.01 set COMPILER=TC2 -rem set COMPILER=TURBOCPP -rem set COMPILER=TC3 -rem set COMPILER=BC5 -rem set COMPILER=MSCL8 +:- Turbo C++ 1.01 +:- set COMPILER=TURBOCPP +:- Turbo C 3.0 +:- set COMPILER=TC3 +:- Borland C +:- set COMPILER=BC5 +:- Microsoft C +:- set COMPILER=MSCL8 -rem warning: watcom can compile but the result does not work yet. -rem set COMPILER=WATCOM +:- warning: watcom can compile but the result does not work yet. +:- set COMPILER=WATCOM -rem skip MS compiler in buildall. -rem set SKIPMS=yes +:-********************************************************************** +:-- where is the BASE dir of your compiler(s) ?? +:-********************************************************************** + +set TC2_BASE=c:\tc201 +:- set TP1_BASE=c:\tcpp +:- set TC3_BASE=c:\tc3 +:- set BC5_BASE=c:\bc5 +:- set MS_BASE=c:\msvc + +:- if WATCOM maybe you need to set your WATCOM environment variables +:- and path +:- if not %WATCOM% == \ goto watcom_defined +:- set WATCOM=c:\watcom +:- set PATH=%PATH%;%WATCOM%\binw +:watcom_defined + +:-********************************************************************** +:- (optionally) which linker to use: +:- (otherwise will be determined automatically) +:- WATCOM wlink is not (yet) suitable for linking +:- (the map file and syntax are not compatible) +:- Turbo C 2.01 TLINK 2.0 can't link WATCOM (but can link TC2) +:- Turbo C++ 1.01 and higher TLINK 3.01+ are ok +:- or get TLINK 4 (creates nice map file) from simtel at +:- ftp://ftp.simtel.net/pub/simtelnet/msdos/borland/tlink4.zip +:-********************************************************************** + +:- Turbo Link +:- set XLINK=%TC2_BASE%\tlink /m/c +:- Microsoft Link +:- set XLINK=%MS_BASE%\bin\link /ONERROR:NOEXE /ma /nologo + +:********************************************************************** +:* optionally define your MAKE type here, if not then +:* it will be automatically determined, pick one of them +:* use MS nmake if you want to compile with MSCL +:********************************************************************** + +:- Borland MAKE +:- set MAKE=%TC2_BASE%\make +:- Watcom MAKE in MS mode +:- set MAKE=%WATCOM%\binw\wmake /ms +:- Microsoft MAKE +:- set MAKE=%MS_BASE%\bin\nmake /nologo + +:********************************************************************** +:* select your default target: required CPU and what FAT system to support +:********************************************************************** + +set XCPU=86 +:- set XCPU=186 +:- set XCPU=386 + +set XFAT=16 +:- set XFAT=32 + +:- Give extra compiler DEFINE flags here +:- such as -DDEBUG : extra DEBUG output +:- -DDOSEMU : printf output goes to dosemu log +:- set ALLCFLAGS=-DDEBUG + + +:- +:- $Id$ +:- +:- $Log$ +:- Revision 1.5 2001/11/13 23:36:43 bartoldeman +:- Kernel 2025a final changes. +:- +:- 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 +:- +:- Revision 1.7 2001/04/16 14:36:56 bartoldeman +:- Added ALLCFLAGS for compiler option configuration. +:- +:- Revision 1.6 2001/04/15 03:21:49 bartoldeman +:- See history.txt for the list of fixes. +:- +:- Revision 1.5 2001/03/22 10:51:04 bartoldeman +:- Suggest to extract F_SCOPY into libm.lib for Borland C++. +:- +:- Revision 1.4 2001/03/19 04:50:56 bartoldeman +:- See history.txt for overview: put kernel 2022beo1 into CVS +:- +:- Revision 1.3 2000/05/25 20:56:19 jimtabor +:- Fixed project history +:- +:- Revision 1.2 2000/05/14 17:07:07 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.3 1999/09/13 20:40:17 jprice +:- Added COMPILER variable +:- +:- Revision 1.2 1999/08/25 03:59:14 jprice +:- New build batch files. +:- +:- Revision 1.1 1999/08/25 03:20:39 jprice +:- ror4 patches to allow TC 2.01 compile. +:- +:- diff --git a/docs/history.txt b/docs/history.txt index 22198e2..7aac762 100644 --- a/docs/history.txt +++ b/docs/history.txt @@ -1,3 +1,34 @@ +2001 Nov 12 - Build 2025a +-------- Bart Oldeman (bart.oldeman@bristol.ac.uk) ++ Changes Tom + * initialize LBA parameter struct to 0's - some BIOSes don't fill + in everything. Thanks to Bernd Blaauw's bug report. + * Minor boot sector optimization. + * added some exeflat options ++ Changes Jeremy + * changes to fdkrncfg.c: mostly cosmetic to the output + * added sys.doc file (updated by Bart) ++ Changes Bart + * let int 0 (divide by zero) and int 6 (invalid opcode) print a + stack trace to aid in debugging + * fixed floppy drive detection for XT's. + * fixed bug in int21/ah=0x32 and friends - we should flush data before the + forced media_check + * Use CHS addressing if possible on partitions with the relevant ID, + you can overide this using the new FORCELBA and GLOBALENABLELBASUPPORT + sys config options. + * Always use BIOS values for translating LBA to CHS for fixed disks - + ignoring the boot sector values. For floppies the boot sector is used. + * fixed "truename hello." to remove the trailing dot. + * added options to SYS to write to a boot sector image file + * set Critical Error Code for ioctl's + * fake cluster size for 64k clusters just like FAT32 for INT21/AH=0x36 + and friends. ++ Changes Bart+Tom+Victor + * make makefile system more robust ++ Changes Victor + * cleaned up map_cluster and dir_read (bug fixed by Bart) + * updated LFN API (in development, not used yet) 2001 Nov 4 - Build 2025a (test) -------- Bart Oldeman (bart.oldeman@bristol.ac.uk) + Changes tom @@ -25,6 +56,8 @@ compilers (MS, Watcom, Borland). Watcom compiles but the result does not run yet. + Changes Bart + * extended the double-byte lead table from int21/ah=63 to 4 zeros + to make Watcom happy * 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 diff --git a/docs/lfnapi.txt b/docs/lfnapi.txt index 8270b52..a2e8d57 100644 --- a/docs/lfnapi.txt +++ b/docs/lfnapi.txt @@ -1,24 +1,22 @@ - FreeDOS LFN aid API. - + FreeDOS LFN helper API. struct lfn_inode { - UNICODE name[255]; + UNICODE name[256]; struct dirent l_dir; /* this file's dir entry image */ ULONG l_diroff; /* offset of the dir entry */ - CLUSTER l_dirstart; /* the starting cluster of dir */ - /* when dir is not root */ }; - typedef struct lfn_inode FAR * lfn_inode_ptr; -COUNT lfn_allocate_inode(); +COUNT lfn_allocate_inode(VOID); COUNT lfn_free_inode(COUNT handle); +COUNT lfn_setup_inode(COUNT handle, CLUSTER dirstart, ULONG diroff); + COUNT lfn_create_entries(COUNT handle, lfn_inode_ptr lip); -COUNT lfn_remove_entries(COUNT handle, lfn_inode_ptr lip); +COUNT lfn_remove_entries(COUNT handle); COUNT lfn_dir_read(COUNT handle, lfn_inode_ptr lip); -COUNT lfn_dir_write(COUNT handle, lfn_inode_ptr lip); +COUNT lfn_dir_write(COUNT handle); diff --git a/drivers/makefile b/drivers/makefile index 1073f7c..cfae1a1 100644 --- a/drivers/makefile +++ b/drivers/makefile @@ -5,6 +5,9 @@ # # $Log$ +# Revision 1.2 2001/11/13 23:36:45 bartoldeman +# Kernel 2025a final changes. +# # Revision 1.1 2001/11/04 20:10:15 bartoldeman # Added new makefile names, utils sources, kconfig.h # @@ -56,7 +59,7 @@ #Initial revision. # -!include "..\config.mak" +!include "..\mkfiles\generic.mak" # MICROSOFT C @@ -90,11 +93,11 @@ production: ..\lib\device.lib copy device.lib ..\lib clobber: clean - $(RM) device.lib status.me ..\lib\device.lib + -$(RM) device.lib status.me ..\lib\device.lib clean: - $(RM) *.obj *.bak *.crf *.xrf *.map *.lst + -$(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.cod device.lib : $(OBJS) - $(RM) device.lib + -$(RM) device.lib $(LIBUTIL) $(LIBFLAGS) device $(LIBOBJS) $(LIBTERM) diff --git a/hdr/fat.h b/hdr/fat.h index fb1736e..c67ce57 100644 --- a/hdr/fat.h +++ b/hdr/fat.h @@ -36,6 +36,9 @@ static BYTE *fat_hRcsId = "$Id$"; /* * $Log$ + * Revision 1.10 2001/11/13 23:36:45 bartoldeman + * Kernel 2025a final changes. + * * Revision 1.9 2001/11/04 19:47:39 bartoldeman * kernel 2025a changes: see history.txt * @@ -161,6 +164,18 @@ struct dirent ULONG dir_size; /* File size in bytes */ }; +struct lfn_entry +{ + UBYTE lfn_id; + UNICODE lfn_name0_4[5]; + UBYTE lfn_attrib; + UBYTE lfn_reserved1; + UBYTE lfn_checksum; + UNICODE lfn_name5_10[6]; + UWORD lfn_reserved2; + UNICODE lfn_name11_12[2]; +}; + /* */ /* filesystem sizeof(dirent) - may be different from core */ /* */ @@ -193,3 +208,14 @@ struct dirent #define DIR_SIZE FNAME_SIZE+FEXT_SIZE+17 #define DIRENT_SIZE 32 + +struct lfn_inode +{ + UNICODE name[256]; + + struct dirent l_dir; + + ULONG l_diroff; /* offset of the dir entry */ +}; + +typedef struct lfn_inode FAR * lfn_inode_ptr; diff --git a/hdr/kconfig.h b/hdr/kconfig.h index dd2e6a5..cddbfcb 100644 --- a/hdr/kconfig.h +++ b/hdr/kconfig.h @@ -21,5 +21,7 @@ typedef struct _KernelConfig { unsigned char DLASortByDriveNo; unsigned char InitDiskShowDriveAssignment; signed char SkipConfigSeconds; + unsigned char ForceLBA; + unsigned char GlobalEnableLBAsupport; /* = 0 --> disable LBA support */ } KernelConfig; extern struct _KernelConfig FAR LowKernelConfig; diff --git a/hdr/version.h b/hdr/version.h index b80e9d1..b8bbd66 100644 --- a/hdr/version.h +++ b/hdr/version.h @@ -44,6 +44,6 @@ static BYTE *date_hRcsId = "$Id$"; #define REVISION_MINOR 1 #define REVISION_SEQ 25 #define BUILD "2025" -#define SUB_BUILD "a test" -#define KERNEL_VERSION_STRING "1.1.25" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ*/ -#define KERNEL_BUILD_STRING "2025a test" /*#BUILD SUB_BUILD*/ +#define SUB_BUILD "a" +#define KERNEL_VERSION_STRING "1.1.25a" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ*/ +#define KERNEL_BUILD_STRING "2025a" /*#BUILD SUB_BUILD*/ diff --git a/kernel/blockio.c b/kernel/blockio.c index 1c697aa..7e54b16 100644 --- a/kernel/blockio.c +++ b/kernel/blockio.c @@ -37,6 +37,9 @@ static BYTE *blockioRcsId = "$Id$"; /* * $Log$ + * Revision 1.15 2001/11/13 23:36:45 bartoldeman + * Kernel 2025a final changes. + * * Revision 1.14 2001/11/04 19:47:39 bartoldeman * kernel 2025a changes: see history.txt * @@ -592,7 +595,7 @@ UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks, COUNT mod return 0x0201; /* illegal command */ } -#if 1 +#if TOM #define KeyboardShiftState() (*(BYTE FAR *)(MK_FP(0x40,0x17))) if (KeyboardShiftState() & 0x01) diff --git a/kernel/config.c b/kernel/config.c index 243beb0..5b8a230 100644 --- a/kernel/config.c +++ b/kernel/config.c @@ -89,6 +89,9 @@ static BYTE *RcsId = "$Id$"; /* * $Log$ + * Revision 1.30 2001/11/13 23:36:45 bartoldeman + * Kernel 2025a final changes. + * * Revision 1.29 2001/11/04 19:47:39 bartoldeman * kernel 2025a changes: see history.txt * @@ -366,6 +369,7 @@ STATIC struct table commands[] = {"NUMLOCK", 1, Numlock}, /* rem is never executed by locking out pass */ {"REM", 0, CfgFailure}, + {";", 0, CfgFailure}, {"SHELL", 1, InitPgm}, {"SHELLHIGH", 1, InitPgmHigh}, {"STACKS", 1, Stacks}, @@ -1419,7 +1423,11 @@ INIT BYTE * askThisSingleCommand = FALSE; s = skipwh(s); - while (*s && + if (*s == ';') { + /* semicolon is a synonym for rem */ + *d++ = *s++; + } + else while (*s && !(*s == 0x0d || *s == 0x0a || *s == ' ' diff --git a/kernel/dosfns.c b/kernel/dosfns.c index e96fb90..aa52805 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.30 2001/11/13 23:36:45 bartoldeman + * Kernel 2025a final changes. + * * Revision 1.29 2001/11/04 19:47:39 bartoldeman * kernel 2025a changes: see history.txt * @@ -1134,8 +1137,7 @@ COUNT DosCloseSft(WORD sft_idx) return DE_INVLDHNDL; /* If this is not opened another error */ - /* The second condition is a sanity check and necessary for FcbCloseAll */ - if (sftp->sft_count == 0 || (sftp->sft_count == 1 && sftp->sft_psp != cu_psp)) + if (sftp->sft_count == 0) return DE_ACCESS; lpCurSft = sftp; @@ -1181,8 +1183,9 @@ COUNT DosClose(COUNT hndl) return ret; } -VOID DosGetFree(UBYTE drive, COUNT FAR * spc, COUNT FAR * navc, COUNT FAR * bps, COUNT FAR * nc) +BOOL DosGetFree(UBYTE drive, UCOUNT FAR * spc, UCOUNT FAR * navc, UCOUNT FAR * bps, UCOUNT FAR * nc) { + /* *nc==0xffff means: called from FatGetDrvData, fcbfns.c */ struct dpb FAR *dpbp; struct cds FAR *cdsp; COUNT rg[4]; @@ -1193,29 +1196,45 @@ VOID DosGetFree(UBYTE drive, COUNT FAR * spc, COUNT FAR * navc, COUNT FAR * bps, /* first check for valid drive */ *spc = -1; if (drive >= lastdrive) - return; + return FALSE; cdsp = &CDSp->cds_table[drive]; if (!(cdsp->cdsFlags & CDSVALID)) - return; + return FALSE; if (cdsp->cdsFlags & CDSNETWDRV) { + if (*nc == 0xffff) + { + /* Undoc DOS says, its not supported for + network drives. so it's probably OK */ + /*printf("FatGetDrvData not yet supported over network drives\n");*/ + return FALSE; + } + remote_getfree(cdsp, rg); *spc = (COUNT) rg[0]; *nc = (COUNT) rg[1]; *bps = (COUNT) rg[2]; *navc = (COUNT) rg[3]; - return; + return TRUE; } dpbp = CDSp->cds_table[drive].cdsDpb; - if (dpbp == NULL || media_check(dpbp) < 0) - return; + if (dpbp == NULL) + return FALSE; + + if (*nc == 0xffff) + { + flush_buffers(dpbp->dpb_unit); + dpbp->dpb_flags = M_CHANGED; + } + + if (media_check(dpbp) < 0) + return FALSE; /* get the data available from dpb */ - *nc = dpbp->dpb_size - 1; *spc = dpbp->dpb_clsmask + 1; *bps = dpbp->dpb_secsize; @@ -1229,7 +1248,7 @@ VOID DosGetFree(UBYTE drive, COUNT FAR * spc, COUNT FAR * navc, COUNT FAR * bps, /* 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); + if (*nc != 0xffff) nfree = dos_free(dpbp); while (ntotal > FAT_MAGIC16 && cluster_size < 0x8000) { cluster_size <<= 1; @@ -1243,10 +1262,21 @@ VOID DosGetFree(UBYTE drive, COUNT FAR * spc, COUNT FAR * navc, COUNT FAR * bps, /* now tell fs to give us free cluster */ /* count */ *navc = nfree > FAT_MAGIC16 ? FAT_MAGIC16 : (UCOUNT)nfree; - return; + return TRUE; } #endif - *navc = (COUNT)dos_free(dpbp); + /* a passed nc of 0xffff means: skip free; see FatGetDrvData + fcbfns.c */ + if (*nc != 0xffff) *navc = (COUNT)dos_free(dpbp); + *nc = dpbp->dpb_size - 1; + if (*spc > 64) { + /* fake for 64k clusters do confuse some DOS programs, but let + others work without overflowing */ + *spc >>= 1; + *navc = (*navc < FAT_MAGIC16/2) ? (*navc << 1) : FAT_MAGIC16; + *nc = (*nc < FAT_MAGIC16/2) ? (*nc << 1) : FAT_MAGIC16; + } + return TRUE; } #ifdef WITHFAT32 diff --git a/kernel/dsk.c b/kernel/dsk.c index 43a3996..e3d7668 100644 --- a/kernel/dsk.c +++ b/kernel/dsk.c @@ -34,6 +34,9 @@ static BYTE *dskRcsId = "$Id$"; /* * $Log$ + * Revision 1.22 2001/11/13 23:36:45 bartoldeman + * Kernel 2025a final changes. + * * Revision 1.21 2001/11/04 19:47:39 bartoldeman * kernel 2025a changes: see history.txt * @@ -979,12 +982,19 @@ STATIC WORD dskerr(COUNT code) void LBA_to_CHS(struct CHS *chs, ULONG LBA_address, ddt *pddt) { - chs->Sector = LBA_address% pddt->ddt_bpb.bpb_nsecs + 1; + /* we need the defbpb values since those are taken from the + BIOS, not from some random boot sector, except when + we're dealing with a floppy */ + bpb *pbpb = hd(pddt->ddt_descflags) ? + &pddt->ddt_defbpb : + &pddt->ddt_bpb; + + chs->Sector = LBA_address % pbpb->bpb_nsecs + 1; - LBA_address /= pddt->ddt_bpb.bpb_nsecs; + LBA_address /= pbpb->bpb_nsecs; - chs->Head = LBA_address % pddt->ddt_bpb.bpb_nheads; - chs->Cylinder = LBA_address / pddt->ddt_bpb.bpb_nheads; + chs->Head = LBA_address % pbpb->bpb_nheads; + chs->Cylinder = LBA_address / pbpb->bpb_nheads; } @@ -1079,7 +1089,7 @@ int LBA_Transfer(ddt *pddt ,UWORD mode, VOID FAR *buffer, count = DMA_max_transfer(buffer,count); - if (FP_SEG(buffer) == 0xffff || count == 0) + if (FP_SEG(buffer) >= 0xa000 || count == 0) { transfer_address = DiskTransferBuffer; count = 1; diff --git a/kernel/entry.asm b/kernel/entry.asm index e32fbe3..a7deb29 100644 --- a/kernel/entry.asm +++ b/kernel/entry.asm @@ -28,6 +28,9 @@ ; $Id$ ; ; $Log$ +; Revision 1.16 2001/11/13 23:36:45 bartoldeman +; Kernel 2025a final changes. +; ; Revision 1.15 2001/11/04 19:47:39 bartoldeman ; kernel 2025a changes: see history.txt ; @@ -183,7 +186,7 @@ reloc_call_cpm_entry: cmp cl,024h jbe cpm_error mov ah,cl ; get the call # from cl to ah - jmp short reloc_call_int21_handler ; do the system call + jmp reloc_call_int21_handler ; do the system call cpm_error: mov al,0 iret @@ -218,13 +221,30 @@ _RestartSysCall: ; int20_handler(iregs UserRegs) ; -divide_by_zero_message db 0dh,0ah,'Interrupt divide by zero',0dh,0ah,0 +print_hex: mov cx, 404h +hex_loop: + rol dx, cl + mov al, dl + and al, 0fh + add al, 30h + cmp al, 39h + jbe no_letter + add al, 7 +no_letter: + mov bx, 0070h + mov ah, 0eh + int 10h + dec ch + jnz hex_loop + ret + +divide_by_zero_message db 0dh,0ah,'Interrupt divide by zero, stack:',0dh,0ah,0 global reloc_call_int0_handler reloc_call_int0_handler: mov si,divide_by_zero_message - + zero_message_loop: mov al, [cs:si] test al,al @@ -239,10 +259,26 @@ zero_message_loop: jmp short zero_message_loop zero_done: + mov bp, sp + xor si, si ; print 13 words of stack for debugging LUDIV etc. +stack_loop: + mov dx, [bp+si] + call print_hex + mov al, ' ' + int 10h + inc si + inc si + cmp si, 13*2 + jb stack_loop + mov al, 0dh + int 10h + mov al, 0ah + int 10h + mov ax,04c7fh ; terminate with errorlevel 127 int 21h -invalid_opcode_message db 0dh,0ah,'Invalid Opcode',0dh,0ah,0 +invalid_opcode_message db 0dh,0ah,'Invalid Opcode at ',0 global reloc_call_int6_handler reloc_call_int6_handler: diff --git a/kernel/fatdir.c b/kernel/fatdir.c index 91e2a8a..35be036 100644 --- a/kernel/fatdir.c +++ b/kernel/fatdir.c @@ -36,6 +36,9 @@ static BYTE *fatdirRcsId = "$Id$"; /* * $Log$ + * Revision 1.25 2001/11/13 23:36:45 bartoldeman + * Kernel 2025a final changes. + * * Revision 1.24 2001/11/04 19:47:39 bartoldeman * kernel 2025a changes: see history.txt * @@ -388,10 +391,8 @@ f_node_ptr dir_open(BYTE * dirname) * 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 + * DE_SEEK - Attempt to read beyound the end of the directory. + * DE_BLKINVLD - Invalid block. * Note. Empty directory entries always resides at the end of the directory. */ COUNT dir_read(REG f_node_ptr fnp) { @@ -415,7 +416,7 @@ COUNT dir_read(REG f_node_ptr fnp) if (fnp->f_flags.f_droot) { if (new_diroff >= DIRENT_SIZE * (ULONG)fnp->f_dpb->dpb_dirents) - return DE_TOOMANY; + return DE_SEEK; bp = getblock((ULONG) (new_diroff / secsize + fnp->f_dpb->dpb_dirstrt), @@ -426,8 +427,6 @@ COUNT dir_read(REG f_node_ptr fnp) } else { - COUNT rc; - /* Do a "seek" to the directory position */ fnp->f_offset = new_diroff; @@ -436,14 +435,8 @@ COUNT dir_read(REG f_node_ptr fnp) #ifdef DISPLAY_GETBLOCK printf("dir_read: "); #endif - if ((rc = map_cluster(fnp, XFR_READ)) != SUCCESS) - return rc; - - /* If the returned cluster is FREE, LAST_CLUSTER */ - /* LONG_LAST_CLUSTER, return "disk as full" */ - - if (fnp->f_cluster == FREE || last_link(fnp)) - return DE_HNDLDSKFULL; + if (map_cluster(fnp, XFR_READ) != SUCCESS) + return DE_SEEK; /* Compute the block within the cluster and the */ /* offset within the block. */ @@ -527,9 +520,7 @@ BOOL dir_write(REG f_node_ptr fnp) #ifdef DISPLAY_GETBLOCK printf("dir_write: "); #endif - /* 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) + if (map_cluster(fnp, XFR_READ) != SUCCESS) { release_f_node(fnp); return FALSE; diff --git a/kernel/fatfs.c b/kernel/fatfs.c index 3da3c89..08000d1 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.26 2001/11/13 23:36:45 bartoldeman + * Kernel 2025a final changes. + * * Revision 1.25 2001/11/04 19:47:39 bartoldeman * kernel 2025a changes: see history.txt * @@ -1543,13 +1546,25 @@ STATIC BOOL first_fat(f_node_ptr fnp) return TRUE; } -/* JPP: I think this starts at the beginning of a file, and follows - the fat chain to find the cluster that contains the data for the - file at f_offset. */ +/* Description. + * Finds the cluster which contains byte at the fnp->f_offset offset and + * stores its number to the fnp->f_cluster. The search begins from the start of + * a file or a directory depending whether fnp->f_ddir is FALSE or TRUE + * and continues through the FAT chain until the target cluster is found. + * The mode can have only XFR_READ or XFR_WRITE values. + * In the XFR_WRITE mode map_cluster extends the FAT chain by creating + * new clusters upon necessity. + * Return value. + * DE_HNDLDSKFULL - [XFR_WRITE mode only] unable to find free cluster + * for extending the FAT chain, the disk is full. + * The fnode is released from memory. + * DE_SEEK - [XFR_READ mode only] byte at f_offset lies outside of + * the FAT chain. The fnode is not released. + * Notes. + * JPP: new map_cluster. If we are moving forward, then use the offset + * that we are at now (f_cluster_offset) to start, instead of starting + * at the beginning. */ -/* JPP: new map_cluster. If we are moving forward, then use the offset - that we are at now (f_cluster_offset) to start, instead of starting - at the beginning. */ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode) { ULONG idx; @@ -1570,7 +1585,10 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode) { /* If there are no more free fat entries, then we are full! */ if (!first_fat(fnp)) + { + dir_close(fnp); return DE_HNDLDSKFULL; + } } if (fnp->f_offset >= fnp->f_cluster_offset) /*JPP */ @@ -1594,19 +1612,16 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode) /* physical cluster. Our search is performed by pacing an index */ /* up to the relative cluster position where the index falls */ /* within the cluster. */ - /* */ - /* NOTE: make sure your compiler does not optimize for loop */ - /* tests to the loop exit. We need to fall out immediately for */ - /* files whose length < cluster size. */ - for (; idx >= clssize; idx -= clssize) + + FOREVER { /* If this is a read and the next is a LAST_CLUSTER, */ /* then we are going to read past EOF, return zero read */ - if ((mode == XFR_READ) && last_link(fnp)) + if ((mode == XFR_READ) && (last_link(fnp) || fnp->f_cluster == FREE)) return DE_SEEK; -/* expand the list if we're going to write and have run into */ -/* the last cluster marker. */ - else if ((mode == XFR_WRITE) && last_link(fnp)) + /* expand the list if we're going to write and have run into */ + /* the last cluster marker. */ + if ((mode == XFR_WRITE) && (last_link(fnp))) { if (!extend(fnp)) { @@ -1614,13 +1629,18 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode) return DE_HNDLDSKFULL; } } + + if (idx < clssize) + break; + fnp->f_back = fnp->f_cluster; /* get next cluster in the chain */ fnp->f_cluster = next_cluster(fnp->f_dpb, fnp->f_cluster); fnp->f_cluster_offset += clssize; + idx -= clssize; } - + #ifdef DISPLAY_GETBLOCK printf("done.\n"); #endif @@ -1799,20 +1819,11 @@ UCOUNT readblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err) #ifdef DISPLAY_GETBLOCK printf("readblock: "); #endif - switch (map_cluster(fnp, XFR_READ)) + if (map_cluster(fnp, XFR_READ) != SUCCESS) { - case DE_SEEK: - *err = DE_SEEK; - dir_close(fnp); - return ret_cnt; - - default: - *err = DE_HNDLDSKFULL; - dir_close(fnp); - return ret_cnt; - - case SUCCESS: - break; + *err = DE_SEEK; + dir_close(fnp); + return ret_cnt; } } @@ -1984,20 +1995,8 @@ STATIC COUNT dos_extend(f_node_ptr fnp) 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; - } + if (map_cluster(fnp, XFR_WRITE) != SUCCESS) + return DE_HNDLDSKFULL; #ifdef WRITEZEROS /* Compute the block within the cluster and the offset */ @@ -2181,31 +2180,9 @@ UCOUNT writeblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err) #ifdef DISPLAY_GETBLOCK printf("writeblock: "); #endif - switch (map_cluster(fnp, XFR_WRITE)) + if (map_cluster(fnp, XFR_WRITE) != SUCCESS) { - case DE_SEEK: - *err = DE_SEEK; - dir_close(fnp); - return ret_cnt; - - default: - dir_close(fnp); - *err = DE_HNDLDSKFULL; - return ret_cnt; - - case SUCCESS: - merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */ - break; - } - } - - /* XFR_WRITE case only - if we're at the end, the next */ - /* FAT is an EOF marker, so just extend the file length */ - if (last_link(fnp)) { - if (!extend(fnp)) - { - dir_close(fnp); - *err = DE_HNDLDSKFULL; + *err = DE_HNDLDSKFULL; return ret_cnt; } merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */ @@ -2708,10 +2685,6 @@ STATIC VOID shrink_file(f_node_ptr fnp) st = fnp->f_cluster; - /* first cluster is free or EOC */ - if (st == FREE || st == LONG_LAST_CLUSTER) - goto done; - next = next_cluster(dpbp, st); if (next == LONG_LAST_CLUSTER) /* last cluster found */ diff --git a/kernel/fattab.c b/kernel/fattab.c index 35c36b5..eaec6df 100644 --- a/kernel/fattab.c +++ b/kernel/fattab.c @@ -35,6 +35,9 @@ static BYTE *RcsId = "$Id$"; /* * $Log$ + * Revision 1.10 2001/11/13 23:36:45 bartoldeman + * Kernel 2025a final changes. + * * Revision 1.9 2001/11/04 19:47:39 bartoldeman * kernel 2025a changes: see history.txt * @@ -401,8 +404,10 @@ UCOUNT link_fat12(struct dpb FAR *dpbp, CLUSTER Cluster1, CLUSTER Cluster2) CLUSTER next_cluster(struct dpb FAR *dpbp, CLUSTER ClusterNum) { struct buffer FAR *bp; +#ifdef DEBUG if (ClusterNum == LONG_LAST_CLUSTER) printf("fatal error: trying to do next_cluster(dpbp, EOC)!\n"); - + if (ClusterNum == 0) printf("fatal error: trying to do next_cluster(dpbp, 0)!\n"); +#endif /* Get the block that this cluster is in */ bp = getFATblock(ClusterNum, dpbp); diff --git a/kernel/fcbfns.c b/kernel/fcbfns.c index f207945..65b7042 100644 --- a/kernel/fcbfns.c +++ b/kernel/fcbfns.c @@ -35,6 +35,9 @@ static BYTE *RcsId = "$Id$"; /* * $Log$ + * Revision 1.20 2001/11/13 23:36:45 bartoldeman + * Kernel 2025a final changes. + * * Revision 1.19 2001/11/04 19:47:39 bartoldeman * kernel 2025a changes: see history.txt * @@ -178,68 +181,16 @@ BOOL FcbCalcRec(); static dmatch Dmatch; -VOID FatGetDrvData(UCOUNT drive, COUNT FAR * spc, COUNT FAR * bps, - COUNT FAR * nc, BYTE FAR ** mdp) +VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps, + UCOUNT FAR * nc, BYTE FAR ** mdp) { - struct dpb FAR *dpbp; - struct cds FAR *cdsp; - - /* first check for valid drive */ - *spc = -1; - - drive = (drive == 0 ? default_drive : drive - 1); - - if (drive >= lastdrive) - return; - - cdsp = &CDSp->cds_table[drive]; - - if (!(cdsp->cdsFlags & CDSVALID)) - return; - - /* next - "log" in the drive */ - if (cdsp->cdsFlags & CDSNETWDRV) { - /* Undoc DOS says, its not supported for - network drives. so it's probably OK */ - /*printf("FatGetDrvData not yet supported over network drives\n");*/ - return; - } - dpbp = CDSp->cds_table[drive].cdsDpb; - - if (dpbp == NULL) - { - return; - } - - dpbp->dpb_flags = -1; - if ((media_check(dpbp) < 0)) - { - return; - } - + UCOUNT navc; + /* 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; - + *nc = 0xffff; /* pass 0xffff to skip free count */ + if (DosGetFree(drive, spc, &navc, bps, nc)) /* Point to the media desctriptor for this drive */ - *mdp = (BYTE FAR*)&(dpbp->dpb_mdb); + *mdp = (BYTE FAR*)&(CDSp->cds_table[drive].cdsDpb->dpb_mdb); } #define PARSE_SEP_STOP 0x01 @@ -628,6 +579,7 @@ see get_free_sft in dosfns.c BOOL FcbCreate(xfcb FAR * lpXfcb) { + sft FAR *sftp; COUNT sft_idx, FcbDrive; struct dhdr FAR *dhp; @@ -638,6 +590,9 @@ BOOL FcbCreate(xfcb FAR * lpXfcb) if (sft_idx < 0) return FALSE; + sftp = idx_to_sft(sft_idx); + sftp->sft_attrib |= SFT_MFCB; + /* check for a device */ dhp = IsDevice(PriPathName); lpFcb->fcb_sftno = sft_idx; @@ -709,6 +664,9 @@ BOOL FcbOpen(xfcb FAR * lpXfcb) if (sft_idx < 0) return FALSE; + sftp = idx_to_sft(sft_idx); + sftp->sft_attrib |= SFT_MFCB; + /* check for a device */ lpFcb->fcb_curec = 0; lpFcb->fcb_rndm = 0; @@ -723,7 +681,6 @@ BOOL FcbOpen(xfcb FAR * lpXfcb) } else { - sftp = idx_to_sft(sft_idx); lpFcb->fcb_drive = FcbDrive; lpFcb->fcb_recsiz = 128; lpFcb->fcb_fsize = sftp->sft_size; @@ -902,15 +859,15 @@ BOOL FcbClose(xfcb FAR * lpXfcb) return FALSE; } -/* close all files opened by FCBs - DosCloseSft checks the open count (has to be 1) and current psp - */ +/* close all files the current process opened by FCBs */ VOID FcbCloseAll() { COUNT idx = 0; + sft FAR *sftp; - for (idx = 0; DosCloseSft(idx) != DE_INVLDHNDL; idx++) - ; + for (idx = 0; (sftp = idx_to_sft(idx)) != (sft FAR *) -1; idx++) + if ((sftp->sft_attrib & SFT_MFCB) && sftp->sft_psp == cu_psp) + DosCloseSft(idx); } BOOL FcbFindFirst(xfcb FAR * lpXfcb) diff --git a/kernel/init-mod.h b/kernel/init-mod.h index f18c449..5dffac9 100644 --- a/kernel/init-mod.h +++ b/kernel/init-mod.h @@ -36,6 +36,7 @@ extern struct _KernelConfig InitKernelConfig; * entry points. */ #define printf init_printf +#define sprintf init_sprintf #define execrh reloc_call_execrh #define fmemcpy reloc_call_fmemcpy #define fmemset reloc_call_fmemset @@ -192,6 +193,7 @@ INIT VOID init_fatal(BYTE * err_msg); /* prf.c */ WORD init_printf(CONST BYTE * fmt,...); +WORD init_sprintf(BYTE * buff, CONST BYTE * fmt, ...); void MoveKernel(unsigned NewKernelSegment); extern WORD HMAFree; /* first byte in HMA not yet used */ diff --git a/kernel/initdisk.c b/kernel/initdisk.c index 5ee1343..358ff26 100644 --- a/kernel/initdisk.c +++ b/kernel/initdisk.c @@ -103,9 +103,58 @@ extern UWORD DOSFAR LBA_WRITE_VERIFY; * * e) and all this is my private opinion. tom ehlert. * + * + * Some thoughts about LBA vs. CHS. by Bart Oldeman 2001/Nov/11 + * Matthias Paul writes in www.freedos.org/freedos/news/technote/113.html: + * (...) MS-DOS 7.10+, which will always access logical drives in a type + * 05h extended partition via CHS, even if the individual logical drives + * in there are of LBA type, or go beyond 8 Gb... (Although this workaround + * is sometimes used in conjunction with OS/2, using a 05h partition going + * beyond 8 Gb may cause MS-DOS 7.10 to hang or corrupt your data...) (...) + * + * Also at http://www.win.tue.nl/~aeb/partitions/partition_types-1.html: + * (...) 5 DOS 3.3+ Extended Partition + * Supports at most 8.4 GB disks: with type 5 DOS/Windows will not use the + * extended BIOS call, even if it is available. (...) + * + * So MS-DOS 7.10+ is brain-dead in this respect, but we knew that ;-) + * However there is one reason to use old-style CHS calls: + * some programs intercept int 13 and do not support LBA addressing. So + * it is worth using CHS if possible, unless the user asks us not to, + * either by specifying a 0x0c/0x0e/0x0f partition type or enabling + * the ForceLBA setting in the fd kernel (sys) config. This will make + * multi-sector reads and BIOS computations more efficient, at the cost + * of some compatibility. + * + * However we need to be safe, and with varying CHS at different levels + * that might be difficult. Hence we _only_ trust the LBA values in the + * partition tables and the heads and sectors values the BIOS gives us. + * After all these are the values the BIOS uses to process our CHS values. + * So unless the BIOS is buggy, using CHS on one partition and LBA on another + * should be safe. The CHS values in the partition table are NOT trusted. + * We print a warning if there is a mismatch with the calculated values. + * + * The CHS values in the boot sector are used at a higher level. The CHS + * that DOS uses in various INT21/AH=44 IOCTL calls are converted to LBA + * using the boot sector values and then converted back to CHS using BIOS + * values if necessary. Internally we do LBA as much as possible. + * + * However if the partition extends beyond cylinder 1023 and is not labelled + * as one of the LBA types, we can't use CHS and print a warning, using LBA + * instead if possible, and otherwise refuse to use it. + * + * As for EXTENDED_LBA vs. EXTENDED, FreeDOS makes no difference. This is + * boot time - there is no reason not to use LBA for reading partition tables, + * and the MSDOS 7.10 behaviour is not desirable. + * + * Note: for floppies we need the boot sector values though and the boot sector + * code does not use LBA addressing yet. + * + * Conclusion: with all this implemented, FreeDOS should be able to gracefully + * handle and read foreign hard disks moved across computers, whether using + * CHS or LBA, strengthening its role as a rescue environment. */ - /* #define DEBUG */ #define _BETA_ /* messages for initial phase only */ @@ -146,6 +195,7 @@ extern UWORD DOSFAR LBA_WRITE_VERIFY; /* boundary. LBA is needed to access this. */ #define FAT16_LBA 0x0e /* like 0x06, but it is supposed to end past */ /* the 8.4GB boundary */ +#define FAT12_LBA 0xff /* fake FAT12 LBA entry for internal use */ #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 * @@ -160,6 +210,10 @@ extern UWORD DOSFAR LBA_WRITE_VERIFY; #define IsExtPartition(parttyp) ((parttyp) == EXTENDED || \ (parttyp) == EXTENDED_LBA ) +#define IsLBAPartition(parttyp) ((parttyp) == FAT12_LBA || \ + (parttyp) == FAT16_LBA || \ + (parttyp) == FAT32_LBA) + #ifdef WITHFAT32 #define IsFATPartition(parttyp) ((parttyp) == FAT12 || \ (parttyp) == FAT16SMALL || \ @@ -221,8 +275,6 @@ struct PartTableEntry /* INTERNAL representation of partition table entry */ internal global data */ -UBYTE GlobalEnableLBAsupport = 1; /* = 0 --> disable LBA support */ - COUNT init_readdasd(UBYTE drive) { static iregs regs; @@ -266,37 +318,31 @@ floppy_bpb floppy_bpbs[5] = { COUNT init_getdriveparm(UBYTE drive, bpb FAR *pbpbarray) { static iregs regs; + REG UBYTE type; if (drive & 0x80) return 5; regs.a.b.h = 0x08; regs.d.b.l = drive; init_call_intr(0x13,®s); + type = regs.b.b.l - 1; if (regs.flags & 1) - return 0; /* return 320-360 for XTs */ + type = 0; /* return 320-360 for XTs */ + else if (type > 6) + type = 8; /* any odd ball drives get 8&7=0: the 320-360 table */ + else if (type == 5) + type = 4; /* 5 and 4 are both 2.88 MB */ + + fmemcpy(pbpbarray, &floppy_bpbs[type & 7], sizeof(floppy_bpb)); - 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; + if (type == 3) + return 7; /* 1.44 MB */ + + if (type == 4) + return 9; /* 2.88 almost forgot this one*/ + + /* 0=320-360kB, 1=1.2MB, 2=720kB, 8=any odd ball drives */ + return type; } /* @@ -363,6 +409,7 @@ VOID CalculateFATData(ddt FAR *pddt, ULONG NumSectors, UBYTE FileSystem) switch(FileSystem) { case FAT12: + case FAT12_LBA: /* in DOS, FAT12 defaults to 4096kb (8 sector) - clusters. */ defbpb->bpb_nsector = 8; /* Force maximal fatdata=32696 sectors since with our only possible sector @@ -502,6 +549,11 @@ void DosDefinePartition(struct DriveParamS *driveParam, pddt->ddt_driveno = driveParam->driveno; pddt->ddt_logdriveno = nUnits; pddt->ddt_LBASupported = driveParam->LBA_supported; + /* Turn of LBA if not forced and the partition is within 1023 cyls and of the right type */ + /* the FileSystem type was internally converted to LBA_xxxx if a non-LBA partition + above cylinder 1023 was found */ + if (!InitKernelConfig.ForceLBA && !IsLBAPartition(pEntry->FileSystem)) + pddt->ddt_LBASupported = FALSE; pddt->ddt_WriteVerifySupported = driveParam->WriteVerifySupported; pddt->ddt_ncyl = driveParam->chs.Cylinder; @@ -576,7 +628,7 @@ int LBA_Get_Drive_Parameters(int drive,struct DriveParamS *driveParam) /* for tests - disable LBA support, even if exists */ - if (!GlobalEnableLBAsupport) + if (!InitKernelConfig.GlobalEnableLBAsupport) { goto StandardBios; } @@ -611,6 +663,7 @@ int LBA_Get_Drive_Parameters(int drive,struct DriveParamS *driveParam) LBA_WRITE_VERIFY = 0x4301; + memset(&lba_bios_parameters, 0, sizeof(lba_bios_parameters)); lba_bios_parameters.size = sizeof(lba_bios_parameters); @@ -637,7 +690,7 @@ int LBA_Get_Drive_Parameters(int drive,struct DriveParamS *driveParam) drive, (ULONG)lba_bios_parameters.heads, (ULONG)lba_bios_parameters.sectors, - (ULONG)lba_bios_parameters.sectors, + (ULONG)lba_bios_parameters.totalSect, (ULONG)lba_bios_parameters.totalSectHigh); goto StandardBios; @@ -751,6 +804,8 @@ ScanForPrimaryPartitions(struct DriveParamS *driveParam,int scan_type, int i; struct CHS chs,end; ULONG partitionStart; + char partitionName[12]; + for (i = 0; i < 4; i++,pEntry++) { @@ -775,6 +830,12 @@ ScanForPrimaryPartitions(struct DriveParamS *driveParam,int scan_type, continue; } + + + if (extendedPartNo) sprintf(partitionName, "Ext:%d", extendedPartNo); + else sprintf(partitionName, "Pri:%d",i+1); + + /* some sanity checks, that partition structure is OK @@ -792,8 +853,8 @@ ScanForPrimaryPartitions(struct DriveParamS *driveParam,int scan_type, chs.Head != pEntry->Begin.Head || chs.Sector != pEntry->Begin.Sector ) { - printf("WARNING: using suspect partition %u FS %02x:", - i, pEntry->FileSystem); + printf("WARNING: using suspect partition %s FS %02x:", + partitionName, pEntry->FileSystem); printCHS(" with calculated values ",&chs); printCHS(" instead of ",&pEntry->Begin); printf("\n"); @@ -809,12 +870,12 @@ ScanForPrimaryPartitions(struct DriveParamS *driveParam,int scan_type, { if (pEntry->NumSect == 0) { - printf("Not using partition %u with 0 sectors\n", i); + printf("Not using partition %s with 0 sectors\n", partitionName); continue; } - printf("WARNING: using suspect partition %u FS %02x:", - i, pEntry->FileSystem); + printf("WARNING: using suspect partition %s FS %02x:", + partitionName, pEntry->FileSystem); printCHS(" with calculated values ",&end); printCHS(" instead of ",&pEntry->End); @@ -825,12 +886,12 @@ ScanForPrimaryPartitions(struct DriveParamS *driveParam,int scan_type, if (chs.Cylinder > 1023 || end.Cylinder > 1023) - { + { if (!driveParam->LBA_supported) { - printf("can't use LBA partition without LBA support - part %u FS %02x", - i, pEntry->FileSystem); + printf("can't use LBA partition without LBA support - part %s FS %02x", + partitionName, pEntry->FileSystem); printCHS(" start ",&chs); printCHS(", end ", &end); @@ -839,15 +900,29 @@ ScanForPrimaryPartitions(struct DriveParamS *driveParam,int scan_type, continue; } - /* else its a diagnostic message only */ + if (!InitKernelConfig.ForceLBA && !IsLBAPartition(pEntry->FileSystem)) + { + printf("WARNING: Partition ID does not suggest LBA - part %s FS %02x.\n" + "Please run FDISK to correct this - using LBA to access partition.\n", + partitionName, pEntry->FileSystem); + + printCHS(" start ",&chs); + printCHS(", end ", &end); + printf("\n"); + pEntry->FileSystem = (pEntry->FileSystem == FAT12 ? FAT12_LBA : + pEntry->FileSystem == FAT32 ? FAT32_LBA : + /* pEntry->FileSystem == FAT16 ? */ FAT16_LBA); + } + + /* else its a diagnostic message only */ #ifdef DEBUG - printf("found and using LBA partition %u FS %02x", - i, pEntry->FileSystem); + printf("found and using LBA partition %s FS %02x", + partitionName, pEntry->FileSystem); printCHS(" start ",&chs); printCHS(", end ", &end); printf("\n"); #endif - } + } /* diff --git a/kernel/inthndlr.c b/kernel/inthndlr.c index 38d1403..f88365c 100644 --- a/kernel/inthndlr.c +++ b/kernel/inthndlr.c @@ -37,6 +37,9 @@ BYTE *RcsId = "$Id$"; /* * $Log$ + * Revision 1.33 2001/11/13 23:36:45 bartoldeman + * Kernel 2025a final changes. + * * Revision 1.32 2001/11/04 19:47:39 bartoldeman * kernel 2025a changes: see history.txt * @@ -668,9 +671,9 @@ dispatch: BYTE FAR *p; FatGetDrvData(0, - (COUNT FAR *) & r->AX, - (COUNT FAR *) & r->CX, - (COUNT FAR *) & r->DX, + (UCOUNT FAR *) & r->AX, + (UCOUNT FAR *) & r->CX, + (UCOUNT FAR *) & r->DX, (BYTE FAR **) & p); r->DS = FP_SEG(p); r->BX = FP_OFF(p); @@ -683,9 +686,9 @@ dispatch: BYTE FAR *p; FatGetDrvData(r->DL, - (COUNT FAR *) & r->AX, - (COUNT FAR *) & r->CX, - (COUNT FAR *) & r->DX, + (UCOUNT FAR *) & r->AX, + (UCOUNT FAR *) & r->CX, + (UCOUNT FAR *) & r->DX, (BYTE FAR **) & p); r->DS = FP_SEG(p); r->BX = FP_OFF(p); @@ -902,8 +905,9 @@ dispatch: r->AL = 0xFF; CritErrCode = 0x0f; break; - } - dpb->dpb_flags = M_CHANGED; /* force reread of drive BPB/DPB */ + } + flush_buffers(dpb->dpb_unit); + dpb->dpb_flags = M_CHANGED; /* force flush and reread of drive BPB/DPB */ #ifdef WITHFAT32 if (media_check(dpb) < 0 || ISFAT32(dpb)) @@ -951,10 +955,10 @@ dispatch: case 0x36: DosGetFree( r->DL, - (COUNT FAR *) & r->AX, - (COUNT FAR *) & r->BX, - (COUNT FAR *) & r->CX, - (COUNT FAR *) & r->DX); + (UCOUNT FAR *) & r->AX, + (UCOUNT FAR *) & r->BX, + (UCOUNT FAR *) & r->CX, + (UCOUNT FAR *) & r->DX); break; /* Undocumented Get/Set Switchar */ @@ -1105,10 +1109,15 @@ dispatch: /* Device I/O Control */ case 0x44: - rc = DosDevIOctl(r); + rc = DosDevIOctl(r); /* can set critical error code! */ if (rc != SUCCESS) - goto error_exit; + { + r->AX = -rc; + if (rc != DE_DEVICE && rc != DE_ACCESS) + CritErrCode = -rc; + SET_CARRY_FLAG(); + } break; /* Duplicate File Handle */ @@ -1753,6 +1762,7 @@ break_out: dpb = GetDriveDPB(r->DL, &rc); if (rc != SUCCESS) goto error_exit; + flush_buffers(dpbp->dpb_unit); dpb->dpb_flags = M_CHANGED; /* force reread of drive BPB/DPB */ if (media_check(dpb) < 0) @@ -1845,6 +1855,7 @@ break_out: case 0x02: { rebuild_dpb: + flush_buffers(dpbp->dpb_unit); dpb->dpb_flags = M_CHANGED; if (media_check(dpb) < 0) @@ -1953,6 +1964,58 @@ rebuild_dpb: } break; } +#endif +#ifdef WITHLFNAPI + /* FreeDOS LFN helper API functions */ + case 0x74: + { + switch(r->AL) + { + /* Allocate LFN inode */ + case 0x01: + { + r->AX = lfn_allocate_inode(); + break; + } + /* Free LFN inode */ + case 0x02: + { + r->AX = lfn_free_inode(r->BX); + break; + } + /* Setup LFN inode */ + case 0x03: + { + r->AX = lfn_setup_inode(r->BX, r->CX, r->DX); + break; + } + /* Create LFN entries */ + case 0x04: + { + r->AX = lfn_create_entries(r->BX, (lfn_inode_ptr)FP_DS_DX); + break; + } + /* Delete LFN entries */ + case 0x05: + { + r->AX = lfn_remove_entries(r->BX); + break; + } + /* Read next LFN */ + case 0x06: + { + r->AX = lfn_dir_read(r->BX, (lfn_inode_ptr)FP_DS_DX); + break; + } + /* Write SFN pointed by LFN inode */ + case 0x07: + { + r->AX = lfn_dir_write(r->BX); + break; + } + } + break; + } #endif } #ifdef DEBUG diff --git a/kernel/ioctl.c b/kernel/ioctl.c index eeca65d..5f99641 100644 --- a/kernel/ioctl.c +++ b/kernel/ioctl.c @@ -35,6 +35,9 @@ static BYTE *RcsId = "$Id$"; /* * $Log$ + * Revision 1.13 2001/11/13 23:36:45 bartoldeman + * Kernel 2025a final changes. + * * Revision 1.12 2001/11/04 19:47:39 bartoldeman * kernel 2025a changes: see history.txt * @@ -265,7 +268,10 @@ COUNT DosDevIOctl(iregs FAR * r) execrh((request FAR *) & CharReqHdr, s->sft_dev); if (CharReqHdr.r_status & S_ERROR) + { + CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13; return DE_DEVICE; + } if (r->AL == 0x07) { @@ -316,6 +322,7 @@ COUNT DosDevIOctl(iregs FAR * r) if (CharReqHdr.r_status & S_ERROR) { + CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13; return DE_DEVICE; } if (r->AL == 0x08) @@ -407,7 +414,10 @@ COUNT DosDevIOctl(iregs FAR * r) dpbp->dpb_device); if (CharReqHdr.r_status & S_ERROR) + { + CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13; return DE_ACCESS; + } else { r->AL = CharReqHdr.r_unit; diff --git a/kernel/kernel.asm b/kernel/kernel.asm index c0cd5c3..c0ebdff 100644 --- a/kernel/kernel.asm +++ b/kernel/kernel.asm @@ -28,6 +28,9 @@ ; $Id$ ; ; $Log$ +; Revision 1.20 2001/11/13 23:36:45 bartoldeman +; Kernel 2025a final changes. +; ; Revision 1.19 2001/11/04 19:47:39 bartoldeman ; kernel 2025a changes: see history.txt ; @@ -183,6 +186,8 @@ configstart: DLASortByDriveNo db 0 ; sort disks by drive order InitDiskShowDriveAssignment db 1 ; SkipConfigSeconds db 2 ; +ForceLBA db 0 ; +GlobalEnableLBAsupport db 1 ; configend: diff --git a/kernel/lfnapi.c b/kernel/lfnapi.c index 22ea140..b25b5f0 100644 --- a/kernel/lfnapi.c +++ b/kernel/lfnapi.c @@ -2,8 +2,8 @@ /* */ /* lfnapi.c */ /* */ -/* Directory access functions for LFN aid API */ -/* Module is under construction! */ +/* Directory access functions for LFN helper API */ +/* */ /****************************************************************/ #include "portab.h" @@ -13,24 +13,37 @@ static BYTE *lfnaidRcsId = "$Id$"; #endif -#if 0 -#define E_INVLDHNDL -1 -#define E_NOFREEHNDL -2 -#define E_IOERROR -3 -#define E_INVLDDRV -4 +#ifdef WITHLFNAPI -COUNT lfn_allocate_inode() +#define LHE_INVLDHNDL -1 +#define LHE_NOFREEHNDL -2 +#define LHE_IOERROR -3 +#define LHE_INVLDDRV -4 +#define LHE_DAMAGEDFS -5 +#define LHE_NOSPACE -6 +#define LHE_SEEK -7 + +#define lfn(fnp) ((struct lfn_entry FAR *)&(fnp->f_dir)) +#define CHARS_IN_LFN_ENTRY 13 +#define UNICODE_FILLER 0xffff + +COUNT ufstrlen(REG UNICODE FAR *); /* fstrlen for UNICODE strings */ +UBYTE lfn_checksum(UBYTE *); +COUNT extend_dir(f_node_ptr); +COUNT remove_lfn_entries(f_node_ptr fnp); + +COUNT lfn_allocate_inode(VOID) { f_node_ptr fnp = get_f_node(); struct cds FAR *cdsp; - if (fnp == 0) return E_NOFREEHNDL; + if (fnp == 0) return LHE_NOFREEHNDL; cdsp = &CDSp->cds_table[default_drive]; if (cdsp->cdsDpb == 0) { release_f_node(fnp); - return E_INVLDDRV; + return LHE_INVLDDRV; } fnp->f_dpb = cdsp->cdsDpb; @@ -38,110 +51,231 @@ COUNT lfn_allocate_inode() if (media_check(fnp->f_dpb) < 0) { release_f_node(fnp); - return E_INVLDDRV; + return LHE_INVLDDRV; } - fnp->f_dsize = DIRENT_SIZE * fnp->f_dpb->dpb_dirents; - return xlt_fnp(fnp); } COUNT lfn_free_inode(COUNT handle) { f_node_ptr fnp = xlt_fd(handle); - if (fnp == 0 || fnp->f_count <= 0) return E_INVLDHNDL; + if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL; release_f_node(fnp); -} - -COUNT lfn_to_unicode_chunk(UNICODE FAR **nptr, UNICODE FAR **uptr, - UCOUNT *index, COUNT count) -{ - COUNT j; - - for (j = 0; j < count; j++, *uptr++, *index++, *nptr++) - { - **nptr = **uptr; - if (**uptr == 0) return 0; - } - - return 1; -} - -COUNT lfn_to_unicode(UNICODE FAR *name, UBYTE FAR *lfn_entry, UCOUNT *index) -{ - COUNT j; - UNICODE FAR *uptr; - UNICODE FAR *nptr = name; - - uptr = (UNICODE FAR *)&lfn_entry[1]; - if (!lfn_to_unicode_chunk(&nptr, &uptr, index, 5)) return 0; - uptr = (UNICODE FAR *)&lfn_entry[0xe]; - if (!lfn_to_unicode_chunk(&nptr, &uptr, index, 6)) return 0; - uptr = (UNICODE FAR *)&lfn_entry[0x1c]; - if (!lfn_to_unicode_chunk(&nptr, &uptr, index, 2)) return 0; - - return 1; -} - -COUNT lfn_dir_read(COUNT handle, lfn_inode_ptr lip) -{ - COUNT index = 0; /* index of the first non-filled char in the long file - name string */ - ULONG original_diroff; - f_node_ptr fnp = xlt_fd(handle); - if (fnp == 0 || fnp->f_count <= 0) return E_INVLDHNDL; - - if (lfnp->l_dirstart == 0) - { - } - - original_diroff = fnp->f_diroff; - - lip->name[0] = 0; - - while (TRUE) - { - 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)); - lip->l_diroff = fnp->f_diroff; - lip->l_dirstart = fnp->f_dirstart; - break; - } - } - fnp->f_diroff = original_diroff - DIRENT_SIZE; - - while (TRUE) - { - if (fnp->f_diroff == 0) break; - fnp->f_diroff -= 2*DIRENT_SIZE; - 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; - } - - if (lip->name[0] == 0) - { - ConvertName83ToNameSZ(lip->name, lip->l_dir.dir_name); - } return SUCCESS; } +COUNT lfn_setup_inode(COUNT handle, CLUSTER dirstart, ULONG diroff) +{ + f_node_ptr fnp = xlt_fd(handle); + if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL; + + dir_init_fnode(fnp, dirstart); + fnp->f_diroff = diroff; + + return SUCCESS; +} + +BOOL transfer_unicode(UNICODE FAR **dptr, UNICODE FAR **sptr, COUNT count) +{ + COUNT j; + BOOL found_zerro = FALSE; + + for (j = 0; j < count; j++, (*dptr)++, (*sptr)++) + { + if (found_zerro) **dptr = UNICODE_FILLER; + else **dptr = **sptr; + if (**sptr == 0) found_zerro = TRUE; + } + + return found_zerro; +} + +BOOL lfn_to_unicode(UNICODE FAR **name, struct lfn_entry FAR *lep) +{ + UNICODE FAR *ptr; + + ptr = lep->lfn_name0_4; + if (!transfer_unicode(name, &ptr, 5)) return FALSE; + ptr = lep->lfn_name5_10; + if (!transfer_unicode(name, &ptr, 6)) return FALSE; + ptr = lep->lfn_name11_12; + if (!transfer_unicode(name, &ptr, 2)) return FALSE; + + return TRUE; +} + +VOID unicode_to_lfn(UNICODE FAR **name, struct lfn_entry FAR *lep) +{ + UNICODE FAR *ptr; + + ptr = lep->lfn_name0_4; + transfer_unicode(&ptr, name, 5); + ptr = lep->lfn_name5_10; + transfer_unicode(&ptr, name, 6); + ptr = lep->lfn_name11_12; + transfer_unicode(&ptr, name, 2); +} + +COUNT lfn_dir_read(COUNT handle, lfn_inode_ptr lip) +{ + COUNT rc; + UBYTE id = 1, real_id; + UNICODE FAR *lfn_name = lip->name; + ULONG sfn_diroff; + BOOL name_tail = FALSE; + f_node_ptr fnp = xlt_fd(handle); + if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL; + + while (TRUE) + { + rc = dir_read(fnp); + if (rc == 0) return SUCCESS; + else if (rc == DE_SEEK) return LHE_SEEK; + else if (rc == DE_BLKINVLD) return LHE_IOERROR; + if (fnp->f_dir.dir_name[0] != DELETED && fnp->f_dir.dir_attrib != D_LFN) + { + fmemcpy(&lip->l_dir, &fnp->f_dir, sizeof(struct dirent)); + sfn_diroff = fnp->f_diroff; + break; + } + } + fnp->f_diroff = lip->l_diroff; + + fmemset(lip->name, 0, 256 * sizeof(UNICODE)); + while (TRUE) + { + if (fnp->f_diroff == 0) break; + fnp->f_diroff -= 2*DIRENT_SIZE; + rc = dir_read(fnp); + if (rc == DE_BLKINVLD) return LHE_IOERROR; + if (fnp->f_dir.dir_name[0] == DELETED + || fnp->f_dir.dir_attrib != D_LFN) break; + name_tail = lfn_to_unicode(&lfn_name, lfn(fnp)); + real_id = lfn(fnp)->lfn_id; + if (real_id & 0x40) + { + if ((real_id | 0x40) != id) return LHE_DAMAGEDFS; + } + else + { + if (name_tail || real_id != id + || lfn(fnp)->lfn_checksum != lfn_checksum(fnp->f_dir.dir_name)) + return LHE_DAMAGEDFS; + } + } + + fnp->f_diroff = lip->l_diroff = sfn_diroff; + fnp->f_flags.f_dnew = TRUE; + + return SUCCESS; +} + +COUNT lfn_dir_write(COUNT handle) +{ + f_node_ptr fnp = xlt_fd(handle); + if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL; + + if (!dir_write(fnp)) + { + lfn_allocate_inode(); /* protection against dir_write fault + * this must restore things to the state before + * the call */ + /* Yes, it's a hack! */ + return LHE_IOERROR; + } + + return SUCCESS; +} + +COUNT lfn_create_entries(COUNT handle, lfn_inode_ptr lip) +{ + f_node_ptr fnp = xlt_fd(handle); + COUNT entries_needed, free_entries, i, rc; + UNICODE FAR *lfn_name = lip->name; + ULONG sfn_offset; + if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL; + + entries_needed = (ufstrlen(lfn_name) + CHARS_IN_LFN_ENTRY - 1) + / CHARS_IN_LFN_ENTRY + 1; /* We want to create SFN entry too */ + + /* Scan the directory from the very begining for the free directory entries */ + lfn_setup_inode(handle, fnp->f_dirstart, 0); + + free_entries = 0; + while ((rc = dir_read(fnp)) == 1) + { + if (fnp->f_dir.dir_name[0] == DELETED) + { + free_entries++; + if (free_entries == entries_needed) + break; + } + else free_entries = 0; + } + if (rc == DE_BLKINVLD) return LHE_IOERROR; + /* We have reached the end of the directory here. */ + + if (free_entries != entries_needed) free_entries = 0; + while (free_entries != entries_needed) + { + rc = dir_read(fnp); + if (rc == 0) free_entries++; + else if (rc == DE_BLKINVLD) return LHE_IOERROR; + else if (rc == DE_SEEK && extend_dir(fnp) != SUCCESS) + { + lfn_allocate_inode(); /* Another hack. */ + return LHE_IOERROR; + } + } + sfn_offset = fnp->f_diroff; + fnp->f_diroff -= DIRENT_SIZE; + + for (i = entries_needed - 2; i >= 0; i++) + { + lfn_name = &lip->name[i * CHARS_IN_LFN_ENTRY]; + unicode_to_lfn(&lfn_name, lfn(fnp)); + fnp->f_dir.dir_attrib = D_LFN; + if (!dir_write(fnp)) return LHE_IOERROR; + fnp->f_diroff -= DIRENT_SIZE; + } + + fnp->f_diroff = sfn_offset; + + return SUCCESS; +} + +COUNT lfn_remove_entries(COUNT handle) +{ + f_node_ptr fnp = xlt_fd(handle); + if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL; + + if(remove_lfn_entries(fnp) < 0) return LHE_IOERROR; + + return SUCCESS; +} + /* Calculate checksum for the 8.3 name */ -UBYTE lfn_checksum(char *name) +UBYTE lfn_checksum(UBYTE *sfn_name) { UBYTE sum; COUNT i; - for (sum = 0, i = 11; --i >= 0; sum += *name++) + for (sum = 0, i = 11; --i >= 0; sum += *sfn_name++) sum = (sum << 7) | (sum >> 1); return sum; } + +COUNT ufstrlen(REG UNICODE FAR *s) +{ + REG COUNT cnt = 0; + + while (*s++ != 0) + ++cnt; + return cnt; +} + #endif diff --git a/kernel/main.c b/kernel/main.c index 07c41c9..bdf6cc3 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -79,11 +79,14 @@ extern BYTE FAR _HMATextEnd[]; static BYTE *mainRcsId = "$Id$"; #endif -struct _KernelConfig InitKernelConfig = {0}; +struct _KernelConfig InitKernelConfig = {"", 0, 0, 0, 0, 0, 0}; /* * $Log$ + * Revision 1.23 2001/11/13 23:36:45 bartoldeman + * Kernel 2025a final changes. + * * Revision 1.22 2001/11/04 19:47:39 bartoldeman * kernel 2025a changes: see history.txt * diff --git a/kernel/makefile b/kernel/makefile index 5ad94d2..c09fa40 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -5,6 +5,9 @@ # # $Log$ +# Revision 1.2 2001/11/13 23:36:45 bartoldeman +# Kernel 2025a final changes. +# # Revision 1.1 2001/11/04 20:10:15 bartoldeman # Added new makefile names, utils sources, kconfig.h # @@ -137,31 +140,13 @@ # $EndLog$ # -!include "..\config.mak" +!include "..\mkfiles\generic.mak" RELEASE = 1.00 -# Compiler and Options for Borland C++ -# ------------------------------------ -# -# -zAname ¦ ¦ Code class -# -zBname ¦ ¦ BSS class -# -zCname ¦ ¦ Code segment -# -zDname ¦ ¦ BSS segment -# -zEname ¦ ¦ Far segment -# -zFname ¦ ¦ Far class -# -zGname ¦ ¦ BSS group -# -zHname ¦ ¦ Far group -# -zPname ¦ ¦ Code group -# -zRname ¦ ¦ Data segment -# -zSname ¦ ¦ Data group -# -zTname ¦ ¦ Data class -# -zX ¦«¦ Use default name for "X" - - # Compiler and Options -INCLUDE=$(COMPILERBASE)\include +INCLUDE=..\hdr LIB= $(COMPILERBASE)\lib LIBPATH = . @@ -212,6 +197,7 @@ EXE_dependencies = \ ioctl.obj \ irqstack.obj \ kernel.obj \ + lfnapi.obj \ main.obj \ memmgr.obj \ misc.obj \ @@ -244,18 +230,18 @@ production: ..\bin\kernel.sys copy kernel.map ..\bin\$(THETARGET).map kernel.sys: kernel.exe ..\utils\exeflat.exe - ..\utils\exeflat kernel.exe kernel.sys 0x60 + ..\utils\exeflat kernel.exe kernel.sys 0x60 -S0x10 -S0x8B clobber: clean - $(RM) kernel.exe kernel.sys status.me + -$(RM) kernel.exe kernel.sys status.me clean: - $(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.cod + -$(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.cod # XXX: This is a very ugly way of linking the kernel, forced upon us by the # inability of Turbo `make' 2.0 to perform command line redirection. -- ror4 kernel.exe: $(EXE_dependencies) $(LIBS) - $(RM) kernel.lib + -$(RM) kernel.lib $(LIBUTIL) kernel.lib $(LIBPLUS)entry.obj $(LIBPLUS)io.obj $(LIBPLUS)blockio.obj $(LIBPLUS)chario.obj $(LIBPLUS)dosfns.obj $(LIBPLUS)console.obj$(LIBTERM) $(LIBUTIL) kernel.lib $(LIBPLUS)printer.obj $(LIBPLUS)serial.obj $(LIBPLUS)dsk.obj $(LIBPLUS)initdisk.obj $(LIBPLUS)error.obj $(LIBPLUS)fatdir.obj $(LIBPLUS)fatfs.obj$(LIBTERM) $(LIBUTIL) kernel.lib $(LIBPLUS)fattab.obj $(LIBPLUS)fcbfns.obj $(LIBPLUS)initoem.obj $(LIBPLUS)initHMA.obj $(LIBPLUS)inthndlr.obj $(LIBPLUS)ioctl.obj $(LIBPLUS)nls_hc.obj$(LIBTERM) @@ -264,9 +250,9 @@ kernel.exe: $(EXE_dependencies) $(LIBS) $(LIBUTIL) kernel.lib $(LIBPLUS)systime.obj $(LIBPLUS)task.obj $(LIBPLUS)int2f.obj $(LIBPLUS)irqstack.obj $(LIBPLUS)apisupt.obj$(LIBTERM) $(LIBUTIL) kernel.lib $(LIBPLUS)asmsupt.obj $(LIBPLUS)execrh.obj $(LIBPLUS)nlssupt.obj $(LIBPLUS)procsupt.obj $(LIBPLUS)break.obj$(LIBTERM) $(LIBUTIL) kernel.lib $(LIBPLUS)dosidle.obj $(LIBPLUS)dyndata.obj $(LIBPLUS)dyninit.obj $(LIBPLUS)rtlsupt.obj $(LIBTERM) - $(RM) kernel.bak - $(LINK) kernel iprf,kernel,kernel,kernel+$(LIBS)$(LINKTERM) - $(RM) kernel.lib + -$(RM) kernel.bak + $(LINK) kernel iprf,kernel,kernel,kernel+$(LIBS); + -$(RM) kernel.lib # *Individual File Dependencies* kernel.obj: kernel.asm segs.inc @@ -306,7 +292,7 @@ dosidle.obj: dosidle.asm segs.inc INITHEADERS=init-mod.h init-dat.h -CONFIGURATION = turboc.cfg makefile ..\config.mak ..\mkfiles\$(COMPILER).MAK +CONFIGURATION = turboc.cfg makefile ..\mkfiles\generic.mak ..\mkfiles\$(COMPILER).MAK HEADERS=\ $(HDR)portab.h $(HDR)device.h $(HDR)mcb.h $(HDR)pcb.h \ @@ -348,6 +334,8 @@ memmgr.obj: memmgr.c $(HEADERS) $(CONFIGURATION) misc.obj: misc.c $(HEADERS) $(CONFIGURATION) +lfnapi.obj: lfnapi.c $(HEADERS) $(CONFIGURATION) + newstuff.obj: newstuff.c $(HEADERS) $(CONFIGURATION) network.obj: network.c $(HEADERS) $(CONFIGURATION) @@ -399,23 +387,16 @@ initdisk.obj: initdisk.c $(INITHEADERS) $(HEADERS) $(CONFIGURATION) $(CC) $(INITCFLAGS) -c $*.c $(PATCHOBJ) $*.obj $(INITPATCH) +#the printf for INIT_TEXT - yet another special case, this file includes prf.c +iprf.obj: iprf.c prf.c $(HDR)\portab.h $(CONFIGURATION) + $(CC) $(INITCFLAGS) -c $*.c + $(PATCHOBJ) $*.obj $(INITPATCH) -# $(CC) $(CFLAGS) -c $*.c -# patchobj $*.obj _DATA=DYN_DATA DATA=DYN_DATA CODE=HMA CONST=DCONST - +#dynamic NEAR data dyndata.obj: dyndata.c dyndata.h $(CC) $(DYNCFLAGS) -c $*.c $(PATCHOBJ) $*.obj $(DYNPATCH) -#the printf for INIT_TEXT - yet another special case -# $(CC) -D_INIT $(INITCFLAGS) -Foiprf.obj -c prf.c -# patchobj Iprf.obj $(INITPATCH) - -iprf.obj: prf.c $(HDR)\portab.h $(CONFIGURATION) - $(CC) -D_INIT $(IPRFCFLAGS) -c prf.c - $(PATCHOBJ) iprf.obj $(INITPATCH) - - diff --git a/kernel/newstuff.c b/kernel/newstuff.c index 00a31c4..aeb9ac4 100644 --- a/kernel/newstuff.c +++ b/kernel/newstuff.c @@ -31,6 +31,9 @@ static BYTE *mainRcsId = "$Id$"; /* * $Log$ + * Revision 1.15 2001/11/13 23:36:45 bartoldeman + * Kernel 2025a final changes. + * * Revision 1.14 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -529,7 +532,7 @@ COUNT ASMCFUNC truename(char FAR * src, char FAR * dest, COUNT t) break; } if (c == '.') { - *(bufp++) = '.'; + if (src[i+1] != '.' && i+1 < seglen) *(bufp++) = '.'; copylen = 0; state = 2; /* Copy extension next */ break; @@ -543,7 +546,7 @@ COUNT ASMCFUNC truename(char FAR * src, char FAR * dest, COUNT t) } break; case 1: /* Looking for dot so we can copy exten */ - if (src[i] == '.') { + if (src[i] == '.' && src[i+1] != '.' && i+1 < seglen) { *(bufp++) = '.'; state = 2; } diff --git a/kernel/proto.h b/kernel/proto.h index 0fe04b5..db393b7 100644 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -34,6 +34,9 @@ static BYTE *Proto_hRcsId = "$Id$"; /* * $Log$ + * Revision 1.24 2001/11/13 23:36:45 bartoldeman + * Kernel 2025a final changes. + * * Revision 1.23 2001/11/04 19:47:39 bartoldeman * kernel 2025a changes: see history.txt * @@ -250,7 +253,7 @@ COUNT DosOpen(BYTE FAR * fname, COUNT mode); COUNT DosOpenSft(BYTE * fname, COUNT mode); COUNT DosClose(COUNT hndl); COUNT DosCloseSft(WORD sft_idx); -VOID DosGetFree(UBYTE drive, COUNT FAR * spc, COUNT FAR * navc, COUNT FAR * bps, COUNT FAR * nc); +BOOL DosGetFree(UBYTE drive, UCOUNT FAR * spc, UCOUNT FAR * navc, UCOUNT FAR * bps, UCOUNT FAR * nc); COUNT DosGetExtFree(BYTE FAR *DriveString, struct xfreespace FAR *xfsp); COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s); COUNT DosChangeDir(BYTE FAR * s); @@ -369,7 +372,7 @@ int DosCharInput(VOID); VOID DosDirectConsoleIO(iregs FAR * r); VOID DosCharOutput(COUNT c); VOID DosDisplayOutput(COUNT c); -VOID FatGetDrvData(UCOUNT drive, COUNT FAR * spc, COUNT FAR * bps, COUNT FAR * nc, BYTE FAR ** mdp); +VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps, UCOUNT FAR * nc, BYTE FAR ** mdp); WORD FcbParseFname(int wTestMode, BYTE FAR ** lpFileName, fcb FAR * lpFcb); BYTE FAR *ParseSkipWh(BYTE FAR * lpFileName); BOOL TestCmnSeps(BYTE FAR * lpFileName); @@ -439,6 +442,17 @@ void ASMCFUNC memcpy(REG void * d, REG VOID * s, REG COUNT n); void ASMCFUNC fmemset(REG VOID FAR * s, REG int ch, REG COUNT n); void ASMCFUNC memset(REG VOID * s, REG int ch, REG COUNT n); +/* lfnapi.c */ +COUNT lfn_allocate_inode(VOID); +COUNT lfn_free_inode(COUNT handle); + +COUNT lfn_setup_inode(COUNT handle, CLUSTER dirstart, ULONG diroff); + +COUNT lfn_create_entries(COUNT handle, lfn_inode_ptr lip); +COUNT lfn_remove_entries(COUNT handle); + +COUNT lfn_dir_read(COUNT handle, lfn_inode_ptr lip); +COUNT lfn_dir_write(COUNT handle); /* nls.c */ BYTE DosYesNo(unsigned char ch); diff --git a/lib/makefile b/lib/makefile index 50858a8..012d12c 100644 --- a/lib/makefile +++ b/lib/makefile @@ -5,6 +5,9 @@ # # $Log$ +# Revision 1.2 2001/11/13 23:36:45 bartoldeman +# Kernel 2025a final changes. +# # Revision 1.1 2001/11/04 20:10:15 bartoldeman # Added new makefile names, utils sources, kconfig.h # @@ -40,18 +43,18 @@ # Improved by jprice # -!include "..\config.mak" +!include "..\mkfiles\generic.mak" -libm.lib: $(CLIB) ..\config.mak - $(RM) libm.lib +libm.lib: $(CLIB) + -$(RM) libm.lib $(LIBUTIL) $(CLIB) $(MATH_EXTRACT) $(LIBTERM) $(LIBUTIL) libm $(MATH_INSERT) $(LIBTERM) - $(RM) *.OBJ + -$(RM) *.OBJ clobber: clean - $(RM) libm.lib status.me + -$(RM) libm.lib status.me clean: - $(RM) *.obj *.bak + -$(RM) *.obj *.bak diff --git a/mkfiles/bc5.mak b/mkfiles/bc5.mak index 6c3393d..13a3c8a 100644 --- a/mkfiles/bc5.mak +++ b/mkfiles/bc5.mak @@ -6,15 +6,16 @@ COMPILERPATH=$(BC5_BASE) COMPILERBIN=$(COMPILERPATH)\bin -CC=$(COMPILERBIN)\tcc -CFLAGST=-mt -lt -a- -k- -f- -ff- -O -Z -d -CFLAGSC=-a- -mc +CC=$(COMPILERBIN)\bcc INCLUDEPATH=$(COMPILERPATH)\include LIBUTIL=$(COMPILERBIN)\tlib LIBPATH=$(COMPILERPATH)\lib LIBTERM= LIBPLUS=+ +CFLAGST=-L$(LIBPATH) -mt -lt -a- -k- -f- -ff- -O -Z -d +CFLAGSC=-L$(LIBPATH) -a- -mc + TARGET=KBC # used for building the library @@ -45,9 +46,7 @@ MATH_INSERT=+H_LDIV +H_LLSH +H_LURSH +N_LXMUL +F_LXMUL +H_LRSH # # ALLCFLAGS specified by turbo.cfg and config.mak # -ALLCFLAGS = $(TARGETOPT) $(ALLCFLAGS) -INITCFLAGS = $(ALLCFLAGS) -zAINIT -zCINIT_TEXT -zDIB -zRID -zTID -zPIGROUP -zBIB -zGIGROUP -zSIGROUP -CFLAGS = $(ALLCFLAGS) -zAHMA -zCHMA_TEXT -DYNCFLAGS = $(ALLCFLAGS) -zRDYN_DATA -zTDYN_DATA -zDDYN_DATA -zBDYN_DATA -IPRFCFLAGS = $(INITCFLAGS) -oiprf.obj - +ALLCFLAGS=$(TARGETOPT) $(ALLCFLAGS) +INITCFLAGS=$(ALLCFLAGS) -zAINIT -zCINIT_TEXT -zDIB -zRID -zTID -zPIGROUP -zBIB -zGIGROUP -zSIGROUP +CFLAGS=$(ALLCFLAGS) -zAHMA -zCHMA_TEXT +DYNCFLAGS=$(ALLCFLAGS) -zRDYN_DATA -zTDYN_DATA -zDDYN_DATA -zBDYN_DATA diff --git a/mkfiles/generic.mak b/mkfiles/generic.mak index 2e01e3a..486e70a 100644 --- a/mkfiles/generic.mak +++ b/mkfiles/generic.mak @@ -1,3 +1,5 @@ +# These are generic definitions + #********************************************************************** #* TARGET : we create a %TARGET%.sys file #* TARGETOPT : options, handled down to the compiler @@ -5,27 +7,26 @@ TARGETOPT=-1- -!if $(XCPU)+1 != 1 !if $(XCPU) == 186 TARGETOPT=-1 !endif !if $(XCPU) == 386 TARGETOPT=-3 !endif -!endif -!if $(XFAT)+1 != 1 !if $(XFAT) == 32 ALLCFLAGS=$(ALLCFLAGS) -DWITHFAT32 !endif -!endif +NASM=$(XNASM) !if $(XCPU) == 386 NASMFLAGS = $(NASMFLAGS) -i../hdr/ -DI386 !else NASMFLAGS = $(NASMFLAGS) -i../hdr/ !endif +LINK=$(XLINK) + PATCHOBJ=@rem INITPATCH = CODE=INIT _DATA=IDATA DATA=ID BSS=ID DGROUP=IGROUP CONST=IC STDPATCH = CODE=HMA CONST=DCONST @@ -34,8 +35,7 @@ DYNPATCH = _DATA=DYN_DATA DATA=DYN_DATA CODE=HMA CONST=DCONST !include "..\mkfiles\$(COMPILER).mak" THETARGET=$(TARGET)$(XCPU)$(XFAT) -# These are generic definitions -RM=-del +RM=..\utils\rmfiles .asm.obj : $(NASM) $(NASMFLAGS) -f obj $*.asm diff --git a/mkfiles/mscl8.mak b/mkfiles/mscl8.mak index 64498c2..756d1b2 100644 --- a/mkfiles/mscl8.mak +++ b/mkfiles/mscl8.mak @@ -7,13 +7,16 @@ COMPILERPATH=$(MS_BASE) COMPILERBIN=$(COMPILERPATH)\bin INCLUDEPATH=$(COMPILERPATH)\include CC=$(COMPILERBIN)\cl -CFLAGST = /Fm /AS /Os ???? -CFLAGSC=-a- -mc ???? -LIBUTIL=$(COMPILERBIN)\lib /nologo +CFLAGST=/Fm /AT /Os +CFLAGSC=/Fm /AL /Os LIBPATH=$(COMPILERPATH)\lib +LIB=$(COMPILERPATH)\lib +INCLUDE=$(COMPILERPATH)\include LIBUTIL=$(COMPILERBIN)\lib /nologo +LIBPLUS=+ LIBTERM=; - +INCLUDE=$(COMPILERPATH)\include +LIB=$(COMPILERPATH)\lib # used for building the library @@ -21,12 +24,13 @@ CLIB=$(COMPILERPATH)\lib\slibce.lib MATH_EXTRACT=*aflmul *aFlshl *aFNauldi *aFulrem *aFulshr *aFuldiv *aFlrem *aFldiv MATH_INSERT= +aflmul +aFlshl +aFNauldi +aFulrem +aFulshr +aFuldiv +aFlrem +aFldiv +TARGETOPT= !if $(XCPU) == 186 TARGETOPT=-G1 -!end +!endif !if $(XCPU) == 386 TARGETOPT=-G3 -!end +!endif TARGET=KMS @@ -34,9 +38,8 @@ TARGET=KMS # heavy stuff - building -ALLCFLAGS = -I..\hdr $(TARGETOPT) $(ALLCFLAGS) -nologo -c -Zl -Fc -Zp1 -Gs -Os -WX -INITCFLAGS = $(ALLCFLAGS) -NTINIT_TEXT -AT -CFLAGS = $(ALLCFLAGS) -NTHMA_TEXT -DYNCFLAGS = $(ALLCFLAGS) -NTHMA_TEXT -IPRFCFLAGS = $(INITCFLAGS) -Foiprf.obj -PATCHOBJ = patchobj +ALLCFLAGS=-I..\hdr $(TARGETOPT) $(ALLCFLAGS) -nologo -Zl -Fc -Zp1 -Gs -Os -WX +INITCFLAGS=$(ALLCFLAGS) -NTINIT_TEXT -AT +CFLAGS=$(ALLCFLAGS) -NTHMA_TEXT +DYNCFLAGS=$(ALLCFLAGS) -NTHMA_TEXT +PATCHOBJ=patchobj diff --git a/mkfiles/tc2.mak b/mkfiles/tc2.mak index 1a938ab..290d97b 100644 --- a/mkfiles/tc2.mak +++ b/mkfiles/tc2.mak @@ -7,14 +7,15 @@ COMPILERPATH=$(TC2_BASE) COMPILERBIN=$(COMPILERPATH) CC=$(COMPILERBIN)\tcc -CFLAGST=-mt -lt -a- -k- -f- -ff- -O -Z -d -CFLAGSC=-a- -mc INCLUDEPATH=$(COMPILERPATH)\include LIBUTIL=$(COMPILERBIN)\tlib LIBPATH=$(COMPILERPATH)\lib LIBTERM= LIBPLUS=+ +CFLAGST=-L$(LIBPATH) -mt -lt -a- -k- -f- -ff- -O -Z -d +CFLAGSC=-L$(LIBPATH) -a- -mc + TARGET=KTC # used for building the library @@ -45,12 +46,7 @@ MATH_INSERT=+LDIV +LXMUL +LURSH +LLSH +LRSH # # ALLCFLAGS specified by turbo.cfg and config.mak # -ALLCFLAGS = $(TARGETOPT) $(ALLCFLAGS) -INITCFLAGS = $(ALLCFLAGS) -zAINIT -zCINIT_TEXT -zDIB -zRID -zTID -zPIGROUP -zBIB -zGIGROUP -zSIGROUP -CFLAGS = $(ALLCFLAGS) -zAHMA -zCHMA_TEXT -DYNCFLAGS = $(ALLCFLAGS) -zRDYN_DATA -zTDYN_DATA -zDDYN_DATA -zBDYN_DATA -IPRFCFLAGS = $(INITCFLAGS) -oiprf.obj - - - - +ALLCFLAGS=$(TARGETOPT) $(ALLCFLAGS) +INITCFLAGS=$(ALLCFLAGS) -zAINIT -zCINIT_TEXT -zDIB -zRID -zTID -zPIGROUP -zBIB -zGIGROUP -zSIGROUP +CFLAGS=$(ALLCFLAGS) -zAHMA -zCHMA_TEXT +DYNCFLAGS=$(ALLCFLAGS) -zRDYN_DATA -zTDYN_DATA -zDDYN_DATA -zBDYN_DATA diff --git a/mkfiles/tc3.mak b/mkfiles/tc3.mak index 2740121..18c1850 100644 --- a/mkfiles/tc3.mak +++ b/mkfiles/tc3.mak @@ -7,14 +7,15 @@ COMPILERPATH=$(TC3_BASE) COMPILERBIN=$(COMPILERPATH)\bin CC=$(COMPILERBIN)\tcc -CFLAGST=-mt -lt -a- -k- -f- -ff- -O -Z -d -CFLAGSC=-a- -mc INCLUDEPATH=$(COMPILERPATH)\include LIBUTIL=$(COMPILERBIN)\tlib LIBPATH=$(COMPILERPATH)\lib LIBTERM= LIBPLUS=+ +CFLAGST=-L$(LIBPATH) -mt -lt -a- -k- -f- -ff- -O -Z -d +CFLAGSC=-L$(LIBPATH) -a- -mc + TARGET=KT3 # used for building the library @@ -45,9 +46,7 @@ MATH_INSERT=+H_LDIV +H_LLSH +H_LURSH +N_LXMUL +F_LXMUL +H_LRSH # # ALLCFLAGS specified by turbo.cfg and config.mak # -ALLCFLAGS = $(TARGETOPT) $(ALLCFLAGS) -INITCFLAGS = $(ALLCFLAGS) -zAINIT -zCINIT_TEXT -zDIB -zRID -zTID -zPIGROUP -zBIB -zGIGROUP -zSIGROUP -CFLAGS = $(ALLCFLAGS) -zAHMA -zCHMA_TEXT -DYNCFLAGS = $(ALLCFLAGS) -zRDYN_DATA -zTDYN_DATA -zDDYN_DATA -zBDYN_DATA -IPRFCFLAGS = $(INITCFLAGS) -oiprf.obj - +ALLCFLAGS=$(TARGETOPT) $(ALLCFLAGS) +INITCFLAGS=$(ALLCFLAGS) -zAINIT -zCINIT_TEXT -zDIB -zRID -zTID -zPIGROUP -zBIB -zGIGROUP -zSIGROUP +CFLAGS=$(ALLCFLAGS) -zAHMA -zCHMA_TEXT +DYNCFLAGS=$(ALLCFLAGS) -zRDYN_DATA -zTDYN_DATA -zDDYN_DATA -zBDYN_DATA diff --git a/mkfiles/turbocpp.mak b/mkfiles/turbocpp.mak index a6c45b7..7187111 100644 --- a/mkfiles/turbocpp.mak +++ b/mkfiles/turbocpp.mak @@ -7,14 +7,15 @@ COMPILERPATH=$(TP1_BASE) COMPILERBIN=$(COMPILERPATH)\bin CC=$(COMPILERBIN)\tcc -CFLAGST=-mt -lt -a- -k- -f- -ff- -O -Z -d -CFLAGSC=-a- -mc INCLUDEPATH=$(COMPILERPATH)\include LIBUTIL=$(COMPILERBIN)\tlib LIBPATH=$(COMPILERPATH)\lib LIBTERM= LIBPLUS=+ +CFLAGST=-L$(LIBPATH) -mt -lt -a- -k- -f- -ff- -O -Z -d +CFLAGSC=-L$(LIBPATH) -a- -mc + TARGET=KTP # used for building the library @@ -45,8 +46,7 @@ MATH_INSERT=+H_LDIV +F_LXMUL +H_LURSH +H_LLSH +H_LRSH # # ALLCFLAGS specified by turbo.cfg and config.mak # -ALLCFLAGS = $(TARGETOPT) $(ALLCFLAGS) -INITCFLAGS = $(ALLCFLAGS) -zAINIT -zCINIT_TEXT -zDIB -zRID -zTID -zPIGROUP -zBIB -zGIGROUP -zSIGROUP -CFLAGS = $(ALLCFLAGS) -zAHMA -zCHMA_TEXT -DYNCFLAGS = $(ALLCFLAGS) -zRDYN_DATA -zTDYN_DATA -zDDYN_DATA -zBDYN_DATA -IPRFCFLAGS = $(INITCFLAGS) -oiprf.obj +ALLCFLAGS=$(TARGETOPT) $(ALLCFLAGS) +INITCFLAGS=$(ALLCFLAGS) -zAINIT -zCINIT_TEXT -zDIB -zRID -zTID -zPIGROUP -zBIB -zGIGROUP -zSIGROUP +CFLAGS=$(ALLCFLAGS) -zAHMA -zCHMA_TEXT +DYNCFLAGS=$(ALLCFLAGS) -zRDYN_DATA -zTDYN_DATA -zDDYN_DATA -zBDYN_DATA diff --git a/mkfiles/watcom.mak b/mkfiles/watcom.mak index 5b5dca6..ac61955 100644 --- a/mkfiles/watcom.mak +++ b/mkfiles/watcom.mak @@ -1,16 +1,12 @@ # -# WATCOM.MAK - kernel copiler options for MS CL8 = MSVC1.52 +# WATCOM.MAK - kernel copiler options for WATCOM C 11.0c # # Use these for WATCOM 11.0c -COMPILERPATH=$(WC_BASE) -COMPILERBIN=$(WC_BASE)\binw +COMPILERPATH=$(WATCOM) +COMPILERBIN=$(WATCOM)\binw CC=$(COMPILERBIN)\wcl -CFLAGST=-mt -CFLAGSC=-mc INCLUDEPATH=$(COMPILERPATH)\H -WATCOM=$(COMPILERPATH) -PATH=$(COMPILERPATH)\binnt;$(COMPILERPATH)\binw INCLUDE=$(COMPILERPATH)\h EDPATH=$(COMPILERPATH)\EDDAT @@ -20,15 +16,16 @@ TARGETOPT=-0 !endif !endif -TARGET=KWC - -LINKTERM=; - -LIBPATH=$(COMPILERPATH)\lib +LIBPATH=$(COMPILERPATH)\lib286 LIBUTIL=$(COMPILERBIN)\wlib LIBPLUS= LIBTERM= +CFLAGST=-mt +CFLAGSC=-zp=1 -mc + +TARGET=KWC + # used for building the library CLIB=$(COMPILERPATH)\lib286\dos\clibs.lib @@ -72,9 +69,8 @@ MATH_INSERT= +i4d +i4m # -3 optimization for 386 - given in CONFIG.MAK, not here # -ALLCFLAGS = $(TARGETOPT) $(ALLCFLAGS) -c -zq -os -ms -s -e=5 -j -zl -zp=1 -INITCFLAGS = $(ALLCFLAGS) -nt=INIT_TEXT -nc=INIT -g=IGROUP -CFLAGS = $(ALLCFLAGS) -nt=HMA_TEXT -nc=HMA -g=HGROUP -DYNCFLAGS = $(ALLCFLAGS) -IPRFCFLAGS = $(INITCFLAGS) -Foiprf.obj +ALLCFLAGS=-I..\hdr $(TARGETOPT) $(ALLCFLAGS) -zq -os -ms -s -e=5 -j -zl -zp=1 +INITCFLAGS=$(ALLCFLAGS) -nt=INIT_TEXT -nc=INIT -g=IGROUP +CFLAGS=$(ALLCFLAGS) -nt=HMA_TEXT -nc=HMA -g=HGROUP +DYNCFLAGS=$(ALLCFLAGS) diff --git a/sys/fdkrncfg.c b/sys/fdkrncfg.c index a68d5e5..d1dd706 100644 --- a/sys/fdkrncfg.c +++ b/sys/fdkrncfg.c @@ -34,8 +34,11 @@ KernelConfig cfg = {0}; typedef unsigned char byte; +typedef signed char sbyte; typedef unsigned short word; +typedef signed short sword; typedef unsigned long dword; +typedef signed long sdword; /* These structures need to be byte packed, if your compiler @@ -48,8 +51,6 @@ typedef unsigned long dword; /* Displays command line syntax */ void showUsage(void) { - - printf("FreeDOS Kernel Configuration %s\n", VERSION); printf("Usage: \n" " %s \n" " %s [/help | /?]\n" @@ -57,15 +58,17 @@ void showUsage(void) PROGRAM, PROGRAM, PROGRAM, KERNEL); printf("\n"); printf(" If no options are given, the current values are shown.\n"); - printf(" %/help or ? displays this usage information.\n" + printf(" /help or /? displays this usage information.\n" " [drive:][path]KERNEL.SYS specifies the kernel file to\n" - " modify, if not given defaults to \\%s\n", + " modify, if not given defaults to %s\n", KERNEL); printf("\n"); printf(" option=value ... specifies one or more options and the values\n" " to set each to. If an option is given multiple times,\n" " the value set will be the rightmost one.\n"); - printf(" Current Options are: DLASORT=0|1, SHOWDRIVEASSIGNMENT=0|1\n"); + printf(" Current Options are: DLASORT=0|1, SHOWDRIVEASSIGNMENT=0|1\n" + " SKIPCONFIGSECONDS=#, FORCELBA=0|1\n" + " GLOBALENABLELBASUPPORT=0|1\n"); } @@ -152,10 +155,22 @@ void displayConfigSettings(KernelConfig *cfg) if (cfg->ConfigSize >= 3) { - printf("SKIPCONFIGSECONDS=%-2d time to wait for F5/F8 : *2 sec\n", + printf("SKIPCONFIGSECONDS=%-3d time to wait for F5/F8 : *2 sec (skip < 0)\n", cfg->SkipConfigSeconds); } + if (cfg->ConfigSize >= 4) + { + printf("FORCELBA=0x%02X Always use LBA if possible: *0=no, 1=yes\n", + cfg->ForceLBA); + } + + if (cfg->ConfigSize >= 5) + { + printf("GLOBALENABLELBASUPPORT=0x%02X Enable LBA support: *1=yes, 0=no\n", + cfg->GlobalEnableLBAsupport); + } + #if 0 /* we assume that SYS is as current as the kernel */ /* Print value any options added that are unknown as hex dump */ @@ -177,16 +192,32 @@ void displayConfigSettings(KernelConfig *cfg) +/* Note: The setXXXOption functions will set the config option of + type XXX to the value given. It will display a warning, but + allow probably invalid values to be used (cause I believe in + letting the user do what they want, not what we guess they mean). + Additionally, we only indicate a change if a new value is used, + to force changes written even if same value is used, use same + option twice, first with a different value & second time with + (same) value desired. kjd +*/ -/* Sets the given location to a byte value if different, +/* Sets the given location to an unsigned byte value if different, displays warning if values exceeds max */ void setByteOption(byte *option, char *value, word max, int *updated, char *name) { - int optionValue; + unsigned long optionValue; - optionValue = atoi(value); - if (optionValue > max) + /* optionValue = atoi(value); Use strtoul instead of atoi/atol as it detect base (0xFF & 255) */ + optionValue = strtoul(value, NULL, 0); + + if (optionValue > 255) + { + printf("Warning: Option %s: Value <0x%02lX> will be truncated!\n", + name, optionValue); + } + if ((byte)optionValue > max) { printf("Warning: Option %s: Value <0x%02X> may be invalid!\n", name, (unsigned int)((byte)optionValue)); @@ -199,6 +230,93 @@ void setByteOption(byte *option, char *value, word max, int *updated, char *name } } +/* Sets the given location to a signed byte value if different, + displays warning if values exceeds max or is less than min +*/ +void setSByteOption(sbyte *option, char *value, sword min, sword max, int *updated, char *name) +{ + signed long optionValue; + + /* optionValue = atoi(value); Use strtol instead of atoi/atol as it detects base */ + optionValue = strtol(value, NULL, 0); + + if ( (optionValue < -128) || (optionValue > 127) ) + { + printf("Warning: Option %s: Value <0x%02lX> will be truncated!\n", + name, optionValue); + } + if ( ((sbyte)optionValue > max) || ((sbyte)optionValue < min) ) + { + printf("Warning: Option %s: Value <0x%02X> may be invalid!\n", + name, (signed int)((byte)optionValue)); + } + /* Don't bother updating if same value */ + if ((sbyte)optionValue != *option) + { + *option = (sbyte)optionValue; + *updated = 1; + } +} + +#if 0 /* disable until there are (un)signed word configuration values */ +/* Sets the given location to an unsigned word value if different, + displays warning if values exceeds max +*/ +void setWordOption(word *option, char *value, dword max, int *updated, char *name) +{ + unsigned long optionValue; + + /* optionValue = atol(value); Use strtoul instead of atoi/atol as it allows 0xFF and 255 */ + optionValue = strtoul(value, NULL, 0); + + if (optionValue > 65535) + { + printf("Warning: Option %s: Value <0x%02lX> will be truncated!\n", + name, optionValue); + } + if ((word)optionValue > max) + { + printf("Warning: Option %s: Value <0x%02X> may be invalid!\n", + name, (unsigned int)optionValue); + } + /* Don't bother updating if same value */ + if ((word)optionValue != *option) + { + *option = (word)optionValue; + *updated = 1; + } +} + +/* Sets the given location to a signed byte value if different, + displays warning if values exceeds max or is less than min +*/ +void setSWordOption(sword *option, char *value, sdword min, sdword max, int *updated, char *name) +{ + signed long optionValue; + + /* optionValue = atol(value); Use strtol instead of atoi/atol as it allows 0xFF and 255 */ + optionValue = strtol(value, NULL, 0); + + if ( (optionValue < -32768) || (optionValue > 32767) ) + { + printf("Warning: Option %s: Value <0x%02lX> will be truncated!\n", + name, optionValue); + } + + if ( ((sword)optionValue > max) || ((sword)optionValue < min) ) + { + printf("Warning: Option %s: Value <0x%02X> may be invalid!\n", + name, (signed int)optionValue); + } + /* Don't bother updating if same value */ + if ((sword)optionValue != *option) + { + *option = (sword)optionValue; + *updated = 1; + } +} +#endif + /* Main, processes command line options and calls above functions as required. @@ -212,7 +330,7 @@ int FDKrnConfigMain(int argc,char **argv) char *cptr; char *argptr; - printf("FreeDOS System configurator %s \n", VERSION); + printf("FreeDOS Kernel Configuration %s\n", VERSION); /* 1st go through and just process arguments (help/filename/etc) */ @@ -243,15 +361,16 @@ int FDKrnConfigMain(int argc,char **argv) argptr = argv[argstart]; - cptr = strchr(argptr, '='); - +#if 0 /* No arguments is acceptable, just displays current settings using default kernel file */ if (argptr == 0) { showUsage(); exit(1); } +#endif + /* the first argument may be the kernel name */ - if (strchr(argptr, '=') == NULL) + if ( (argstart < argc) && (strchr(argptr, '=') == NULL) ) { kfilename = argptr; argstart++; @@ -291,9 +410,18 @@ int FDKrnConfigMain(int argc,char **argv) } else if (memicmp(argptr, "SKIPCONFIGSECONDS",3) == 0) { - setByteOption(&(cfg.SkipConfigSeconds), - cptr, 1, &updates, "SKIPCONFIGSECONDS"); - updates++; + setSByteOption(&(cfg.SkipConfigSeconds), + cptr, -128, 127, &updates, "SKIPCONFIGSECONDS"); + } + else if (memicmp(argptr, "FORCELBA",3) == 0) + { + setByteOption(&(cfg.ForceLBA), + cptr, 1, &updates, "FORCELBA"); + } + else if (memicmp(argptr, "GLOBALENABLELBASUPPORT",3) == 0) + { + setByteOption(&(cfg.GlobalEnableLBAsupport), + cptr, 1, &updates, "GLOBALENABLELBASUPPORT"); } else { @@ -321,7 +449,7 @@ illegal_arg: printf("\nUpdated Kernel settings.\n"); } else - printf("Current Kernel settings.\n"); + printf("\nCurrent Kernel settings.\n"); /* display current settings */ diff --git a/sys/makefile b/sys/makefile index 4d7a787..ffeafd6 100644 --- a/sys/makefile +++ b/sys/makefile @@ -4,6 +4,9 @@ # $Id$ # # $Log$ +# Revision 1.2 2001/11/13 23:36:45 bartoldeman +# Kernel 2025a final changes. +# # Revision 1.1 2001/11/04 20:10:15 bartoldeman # Added new makefile names, utils sources, kconfig.h # @@ -30,7 +33,7 @@ # Improved by jprice # -!include "..\config.mak" +!include "..\mkfiles\generic.mak" CFLAGS = -I$(INCLUDEPATH) -I..\hdr -DFORSYS -DWITHFAT32 $(CFLAGST) NASMFLAGS = -DSYS=1 @@ -49,7 +52,7 @@ SYS_EXE_dependencies = \ production: bin2c.com ..\bin\sys.com bin2c.com: $(BIN2C_EXE_dependencies) - $(CC) $(CFLAGST) -L$(LIBPATH) $(BIN2C_EXE_dependencies) + $(CC) $(CFLAGST) $(BIN2C_EXE_dependencies) ..\bin\sys.com: sys.com copy sys.com ..\bin @@ -69,13 +72,13 @@ prf.obj: ..\kernel\prf.c fdkrncfg.obj: fdkrncfg.c ..\hdr\kconfig.h sys.com: $(SYS_EXE_dependencies) - $(CC) $(CFLAGST) -L$(LIBPATH) $(SYS_EXE_dependencies) + $(CC) $(CFLAGST) $(SYS_EXE_dependencies) clobber: clean - $(RM) bin2c.com sys.com b_fat12.h b_fat16.h b_fat32.h + -$(RM) bin2c.com sys.com b_fat12.h b_fat16.h b_fat32.h clean: - $(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.las status.me + -$(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.las *.cod status.me # *Individual File Dependencies* bin2c.obj: bin2c.c diff --git a/sys/sys.c b/sys/sys.c index c2ed358..354f957 100644 --- a/sys/sys.c +++ b/sys/sys.c @@ -26,9 +26,12 @@ ***************************************************************/ /* $Log$ - * Revision 1.11 2001/11/04 19:47:39 bartoldeman - * kernel 2025a changes: see history.txt + * Revision 1.12 2001/11/13 23:36:45 bartoldeman + * Kernel 2025a final changes. * +/* 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. /* @@ -148,7 +151,7 @@ #define DEBUG /* #define DDEBUG */ -#define SYS_VERSION "v2.2" +#define SYS_VERSION "v2.3" #include #include @@ -175,7 +178,7 @@ BYTE pgm[] = "SYS"; -void put_boot(COUNT); +void put_boot(COUNT, BYTE *, BOOL); BOOL check_space(COUNT, BYTE *); BOOL copy(COUNT drive, BYTE * srcPath, BYTE * rootPath, BYTE * file); COUNT DiskRead(WORD, WORD, WORD, WORD, WORD, BYTE FAR *); @@ -185,8 +188,9 @@ COUNT DiskWrite(WORD, WORD, WORD, WORD, WORD, BYTE FAR *); #define SEC_SIZE 512 #define COPY_SIZE 32768u - - +#ifdef _MSC_VER + #pragma pack(1) +#endif struct bootsectortype { @@ -260,12 +264,20 @@ UBYTE newboot[SEC_SIZE], oldboot[SEC_SIZE]; #define SBSIZE (sizeof(struct bootsectortype) - SBOFFSET) #define SBSIZE32 (sizeof(struct bootsectortype32) - SBOFFSET) +/* essentially - verify alignment on byte boundaries at compile time */ +struct VerifyBootSectorSize +{ + char failure1[sizeof(struct bootsectortype) == 78 ? 1 : -1]; + char failure2[sizeof(struct bootsectortype) == 78 ? 1 : 0]; +}; int FDKrnConfigMain(int argc,char **argv); int main(int argc, char **argv) { COUNT drive; /* destination drive */ + COUNT drivearg = 0; /* drive argument position */ + BYTE *bsFile = NULL; /* user specified destination boot sector */ COUNT srcDrive; /* source drive */ BYTE srcPath[MAXPATH]; /* user specified source drive and/or path */ BYTE rootPath[4]; /* alternate source path to try if not '\0' */ @@ -273,19 +285,18 @@ int main(int argc, char **argv) printf("FreeDOS System Installer " SYS_VERSION "\n\n"); - if (memicmp(argv[1],"CONFIG",6) == 0) + if (argc > 1 && memicmp(argv[1],"CONFIG",6) == 0) { exit(FDKrnConfigMain(argc,argv)); } - if (argc == 2) + srcPath[0] = '\0'; + if (argc > 1 && argv[1][1] == ':' && argv[1][2] == '\0') + drivearg = 1; + + if (argc > 2 && argv[2][1] == ':' && argv[2][2] == '\0') { - drive = toupper(*argv[1]) - 'A'; - srcPath[0] = '\0'; - } - else if (argc == 3) - { - drive = toupper(*argv[2]) - 'A'; + drivearg = 2; strncpy(srcPath, argv[1], MAXPATH-12); /* leave room for COMMAND.COM\0 */ srcPath[MAXPATH-13] = '\0'; @@ -299,14 +310,19 @@ int main(int argc, char **argv) srcPath[slen] = '\0'; } } - else + + if (drivearg == 0) { - 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("Usage: %s [source] drive: [bootsect [BOTH]]\n", pgm); + printf(" source = A:,B:,C:\\KERNEL\\BIN\\,etc., or current directory if not given\n"); + printf(" drive = A,B,etc.\n"); + printf(" bootsect = name of 512-byte boot sector file image for drive:\n"); + printf(" to write to instead of real boot sector\n"); + printf(" BOTH : write to both the real boot sector and the image file\n"); printf("%s CONFIG /help\n",pgm); exit(1); } + drive = toupper(argv[drivearg][0]) - 'A'; if (drive < 0 || drive >= 26) { @@ -353,9 +369,13 @@ int main(int argc, char **argv) printf("\n%s: cannot copy \"COMMAND.COM\"\n", pgm); exit(1); } - + + if (argc > drivearg+1) + bsFile = argv[drivearg+1]; + printf("\nWriting boot sector...\n"); - put_boot(drive); + put_boot(drive, bsFile, + (argc > drivearg+2) && memicmp(argv[drivearg+2], "BOTH", 4) == 0); printf("\nSystem transferred.\n"); return 0; @@ -435,7 +455,7 @@ int MyAbsReadWrite(int DosDrive, int count, ULONG sector, void *buffer, unsigned } -VOID put_boot(COUNT drive) +VOID put_boot(COUNT drive, BYTE *bsFile, BOOL both) { COUNT i, z; WORD head, track, sector, ret; @@ -635,16 +655,43 @@ VOID put_boot(COUNT drive) dump_sector(newboot); #endif + if ((bsFile == NULL) || both) + { + #ifdef DEBUG printf("writing new bootsector to drive %c:\n",drive+'A'); #endif - if (MyAbsReadWrite(drive, 1, 0, newboot,0x26) != 0) + if (MyAbsReadWrite(drive, 1, 0, newboot,0x26) != 0) { - printf("Can't write new boot sector to drive %c:\n", drive +'A'); - exit(1); + printf("Can't write new boot sector to drive %c:\n", drive +'A'); + exit(1); } + } + + if (bsFile != NULL) + { + int fd; + +#ifdef DEBUG + printf("writing new bootsector to file %s\n", bsFile); +#endif + /* write newboot to bsFile */ + if ((fd = open(bsFile, O_RDWR | O_TRUNC | O_CREAT | O_BINARY,S_IREAD|S_IWRITE)) < 0) + { + printf( " %s: can't create\"%s\"\nDOS errnum %d", pgm, bsFile, errno); + exit(1); + } + if (write(fd, newboot, SEC_SIZE) != SEC_SIZE) + { + printf("Can't write %u bytes to %s\n", SEC_SIZE, bsFile); + close(fd); + unlink(bsFile); + exit(1); + } + close(fd); + } } diff --git a/utils/exeflat.c b/utils/exeflat.c index 348e227..779505b 100644 --- a/utils/exeflat.c +++ b/utils/exeflat.c @@ -42,48 +42,12 @@ large portions copied from task.c #define BUFSIZE 32768u -/* JPP - changed so will accept hex number. */ -COUNT our_atoi(REG BYTE * pszString) -{ - BYTE Base = 10; - BOOL Sign = FALSE; - COUNT pnNum = 0; - UCOUNT digit; - if (*pszString == '-') +#define LENGTH(x) (sizeof(x)/sizeof(x[0])) - { - pszString++; - Sign = TRUE; - } - if (pszString[0] == '0' && toupper(pszString[1]) == 'X') - - { - Base = 16; - pszString += 2; - } - for (; isxdigit(*pszString); pszString++) - - { - if (isdigit(pszString[0])) - digit = pszString[0] - '0'; - - else - digit = toupper(pszString[0]) - 'A' + 10; - if (digit > Base) - - { - printf("illegal digit '%s' in offset\n", pszString); - exit(1); - } - pnNum = pnNum * Base + digit; - } - if (Sign) - pnNum = -pnNum; - return pnNum; -} typedef struct { UWORD off, seg; } farptr; + int compReloc(const void *p1, const void *p2) { farptr *r1 = (farptr *) p1; @@ -98,10 +62,20 @@ int compReloc(const void *p1, const void *p2) return -1; return 0; } + +void usage() +{ + printf("usage: exeflat (src.exe) (dest.sys) (relocation-factor)\n"); + printf + (" -S10 - Silent relocate segment 10 (down list)\n"); + + exit(1); +} + int main(int argc, char **argv) { exe_header header; - int i; + int i, j; size_t bufsize; farptr *reloc; UWORD start_seg; @@ -109,51 +83,75 @@ int main(int argc, char **argv) UBYTE **buffers; UBYTE **curbuf; FILE *src, *dest; - if (argc != 4) + short silentSegments[20], silentcount = 0, silentdone = 0; + /* do optional argument processing here */ + for (i = 4; i < argc; i++) { - printf("usage: exeflat (src.exe) (dest.sys) (relocation-factor)\n"); - return 1; - } - if ((src = fopen(argv[1], "rb")) == NULL) + char *argptr = argv[i]; + if (argptr[0] != '-' && argptr[0] != '/') + usage(); + + argptr++; + + switch (toupper(argptr[0])) + { + case 'S': + if (silentcount >= LENGTH(silentSegments)) + { + printf("can't handle more then %d silent's\n", + LENGTH(silentSegments)); + exit(1); + } + + silentSegments[silentcount++] = strtol(argptr + 1, NULL, 0); + break; + + default: + usage(); + } + } + + /* arguments left : + infile outfile relocation offset */ + + if ((src = fopen(argv[1], "rb")) == NULL) { printf("Source file %s could not be opened\n", argv[1]); return 1; } if (fread(&header, sizeof(header), 1, src) != 1) - { printf("Error reading header from %s\n", argv[1]); fclose(src); return 1; } if (header.exSignature != MAGIC) - { printf("Source file %s is not a valid .EXE\n", argv[1]); fclose(src); return 1; } if ((dest = fopen(argv[2], "wb+")) == NULL) - { printf("Destination file %s could not be created\n", argv[2]); return 1; } - start_seg = our_atoi(argv[3]); - printf("header len = %ld = 0x%lx\n", header.exHeaderSize * 16UL, + start_seg = strtol(argv[3], NULL, 0); + printf("header len = %lu = 0x%lx\n", header.exHeaderSize * 16UL, header.exHeaderSize * 16UL); - fseek(src, 0, SEEK_END); - size = ftell(src) - header.exHeaderSize * 16UL; - printf("image size (less header) = %ld = 0x%lx\n", size, size); - printf("first relocation offset = 0 = 0x0\n"); + size = + ((DWORD) (header.exPages - 1) << 9) + header.exExtraBytes - + header.exHeaderSize * 16UL; + printf("image size (less header) = %lu = 0x%lx\n", size, size); + printf("first relocation offset = %u = 0x%u\n", header.exOverlay, + header.exOverlay); /* first read file into memory chunks */ fseek(src, header.exHeaderSize * 16UL, SEEK_SET); buffers = malloc((size + BUFSIZE - 1) / BUFSIZE * sizeof(char *)); if (buffers == NULL) - { printf("Allocation error\n"); return 1; @@ -161,19 +159,16 @@ int main(int argc, char **argv) bufsize = BUFSIZE; for (to_xfer = size, curbuf = buffers; to_xfer > 0; to_xfer -= bufsize, curbuf++) - { if (to_xfer < BUFSIZE) bufsize = to_xfer; *curbuf = malloc(bufsize); if (*curbuf == NULL) - { printf("Allocation error\n"); return 1; } if (fread(*curbuf, sizeof(char), bufsize, src) != bufsize) - { printf("Source file read error %ld %d\n", to_xfer, bufsize); return 1; @@ -182,14 +177,12 @@ int main(int argc, char **argv) fseek(src, header.exRelocTable, SEEK_SET); reloc = malloc(header.exRelocItems * sizeof(farptr)); if (reloc == NULL) - { printf("Allocation error\n"); return 1; } if (fread(reloc, sizeof(farptr), header.exRelocItems, src) != header.exRelocItems) - { printf("Source file read error\n"); return 1; @@ -197,14 +190,24 @@ int main(int argc, char **argv) fclose(src); qsort(reloc, header.exRelocItems, sizeof(reloc[0]), compReloc); for (i = 0; i < header.exRelocItems; i++) - { ULONG spot = ((ULONG) reloc[i].seg << 4) + reloc[i].off; UBYTE *spot0 = &buffers[spot / BUFSIZE][spot % BUFSIZE]; UBYTE *spot1 = &buffers[(spot + 1) / BUFSIZE][(spot + 1) % BUFSIZE]; UWORD segment = ((UWORD) * spot1 << 8) + *spot0; + + for (j = 0; j < silentcount; j++) + if (segment == silentSegments[j]) + { + silentdone++; + goto dontPrint; + } + printf("relocation at 0x%04x:0x%04x ->%04x\n", reloc[i].seg, reloc[i].off, segment); + + dontPrint: + segment += start_seg; *spot0 = segment & 0xff; *spot1 = segment >> 8; @@ -214,7 +217,6 @@ int main(int argc, char **argv) bufsize = BUFSIZE; for (to_xfer = size, curbuf = buffers; to_xfer > 0; to_xfer -= bufsize, curbuf++) - { if (to_xfer < BUFSIZE) bufsize = to_xfer; @@ -225,7 +227,9 @@ int main(int argc, char **argv) return 1; } } + fclose(dest); - printf("\nProcessed %d relocations\n", header.exRelocItems); + printf("\nProcessed %d relocations, %d not shown\n", header.exRelocItems, + silentdone); return 0; } diff --git a/utils/makefile b/utils/makefile index b88a619..20b628b 100644 --- a/utils/makefile +++ b/utils/makefile @@ -1,23 +1,19 @@ -!include "..\config.mak" +!include "..\mkfiles\generic.mak" CFLAGS = -I$(INCLUDEPATH) -I..\hdr production: patchobj.exe exeflat.exe -patchobj.exe: patchobj.obj - $(CC) -L$(LIBPATH) patchobj.obj +patchobj.exe: patchobj.c + $(CC) $(CFLAGST) $(CFLAGS) patchobj.c -exeflat.exe: exeflat.obj - $(CC) -L$(LIBPATH) $(CFLAGSC) exeflat.obj +exeflat.exe: exeflat.c ..\hdr\exe.h + $(CC) $(CFLAGSC) $(CFLAGS) exeflat.c -patchobj.obj: patchobj.c ..\config.mak - -exeflat.obj: exeflat.c ..\hdr\exe.h ..\config.mak - $(CC) $(CFLAGSC) $(CFLAGS) -c exeflat.c clobber: clean $(RM) bin2c.com exeflat.exe patchobj.exe clean: - $(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.las status.me + $(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.las *.cod status.me diff --git a/utils/patchobj.c b/utils/patchobj.c index 74c20dc..478f571 100644 --- a/utils/patchobj.c +++ b/utils/patchobj.c @@ -201,10 +201,10 @@ do { for (s = (unsigned char *)&Outrecord; s < &Outrecord.buffer[Outrecord.datalen]; s++) chksum += *s; - Outrecord.buffer[Outrecord.datalen] = -chksum; + Outrecord.buffer[Outrecord.datalen] = ~chksum; Outrecord.datalen++; - /* printf("^sum = %02x - %02x\n",chksum,-chksum); */ + /* printf("^sum = %02x - %02x\n",chksum,~chksum); */ fwrite(&Outrecord,1,3+Outrecord.datalen,fdo);