From 9c94426d7a3b3d88cf64b179b30a3a2c99539e53 Mon Sep 17 00:00:00 2001 From: Kenneth J Davis Date: Fri, 9 Jul 2004 02:16:31 +0000 Subject: [PATCH] Lucho's kernel with Arkady's changes, initial unstable branch git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/branches/UNSTABLE@988 6ac86273-5f31-0410-b378-82cca8765d1b --- boot/makefile | 28 +- build.bat | 40 +- buildall.bat | 85 +- clean.bat | 30 +- clobber.bat | 39 +- config.b | 177 +-- default.bat | 66 - defaults.bat | 87 ++ drivers/floppy.asm | 200 ++- drivers/makefile | 45 +- filelist | 155 --- hdr/portab.h | 84 +- hdr/stacks.inc | 8 +- hdr/version.h | 6 +- kernel/break.c | 13 +- kernel/config.c | 3059 ++++++++++++++++++------------------------ kernel/config.h | 17 +- kernel/dsk.c | 859 ++++++------ kernel/entry.asm | 2 +- kernel/globals.h | 6 +- kernel/init-mod.h | 65 +- kernel/initoem.c | 72 - kernel/int2f.asm | 7 +- kernel/inthndlr.c | 5 +- kernel/intr.asm | 88 +- kernel/ioctl.c | 382 +++--- kernel/main.c | 426 +++--- kernel/makefile | 211 +-- kernel/msc.cfg | 5 + kernel/nls.c | 24 +- kernel/procsupt.asm | 27 +- kernel/proto.h | 39 +- kernel/segs.inc | 6 +- kernel/task.c | 767 +++++------ kernel/tci.cfg | 7 + kernel/turboc.cfg | 20 +- kernel/vc.cfg | 5 + kernel/wc.cfg | 9 + kernel/wci.cfg | 11 + lib/makefile | 22 +- mkfiles/bc.mak | 10 + mkfiles/bc5.mak | 49 +- mkfiles/generic.mak | 66 +- mkfiles/msc.mak | 31 + mkfiles/mscl8.mak | 60 +- mkfiles/tc.mak | 16 + mkfiles/tc2.mak | 49 +- mkfiles/tc3.mak | 50 +- mkfiles/tcpp.mak | 42 + mkfiles/tcpp3.mak | 7 + mkfiles/turbocpp.mak | 40 +- mkfiles/watcom.mak | 75 +- sys/fdkrncfg.c | 2 +- sys/makefile | 57 +- sys/turboc.cfg | 7 + utils/echoto.bat | 2 +- utils/exeflat.c | 54 +- utils/makefile | 18 +- utils/rmfiles.bat | 1 - utils/turboc.cfg | 7 + utils/wlinker.bat | 6 +- 61 files changed, 3474 insertions(+), 4379 deletions(-) delete mode 100644 default.bat create mode 100644 defaults.bat delete mode 100644 filelist create mode 100644 kernel/msc.cfg create mode 100644 kernel/tci.cfg create mode 100644 kernel/vc.cfg create mode 100644 kernel/wc.cfg create mode 100644 kernel/wci.cfg create mode 100644 mkfiles/bc.mak create mode 100644 mkfiles/msc.mak create mode 100644 mkfiles/tc.mak create mode 100644 mkfiles/tcpp.mak create mode 100644 mkfiles/tcpp3.mak create mode 100644 sys/turboc.cfg create mode 100644 utils/turboc.cfg diff --git a/boot/makefile b/boot/makefile index 0299d17..a2ee089 100644 --- a/boot/makefile +++ b/boot/makefile @@ -4,26 +4,28 @@ # $Id$ # - !include "../mkfiles/generic.mak" -production: fat12com.bin fat16com.bin fat32chs.bin fat32lba.bin +######################################################################## -fat12com.bin: boot.asm - $(NASM) -dISFAT12 boot.asm -ofat12com.bin +all: fat12.bin fat16.bin fat32chs.bin fat32lba.bin -fat16com.bin: boot.asm - $(NASM) -dISFAT16 boot.asm -ofat16com.bin +fat12.bin: boot.asm $(DEPENDS) + $(NASM) -DISFAT12 boot.asm -o$*.bin -fat32chs.bin: boot32.asm - $(NASM) boot32.asm -ofat32chs.bin +fat16.bin: boot.asm $(DEPENDS) + $(NASM) -DISFAT16 boot.asm -o$*.bin -fat32lba.bin: boot32lb.asm - $(NASM) boot32lb.asm -ofat32lba.bin +fat32chs.bin: boot32.asm $(DEPENDS) + $(NASM) boot32.asm -o$*.bin -clobber: clean - -$(RM) *.bin status.me +fat32lba.bin: boot32lb.asm $(DEPENDS) + $(NASM) boot32lb.asm -o$*.bin + +######################################################################## clean: - -$(RM) *.lst *.map *.bak *.obj + -$(RM) *.bak *.cod *.crf *.err *.las *.lst *.map *.obj *.xrf +clobber: clean + -$(RM) *.bin status.me diff --git a/build.bat b/build.bat index 75a0e22..29eba7a 100644 --- a/build.bat +++ b/build.bat @@ -3,18 +3,22 @@ :- batch file to build everything :- $Id$ +:----------------------------------------------------------------------- :- Syntax: BUILD [-r] [fat32|fat16] [msc|wc|tc|tcpp] [86|186|386] :- option case is significant !! +:----------------------------------------------------------------------- + +set XERROR=1 +if "%XERROR%" == "" goto noenv if "%1" == "-r" call clobber.bat if "%1" == "-r" shift -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 abort call config.bat +if "%LAST%" == "" goto noenv :----------------------------------------------------------------------- :- following is command line handling @@ -26,10 +30,10 @@ call config.bat if "%1" == "fat32" set XFAT=32 if "%1" == "fat16" set XFAT=16 -if "%1" == "msc" set COMPILER=MSCL8 +if "%1" == "msc" set COMPILER=MSC if "%1" == "wc" set COMPILER=WATCOM -if "%1" == "tc" set COMPILER=TC2 -if "%1" == "tcpp" set COMPILER=TURBOCPP +if "%1" == "tc" set COMPILER=TC +if "%1" == "tcpp" set COMPILER=TCPP if "%1" == "86" set XCPU=86 if "%1" == "186" set XCPU=186 @@ -41,7 +45,8 @@ if not "%1" == "" goto loop_commandline if "%COMPILER%" == "" echo you MUST define a COMPILER variable in CONFIG.BAT if "%COMPILER%" == "" goto abort -call default.bat +call defaults.bat +if "%LAST%" == "" goto noenv :----------------------------------------------------------------------- :- finally - we are going to compile @@ -51,50 +56,51 @@ echo. echo Process UTILS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ echo. cd utils -%MAKE% production +call %MAKE% all if errorlevel 1 goto abort-cd echo. echo Process LIB ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ echo. cd ..\lib -%MAKE% +call %MAKE% all if errorlevel 1 goto abort-cd echo. echo Process DRIVERS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ echo. cd ..\drivers -%MAKE% production +call %MAKE% all if errorlevel 1 goto abort-cd echo. echo Process BOOT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ echo. cd ..\boot -%MAKE% production +call %MAKE% all if errorlevel 1 goto abort-cd echo. echo Process SYS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ echo. cd ..\sys -%MAKE% production +call %MAKE% all if errorlevel 1 goto abort-cd echo. echo Process KERNEL +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ echo. cd ..\kernel -%MAKE% production +call %MAKE% all if errorlevel 1 goto abort-cd cd .. -:- if you like, put some finalizing commands (like copy to floppy) -:- into build2.bat +:- if you like, put finalizing commands (like copy to floppy) into build2.bat -if exist build2.bat call build2 +set XERROR= + +if exist build2.bat call build2.bat echo. echo Processing is done. @@ -104,9 +110,9 @@ goto end :abort-cd cd .. +:noenv :abort echo Compilation was aborted! -set XERROR=1 :end -default.bat clearset +defaults.bat clearset diff --git a/buildall.bat b/buildall.bat index e347a2b..9785bb0 100644 --- a/buildall.bat +++ b/buildall.bat @@ -9,56 +9,48 @@ if "%1" == "$SUMMARY" goto summary -set onerror=if not "%XERROR%" == "" goto daswarwohlnix - -:***** MSCL kernels - call config.bat +if "%LAST%" == "" goto end -if "%MS_BASE%" == "" goto no_ms -call build -r msc 386 fat16 -%ONERROR% -call build -r msc 186 fat16 -%ONERROR% -call build -r msc 86 fat16 -%ONERROR% -call build -r msc 386 fat32 -%ONERROR% -call build -r msc 186 fat32 -%ONERROR% -call build -r msc 86 fat32 -%ONERROR% +:***** MSVC kernels + +if "%MSC_BASE%" == "" goto no_ms + call build.bat -r msc 386 fat16 +if "%XERROR%" == "" call build.bat -r msc 186 fat16 +if "%XERROR%" == "" call build.bat -r msc 86 fat16 +if "%XERROR%" == "" call build.bat -r msc 386 fat32 +if "%XERROR%" == "" call build.bat -r msc 186 fat32 +if "%XERROR%" == "" call build.bat -r msc 86 fat32 + +if not "%XERROR%" == "" goto daswarwohlnix :no_ms :***** TC 2.01 kernels -if "%TC2_BASE%" == "" goto no_tc -call build -r tc 186 fat16 -%ONERROR% -call build -r tc 86 fat16 -%ONERROR% -call build -r tc 186 fat32 -%ONERROR% -call build -r tc 86 fat32 -%ONERROR% +if "%TC_BASE%" == "" goto no_tc + call build.bat -r tc 186 fat16 +if "%XERROR%" == "" call build.bat -r tc 86 fat16 +if "%XERROR%" == "" call build.bat -r tc 186 fat32 +if "%XERROR%" == "" call build.bat -r tc 86 fat32 + +if not "%XERROR%" == "" goto daswarwohlnix :no_tc :***** (Open) Watcom kernels if "%WATCOM%" == "" goto no_wc -call build -r wc 386 fat32 -%ONERROR% -call build -r wc 386 fat16 -%ONERROR% -call build -r wc 86 fat32 -%ONERROR% -call build -r wc 86 fat16 -%ONERROR% + call build.bat -r wc 386 fat32 +if "%XERROR%" == "" call build.bat -r wc 386 fat16 +if "%XERROR%" == "" call build.bat -r wc 86 fat32 +if "%XERROR%" == "" call build.bat -r wc 86 fat16 + +if not "%XERROR%" == "" goto daswarwohlnix :no_wc - + :***** now rebuild the default kernel -call build -r +call build.bat -r +if not "%XERROR%" == "" goto daswarwohlnix :************************************************************** :* now we build a summary of all kernels HMA size + total size @@ -70,30 +62,30 @@ set Sumfile=bin\ksummary.txt set TempSumfile=bin\tsummary.txt :****echo >%TempSumfile% Summary of all kernels build -:****echo.|date >>%TempSumfile% -:****echo.|time >>%TempSumfile% +:****echo.|date >>%TempSumfile% +:****echo.|time >>%TempSumfile% :****for %%i in (bin\k*.map) do call %0 $SUMMARY %%i -if exist %Sumfile% del %Sumfile% -if exist %TempSumfile% del %TempSumfile% +if exist %Sumfile% del %Sumfile%>nul +if exist %TempSumfile% del %TempSumfile%>nul >ktemp.bat for %%i in (bin\k*.map) do echo call %0 $SUMMARY %%i >>ktemp.bat sort ktemps.bat call ktemps.bat -del ktemp.bat -del ktemps.bat +del ktemp.bat>nul +del ktemps.bat>nul echo >>%Sumfile% Summary of all kernels build -echo.|date >>%Sumfile% -echo.|time >>%Sumfile% +echo.|date >>%Sumfile% +echo.|time >>%Sumfile% find <%TempSumfile% "H" >>%Sumfile% -del %TempSumfile% +del %TempSumfile%>nul set TempSumfile= set Sumfile= goto end -:summary +:summary echo H************************************************* %2 >>%TempSumfile% find<%2 " HMA_TEXT"|find/V "HMA_TEXT_START"|find/V "HMA_TEXT_END">>%TempSumfile% find<%2 " STACK">>%TempSumfile% @@ -103,6 +95,5 @@ goto end :daswarwohlnix echo Sorry, something didn't work as expected :-( -set ONERROR= :end diff --git a/clean.bat b/clean.bat index b2028c1..ed74cd7 100644 --- a/clean.bat +++ b/clean.bat @@ -1,37 +1,45 @@ @echo off -:- batch file to clean everything +:- batch file to clean and clobber everything :- $Id$ +if "%1" == "" %0 clean +goto %1 +goto end + +:clean +:clobber 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 call config.bat -call default.bat +if not "%LAST%" == "" call defaults.bat +if "%LAST%" == "" goto end cd utils -%MAKE% clean +call %MAKE% %1 cd ..\lib -%MAKE% clean +call %MAKE% %1 cd ..\drivers -%MAKE% clean +call %MAKE% %1 cd ..\boot -%MAKE% clean +call %MAKE% %1 cd ..\sys -%MAKE% clean +call %MAKE% %1 cd ..\kernel -%MAKE% clean +call %MAKE% %1 cd ..\hdr -if exist *.bak del *.bak +if exist *.bak del *.bak>nul cd .. -if exist *.bak del *.bak +if exist *.bak del *.bak>nul +if "%1"=="clobber" if exist status.me del status.me>nul :end -default.bat clearset +defaults.bat clearset diff --git a/clobber.bat b/clobber.bat index 2fcc81c..074a636 100644 --- a/clobber.bat +++ b/clobber.bat @@ -1,38 +1 @@ -@echo off - -:- batch file to clobber everything -:- $Id$ - -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 - -call config.bat -call default.bat - -cd utils -%MAKE% clobber - -cd ..\lib -%MAKE% clobber - -cd ..\drivers -%MAKE% clobber - -cd ..\boot -%MAKE% clobber - -cd ..\sys -%MAKE% clobber - -cd ..\kernel -%MAKE% clobber - -cd ..\hdr -if exist *.bak del *.bak - -cd .. -if exist *.bak del *.bak -if exist status.me del status.me - -:end -default.bat clearset +@clean clobber \ No newline at end of file diff --git a/config.b b/config.b index b839785..5f08918 100644 --- a/config.b +++ b/config.b @@ -1,119 +1,128 @@ -:- +@echo off + :- batch file that is included in all other batch files for configuration +:- $Id$ + +:----------------------------------------------------------------------- +:- NOTICE! You must edit and rename this file to CONFIG.BAT! +:----------------------------------------------------------------------- + +:- determine compiler(s) settings. :- +:- you REQUIRED to +:- search for NASM - and set the path to NASM +:- search for COMPILER - and set the default compiler name +:- search for ??_BASE - and set the path to (all) compiler(s) -:-**************************************************************** -:- NOTICE! You must edit and rename this file to CONFIG.BAT! * -:-**************************************************************** +set LAST= -:-********************************************************************* -:- 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 NASM executable. It should not be protected mode DJGPP +:- version if you're using Windows NT/2k/XP to compile. also: +:- NASM/DJGPP crashes when using protected mode Borland's make. -:-********************************************************************** -:-- define NASM executable - 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 NASM=c:\bin\nasm16 -set XNASM=c:\bin\nasm16 - -:********************************************************************** -:- define your COMPILER type here, pick one of them -:********************************************************************** +:----------------------------------------------------------------------- +:- define COMPILER name here, pick one of them. :- Turbo C 2.01 -set COMPILER=TC2 +set COMPILER=TC :- Turbo C++ 1.01 -:- set COMPILER=TURBOCPP -:- Turbo C 3.0 -:- set COMPILER=TC3 +::set COMPILER=TCPP +:- Turbo C++ 3.0 +::set COMPILER=TCPP3 :- Borland C -:- set COMPILER=BC5 +::set COMPILER=BC :- Microsoft C -:- set COMPILER=MSCL8 +::set COMPILER=MSC :- Watcom C -:- set COMPILER=WATCOM +::set COMPILER=WATCOM -:-********************************************************************** -:-- 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 +:----------------------------------------------------------------------- +:- define BASE dir of compiler; +:- may be defined for all installed compilers. -:- 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 +set TC_BASE=c:\tc +::set TCPP_BASE=c:\tcpp +::set TCPP3_BASE=c:\tcpp3 +::set BC_BASE=c:\bc +::set MSC_BASE=c:\msc +::set WATCOM=c:\watcom -:-********************************************************************** -:- where is UPX and which options to use? -:-********************************************************************** -set XUPX=upx --8086 --best -:- or use set XUPX= -:- if you don't want to use it +:----------------------------------------------------------------------- +:- When compiling executable, compilers search linker through PATH; +:- if some linker not in PATH, uncomment OLDPATH and required SETs PATH. -:-********************************************************************** -:- (optionally) which linker to use: -:- (otherwise will be determined automatically) -:- -:- WARNING TLINK needs to be in your PATH! -:-********************************************************************** +::set OLDPATH=%PATH% +::set PATH=%TC_BASE%;%PATH% +::set PATH=%TCPP_BASE%\bin;%PATH% +::set PATH=%TCPP3_BASE%\bin;%PATH% +::set PATH=%BC_BASE%\bin;%PATH% +::set PATH=%MSC_BASE%\bin;%PATH% +::set PATH=%WATCOM%\binw;%PATH% + +:- MSC searches libraries only through LIB variable. +::set LIB=%MSC_BASE%\lib + +:----------------------------------------------------------------------- +:- define which linker to use OR it will be determined AUTOMATICALLY. :- Turbo Link -:- set XLINK=tlink /m/c/s/l +::set LINK=tlink /c/m/s/l :- Microsoft Link -:- set XLINK=d:\qb\link /ma -:- set XLINK=%MS_BASE%\bin\link /ONERROR:NOEXE /ma /nologo +::set LINK=link /ONERROR:NOEXE /nologo :- WATCOM Link (wlinker is a batch file calling ms2wlink and wlink) -:- set XLINK=..\utils\wlinker /ma /nologo +::set LINK=..\utils\wlinker /nologo -:- set path for Turbo Link - use OLDPATH to restore normal path -:- set OLDPATH=%PATH% -:- set PATH=%PATH%;%TC2_BASE% +:----------------------------------------------------------------------- +:- define which librarian to use OR it will be determined AUTOMATICALLY. -:********************************************************************** -:* 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 -:********************************************************************** +:- Turbo Lib +::set LIBUTIL=tlib +::set LIBTERM= +:- Microsoft Lib +::set LIBUTIL=lib /nologo +::set LIBTERM=; +:- WATCOM Lib +::set LIBUTIL=wlib -q +::set LIBTERM= + +:----------------------------------------------------------------------- +:- define which MAKE to use OR it will be determined AUTOMATICALLY. :- Borland MAKE -:- set MAKE=%TC2_BASE%\make +::set MAKE=make +::set MAKE=maker -S :- Watcom MAKE in MS mode -:- set MAKE=%WATCOM%\binw\wmake /ms +::set MAKE=wmake /ms :- Microsoft MAKE -:- set MAKE=%MS_BASE%\bin\nmake /nologo +::set MAKE=nmake /nologo +::set MAKE=nmaker /nologo -:********************************************************************** -:* select your default target: required CPU and what FAT system to support -:********************************************************************** +:----------------------------------------------------------------------- +:- where is UPX and which options to use +:- (comment this out if you don't want to use it) -set XCPU=86 -:- set XCPU=186 -:- set XCPU=386 +set XUPX=upx --8086 --best -set XFAT=16 -:- set XFAT=32 +:----------------------------------------------------------------------- +:- select default target: CPU type (default is 86) and +:- what FAT system (default is 32) 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 +::set ALLCFLAGS=-DDEBUG +:----------------------------------------------------------------------- -:- -:- $Id$ -:- +set LAST=1 +if not "%LAST%" == "1" defaults.bat clearset diff --git a/default.bat b/default.bat deleted file mode 100644 index d3c73ce..0000000 --- a/default.bat +++ /dev/null @@ -1,66 +0,0 @@ -@echo off - -:- $Id$ - -if "%1" == "clearset" goto clearset - -:----------------------------------------------------------------------- - -if not "%MAKE%" == "" goto skip_make - -if "%COMPILER%" == "TC2" set MAKE=%TC2_BASE%\make -if "%COMPILER%" == "TURBOCPP" set MAKE=%TP1_BASE%\bin\make -if "%COMPILER%" == "TC3" set MAKE=%TC3_BASE%\bin\make -if "%COMPILER%" == "BC5" set MAKE=%BC5_BASE%\bin\make -if "%COMPILER%" == "WATCOM" set MAKE=wmake /ms /h -if "%COMPILER%" == "MSCL8" set MAKE=%MS_BASE%\bin\nmake /nologo - -echo Make is %MAKE%. - -:skip_make - -:----------------------------------------------------------------------- - -if not "%XLINK%" == "" goto skip_xlink - -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" set XLINK=..\utils\wlinker /ma/nologo -if "%COMPILER%" == "MSCL8" set XLINK=%MS_BASE%\bin\link /ONERROR:NOEXE /ma /nologo - -echo Linker is %XLINK%. - -:skip_xlink - -:----------------------------------------------------------------------- - -if not "%XUPX%" == "" set UPXOPT=-U -if "%XUPX%" == "" set UPXOPT= -if "%XUPX%" == "" set XUPX=@rem - -goto end - -:----------------------------------------------------------------------- - -:clearset - -if not "%OLDPATH%" == "" set PATH=%OLDPATH% -if not "%OLDPATH%" == "" set OLDPATH= - -set MAKE= -set COMPILER= -set XCPU= -set XFAT= -set XLINK= -set TC2_BASE= -set TP1_BASE= -set TC3_BASE= -set BC5_BASE= -set MS_BASE= -set XNASM= -set XUPX= -set UPXOPT= - -:end diff --git a/defaults.bat b/defaults.bat new file mode 100644 index 0000000..2abde5e --- /dev/null +++ b/defaults.bat @@ -0,0 +1,87 @@ +@echo off + +:- $Id$ + +set LAST= +if "%1" == "clearset" goto clearset + +:----------------------------------------------------------------------- + +if "%COMPILER%" == "TC" set BASE=%TC_BASE% +if "%COMPILER%" == "TCPP" set BASE=%TCPP_BASE% +if "%COMPILER%" == "TCPP3" set BASE=%TCPP3_BASE% +if "%COMPILER%" == "BC" set BASE=%BC_BASE% +if "%COMPILER%" == "WATCOM" set BASE=%WATCOM% +if "%COMPILER%" == "MSC" set BASE=%MSC_BASE% +if "%BASE%" == "" goto clearset + +:----------------------------------------------------------------------- + +if not "%LINK%" == "" goto skip_link + +set LINK=%BASE%\bin\tlink /c/m +if "%COMPILER%" == "TC" set LINK=%BASE%\tlink /c/m +if "%COMPILER%" == "WATCOM" set LINK=..\utils\wlinker /nologo +if "%COMPILER%" == "MSC" set LINK=%BASE%\bin\link /ONERROR:NOEXE /batch + +echo Linker is %LINK% + +:skip_link + +:----------------------------------------------------------------------- + +if not "%LIBUTIL%" == "" goto skip_lib + +set LIBUTIL=%BASE%\bin\tlib +set LIBTERM= +if "%COMPILER%" == "TC" set LIBUTIL=%BASE%\tlib +if "%COMPILER%" == "WATCOM" set LIBUTIL=%BASE%\binw\wlib -q +if "%COMPILER%" == "MSC" set LIBUTIL=%BASE%\bin\lib /nologo +if "%COMPILER%" == "MSC" set LIBTERM=; + +echo Librarian is %LIBUTIL% + +:skip_lib + +:----------------------------------------------------------------------- + +if not "%MAKE%" == "" goto skip_make + +set MAKE=%BASE%\bin\make +if "%COMPILER%" == "TC" set MAKE=%BASE%\make +if "%COMPILER%" == "WATCOM" set MAKE=%BASE%\binw\wmake /ms /h +if "%COMPILER%" == "MSC" set MAKE=%BASE%\bin\nmake /nologo + +echo Make is %MAKE% + +:skip_make + +:----------------------------------------------------------------------- + +set LAST=1 +if "%LAST%" == "1" goto end + +:----------------------------------------------------------------------- + +:clearset + +set NASM= +set COMPILER= +set BASE= +set TC_BASE= +set TCPP_BASE= +set TCPP3_BASE= +set BC_BASE= +set MSC_BASE= +set LINK= +set LIBUTIL= +set LIBTERM= +set MAKE= +set XUPX= +set XCPU= +set XFAT= + +if not "%OLDPATH%" == "" set PATH=%OLDPATH% +set OLDPATH= + +:end diff --git a/drivers/floppy.asm b/drivers/floppy.asm index fa2d51e..ae31768 100644 --- a/drivers/floppy.asm +++ b/drivers/floppy.asm @@ -32,7 +32,7 @@ segment HMA_TEXT ; -; BOOL ASMPASCAL fl_reset(WORD drive); +; int ASMPASCAL fl_reset(UBYTE drive); ; ; Reset both the diskette and hard disk system. ; returns TRUE if successful. @@ -41,189 +41,175 @@ segment HMA_TEXT global FL_RESET FL_RESET: pop ax ; return address - pop dx ; drive (DL only) + pop dx ; drive push ax ; restore address - mov ah,0 ; BIOS reset diskette & fixed disk + mov ah,0 ; reset disk int 13h - - sbb ax,ax ; carry set indicates error, AX=-CF={-1,0} + sbb ax,ax ; CF=1: error inc ax ; ...return TRUE (1) on success, - ret ; else FALSE (0) on failure + ret ; FALSE (0) on error ; -; COUNT ASMPASCAL fl_diskchanged(WORD drive); +; int ASMPASCAL fl_diskchanged(UBYTE drive); ; ; Read disk change line status. -; returns 1 if disk has changed, 0 if not, 0xFFFF if error. +; returns 1 if disk has changed, 0 if not, 0xFF if error. ; global FL_DISKCHANGED FL_DISKCHANGED: pop ax ; return address - pop dx ; drive (DL only, 00h-7Fh) + pop dx ; drive push ax ; restore stack - push si ; preserve value - mov ah,16h ; read change status type + push si + mov ah,16h ; read change status type xor si,si ; RBIL: avoid crash on AT&T 6300 int 13h - pop si ; restore + pop si - sbb al,al ; AL=-CF={-1,0} where 0==no change - jnc fl_dc ; carry set on error or disk change - cmp ah,6 ; if AH==6 then disk change, else error - jne fl_dc ; if error, return -1 - mov al, 1 ; set change occurred -fl_dc: cbw ; extend AL into AX, AX={1,0,-1} - ret ; note: AH=0 on no change, AL set above + sbb al,al ; CF=0 (disk has not changed) + jnc ret_AH_0 ; ...return 0 + cmp ah,6 ; ah!=6 (error) + jne ret_AH_0 ; ...return 0xFF + mov al,1 ; ah=6 (disk has changed) + jmp short ret_AH_0 ; ...return 1 ; +; int ASMPASCAL fl_read (UBYTE drive, WORD head, WORD track, WORD sector, WORD count, void FAR *buffer); +; int ASMPASCAL fl_write (UBYTE drive, WORD head, WORD track, WORD sector, WORD count, void FAR *buffer); +; int ASMPASCAL fl_verify(UBYTE drive, WORD head, WORD track, WORD sector, WORD count, void FAR *buffer); +; int ASMPASCAL fl_format(UBYTE drive, WORD head, WORD track, WORD sector, WORD count, void FAR *buffer); +; + ; Format tracks (sector should be 0). -; COUNT ASMPASCAL fl_format(WORD drive, WORD head, WORD track, WORD sector, WORD count, UBYTE FAR *buffer); -; Reads one or more sectors. -; COUNT ASMPASCAL fl_read (WORD drive, WORD head, WORD track, WORD sector, WORD count, UBYTE FAR *buffer); -; Writes one or more sectors. -; COUNT ASMPASCAL fl_write (WORD drive, WORD head, WORD track, WORD sector, WORD count, UBYTE FAR *buffer); -; COUNT ASMPASCAL fl_verify(WORD drive, WORD head, WORD track, WORD sector, WORD count, UBYTE FAR *buffer); -; -; Returns 0 if successful, error code otherwise. -; global FL_FORMAT FL_FORMAT: - mov ah,5 ; format track - jmp short fl_common + mov ah,5 ; format track + jmp short fl_common + + global FL_VERIFY +FL_VERIFY: + mov ah,4 ; verify sector(s) + jmp short fl_common global FL_READ FL_READ: - mov ah,2 ; read sector(s) - jmp short fl_common - - global FL_VERIFY -FL_VERIFY: - mov ah,4 ; verify sector(s) - jmp short fl_common - + mov ah,2 ; read sector(s) + jmp short fl_common + global FL_WRITE FL_WRITE: - mov ah,3 ; write sector(s) + mov ah,3 ; write sector(s) -fl_common: - push bp ; setup stack frame - mov bp,sp +fl_common: + push bp + mov bp,sp - mov cx,[bp+0Ch] ; cylinder number + mov cx,[bp+12] ; cylinder number + mov al,1 ; error code + cmp ch,3 + ja fl_error ; can't write above 3FFh=1023 - mov al,1 ; this should be an error code - cmp ch,3 ; this code can't write above 3FFh=1023 - ja fl_error ; as cylinder # is limited to 10 bits. + xchg ch,cl ; ch=low 8 bits of cylinder number + mov dh,[bp+14] ; head number + ror cl,1 ; bits 8-9 of cylinder number... + ror cl,1 ; ...to bits 6-7 in CL + or cl,[bp+10] ; sector number (bits 0-5) - xchg ch,cl ; ch=low 8 bits of cyl number - ror cl,1 ; bits 8-9 of cylinder number... - ror cl,1 ; ...to bits 6-7 in CL - or cl,[bp+0Ah] ; or in the sector number (bits 0-5) - - mov al,[bp+08h] ; count of sectors to read/write/... - les bx,[bp+04h] ; Load 32 bit buffer ptr into ES:BX - - mov dl,[bp+10h] ; drive (if or'ed 80h its a hard drive) - mov dh,[bp+0Eh] ; get the head number - - int 13h ; process sectors + mov al,[bp+8] ; number of sectors + les bx,[bp+4] ; 32-bit buffer ptr + mov dl,[bp+16] ; drive (if or'ed 80h its hard drive) + int 13h ; process sectors sbb al,al ; carry: al=ff, else al=0 and al,ah ; carry: error code, else 0 fl_error: - mov ah,0 ; extend AL into AX without sign extension - pop bp - ret 14 + mov ah,0 + pop bp + ret 14 ; -; COUNT ASMPASCAL fl_lba_ReadWrite(BYTE drive, WORD mode, void FAR * dap_p); +; int ASMPASCAL fl_lba_ReadWrite(UBYTE drive, WORD mode, void FAR * dap); ; ; Returns 0 if successful, error code otherwise. ; - global FL_LBA_READWRITE + global FL_LBA_READWRITE FL_LBA_READWRITE: - push bp ; setup stack frame - mov bp,sp - - push ds - push si ; wasn't in kernel < KE2024Bo6!! - - mov dl,[bp+10] ; drive (if or'ed with 80h a hard drive) - mov ax,[bp+8] ; get the command - lds si,[bp+4] ; get far dap pointer - int 13h ; read from/write to drive - - pop si - pop ds - - pop bp - - mov al,ah ; place any error code into al - mov ah,0 ; zero out ah - ret 8 + push bp + mov bp,sp + push si + push ds + mov dl,[bp+10] ; drive (if or'ed 80h its hard drive) + mov ax,[bp+8] ; command + lds si,[bp+4] ; far dap pointer + int 13h ; process sectors + pop ds + pop si + pop bp + mov al,ah ; place error code into al + mov ah,0 + ret 8 ; ; void ASMPASCAL fl_readkey (void); ; global FL_READKEY -FL_READKEY: xor ah, ah +FL_READKEY: + mov ah,0 int 16h ret ; -; COUNT ASMPASCAL fl_setdisktype (WORD drive, WORD type); +; int ASMPASCAL fl_setdisktype (UBYTE drive, WORD type); ; global FL_SETDISKTYPE FL_SETDISKTYPE: pop bx ; return address - pop ax ; disk format type (al) - pop dx ; drive number (dl) + pop ax ; disk type + pop dx ; drive push bx ; restore stack - mov ah,17h ; floppy set disk type for format + mov ah,17h ; set disk type for format int 13h ret_AH: - mov al,ah ; place any error code into al - mov ah,0 ; zero out ah + mov al,ah ; place error code into al +ret_AH_0: + mov ah,0 ret - + ; -; COUNT ASMPASCAL fl_setmediatype (WORD drive, WORD tracks, WORD sectors); +; int ASMPASCAL fl_setmediatype (UBYTE drive, WORD tracks, WORD sectors); ; + global FL_SETMEDIATYPE FL_SETMEDIATYPE: pop ax ; return address pop bx ; sectors/track pop cx ; number of tracks - pop dx ; drive number + pop dx ; drive push ax ; restore stack push di - dec cx ; number of cylinders - 1 (last cyl number) + dec cx ; last cylinder number xchg ch,cl ; CH=low 8 bits of last cyl number - - ror cl,1 ; extract bits 8-9 of cylinder number... - ror cl,1 ; ...into cl bit 6-7 - - or cl,bl ; sectors/track (bits 0-5) or'd with high cyl bits 7-6 - - mov ah,18h ; disk set media type for format + ror cl,1 ; bits 8-9 of cylinder number... + ror cl,1 ; ...to bits 6-7 in CL + or cl,bl ; sectors/track (bits 0-5) + mov ah,18h ; set media type for format int 13h jc skipint1e push es - xor dx,dx - mov es,dx + xor dx,dx + mov es,dx cli - pop word [es:0x1e*4+2] ; set int 0x1e table to es:di - mov [es:0x1e*4 ], di + mov [es:0x1e*4],di + pop word [es:0x1e*4+2] ; set int 0x1e table to es:di sti -skipint1e: - pop di +skipint1e: + pop di jmp short ret_AH - diff --git a/drivers/makefile b/drivers/makefile index 94bba96..978f380 100644 --- a/drivers/makefile +++ b/drivers/makefile @@ -4,46 +4,25 @@ # $Id$ # - !include "../mkfiles/generic.mak" +OBJS=floppy.obj rdpcclk.obj wrpcclk.obj wratclk.obj +LIBOBJS=+floppy +rdpcclk +wrpcclk +wratclk -# MICROSOFT C -# ----------- -#MODEL = s -#CFLAGS = /c /Gs /A$(MODEL) -#AFLAGS = /Mx /Dmem$(MODEL)=1 -#TERM = ; +# Build the LIBRARY #################################################### -# BORLAND C -# ----------- -#MODEL = s -#CFLAGS = -c -m$(MODEL) -#AFLAGS = /Mx /Dmem$(MODEL)=1 -#LIBFLAGS = /c +all: ..\lib\device.lib -OBJS = floppy.obj rdpcclk.obj wrpcclk.obj wratclk.obj +..\lib\device.lib: $(OBJS) + -$(RM) $*.lib + $(LIBUTIL) $(LIBFLAGS) $* $(LIBOBJS) $(LIBTERM) -LIBOBJS= +floppy +rdpcclk +wrpcclk +wratclk +$(OBJS): $(DEPENDS) - - -# Build the LIBRARY -# ----------------- -all: production - -production: ..\lib\device.lib - -..\lib\device.lib: device.lib - copy device.lib ..\lib - -clobber: clean - -$(RM) device.lib status.me ..\lib\device.lib +######################################################################## clean: - -$(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.cod *.err - -device.lib : $(OBJS) - -$(RM) device.lib - $(LIBUTIL) $(LIBFLAGS) device $(LIBOBJS) $(LIBTERM) + -$(RM) *.bak *.cod *.crf *.err *.las *.lst *.map *.obj *.xrf +clobber: clean + -$(RM) ..\lib\device.lib status.me diff --git a/filelist b/filelist deleted file mode 100644 index e86d481..0000000 --- a/filelist +++ /dev/null @@ -1,155 +0,0 @@ -*/*/build.bat -*/*/buildall.bat -*/*/clean.bat -*/*/clobber.bat -*/*/config.b -*/*/filelist -*/*/default.bat -*/*/makefile -*/*/bin/autoexec.bat -*/*/bin/config.sys -*/*/bin/install.bat -*/*/boot/boot.asm -*/*/boot/boot32.asm -*/*/boot/boot32lb.asm -*/*/boot/makefile -*/*/docs/bugs.txt -*/*/docs/build.txt -*/*/docs/config.txt -*/*/docs/contrib.txt -*/*/docs/copying -*/*/docs/fdkernel.lsm -*/*/docs/history.txt -*/*/docs/intfns.txt -*/*/docs/lfnapi.txt -*/*/docs/mkboot.txt -*/*/docs/nls.txt -*/*/docs/readme.cvs -*/*/docs/readme.txt -*/*/docs/sys.txt -*/*/drivers/floppy.asm -*/*/drivers/makefile -*/*/drivers/rdpcclk.asm -*/*/drivers/wratclk.asm -*/*/drivers/wrpcclk.asm -*/*/hdr/algnbyte.h -*/*/hdr/algndflt.h -*/*/hdr/buffer.h -*/*/hdr/cds.h -*/*/hdr/clock.h -*/*/hdr/date.h -*/*/hdr/dcb.h -*/*/hdr/device.h -*/*/hdr/dirmatch.h -*/*/hdr/error.h -*/*/hdr/exe.h -*/*/hdr/fat.h -*/*/hdr/fcb.h -*/*/hdr/file.h -*/*/hdr/fnode.h -*/*/hdr/kbd.h -*/*/hdr/kconfig.h -*/*/hdr/lol.h -*/*/hdr/mcb.h -*/*/hdr/network.h -*/*/hdr/nls.h -*/*/hdr/pcb.h -*/*/hdr/portab.h -*/*/hdr/process.h -*/*/hdr/sft.h -*/*/hdr/stacks.inc -*/*/hdr/tail.h -*/*/hdr/time.h -*/*/hdr/version.h -*/*/hdr/xstructs.h -*/*/kernel/nls/001-437.hc -*/*/kernel/nls/001-437.unf -*/*/kernel/nls/001-437.up -*/*/kernel/nls/049-850.hc -*/*/kernel/nls/049-850.unf -*/*/kernel/nls/049-850.up -*/*/kernel/nls/files -*/*/kernel/apisupt.asm -*/*/kernel/asmsupt.asm -*/*/kernel/blockio.c -*/*/kernel/break.c -*/*/kernel/chario.c -*/*/kernel/config.c -*/*/kernel/config.h -*/*/kernel/console.asm -*/*/kernel/dosfns.c -*/*/kernel/dosidle.asm -*/*/kernel/dosnames.c -*/*/kernel/dsk.c -*/*/kernel/dyndata.h -*/*/kernel/dyninit.c -*/*/kernel/entry.asm -*/*/kernel/error.c -*/*/kernel/execrh.asm -*/*/kernel/fatdir.c -*/*/kernel/fatfs.c -*/*/kernel/fattab.c -*/*/kernel/fcbfns.c -*/*/kernel/globals.h -*/*/kernel/init-dat.h -*/*/kernel/init-mod.h -*/*/kernel/initclk.c -*/*/kernel/initdisk.c -*/*/kernel/inithma.c -*/*/kernel/initoem.c -*/*/kernel/int2f.asm -*/*/kernel/inthndlr.c -*/*/kernel/intr.asm -*/*/kernel/makefile -*/*/kernel/io.asm -*/*/kernel/io.inc -*/*/kernel/ioctl.c -*/*/kernel/iprf.c -*/*/kernel/irqstack.asm -*/*/kernel/kernel.asm -*/*/kernel/kernel.cfg -*/*/kernel/lfnapi.c -*/*/kernel/ludivmul.inc -*/*/kernel/main.c -*/*/kernel/memmgr.c -*/*/kernel/misc.c -*/*/kernel/network.c -*/*/kernel/newstuff.c -*/*/kernel/nls.c -*/*/kernel/nls_hc.asm -*/*/kernel/nls_load.c -*/*/kernel/nlssupt.asm -*/*/kernel/prf.c -*/*/kernel/printer.asm -*/*/kernel/procsupt.asm -*/*/kernel/proto.h -*/*/kernel/segs.inc -*/*/kernel/serial.asm -*/*/kernel/strings.c -*/*/kernel/sysclk.c -*/*/kernel/syspack.c -*/*/kernel/systime.c -*/*/kernel/task.c -*/*/kernel/turboc.cfg -*/*/lib/makefile -*/*/mkfiles/generic.mak -*/*/mkfiles/bc5.mak -*/*/mkfiles/mscl8.mak -*/*/mkfiles/tc2.mak -*/*/mkfiles/tc3.mak -*/*/mkfiles/turbocpp.mak -*/*/mkfiles/watcom.mak -*/*/sys/fdkrncfg.c -*/*/sys/bin2c.c -*/*/sys/makefile -*/*/sys/sys.c -*/*/sys/talloc.c -*/*/utils/echoto.bat -*/*/utils/exeflat.c -*/*/utils/indent.ini -*/*/utils/makefile -*/*/utils/patchobj.c -*/*/utils/proto.bat -*/*/utils/relocinf.c -*/*/utils/rmfiles.bat -*/*/utils/wlinker.bat diff --git a/hdr/portab.h b/hdr/portab.h index 78bb79f..e551d6c 100644 --- a/hdr/portab.h +++ b/hdr/portab.h @@ -35,6 +35,8 @@ static char *portab_hRcsId = #endif #endif +#include + /****************************************************************/ /* */ /* Machine dependant portable types. Note that this section is */ @@ -256,55 +258,105 @@ typedef signed long LONG; #define LONG long #endif +typedef UWORD ofs_t; +typedef UWORD seg_t; + +#define lonibble(v) (0x0f & (v)) +#define hinibble(v) (0xf0 & (v)) + +#if CHAR_BIT == 8 +# define lobyte(v) ((UBYTE)(v)) +#else +# define lobyte(v) ((UBYTE)(0xff & (v))) +#endif +#define hibyte(v) lobyte ((UWORD)(v) >> 8u) + +#if USHRT_MAX == 0xFFFF +# define loword(v) ((unsigned short)(v)) +#else +# define loword(v) (0xFFFF & (unsigned)(v)) +#endif +#define hiword(v) loword ((v) >> 16u) + +#define MK_UWORD(hib,lob) (((UWORD)(hib) << 8u) | (UBYTE)(lob)) +#define MK_ULONG(hiw,low) (((ULONG)(hiw) << 16u) | (UWORD)(low)) + /* General far pointer macros */ #ifdef I86 #ifndef MK_FP -#if defined(__WATCOMC__) +#if defined __WATCOMC__ #define MK_FP(seg,ofs) (((UWORD)(seg)):>((VOID *)(ofs))) -#elif defined(__TURBOC__) && (__TURBOC__ > 0x202) +#elif __TURBOC__ > 0x202 #define MK_FP(seg,ofs) ((void _seg *)(seg) + (void near *)(ofs)) #else -#define MK_FP(seg,ofs) ((void FAR *)(((ULONG)(seg)<<16)|(UWORD)(ofs))) +#define MK_FP(seg,ofs) ((void FAR *)MK_ULONG(seg, ofs)) #endif -#define pokeb(seg, ofs, b) (*((unsigned char far *)MK_FP(seg,ofs)) = b) -#define poke(seg, ofs, w) (*((unsigned far *)MK_FP(seg,ofs)) = w) +#define pokeb(seg, ofs, b) (*(unsigned char far *)MK_FP(seg,ofs) = (b)) +#define poke(seg, ofs, w) (*(unsigned far *)MK_FP(seg,ofs) = (w)) #define pokew poke -#define pokel(seg, ofs, l) (*((unsigned long far *)MK_FP(seg,ofs)) = l) -#define peekb(seg, ofs) (*((unsigned char far *)MK_FP(seg,ofs))) -#define peek(seg, ofs) (*((unsigned far *)MK_FP(seg,ofs))) +#define pokel(seg, ofs, l) (*(unsigned long far *)MK_FP(seg,ofs) = (l)) +#define peekb(seg, ofs) (*(unsigned char far *)MK_FP(seg,ofs)) +#define peek(seg, ofs) (*(unsigned far *)MK_FP(seg,ofs)) #define peekw peek -#define peekl(seg, ofs) (*((unsigned long far *)MK_FP(seg,ofs))) +#define peekl(seg, ofs) (*(unsigned long far *)MK_FP(seg,ofs)) -#if defined(__TURBOC__) && (__TURBOC__ > 0x202) +#if __TURBOC__ > 0x202 #define FP_SEG(fp) ((unsigned)(void _seg *)(void far *)(fp)) #else -#define FP_SEG(fp) ((unsigned)((ULONG)(VOID FAR *)(fp)>>16)) +#define FP_SEG(fp) hiword ((ULONG)(VOID FAR *)(fp)) #endif -#define FP_OFF(fp) ((unsigned)(fp)) +#define FP_OFF(fp) loword (fp) #endif #endif #ifdef MC68K -#define MK_FP(seg,ofs) ((VOID *)(&(((BYTE *)(size_t)(seg))[(ofs)]))) -#define FP_SEG(fp) (0) +#define MK_FP(seg,ofs) ((VOID *)&(((BYTE *)(size_t)(seg))[ofs])) +#define FP_SEG(fp) 0 #define FP_OFF(fp) ((size_t)(fp)) #endif typedef VOID (FAR ASMCFUNC * intvec) (void); +#define MK_PTR(type,seg,ofs) ((type FAR*) MK_FP (seg, ofs)) +#if __TURBOC__ > 0x202 +# define MK_SEG_PTR(type,seg) ((type _seg*) (seg)) +#else +# define _seg FAR +# define MK_SEG_PTR(type,seg) MK_PTR (type, seg, 0) +#endif + /* this suppresses the warning unreferenced parameter 'x' and (hopefully) generates no code */ -#define UNREFERENCED_PARAMETER(x) (void)x; +#define UNREFERENCED_PARAMETER(x) (void)(x) #ifdef I86 /* commandline overflow - removing /DPROTO TE */ #define PROTO #endif -#define LENGTH(x) (sizeof(x)/sizeof(x[0])) +typedef const char CStr[], *PCStr; +typedef char Str[], *PStr; +typedef const void *CVP; +typedef const void FAR *CVFP; +typedef void FAR *VFP; + +#define LENGTH(x) (sizeof (x)/sizeof *(x)) +#define ENDOF(x) ((x) + LENGTH (x)) + +/* (unsigned) modulo arithmetics trick: a<=b<=c equal to b-a<=c-a */ +#define inrange(type,v,lo,hi) ((type)((v) - (lo)) <= (type)((hi) - (lo))) +#define _isdigit(c) inrange(UBYTE, c, '0', '9') +#define _islower(c) inrange(UBYTE, c, 'a', 'z') +#define _isupper(c) inrange(UBYTE, c, 'A', 'Z') + +/* Fast ASCII tolower/toupper */ +#define _fast_lower(ch) ((ch) | 0x20) +#define _fast_dolower(var) ((var) |= 0x20) +#define _fast_upper(ch) ((ch) & ~0x20) +#define _fast_doupper(var) ((var) &= ~0x20) diff --git a/hdr/stacks.inc b/hdr/stacks.inc index f3681b8..b002738 100644 --- a/hdr/stacks.inc +++ b/hdr/stacks.inc @@ -149,10 +149,10 @@ irp_hi equ 26 %else push eax pop ax - %ifdef MSCL8 + %ifdef MSC push ecx pop cx - %else ;BC5 + %else ;BC push ebx pop bx %endif @@ -170,10 +170,10 @@ irp_hi equ 26 %else push dx pop edx - %ifdef MSCL8 + %ifdef MSC push cx pop ecx - %else ;BC5 + %else ;BC push bx pop ebx %endif diff --git a/hdr/version.h b/hdr/version.h index 4009ca6..008deeb 100644 --- a/hdr/version.h +++ b/hdr/version.h @@ -48,7 +48,7 @@ static BYTE *date_hRcsId = #define REVISION_MAJOR 1 #define REVISION_MINOR 1 #define REVISION_SEQ 35 -#define BUILD "2035" -#define SUB_BUILD "a" -#define KERNEL_VERSION_STRING "1.1.35" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ */ +#define BUILD "2035a" +#define SUB_BUILD "" +#define KERNEL_VERSION_STRING "1.1.35a" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ */ #define KERNEL_BUILD_STRING "2035a" /*#BUILD SUB_BUILD */ diff --git a/kernel/break.c b/kernel/break.c index be097c5..7ad2963 100644 --- a/kernel/break.c +++ b/kernel/break.c @@ -53,13 +53,13 @@ unsigned char ctrl_break_pressed(void) unsigned char check_handle_break(struct dhdr FAR **pdev) { - unsigned char c = CTL_C; - if (!ctrl_break_pressed()) - c = (unsigned char)ndread(&syscon); - if (c != CTL_C && *pdev != syscon) - c = (unsigned char)ndread(pdev); - if (c == CTL_C) + unsigned char c; + if (ctrl_break_pressed() || + (c = (unsigned char)ndread(&syscon)) == CTL_C || + *pdev != syscon && (c = (unsigned char)ndread(pdev)) == CTL_C) + { handle_break(pdev, -1); + } return c; } @@ -90,4 +90,3 @@ void handle_break(struct dhdr FAR **pdev, int sft_out) spawn_int23(); /* invoke user INT-23 and never come back */ } - diff --git a/kernel/config.c b/kernel/config.c index 2b8f8d7..6974e8f 100644 --- a/kernel/config.c +++ b/kernel/config.c @@ -36,292 +36,217 @@ static BYTE *RcsId = "$Id$"; #endif +#define testbit(v,bit) ((UBYTE)((v) >> (UBYTE)(bit)) & 1) + #ifdef DEBUG #define DebugPrintf(x) printf x #else #define DebugPrintf(x) #endif -#define para2far(seg) ((mcb FAR *)MK_FP((seg), 0)) -/** - Menu selection bar struct: - x pos, ypos, string -*/ -#define MENULINEMAX 80 -#define MENULINESMAX 10 -struct MenuSelector +static UBYTE MenuColor BSS_INIT(0); + +static unsigned screenwidth(void) { - int x; - int y; - BYTE bSelected; - BYTE Text[MENULINEMAX]; -}; + return peek(0, 0x44a); +} -/** Structure below holds the menu-strings */ -STATIC struct MenuSelector MenuStruct[MENULINESMAX] BSS_INIT({0}); +static unsigned screenbottom(void) +{ + UBYTE row = peekb(0, 0x484); + if (row == 0) + row = 24; + return row; +} -int nMenuLine BSS_INIT(0); -int MenuColor = -1; - -STATIC void WriteMenuLine(struct MenuSelector *menu) +static unsigned screeny(void) { iregs r; - unsigned char attr = (unsigned char)MenuColor; - char *pText = menu->Text; + r.BH = peekb(0, 0x462); /* active video page */ + r.AH = 0x03; /* get cursor pos */ + init_call_intr(0x10, &r); + return r.DH; +} - if (pText[0] == 0) - return; +static void gotoxy(unsigned x, unsigned y) +{ + iregs r; + r.BH = peekb(0, 0x462); /* active video page */ + r.DL = x; + r.DH = y; + r.AH = 0x02; /* set cursor pos */ + init_call_intr(0x10, &r); +} - if(menu->bSelected) - attr = ((attr << 4) | (attr >> 4)); - - /* clear line */ - r.a.x = 0x0600; - r.b.b.h = attr; - r.c.b.l = r.d.b.l = menu->x; - r.c.b.h = r.d.b.h = menu->y; - r.d.b.l += strlen(pText) - 1; +static void ClearScreenArea(UBYTE attr, unsigned x, unsigned y, unsigned w, unsigned h) +{ + iregs r; + r.BH = attr; + r.CL = x; r.DL = x + w - 1; + r.CH = y; r.DH = y + h - 1; + r.AX = 0x0600; /* clear rectangle */ init_call_intr(0x10, &r); - /* set cursor position: */ - r.a.b.h = 0x02; - r.b.b.h = 0; - r.d.b.l = menu->x; - r.d.b.h = menu->y; - init_call_intr(0x10, &r); - - printf("%s", pText); + gotoxy(x, y); } -/* Deselect the previously selected line */ -STATIC void DeselectLastLine(void) +static void say(PCStr s) { - struct MenuSelector *menu; - for (menu = MenuStruct; menu < &MenuStruct[MENULINESMAX]; menu++) - { - if (menu->bSelected) - { - /* deselect it: */ - menu->bSelected = 0; - WriteMenuLine(menu); - break; - } - } + printf(s); } -STATIC void SelectLine(int MenuSelected) +static void say2(PCStr f, PCStr s) { - struct MenuSelector *menu; - - DeselectLastLine(); /* clear previous selection */ - menu = &MenuStruct[MenuSelected]; - menu->bSelected = 1; /* set selection flag for this one */ - WriteMenuLine(menu); + printf(f, s); } -UWORD umb_start BSS_INIT(0), UMB_top BSS_INIT(0); -UWORD ram_top BSS_INIT(0); /* How much ram in Kbytes */ -size_t ebda_size BSS_INIT(0); +static void clearrow(void) +{ + unsigned width; + say("\r"); + for (width = screenwidth(); --width;) + say(" "); + say("\r"); +} -static UBYTE ErrorAlreadyPrinted[128] BSS_INIT({0}); - -char master_env[128] BSS_INIT({0}); -static char *envp = master_env; +static seg_t umb_base_start BSS_INIT(0); +static size_t ebda_size BSS_INIT(0); struct config Config = { - 0, - NUMBUFF, - NFILES, - 0, - NFCBS, - 0, - "command.com", - " /P /E:256\r\n", - NLAST, - 0, - NSTACKS, - 0, - STACKSIZE - /* COUNTRY= is initialized within DoConfig() */ - , 0 /* country ID */ - , 0 /* codepage */ - , 0 /* amount required memory */ - , 0 /* pointer to loaded data */ - , 0 /* strategy for command.com is low by default */ - , 0 /* default value for switches=/E:nnnn */ + /* UBYTE cfgDosDataUmb; */ 0, + /* BYTE cfgBuffers; */ NUMBUFF, + /* UBYTE cfgFiles; */ NFILES, + /* UBYTE cfgFilesHigh; */ 0, + /* UBYTE cfgFcbs; */ NFCBS, + /* UBYTE cfgProtFcbs; */ 0, + /* char cfgShell[256]; */ "command.com /P /E:256", + /* UBYTE cfgLastdrive; */ NLAST, + /* UBYTE cfgLastdriveHigh; */ 0, + /* BYTE cfgStacks; */ NSTACKS, + /* BYTE cfgStacksHigh; */ 0, + /* UWORD cfgStackSize; */ STACKSIZE, + /* UBYTE cfgP_0_startmode; */ 0, /* load command.com (low by default) */ + /* unsigned ebda2move; */ 0, /* value for SWITCHES=/E:nnnn */ }; -STATIC seg base_seg BSS_INIT(0); -STATIC seg umb_base_seg BSS_INIT(0); -BYTE FAR *lpTop BSS_INIT(0); +STATIC seg_t base_seg BSS_INIT(0); +STATIC seg_t umb_base_seg BSS_INIT(0); +VFP lpTop BSS_INIT(0); STATIC unsigned nCfgLine BSS_INIT(0); -COUNT UmbState BSS_INIT(0); -STATIC BYTE szLine[256] BSS_INIT({0}); -STATIC BYTE szBuf[256] BSS_INIT({0}); -BYTE singleStep BSS_INIT(FALSE); /* F8 processing */ -BYTE SkipAllConfig BSS_INIT(FALSE); /* F5 processing */ -BYTE askThisSingleCommand BSS_INIT(FALSE); /* ?device= device?= */ -BYTE DontAskThisSingleCommand BSS_INIT(FALSE); /* !files= */ +static unsigned nPass BSS_INIT(0); +static char configfile [] = "FDCONFIG.SYS"; +STATIC char szLine[256] BSS_INIT({0}); +STATIC char szBuf[256] BSS_INIT({0}); -COUNT MenuTimeout = -1; -BYTE MenuSelected BSS_INIT(0); -UCOUNT MenuLine BSS_INIT(0); -UCOUNT Menus BSS_INIT(0); +UBYTE askCommand BSS_INIT(0); -STATIC VOID CfgMenuColor(BYTE * pLine); +static int MenuTimeout = -1; +static unsigned last_choice = 10; /* =non existing choice */ +static unsigned line_choices BSS_INIT(0); +static unsigned all_choices BSS_INIT(0); -STATIC VOID Config_Buffers(BYTE * pLine); -STATIC VOID sysScreenMode(BYTE * pLine); -STATIC VOID sysVersion(BYTE * pLine); -STATIC VOID CfgBreak(BYTE * pLine); -STATIC VOID Device(BYTE * pLine); -STATIC VOID DeviceHigh(BYTE * pLine); -STATIC VOID Files(BYTE * pLine); -STATIC VOID FilesHigh(BYTE * pLine); -STATIC VOID Fcbs(BYTE * pLine); -STATIC VOID CfgLastdrive(BYTE * pLine); -STATIC VOID CfgLastdriveHigh(BYTE * pLine); -STATIC BOOL LoadDevice(BYTE * pLine, char FAR *top, COUNT mode); -STATIC VOID Dosmem(BYTE * pLine); -STATIC VOID DosData(BYTE * pLine); -STATIC VOID Country(BYTE * pLine); -STATIC VOID InitPgm(BYTE * pLine); -STATIC VOID InitPgmHigh(BYTE * pLine); -STATIC VOID CmdInstall(BYTE * pLine); -STATIC VOID CmdInstallHigh(BYTE * pLine); -STATIC VOID CmdSet(BYTE * pLine); - - -STATIC VOID CfgSwitchar(BYTE * pLine); -STATIC VOID CfgSwitches(BYTE * pLine); -STATIC VOID CfgFailure(BYTE * pLine); -STATIC VOID CfgIgnore(BYTE * pLine); -STATIC VOID CfgMenu(BYTE * pLine); - -STATIC VOID CfgMenuEsc(BYTE * pLine); +STATIC BOOL LoadDevice(PCStr, VFP top, int mode); +STATIC void CfgFailure(PCStr); STATIC VOID DoMenu(void); -STATIC VOID CfgMenuDefault(BYTE * pLine); -STATIC BYTE * skipwh(BYTE * s); -STATIC BYTE * scan(BYTE * s, BYTE * d); -STATIC BOOL isnum(char ch); -#if 0 -STATIC COUNT tolower(COUNT c); -#endif +STATIC PCStr skipwh(PCStr); +STATIC PCStr scanword(PCStr, PStr); +STATIC PCStr scanverb(PCStr, PStr); +#define isdigit(ch) ((UBYTE)((ch) - '0') <= 9) STATIC char toupper(char c); -STATIC VOID strupr(char *s); -STATIC VOID mcb_init(UCOUNT seg, UWORD size, BYTE type); -STATIC VOID mumcb_init(UCOUNT seg, UWORD size); +static PStr strupr(PStr); +static PStr strcat(PStr d, PCStr s); +STATIC void mcb_init(seg_t, size_t, BYTE type); +STATIC void mumcb_init(seg_t, size_t); +#define mcb_next(seg) ((seg) + MK_SEG_PTR(mcb, seg)->m_size + 1) -STATIC VOID Stacks(BYTE * pLine); -STATIC VOID StacksHigh(BYTE * pLine); - -STATIC VOID SetAnyDos(BYTE * pLine); -STATIC VOID Numlock(BYTE * pLine); -STATIC BYTE * GetNumArg(BYTE * pLine, COUNT * pnArg); -BYTE *GetStringArg(BYTE * pLine, BYTE * pszString); -STATIC int SkipLine(char *pLine); -#if 0 -STATIC char * stristr(char *s1, char *s2); -#endif -STATIC char strcaseequal(const char * d, const char * s); -STATIC int LoadCountryInfoHardCoded(char *filename, COUNT ctryCode, COUNT codePage); +STATIC PCStr GetNumArg(PCStr); +STATIC BOOL GetNumArg1(PCStr); +STATIC BOOL GetNumArg2(PCStr, int default2); +static void hintSkipAll(void); +static BOOL askSkipLine(void); +STATIC char strcasediff(PCStr, PCStr); +STATIC void LoadCountryInfoHardCoded(CStr filename, int ccode, int cpage); STATIC void umb_init(void); -void HMAconfig(int finalize); STATIC void config_init_buffers(int anzBuffers); /* from BLOCKIO.C */ STATIC void config_init_fnodes(int f_nodes_cnt); -#ifdef I86 -STATIC VOID FAR * AlignParagraph(VOID FAR * lpPtr); -#else -#define AlignParagraph(x) ((VOID *)x) -#endif - #define EOF 0x1a -STATIC struct table * LookUp(struct table *p, BYTE * token); +typedef void config_sys_func_t(PCStr); -typedef void config_sys_func_t(BYTE * pLine); +STATIC config_sys_func_t + CfgSwitches, + CfgMenuColor, CfgMenuDefault, CfgMenu, CfgMenuEsc, + CfgBreak, Config_Buffers, Country, Dosmem, DosData, + Fcbs, Files, FilesHigh, CfgLastdrive, CfgLastdriveHigh, + Numlock, CmdShell, CmdShellHigh, + Stacks, StacksHigh, CfgSwitchar, + sysScreenMode, sysVersion, SetAnyDos, + Device, DeviceHigh, CmdInstall, CmdInstallHigh, CmdSet; -struct table { - BYTE *entry; - signed char pass; - config_sys_func_t *func; -}; +STATIC struct table { + PCStr const entry; + UBYTE pass; + config_sys_func_t *const func; -STATIC struct table commands[] = { - /* first = switches! this one is special since it is asked for but - also checked before F5/F8 */ +} commands [] = { + + /* this one is special since it checked for /N/F before F5/F8 and + asked for /K/E after menu; DoConfig() changes commands[0].pass */ {"SWITCHES", 0, CfgSwitches}, - /* rem is never executed by locking out pass */ - {"REM", 0, CfgIgnore}, - {";", 0, CfgIgnore}, - - {"MENUCOLOR",0,CfgMenuColor}, + {"REM", 100, NULL}, + {"MENUCOLOR", 0, CfgMenuColor}, {"MENUDEFAULT", 0, CfgMenuDefault}, - {"MENU", 0, CfgMenu}, /* lines to print in pass 0 */ - {"ECHO", 2, CfgMenu}, /* lines to print in pass 2 - install(high) */ - {"EECHO", 2, CfgMenuEsc}, /* modified ECHO (ea) */ + {"MENU", 1, CfgMenu}, /* lines to print in pass 1 */ + {"ECHO", 3, CfgMenu}, /* lines to print in pass 3 */ + {"EECHO", 3, CfgMenuEsc}, /* modified ECHO (ea) */ - {"BREAK", 1, CfgBreak}, - {"BUFFERS", 1, Config_Buffers}, - {"COMMAND", 1, InitPgm}, - {"COUNTRY", 1, Country}, - {"DOS", 1, Dosmem}, - {"DOSDATA", 1, DosData}, - {"FCBS", 1, Fcbs}, - {"FILES", 1, Files}, - {"FILESHIGH", 1, FilesHigh}, - {"LASTDRIVE", 1, CfgLastdrive}, - {"LASTDRIVEHIGH", 1, CfgLastdriveHigh}, - {"NUMLOCK", 1, Numlock}, - {"SHELL", 1, InitPgm}, - {"SHELLHIGH", 1, InitPgmHigh}, - {"STACKS", 1, Stacks}, - {"STACKSHIGH", 1, StacksHigh}, - {"SWITCHAR", 1, CfgSwitchar}, - {"SCREEN", 1, sysScreenMode}, /* JPP */ - {"VERSION", 1, sysVersion}, /* JPP */ - {"ANYDOS", 1, SetAnyDos}, /* tom */ + {"BREAK", 2, CfgBreak}, + {"BUFFERS", 2, Config_Buffers}, + {"BUFFERSHIGH", 2, Config_Buffers}, /* currently dummy */ + {"COUNTRY", 2, Country}, + {"DOS", 2, Dosmem}, + {"DOSDATA", 2, DosData}, + {"FCBS", 2, Fcbs}, + {"FILES", 2, Files}, + {"FILESHIGH", 2, FilesHigh}, + {"LASTDRIVE", 2, CfgLastdrive}, + {"LASTDRIVEHIGH", 2, CfgLastdriveHigh}, + {"NUMLOCK", 2, Numlock}, + {"STACKS", 2, Stacks}, + {"STACKSHIGH", 2, StacksHigh}, + {"SWITCHAR", 2, CfgSwitchar}, + {"SCREEN", 2, sysScreenMode}, /* JPP */ + {"VERSION", 2, sysVersion}, /* JPP */ + {"ANYDOS", 2, SetAnyDos}, /* tom */ - {"DEVICE", 2, Device}, - {"DEVICEHIGH", 2, DeviceHigh}, - {"INSTALL", 2, CmdInstall}, - {"INSTALLHIGH", 2, CmdInstallHigh}, - {"SET", 2, CmdSet}, - - /* default action */ - {"", -1, CfgFailure} + {"DEVICE", 3, Device}, + {"DEVICEHIGH", 3, DeviceHigh}, + + {"INSTALL", 4, CmdInstall}, + {"INSTALLHIGH", 4, CmdInstallHigh}, + {"SET", 4, CmdSet}, + {"SHELL", 4, CmdShell}, + {"SHELLHIGH", 4, CmdShellHigh}, }; -/* RE function for menu. */ -int findend(BYTE * s) -{ - int nLen = 0; - /* 'marks' end if at least ten spaces, 0, or newline is found. */ - while (*s && (*s != 0x0d || *s != 0x0a) ) - { - BYTE *p= skipwh(s); - /* ah, more than 9 whitespaces ? We're done here (hrmph!) */ - if(p - s >= 10) - break; - nLen++; - ++s; - } - return nLen; -} +enum { HMA_NONE, /* do nothing */ + HMA_REQ, /* DOS=HIGH detected */ + HMA_DONE, /* Moved kernel to HMA */ +}; -BYTE *pLineStart BSS_INIT(0); +enum { UMB_NONE, /* do nothing */ + UMB_DONE, /* UMB initialized */ + UMB_REQ, /* DOS=UMB detected */ +}; -BYTE HMAState BSS_INIT(0); -#define HMA_NONE 0 /* do nothing */ -#define HMA_REQ 1 /* DOS = HIGH detected */ -#define HMA_DONE 2 /* Moved kernel to HMA */ -#define HMA_LOW 3 /* Definitely LOW */ +static UBYTE HMAState BSS_INIT(HMA_NONE); +static UBYTE UmbState BSS_INIT(UMB_NONE); /* Do first time initialization. Store last so that we can reset it */ /* later. */ @@ -345,7 +270,7 @@ void PreConfig(void) /* Initialize the file table */ config_init_fnodes(Config.cfgFiles); - LoL->sfthead = MK_FP(FP_SEG(LoL), 0xcc); /* &(LoL->firstsftt) */ + LoL->sfthead = MK_PTR(struct sfttbl, FP_SEG(LoL), 0xcc); /* &(LoL->firstsftt) */ /* LoL->FCBp = (sfttbl FAR *)&FcbSft; */ /* LoL->FCBp = (sfttbl FAR *) KernelAlloc(sizeof(sftheader) @@ -366,17 +291,26 @@ void PreConfig(void) /* Done. Now initialize the MCB structure */ /* This next line is 8086 and 80x86 real mode specific */ #ifdef DEBUG - printf("Preliminary allocation completed: top at %p\n", lpTop); + printf("Preliminary allocation completed: top at %p\n", lpTop); #endif } -/* Do second pass initialization: near allocation and MCBs */ -void PreConfig2(void) +static void KernelAllocSFT(sfttbl FAR *p, unsigned files, int high) { - struct sfttbl FAR *sp; + p = p->sftt_next = (sfttbl FAR *)KernelAlloc(sizeof(sftheader) + + files * sizeof(sft), 'F', high); + p->sftt_count = files; + p->sftt_next = (sfttbl FAR *)-1l; +} +#define EBDASEG 0x40e +#define RAMSIZE 0x413 +#define RAM_size() peek(0, RAMSIZE) + +/* Do pre-drivers initialization: near allocation and MCBs */ +static void PreConfig3(void) +{ /* initialize NEAR allocated things */ - /* Initialize the base memory pointers from last time. */ /* if the kernel could be moved to HMA, everything behind the dynamic @@ -385,52 +319,58 @@ void PreConfig2(void) and allocation starts after the kernel. */ - base_seg = LoL->first_mcb = FP_SEG(AlignParagraph((BYTE FAR *) DynLast() + 0x0f)); - - if (Config.ebda2move) + size_t ram_top = RAM_size(); /* how much conventional RAM, kb */ + seg_t ebdaseg = peek(0, EBDASEG); + size_t ebdasz = peekb(ebdaseg, 0); + if (Config.ebda2move && ram_top * 64 == ebdaseg && ebdasz <= 63) { - ebda_size = ebdasize(); - ram_top += ebda_size / 1024; - if (ebda_size > Config.ebda2move) - ebda_size = Config.ebda2move; + ram_top += ebdasz; + ebdasz *= 1024u; + if (ebdasz > Config.ebda2move) + ebdasz = (Config.ebda2move + 15) & -16; + ebda_size = ebdasz; } /* We expect ram_top as Kbytes, so convert to paragraphs */ - mcb_init(base_seg, ram_top * 64 - LoL->first_mcb - 1, MCB_LAST); + base_seg = LoL->first_mcb = FP_SEG(alignNextPara(DynLast())); + mcb_init(base_seg, ram_top * 64 - base_seg, MCB_LAST); - sp = LoL->sfthead; - sp = sp->sftt_next = KernelAlloc(sizeof(sftheader) + 3 * sizeof(sft), 'F', 0); - sp->sftt_next = (sfttbl FAR *) - 1; - sp->sftt_count = 3; + /* allocate space in low memory for 3 file handles + (SFT) in addition to 5 handles, builtin into LOL */ + KernelAllocSFT(LoL->sfthead, 3, 0); if (ebda_size) /* move the Extended BIOS Data Area from top of RAM here */ - movebda(ebda_size, FP_SEG(KernelAlloc(ebda_size, 'I', 0))); + { + seg_t new_seg = FP_SEG(KernelAlloc(ebda_size, 'I', 0)); + fmemcpy(MK_SEG_PTR(BYTE, new_seg), MK_SEG_PTR(const BYTE, ebdaseg), ebda_size); + poke(0, EBDASEG, new_seg); + poke(0, RAMSIZE, ram_top); + } - if (UmbState == 2) - umb_init(); + umb_init(); } -/* Do third pass initialization. */ -/* Also, run config.sys to load drivers. */ +/* Do last initialization. */ void PostConfig(void) { - sfttbl FAR *sp; - /* We could just have loaded FDXMS or HIMEM */ if (HMAState == HMA_REQ && MoveKernelToHMA()) HMAState = HMA_DONE; - + if (Config.cfgDosDataUmb) { - Config.cfgFilesHigh = TRUE; - Config.cfgLastdriveHigh = TRUE; - Config.cfgStacksHigh = TRUE; + Config.cfgFilesHigh = + Config.cfgStacksHigh = + Config.cfgLastdriveHigh = 1; } - + /* compute lastdrive ... */ - LoL->lastdrive = Config.cfgLastdrive; - if (LoL->lastdrive < LoL->nblkdev) - LoL->lastdrive = LoL->nblkdev; + { + UBYTE drv = Config.cfgLastdrive; + if (drv < LoL->nblkdev) + drv = LoL->nblkdev; + LoL->lastdrive = drv; + } DebugPrintf(("starting FAR allocations at %x\n", base_seg)); @@ -449,12 +389,11 @@ void PostConfig(void) /* LoL->FCBp = (sfttbl FAR *)&FcbSft; */ /* LoL->FCBp = KernelAlloc(sizeof(sftheader) + Config.cfgFiles * sizeof(sft)); */ - sp = LoL->sfthead->sftt_next; - sp = sp->sftt_next = (sfttbl FAR *) - KernelAlloc(sizeof(sftheader) + (Config.cfgFiles - 8) * sizeof(sft), 'F', - Config.cfgFilesHigh); - sp->sftt_next = (sfttbl FAR *) - 1; - sp->sftt_count = Config.cfgFiles - 8; + + /* allocate space for remaining file handles (SFT); 5 are + already builtin and 3 are allocated in PreConfig3() */ + KernelAllocSFT(LoL->sfthead->sftt_next, + Config.cfgFiles - 8, Config.cfgFilesHigh); LoL->CDSp = KernelAlloc(sizeof(struct cds) * LoL->lastdrive, 'L', Config.cfgLastdriveHigh); @@ -465,9 +404,10 @@ void PostConfig(void) printf(" CDS table 0x%p\n", LoL->CDSp); printf(" DPB table 0x%p\n", LoL->DPBp); #endif + if (Config.cfgStacks) { - VOID FAR *stackBase = + void _seg *stackBase = KernelAlloc(Config.cfgStacks * Config.cfgStackSize, 'S', Config.cfgStacksHigh); init_stacks(stackBase, Config.cfgStacks, Config.cfgStackSize); @@ -481,17 +421,18 @@ void PostConfig(void) /* This code must be executed after device drivers has been loaded */ VOID configDone(VOID) { - if (UmbState == 1) - para2far(base_seg)->m_type = MCB_LAST; + if (UmbState == UMB_DONE) + MK_SEG_PTR(mcb, base_seg)->m_type = MCB_LAST; if (HMAState != HMA_DONE) { - mcb FAR *p; - unsigned short kernel_seg; - unsigned short hma_paras = (HMAFree+0xf)/16; - - kernel_seg = allocmem(hma_paras); - p = para2far(kernel_seg - 1); +#ifdef DEBUG + size_t hma_paras = (HMAFree + 15) / 16; + seg_t kernel_seg = allocmem(hma_paras); +#else + seg_t kernel_seg = allocmem((HMAFree + 15) / 16); +#endif + mcb _seg *p = MK_SEG_PTR(mcb, kernel_seg - 1); p->m_name[0] = 'S'; p->m_name[1] = 'C'; @@ -499,357 +440,417 @@ VOID configDone(VOID) DebugPrintf(("HMA not available, moving text to %x\n", kernel_seg)); MoveKernel(kernel_seg); - - kernel_seg += hma_paras + 1; - - DebugPrintf(("kernel is low, start alloc at %x", kernel_seg)); + DebugPrintf(("kernel is low, start alloc at %x\n", + kernel_seg + hma_paras + 1)); } /* The standard handles should be reopened here, because we may have loaded new console or printer drivers in CONFIG.SYS */ } -STATIC seg prev_mcb(seg cur_mcb, seg start) -{ - /* determine prev mcb */ - seg mcb_prev, mcb_next; - mcb_prev = mcb_next = start; - while (mcb_next < cur_mcb && para2far(mcb_next)->m_type == MCB_NORMAL) - { - mcb_prev = mcb_next; - mcb_next += para2far(mcb_prev)->m_size + 1; - } - return mcb_prev; -} - STATIC void umb_init(void) { - UCOUNT umb_seg, umb_size; - seg umb_max; - void far *xms_addr; + CVFP xms_addr; + seg_t umb_seg; + size_t umb_size; - if ((xms_addr = DetectXMSDriver()) == NULL) - return; - - if (UMB_get_largest(xms_addr, &umb_seg, &umb_size)) + if (UmbState == UMB_REQ && + (xms_addr = DetectXMSDriver()) != NULL && + UMB_get_largest(xms_addr, &umb_seg, &umb_size)) { - UmbState = 1; + seg_t umb_furthest = umb_seg; + + /* SAFETY: new block may be too small or below memory top */ + seg_t base_top = RAM_size() * 64 - 1; + if (umb_size < 2 || umb_furthest <= base_top) + return; + + UmbState = UMB_DONE; /* reset root */ - LoL->uppermem_root = ram_top * 64 - 1; + LoL->uppermem_root = base_top; + umb_base_seg = umb_furthest; /* create link mcb (below) */ - para2far(base_seg)->m_type = MCB_NORMAL; - para2far(base_seg)->m_size--; - mumcb_init(LoL->uppermem_root, umb_seg - LoL->uppermem_root - 1); + /* (it prefixes hole between UMBs) */ + MK_SEG_PTR(mcb, base_seg)->m_type = MCB_NORMAL; + MK_SEG_PTR(mcb, base_seg)->m_size--; + mumcb_init(base_top, umb_seg - base_top); /* setup the real mcb for the devicehigh block */ - mcb_init(umb_seg, umb_size - 2, MCB_NORMAL); + mcb_init(umb_seg, umb_size, MCB_NORMAL); - umb_base_seg = umb_max = umb_start = umb_seg; - UMB_top = umb_size; - - /* there can be more UMB's ! - this happens, if memory mapped devces are in between + /* there can be more UMBs ! + this happens, if memory mapped devices are in between like UMB memory c800..c8ff, d8ff..efff with device at d000..d7ff However some of the xxxHIGH commands still only work with the first UMB. */ - while (UMB_get_largest(xms_addr, &umb_seg, &umb_size)) { - seg umb_prev, umb_next; - - /* setup the real mcb for the devicehigh block */ - mcb_init(umb_seg, umb_size - 2, MCB_NORMAL); - - /* determine prev and next umbs */ - umb_prev = prev_mcb(umb_seg, LoL->uppermem_root); - umb_next = umb_prev + para2far(umb_prev)->m_size + 1; - - if (umb_seg < umb_max) + if (umb_furthest < umb_seg) { - if (umb_next - umb_seg - umb_size == 0) + seg_t umb_hole = mcb_next(umb_furthest); + + /* SAFETY: new block may (1) be adjacent to old block, + (2) overlap it or (3) be inside. (2) and (3) are errors + and shouldn't happen, but handle them anyway. */ + if (umb_hole >= umb_seg) { - /* should the UMB driver return - adjacent memory in several pieces */ - umb_size += para2far(umb_next)->m_size + 1; - para2far(umb_seg)->m_size = umb_size; + size_t overlap = umb_hole - umb_seg; + if (overlap < umb_size) + /* join adjacent/overlapped new block to prev block */ + MK_SEG_PTR(mcb, umb_furthest)->m_size += umb_size - overlap; + continue; } + + /* SAFETY: new block may be too small */ + if (umb_size < 2) + continue; + + /* create link mcb (below) */ + MK_SEG_PTR(mcb, umb_furthest)->m_size--; + umb_furthest = umb_seg; + umb_hole--; + mumcb_init(umb_hole, umb_seg - umb_hole); + } + else /* umb_seg <= umb_furthest */ + { + seg_t umb_prev, umb_hole, umb_next, umb_cur_next; + + /* SAFETY: umb_seg may point into base memory */ + if (base_top >= umb_seg) + continue; + + /* find previous block */ + for (umb_hole = base_top;;) + { + umb_next = mcb_next(umb_hole); + /* ASSUME umb_hole->m_type == 'M' && umb_hole->m_psp == 8 && + umb_next->m_type == 'M' && umb_next->m_psp != 8 && + umb_hole < umb_next <= umb_furthest */ + if (umb_seg <= umb_next) + break; + umb_prev = umb_next; + umb_hole = mcb_next(umb_next); + } + /* NOW base_top == umb_hole < umb_seg <= umb_next || + base_top < umb_prev < umb_seg <= umb_next */ + + /* SAFETY: new block may be inside previous block */ + umb_cur_next = umb_seg + umb_size; + if (umb_cur_next <= umb_hole) + continue; + + /* SAFETY: umb_seg may point below hole, + so, use ">=" instead "==" */ + if (umb_hole + 1 >= umb_seg && umb_hole != base_top) + /* join adjacent/overlapped new block to prev block */ + umb_size = umb_cur_next - (umb_seg = umb_prev); else { - /* create link mcb (above) */ - mumcb_init(umb_seg + umb_size - 1, umb_next - umb_seg - umb_size); + /* SAFETY: new block may be too small */ + if (umb_size < 2 && umb_cur_next < umb_next) + continue; + /* adjust link mcb below */ + MK_SEG_PTR(mcb, umb_hole)->m_size = umb_seg - umb_hole - 1; } - } - else /* umb_seg >= umb_max */ - { - umb_prev = umb_next; - } - if (umb_seg - umb_prev - 1 == 0) - /* should the UMB driver return - adjacent memory in several pieces */ - para2far(prev_mcb(umb_prev, LoL->uppermem_root))->m_size += umb_size; - else - { - /* create link mcb (below) */ - mumcb_init(umb_prev, umb_seg - umb_prev - 1); - } + /* SAFETY: new block may overlap next block, + so, use ">=" instead "==" */ + if (umb_cur_next >= umb_next) + { + /* join adjacent/overlapped next block to new block */ + if (umb_furthest == umb_next) + umb_furthest = umb_seg; + if (umb_base_seg == umb_next) + umb_base_seg = umb_seg; + umb_size = mcb_next(umb_next) - umb_seg; + } + else /* umb_cur_next < umb_next */ + { + /* create link mcb (above) */ + umb_size--, umb_cur_next--; + mumcb_init(umb_cur_next, umb_next - umb_cur_next); + } + } /* else */ + + /* setup the real mcb for the devicehigh block */ + mcb_init(umb_seg, umb_size, MCB_NORMAL); + } /* while */ + + MK_SEG_PTR(mcb, umb_furthest)->m_type = MCB_LAST; + umb_base_start = umb_base_seg; - if (umb_seg > umb_max) - umb_max = umb_seg; - } - para2far(umb_max)->m_size++; - para2far(umb_max)->m_type = MCB_LAST; DebugPrintf(("UMB Allocation completed: start at 0x%x\n", umb_base_seg)); - } + } /* if */ } -VOID DoConfig(int nPass) +STATIC const struct table * LookUp(CStr token) { - COUNT nFileDesc; - BYTE *pLine; - BOOL bEof; + const struct table *p = commands; + do + if (!strcasediff(p->entry, token)) + return p; + while (++p < ENDOF(commands)); + p = NULL; + return p; +} +static void DoConfig_(void) +{ + int nFileDesc, done; + + if (askCommand & ASK_SKIPALL) + return; /* Check to see if we have a config.sys file. If not, just */ /* exit since we don't force the user to have one. */ - if ((nFileDesc = open("fdconfig.sys", 0)) >= 0) + /*strcpy (configfile, "FDCONFIG.SYS");*/ + if ((nFileDesc = open(configfile, 0)) < 0) { - DebugPrintf(("Reading FDCONFIG.SYS...\n")); - } - else - { - DebugPrintf(("FDCONFIG.SYS not found\n")); - if ((nFileDesc = open("config.sys", 0)) < 0) + DebugPrintf(("%s not found\n", configfile)); + strcpy (configfile, "CONFIG.SYS"); + if ((nFileDesc = open(configfile, 0)) < 0) { - DebugPrintf(("CONFIG.SYS not found\n")); + DebugPrintf(("%s not found\n", configfile)); return; } - DebugPrintf(("Reading CONFIG.SYS...\n")); } - - /* Have one -- initialize. */ - nCfgLine = 0; - bEof = 0; - pLine = szLine; + DebugPrintf(("Reading %s...\n", configfile)); /* Read each line into the buffer and then parse the line, */ /* do the table lookup and execute the handler for that */ /* function. */ - - for (; !bEof; nCfgLine++) + done = nCfgLine = 0; + do { - struct table *pEntry; - - pLineStart = szLine; + PStr q; + PCStr p; + const struct table *pEntry; /* read in a single line, \n or ^Z terminated */ - - for (pLine = szLine;;) + nCfgLine++; + for (q = szLine;;) { - if (read(nFileDesc, pLine, 1) <= 0) + if (read(nFileDesc, q, 1) <= 0 || *q == EOF) { - bEof = TRUE; + done++; break; } - if (pLine >= szLine + sizeof(szLine) - 3) + if (*q == '\n') /* end of line */ + break; + + if (*q != '\r') /* ignore CR */ { - CfgFailure(pLine); - printf("error - line overflow line %d \n", nCfgLine); - break; + q++; + if (q >= szLine + sizeof szLine - 1) + { + /* *q = 0; */ /* static memory already zeroed */ + CfgFailure(q); + say("error - line overflow\n"); + break; + } } + } /* for */ + *q = 0; /* terminate line - make ASCIIZ */ - if (*pLine == '\n' || *pLine == EOF) /* end of line */ - break; + p = skipwh(szLine); + if (*p == '\0' || *p == ';') + continue; /* skip empty line and comment */ - if (*pLine != '\r') /* ignore CR */ - pLine++; + p = scanverb(p, szBuf); /* extract verb */ + pEntry = LookUp(szBuf); + if (pEntry == NULL) + { + if (nPass == 2) /* only at pass 2 (after menu)... */ + CfgFailure(p); /* ...say error for wrong verb */ + continue; } - *pLine = 0; - pLine = szLine; - - /* Skip leading white space and get verb. */ - pLine = scan(pLine, szBuf); - - /* If the line was blank, skip it. Otherwise, look up */ - /* the verb and execute the appropriate function. */ - if (*szBuf == '\0') + if (nPass != pEntry->pass || + nPass > 1 && /* after menu: check "123?device=" */ + !testbit(line_choices, last_choice)) continue; - pEntry = LookUp(commands, szBuf); - - if (pEntry->pass >= 0 && pEntry->pass != nPass) - continue; - - if (nPass == 0) /* pass 0 always executed (rem Menu prompt switches) */ + if (pEntry->func != CfgMenu && pEntry->func != CfgMenuEsc) { - pEntry->func(pLine); - continue; - } - else - { - if (SkipLine(pLineStart)) /* F5/F8 processing */ + if (*p) + { + if (*p != ' ' && *p != '\t' && *p != '=') + { + CfgFailure(p); + continue; + } + p = skipwh(p); + if (*p == '=') /* accept "device foo.sys" without '=' */ + p = skipwh(p + 1); + } + if (nPass > 1 && askSkipLine()) /* after menu: processing "?" */ continue; } - - if ((pEntry->func != CfgMenu) && (pEntry->func != CfgMenuEsc)) - { - /* compatibility "device foo.sys" */ - if (' ' != *pLine && '\t' != *pLine && '=' != *pLine) - { - CfgFailure(pLine); - continue; - } - pLine = skipwh(pLine); - } - if ('=' == *pLine || pEntry->func == CfgMenu || pEntry->func == CfgMenuEsc) - pLine = skipwh(pLine+1); + if (*p == ' ' || *p == '\t') + p++; /* YES. DO IT */ - pEntry->func(pLine); - } - close(nFileDesc); + pEntry->func(p); + } while (!done && !(askCommand & ASK_SKIPALL)); - if (nPass == 0) - { - DoMenu(); - } + close(nFileDesc); + nPass++; } -STATIC struct table * LookUp(struct table *p, BYTE * token) +void DoConfig() { - while (p->entry[0] != '\0' && !strcaseequal(p->entry, token)) - ++p; - return p; + DoConfig_(); /* switches=/f/n, menucolor= */ + hintSkipAll(); + if (!(askCommand & ASK_SKIPALL)) + { + if (MenuColor) /* color defined? */ + ClearScreenArea(MenuColor, 0, 0, screenwidth(), screenbottom() + 1); + DoConfig_(); /* show MENU, find choices */ + if (all_choices) + { + if (!testbit(all_choices, last_choice)) + { + unsigned ac; + last_choice = 0; /* find lowest existing choice */ + for (ac = all_choices; !testbit(ac, 0); ac >>= 1) + last_choice++; + } + if ((all_choices - 1) & all_choices) /* more than one choice? */ + DoMenu(); + if (!(askCommand & ASK_SKIPALL)) + { + static char choice[] = "CONFIG=0"; + choice[7] = (UBYTE)'0' + last_choice; + CmdSet(choice); /* show choice in environment */ + } + } + commands[0].pass = 2; /* switches=/k/e at pass 2 */ + DoConfig_(); /* break=, files=, etc. */ + } + PreConfig3(); + DoConfig_(); /* device= */ } /* get BIOS key with timeout: - - timeout < 0: no timeout + timeout < 0: no timeout, remove returned key from keyboard buffer timeout = 0: poll only once - timeout > 0: timeout in seconds - + timeout > 0: timeout for poll in seconds return - 0xffff : no key hit - + 0 : no key hit (only for timeout >= 0) 0xHH.. : scancode in upper half 0x..LL : asciicode in lower half */ #define GetBiosTime() peekl(0, 0x46c) -UWORD GetBiosKey(int timeout) +#define ESC 27 +#define K_F5 0x3F00 +#define K_F8 0x4200 +#define K_Left 0x4B00 +#define K_Right 0x4D00 +#define K_Up 0x4800 +#define K_Down 0x5000 + +unsigned GetBiosKey(int timeout) { iregs r; - - ULONG startTime = GetBiosTime(); - - if (timeout >= 0) do + if (timeout >= 0) { - r.a.x = 0x0100; /* are there keys available ? */ - init_call_intr(0x16, &r); - if ((unsigned)(GetBiosTime() - startTime) >= timeout * 18u) - return 0xffff; + ULONG startTime = GetBiosTime(); + do + { + r.AH = 0x01; /* are there keys available ? */ + init_call_intr(0x16, &r); + if (!(r.flags & FLG_ZERO)) + return r.AX; + } while ((unsigned)(GetBiosTime() - startTime) < timeout * 18u); + return 0; } - while (r.flags & FLG_ZERO); /* key available or blocking wait (timeout < 0): fetch it */ - r.a.x = 0x0000; + r.AH = 0x00; init_call_intr(0x16, &r); - return r.a.x; + return r.AX; } -STATIC BOOL SkipLine(char *pLine) +static void hintSkipAll(void) { - short key; - - if (InitKernelConfig.SkipConfigSeconds >= 0) + int timeout = InitKernelConfig.SkipConfigSeconds; + if (timeout >= 0) { + unsigned key; - if (InitKernelConfig.SkipConfigSeconds > 0) - printf("Press F8 to trace or F5 to skip CONFIG.SYS/AUTOEXEC.BAT"); + if ((all_choices - 1) & all_choices) /* more than one choice? */ + timeout = 0; - key = GetBiosKey(InitKernelConfig.SkipConfigSeconds); /* wait 2 seconds */ - - InitKernelConfig.SkipConfigSeconds = -1; + if (timeout > 0) + say2("Press F8 to trace or F5 to skip %s/AUTOEXEC.BAT", configfile); + key = GetBiosKey(timeout); + clearrow(); /* clear hint line */ - if (key == 0x3f00) /* F5 */ + if (key == K_F8) /* F8 */ { - SkipAllConfig = TRUE; + askCommand |= ASK_TRACE; + GetBiosKey(-1); /* remove key from buffer */ } - else if (key == 0x4200) /* F8 */ + else if (key == K_F5) /* F5 */ { - singleStep = TRUE; + askCommand |= ASK_SKIPALL; + say2("Bypassing %s and AUTOEXEC.BAT files.\n", configfile); + GetBiosKey(-1); /* remove key from buffer */ } - - printf("\r%79s\r", ""); /* clear line */ - - if (SkipAllConfig) - printf("Skipping CONFIG.SYS/AUTOEXEC.BAT\n"); } +} - if (SkipAllConfig) - return TRUE; - - /* 1?device=CDROM.SYS */ - /* 12?device=OAKROM.SYS */ - /* 123?device=EMM386.EXE NOEMS */ - if ( MenuLine != 0 && - (MenuLine & (1 << MenuSelected)) == 0) - return TRUE; - - if (DontAskThisSingleCommand) /* !files=30 */ - return FALSE; - - if (!askThisSingleCommand && !singleStep) - return FALSE; - - printf("%s[Y,N]?", pLine); +static BOOL askSkipLine(void) +{ + /* !device= never ask / ?device= always ask / device= ask if ASK_TRACE */ + /* "!device?=" will not be asked... */ + if ((askCommand & (ASK_NOASK | ASK_YESALL)) || /* "!" or Esc */ + !(askCommand & (ASK_ASK | ASK_TRACE))) /* not ("?" or trace) */ + return FALSE; /* do not skip, and do not ask either */ + say2("%s[Y,n]?", szLine); for (;;) { - key = GetBiosKey(-1); - - switch (toupper(key & 0x00ff)) + unsigned key = GetBiosKey(-1); /* wait keypress */ + if (key == K_F5) /* YES, you may hit F5 here, too */ + { + askCommand |= ASK_SKIPALL; + key = 'N'; + } + if (key == K_F8) /* F8 */ + key = ESC; + switch (toupper((UBYTE)key)) { case 'N': - case 'n': - printf("N\n"); + say("N\n"); return TRUE; - case 0x1b: /* don't know where documented - ESCAPE answers all following questions - with YES - */ - singleStep = FALSE; /* and fall through */ + case ESC: /* Esc answers all following questions YES */ + askCommand &= ~ASK_TRACE; + askCommand |= ASK_YESALL; + /* and fall through */ case '\r': case '\n': case 'Y': - case 'y': - printf("Y\n"); + say("Y\n"); return FALSE; - } - - if (key == 0x3f00) /* YES, you may hit F5 here, too */ - { - printf("N\n"); - SkipAllConfig = TRUE; - return TRUE; - } - } - + } /* for */ } +static int numarg BSS_INIT(0); + /* JPP - changed so will accept hex number. */ /* ea - changed to accept hex digits in hex numbers */ -STATIC char *GetNumArg(char *p, int *num) +STATIC PCStr GetNumArg(PCStr p) { static char digits[] = "0123456789ABCDEF"; unsigned char base = 10; @@ -858,15 +859,15 @@ STATIC char *GetNumArg(char *p, int *num) /* look for NUMBER */ p = skipwh(p); - if (*p == '-') + if (!isdigit(*p)) { - p++; + if (*p != '-') + { + CfgFailure(p); + return NULL; + } sign = -1; - } - else if (!isnum(*p)) - { - CfgFailure(p); - return NULL; + p++; } for( ; *p; p++) @@ -876,277 +877,274 @@ STATIC char *GetNumArg(char *p, int *num) base = 16; else { - char *q = strchr(digits, ch); + PCStr q = strchr(digits, ch); if (q == NULL) break; n = n * base + (q - digits); } } - *num = n * sign; + numarg = n * sign; return p; } -BYTE *GetStringArg(BYTE * pLine, BYTE * pszString) +STATIC BOOL isEOL(PCStr p) { - /* look for STRING */ - pLine = skipwh(pLine); - - /* just return whatever string is there, including null */ - return scan(pLine, pszString); + if (*p) /* garbage at line end? */ + { + CfgFailure(p); + return FALSE; + } + return TRUE; } -STATIC void Config_Buffers(BYTE * pLine) +/* Format: nnn EOL */ +STATIC BOOL GetNumArg1(PCStr p) { - COUNT nBuffers; - - /* Get the argument */ - if (GetNumArg(pLine, &nBuffers)) - Config.cfgBuffers = nBuffers; -} - -/** - Set screen mode - rewritten to use init_call_intr() by RE / ICD -*/ -STATIC VOID sysScreenMode(BYTE * pLine) -{ - iregs r; - COUNT nMode; - COUNT nFunc = 0x11; - - /* Get the argument */ - if (GetNumArg(pLine, &nMode) == (BYTE *) 0) - return; - - if(nMode<0x10) - nFunc = 0; /* set lower screenmode */ - else if ((nMode != 0x11) && (nMode != 0x12) && (nMode != 0x14)) - return; /* do nothing; invalid screenmode */ - -/* Modes - 0x11 (17) 28 lines - 0x12 (18) 43/50 lines - 0x14 (20) 25 lines - */ - /* move cursor to pos 0,0: */ - r.a.b.h = nFunc; /* set videomode */ - r.a.b.l = nMode; - r.b.b.l = 0; - init_call_intr(0x10, &r); -} - -STATIC VOID sysVersion(BYTE * pLine) -{ - COUNT major, minor; - char *p = strchr(pLine, '.'); - + p = GetNumArg(p); if (p == NULL) - return; - - p++; - - /* Get major number */ - if (GetNumArg(pLine, &major) == (BYTE *) 0) - return; - - /* Get minor number */ - if (GetNumArg(p, &minor) == (BYTE *) 0) - return; - - printf("Changing reported version to %d.%d\n", major, minor); - - LoL->os_major = major; - LoL->os_minor = minor; + return FALSE; + return isEOL(skipwh(p)); } -STATIC VOID Files(BYTE * pLine) +static int numarg1 BSS_INIT(0); + +/* Format: nnn [, nnn] EOL */ +STATIC BOOL GetNumArg2(PCStr p, int default2) { - COUNT nFiles; + p = GetNumArg(p); + if (p == NULL) + return FALSE; - /* Get the argument */ - if (GetNumArg(pLine, &nFiles) == (BYTE *) 0) - return; + numarg1 = numarg; + numarg = default2; + p = skipwh(p); + if (*p == ',') + return GetNumArg1(p + 1); - /* Got the value, assign either default or new value */ - Config.cfgFiles = max(Config.cfgFiles, nFiles); - Config.cfgFilesHigh = 0; + return isEOL(p); } -STATIC VOID FilesHigh(BYTE * pLine) +/* Format: BUFFERS [=] nnn [, nnn] */ +STATIC void Config_Buffers(PCStr p) { - Files(pLine); - Config.cfgFilesHigh = 1; + if (GetNumArg2(p, 0)) + Config.cfgBuffers = (UBYTE)numarg1; + /* Second argument (0..8 buffers for read-ahead) not supported */ } -STATIC VOID CfgLastdrive(BYTE * pLine) +/* Set screen mode - rewritten to use init_call_intr() by RE / ICD */ +/* Format: SCREEN [=] nnn */ +STATIC void sysScreenMode(PCStr p) { - /* Format: LASTDRIVE = letter */ - BYTE drv; - - pLine = skipwh(pLine); - drv = toupper(*pLine); - - if (drv < 'A' || drv > 'Z') + if (GetNumArg1(p)) { - CfgFailure(pLine); + unsigned mode = numarg; + if (mode >= 0x10) + { + /* Modes + 0x11 (17) 28 lines + 0x12 (18) 43/50 lines + 0x14 (20) 25 lines + */ + if (mode != 0x11 && mode != 0x12 && mode != 0x14) + return; /* do nothing; invalid screenmode */ + mode |= 0x1100; + } + { + iregs r; + r.BL = 0; /* block to load for AH=0x11 */ + r.AX = mode; /* set videomode */ + init_call_intr(0x10, &r); + } + } +} + +/* Format: VERSION [=] nn.nn */ +STATIC void sysVersion(PCStr p) +{ + int major; + p = GetNumArg(p); + major = numarg; + if (p == NULL || *p != '.' || !GetNumArg1(p + 1)) + return; + + printf("Changing reported version to %d.%d\n", + LoL->os_setver_major = (UBYTE)major, + LoL->os_setver_minor = (UBYTE)numarg); +} + +/* Format: FILES [=] nnn */ +/* Format: FILESHIGH [=] nnn */ +static void _Files(PCStr p, UBYTE high) +{ + if (GetNumArg1(p)) + { + UBYTE nFiles = (UBYTE)numarg; + if (Config.cfgFiles < nFiles) + Config.cfgFiles = nFiles; + Config.cfgFilesHigh = high; + } +} + +STATIC void Files(PCStr p) { _Files(p, 0); } + +STATIC void FilesHigh(PCStr p) { _Files(p, 1); } + +/* Format: LASTDRIVE [=] letter */ +/* Format: LASTDRIVEHIGH [=] letter */ +static void _CfgLastdrive(PCStr p, UBYTE high) +{ + BYTE drv = toupper(*p); + if (drv < 'A' || drv > 'Z' || p[1]) + { + /* no or wrong character or garbage at line end? */ + CfgFailure(p); return; } - drv -= 'A' - 1; /* Make real number */ - if (drv > Config.cfgLastdrive) - Config.cfgLastdrive = drv; - Config.cfgLastdriveHigh = 0; + + drv -= 'A' - 1; /* Make real number */ + if (Config.cfgLastdrive < drv) + Config.cfgLastdrive = drv; + Config.cfgLastdriveHigh = high; } -STATIC VOID CfgLastdriveHigh(BYTE * pLine) -{ - /* Format: LASTDRIVEHIGH = letter */ - CfgLastdrive(pLine); - Config.cfgLastdriveHigh = 1; -} +STATIC void CfgLastdrive(PCStr p) { _CfgLastdrive(p, 0); } -/* - UmbState of confidence, 1 is sure, 2 maybe, 4 unknown and 0 no way. +STATIC void CfgLastdriveHigh(PCStr p) { _CfgLastdrive(p, 1); } + +/* UmbState of confidence, UMB_DONE is sure, UMB_REQ maybe, UMB_NONE no way. + Transitions: UMB_NONE -> UMB_NONE/UMB_REQ depending on DOS=UMB, try init + (UMB_REQ -> UMB_DONE) after each driver load, as it could have been the + UMB driver. + If UMB really found, state UMB_DONE is reached and MCBs are adjusted. */ - -STATIC VOID Dosmem(BYTE * pLine) +/* opt = HIGH | UMB + Format: DOS [=] opt {, opt} +*/ +STATIC void Dosmem(PCStr p) { - BYTE *pTmp; - BYTE UMBwanted = FALSE; - - pLine = GetStringArg(pLine, szBuf); - - strupr(szBuf); - - /* printf("DOS called with %s\n", szBuf); */ - - for (pTmp = szBuf;;) + UBYTE UMBwanted = UMB_NONE, HMAwanted = HMA_NONE; + for (;;) { - if (memcmp(pTmp, "UMB", 3) == 0) + PCStr q = scanword(p, szBuf); + if (!strcasediff(szBuf, "UMB")) + UMBwanted = UMB_REQ; + else if (!strcasediff(szBuf, "HIGH")) + HMAwanted = HMA_REQ; +/* else if (!strcasediff(szBuf, "CLAIMINIT")) + * INITDataSegmentClaimed = 0; + */ + else { - UMBwanted = TRUE; - pTmp += 3; + CfgFailure(p); + return; } - if (memcmp(pTmp, "HIGH", 4) == 0) + p = skipwh(q); + if (*p != ',') { - HMAState = HMA_REQ; - pTmp += 4; + if (*p == '\0') + break; + CfgFailure(p); + return; } -/* if (memcmp(pTmp, "CLAIMINIT",9) == 0) { INITDataSegmentClaimed = 0; pTmp += 9; }*/ - pTmp = skipwh(pTmp); + p++; + } /* for */ - if (*pTmp != ',') - break; - pTmp++; - } - - if (UmbState == 0) + if (UmbState == UMB_NONE) { LoL->uppermem_link = 0; LoL->uppermem_root = 0xffff; - UmbState = UMBwanted ? 2 : 0; + UmbState = UMBwanted; } /* Check if HMA is available straight away */ - if (HMAState == HMA_REQ && MoveKernelToHMA()) - { - HMAState = HMA_DONE; - } + if (HMAwanted == HMA_REQ) + HMAState = MoveKernelToHMA() ? HMA_DONE : HMA_REQ; } -STATIC VOID DosData(BYTE * pLine) +/* Format: DOSDATA [=] UMB */ +STATIC void DosData(PCStr p) { - pLine = GetStringArg(pLine, szBuf); - strupr(szBuf); - - if (memcmp(szBuf, "UMB", 3) == 0) + if (!strcasediff(p, "UMB")) Config.cfgDosDataUmb = TRUE; + else + CfgFailure(p); } -STATIC VOID CfgSwitchar(BYTE * pLine) +/* Format: SWITCHAR [=] character */ +STATIC void CfgSwitchar(PCStr p) { - /* Format: SWITCHAR = character */ - - GetStringArg(pLine, szBuf); - init_switchar(*szBuf); -} - -STATIC VOID CfgSwitches(BYTE * pLine) -{ - pLine = skipwh(pLine); - if (*pLine == '=') + if (*p == '\0' || p[1]) { - pLine = skipwh(pLine + 1); + /* no character or garbage at line end */ + CfgFailure(p); + return; } - while (*pLine) + init_switchar(*p); +} + +/* Format: SWITCHES [=] { /K | /N | /F | /E[[:]nnn] } */ +STATIC void CfgSwitches(PCStr p) +{ + do { - if (*pLine == '/') { - pLine++; - switch(toupper(*pLine)) { + if (*p != '/') + { + if (nPass) + CfgFailure(p); + return; + } + switch(toupper(*++p)) + { case 'K': - if (commands[0].pass == 1) + if (nPass) kbdType = 0; /* force conv keyb */ + p++; break; case 'N': InitKernelConfig.SkipConfigSeconds = -1; + p++; break; case 'F': InitKernelConfig.SkipConfigSeconds = 0; + p++; break; case 'E': /* /E[[:]nnnn] Set the desired EBDA amount to move in bytes */ - { /* Note that if there is no EBDA, this will have no effect */ - int n = 0; - if (*++pLine == ':') - pLine++; /* skip optional separator */ - if (!isnum(*pLine)) - { - pLine--; - break; - } - pLine = GetNumArg(pLine, &n) - 1; + /* Note that if there is no EBDA, this will have no effect */ + if (*++p == ':') + p++; /* skip optional separator */ + if (isdigit(*p)) + { + p = GetNumArg(p); + if (p == NULL) + return; /* allowed values: [48..1024] bytes, multiples of 16 * e.g. AwardBIOS: 48, AMIBIOS: 1024 * (Phoenix, MRBIOS, Unicore = ????) */ - if (n == -1) - { - Config.ebda2move = 0xffff; - break; - } - else if (n >= 48 && n <= 1024) - { - Config.ebda2move = (n + 15) & 0xfff0; - break; - } - /* else fall through (failure) */ + if (nPass) + Config.ebda2move = numarg; } + break; default: - CfgFailure(pLine); - } - } else { - CfgFailure(pLine); - } - pLine = skipwh(pLine+1); - } - commands[0].pass = 1; + if (nPass) + CfgFailure(p); + return; + } /* switch */ + p = skipwh(p); + } while (*p); } -STATIC VOID Fcbs(BYTE * pLine) +/* Format: FCBS [=] totalFcbs [, protectedFcbs] */ +STATIC void Fcbs(PCStr p) { - /* Format: FCBS = totalFcbs [,protectedFcbs] */ - COUNT fcbs; - - if ((pLine = GetNumArg(pLine, &fcbs)) == 0) - return; - Config.cfgFcbs = fcbs; - - pLine = skipwh(pLine); - - if (*pLine == ',') + if (GetNumArg2(p, Config.cfgProtFcbs)) { - GetNumArg(++pLine, &fcbs); - Config.cfgProtFcbs = fcbs; + UBYTE fcbs = (UBYTE)numarg1, prot = (UBYTE)numarg; + Config.cfgFcbs = fcbs; + if (prot > fcbs) + prot = fcbs; + Config.cfgProtFcbs = prot; } - - if (Config.cfgProtFcbs > Config.cfgFcbs) - Config.cfgProtFcbs = Config.cfgFcbs; } /* LoadCountryInfo(): @@ -1159,213 +1157,191 @@ STATIC VOID Fcbs(BYTE * pLine) */ #if 0 -STATIC BOOL LoadCountryInfo(char *filename, UWORD ctryCode, UWORD codePage) +STATIC void LoadCountryInfo(CStr filename, int ccode, int cpage) { - printf("Sorry, the COUNTRY= statement has been temporarily disabled\n"); + say("Sorry, the COUNTRY= statement has been temporarily disabled\n"); - UNREFERENCED_PARAMETER(codePage); - UNREFERENCED_PARAMETER(ctryCode); + UNREFERENCED_PARAMETER(cpage); + UNREFERENCED_PARAMETER(ccode); UNREFERENCED_PARAMETER(filename); return FALSE; -} +} #endif -STATIC VOID Country(BYTE * pLine) +/* Format: COUNTRY [=] countryCode [, [codePage] [, filename]] */ +STATIC void Country(PCStr p) { - /* Format: COUNTRY = countryCode, [codePage], filename */ - COUNT ctryCode; - COUNT codePage = NLS_DEFAULT; - char *filename = ""; + int ccode; + /*PCStr filename = "";*/ - if ((pLine = GetNumArg(pLine, &ctryCode)) == 0) - goto error; + p = GetNumArg(p); + if (p == NULL) + return; - - /* currently 'implemented' - COUNTRY=49 */ + ccode = numarg; + /* currently 'implemented' COUNTRY=nnn only */ #if 0 - pLine = skipwh(pLine); - if (*pLine == ',') + numarg = NLS_DEFAULT; + p = skipwh(p); + if (*p == ',') { - pLine = skipwh(pLine + 1); - - if (*pLine != ',') - if ((pLine = GetNumArg(pLine, &codePage)) == 0) - goto error; - - pLine = skipwh(pLine); - if (*pLine == ',') + p = skipwh(p + 1); + if (*p != ',') { - GetStringArg(++pLine, szBuf); - filename = szBuf; + p = GetNumArg(p); + if (p == NULL) + return; + p = skipwh(p); } - } -#endif - - if (!LoadCountryInfoHardCoded(filename, ctryCode, codePage)) + if (*p == ',') + filename = p + 1; + } + + if (*p && *p != ',') /* garbage at line end? */ + { + CfgFailure(p); return; - -error: - CfgFailure(pLine); -} - -STATIC VOID Stacks(BYTE * pLine) -{ - COUNT stacks; - - /* Format: STACKS = stacks [, stackSize] */ - pLine = GetNumArg(pLine, &stacks); - Config.cfgStacks = stacks; - - pLine = skipwh(pLine); - - if (*pLine == ',') - { - GetNumArg(++pLine, &stacks); - Config.cfgStackSize = stacks; } +#endif - if (Config.cfgStacks) + LoadCountryInfoHardCoded(/*filename*/"", ccode, /*numarg*/NLS_DEFAULT); +} + +/* Format: STACKS [=] stacks [, stackSize] */ +/* Format: STACKSHIGH [=] stacks [, stackSize] */ +static void _Stacks(PCStr p, UBYTE high) +{ + if (GetNumArg2(p, Config.cfgStackSize)) { - if (Config.cfgStackSize < 32) - Config.cfgStackSize = 32; - if (Config.cfgStackSize > 512) - Config.cfgStackSize = 512; - if (Config.cfgStacks > 64) - Config.cfgStacks = 64; + UBYTE stacks = (UBYTE)numarg1; + UWORD sz = numarg; + if (stacks > 64) + stacks = 64; + if (sz < 32) + sz = 32; + if (sz > 512) + sz = 512; + Config.cfgStacks = stacks; + Config.cfgStackSize = sz; + Config.cfgStacksHigh = high; } - Config.cfgStacksHigh = 0; } -STATIC VOID StacksHigh(BYTE * pLine) +STATIC void Stacks(PCStr p) { _Stacks(p, 0); } + +STATIC void StacksHigh(PCStr p) { _Stacks(p, 1); } + +/* Format: SHELL [=] command */ +STATIC void CmdShell(PCStr p) { - Stacks(pLine); - Config.cfgStacksHigh = 1; -} - -STATIC VOID InitPgmHigh(BYTE * pLine) -{ - InitPgm(pLine); - Config.cfgP_0_startmode = 0x80; -} - -STATIC VOID InitPgm(BYTE * pLine) -{ - static char init[NAMEMAX]; - static char inittail[NAMEMAX]; - - Config.cfgInit = init; - Config.cfgInitTail = inittail; - - /* Get the string argument that represents the new init pgm */ - pLine = GetStringArg(pLine, Config.cfgInit); - - /* Now take whatever tail is left and add it on as a single */ - /* string. */ - strcpy(Config.cfgInitTail, pLine); - - /* and add a DOS new line just to be safe */ - strcat(Config.cfgInitTail, "\r\n"); - Config.cfgP_0_startmode = 0; + /* assume strlen(p)+1 <= sizeof Config.cfgShell */ + strcpy(Config.cfgShell, p); } -STATIC VOID CfgBreak(BYTE * pLine) +/* Format: SHELLHIGH [=] command */ +STATIC void CmdShellHigh(PCStr p) { - /* Format: BREAK = (ON | OFF) */ - GetStringArg(pLine, szBuf); - break_ena = strcaseequal(szBuf, "OFF") ? 0 : 1; + Config.cfgP_0_startmode = 0x80; + /* assume strlen(p)+1 <= sizeof Config.cfgShell */ + strcpy(Config.cfgShell, p); } -STATIC VOID Numlock(BYTE * pLine) +/* Format: BREAK [=] (ON | OFF) */ +STATIC void CfgBreak(PCStr p) { - /* Format: NUMLOCK = (ON | OFF) */ - BYTE FAR *keyflags = (BYTE FAR *) MK_FP(0x40, 0x17); + if (!strcasediff(p, "ON")) + break_ena = 1; + else if (!strcasediff(p, "OFF")) + break_ena = 0; + else + CfgFailure(p); +} - GetStringArg(pLine, szBuf); - - *keyflags &= ~32; - if (!strcaseequal(szBuf, "OFF")) *keyflags |= 32; +/* Format: NUMLOCK [=] (ON | OFF) */ +STATIC void Numlock(PCStr p) +{ + UBYTE FAR *keyflags = MK_PTR(UBYTE, 0, 0x417); + if (!strcasediff(p, "ON")) + *keyflags |= 32; + else if (!strcasediff(p, "OFF")) + *keyflags &= ~32; + else + { + CfgFailure(p); + return; + } keycheck(); } -STATIC VOID DeviceHigh(BYTE * pLine) +/* Format: DEVICEHIGH [=] command */ +STATIC void DeviceHigh(PCStr p) { - if (UmbState == 1) - { - if (LoadDevice(pLine, MK_FP(umb_start + UMB_top, 0), TRUE) == DE_NOMEM) - { - printf("Not enough free memory in UMB's: loading low\n"); - LoadDevice(pLine, lpTop, FALSE); - } - } - else - { - printf("UMB's unavailable!\n"); - LoadDevice(pLine, lpTop, FALSE); - } + if (UmbState != UMB_DONE || /* UMB not initialized? */ + LoadDevice(p, MK_SEG_PTR(void, mcb_next(umb_base_start)), TRUE) == DE_NOMEM) + Device(p); } -STATIC void Device(BYTE * pLine) +/* Format: DEVICE [=] command */ +STATIC void Device(PCStr p) { - LoadDevice(pLine, lpTop, FALSE); + LoadDevice(p, lpTop, FALSE); } -STATIC BOOL LoadDevice(BYTE * pLine, char FAR *top, COUNT mode) +STATIC BOOL LoadDevice(PCStr p, VFP top, int mode) { - exec_blk eb; - struct dhdr FAR *dhp; - struct dhdr FAR *next_dhp; - BOOL result; - seg base, start; + int ret; + seg_t base = base_seg; + seg_t start = LoL->first_mcb; if (mode) { base = umb_base_seg; - start = umb_start; - } - else - { - base = base_seg; - start = LoL->first_mcb; + start = umb_base_start; } if (base == start) base++; base++; - + /* Get the device driver name */ - GetStringArg(pLine, szBuf); + { + PStr d = szBuf; + PCStr s = p; + for (; (UBYTE)*s > ' '; d++, s++) + *d = *s; + *d = '\0'; + } /* The driver is loaded at the top of allocated memory. */ /* The device driver is paragraph aligned. */ - eb.load.reloc = eb.load.load_seg = base; + { + exec_blk eb; + eb.load.reloc = eb.load.load_seg = base; #ifdef DEBUG - printf("Loading device driver %s at segment %04x\n", szBuf, base); + printf("Loading device driver %s at segment %04x\n", szBuf, base); #endif - if ((result = init_DosExec(3, &eb, szBuf)) != SUCCESS) - { - CfgFailure(pLine); - return result; + ret = init_DosExec(3, &eb, szBuf); + if (ret != SUCCESS) + { + CfgFailure(p); + return ret; + } } - strcpy(szBuf, pLine); + strcpy(szBuf, p); /* uppercase the device driver command */ - strupr(szBuf); + /* add \r\n to the command line */ + strcat(strupr(szBuf), " \r\n"); /* TE this fixes the loading of devices drivers with multiple devices in it. NUMEGA's SoftIce is such a beast */ - /* add \r\n to the command line */ - strcat(szBuf, " \r\n"); - - dhp = MK_FP(base, 0); - /* NOTE - Modification for multisegmented device drivers: */ /* In order to emulate the functionallity experienced with other */ /* DOS operating systems, the original 'top' end address is */ @@ -1373,44 +1349,37 @@ STATIC BOOL LoadDevice(BYTE * pLine, char FAR *top, COUNT mode) /* The updated end address is then used when issuing the next */ /* INIT request for the following device driver within the file */ - for (next_dhp = NULL; FP_OFF(next_dhp) != 0xffff && - (result = init_device(dhp, szBuf, mode, &top)) == SUCCESS; - dhp = next_dhp) { - next_dhp = MK_FP(FP_SEG(dhp), FP_OFF(dhp->dh_next)); - /* Link in device driver and save LoL->nul_dev pointer to next */ - dhp->dh_next = LoL->nul_dev.dh_next; - LoL->nul_dev.dh_next = dhp; + ofs_t next = 0; + do + { + struct dhdr FAR *dhp = MK_PTR(struct dhdr, base, next); + if ((ret = init_device(dhp, szBuf, mode, &top)) != SUCCESS) + break; + + next = FP_OFF(dhp->dh_next); + + /* Link in device driver and save LoL->nul_dev pointer to next */ + dhp->dh_next = LoL->nul_dev.dh_next; + LoL->nul_dev.dh_next = dhp; + } while (next != 0xffff); } - /* might have been the UMB driver or DOS=UMB */ - if (UmbState == 2) - umb_init(); + /* might have been the UMB driver -> try UMB initialization */ + umb_init(); - return result; + return ret; } -STATIC VOID CfgFailure(BYTE * pLine) +STATIC void CfgFailure(PCStr p) { - BYTE *pTmp = pLineStart; - - /* suppress multiple printing of same unrecognized lines */ - - if (nCfgLine < sizeof(ErrorAlreadyPrinted)*8) - { - if (ErrorAlreadyPrinted[nCfgLine/8] & (1 << (nCfgLine%8))) - return; - - ErrorAlreadyPrinted[nCfgLine/8] |= (1 << (nCfgLine%8)); - } - printf("CONFIG.SYS error in line %d\n", nCfgLine); - printf(">>>%s\n ", pTmp); - while (++pTmp != pLine) - printf(" "); - printf("^\n"); + printf("Error in %s line %d:\n" + "%s\n", configfile, nCfgLine, szLine); + gotoxy(p - szLine, screeny()); + say("^\n"); } -struct submcb +struct submcb { char type; unsigned short start; @@ -1419,21 +1388,19 @@ struct submcb char name[8]; }; -void FAR * KernelAllocPara(size_t nPara, char type, char *name, int mode) +void _seg * KernelAllocPara(size_t nPara, UBYTE type, CStr name, int mode) { - seg base, start; - struct submcb FAR *p; + seg_t base, start; + struct submcb _seg *p; - if (UmbState != 1) - mode = 0; - - if (mode) + if (mode && UmbState == UMB_DONE) { base = umb_base_seg; - start = umb_start; + start = umb_base_start; } else { + mode = 0; base = base_seg; start = LoL->first_mcb; } @@ -1443,21 +1410,21 @@ void FAR * KernelAllocPara(size_t nPara, char type, char *name, int mode) if (base == start) { - mcb FAR *p = para2far(base); - base++; - mcb_init(base, p->m_size - 1, p->m_type); - mumcb_init(FP_SEG(p), 0); + mcb _seg *p = MK_SEG_PTR(mcb, base); + mcb_init(++base, p->m_size, p->m_type); + mumcb_init(FP_SEG(p), 1); p->m_name[1] = 'D'; } nPara++; - mcb_init(base + nPara, para2far(base)->m_size - nPara, para2far(base)->m_type); - para2far(start)->m_size += nPara; + mcb_init(base + nPara, MK_SEG_PTR(mcb, base)->m_size - nPara + 1, + MK_SEG_PTR(mcb, base)->m_type); + MK_SEG_PTR(mcb, start)->m_size += nPara; - p = (struct submcb FAR *)para2far(base); + p = MK_SEG_PTR(struct submcb, base); p->type = type; p->start = FP_SEG(p)+1; - p->size = nPara-1; + p->size = nPara - 1; if (name) fmemcpy(p->name, name, 8); base += nPara; @@ -1465,24 +1432,22 @@ void FAR * KernelAllocPara(size_t nPara, char type, char *name, int mode) umb_base_seg = base; else base_seg = base; - return MK_FP(FP_SEG(p)+1, 0); + return MK_SEG_PTR(void, FP_SEG(p) + 1); } -void FAR * KernelAlloc(size_t nBytes, char type, int mode) +void _seg * KernelAlloc(size_t nBytes, UBYTE type, int mode) { - void FAR *p; - size_t nPara = (nBytes + 15)/16; + void _seg *p; + size_t nPara = (nBytes + 15) / 16; if (LoL->first_mcb == 0) { /* prealloc */ - lpTop = MK_FP(FP_SEG(lpTop) - nPara, FP_OFF(lpTop)); - return AlignParagraph(lpTop); - } - else - { - p = KernelAllocPara(nPara, type, NULL, mode); + /* note: lpTop is already para-aligned */ + return alignNextPara(lpTop = MK_FP(FP_SEG(lpTop) - nPara, FP_OFF(lpTop))); } + + p = KernelAllocPara(nPara, type, NULL, mode); fmemset(p, 0, nBytes); return p; } @@ -1498,88 +1463,86 @@ STATIC BYTE FAR * KernelAllocDma(WORD bytes, char type) } #endif -STATIC void FAR * AlignParagraph(VOID FAR * lpPtr) +void _seg * alignNextPara(CVFP p) { - UWORD uSegVal; - /* First, convert the segmented pointer to linear address */ - uSegVal = FP_SEG(lpPtr); - uSegVal += (FP_OFF(lpPtr) + 0xf) >> 4; - if (FP_OFF(lpPtr) > 0xfff0) - uSegVal += 0x1000; /* handle overflow */ + seg_t seg = FP_OFF(p); + if (seg) + seg = (seg - 1) / 16 + 1; + seg += FP_SEG(p); - /* and return an adddress adjusted to the nearest paragraph */ - /* boundary. */ - return MK_FP(uSegVal, 0); + /* return an address adjusted to the nearest paragraph boundary */ + return MK_SEG_PTR(void, seg); } #endif -STATIC int iswh(unsigned char c) +STATIC PCStr skipwh(PCStr s) { - return (c == '\r' || c == '\n' || c == '\t' || c == ' '); -} - -STATIC BYTE * skipwh(BYTE * s) -{ - while (iswh(*s)) - ++s; + s--; + do + s++; + while (*s == ' ' || *s == '\t'); return s; } -STATIC BYTE * scan(BYTE * s, BYTE * d) +STATIC PCStr scanword(PCStr s, PStr d) { - askThisSingleCommand = FALSE; - DontAskThisSingleCommand = FALSE; - s = skipwh(s); - - MenuLine = 0; - - /* does the line start with "123?" */ - - if (isnum(*s)) - { - unsigned numbers = 0; - for ( ; isnum(*s); s++) - numbers |= 1 << (*s -'0'); - - if (*s == '?') - { - MenuLine = numbers; - Menus |= numbers; - s = skipwh(s+1); - } - } - - - /* !dos=high,umb ?? */ - if (*s == '!') - { - DontAskThisSingleCommand = TRUE; - s = skipwh(s+1); - } - - if (*s == ';') - { - /* semicolon is a synonym for rem */ + while (*s >= 'a' && *s <= 'z' || + *s >= 'A' && *s <= 'Z') *d++ = *s++; - } - else - while (*s && !iswh(*s) && *s != '=') - { - if (*s == '?') - askThisSingleCommand = TRUE; - else - *d++ = *s; - s++; - } *d = '\0'; return s; } -STATIC BOOL isnum(char ch) +STATIC PCStr scanverb(PCStr s, PStr d) { - return (ch >= '0' && ch <= '9'); + askCommand &= ~(ASK_ASK | ASK_NOASK); + line_choices = 0xffff; /* statement in all menus */ + + for (;; s++) + { + s = skipwh(s); + + if (*s == '!') /* "!dos" ? */ + askCommand |= ASK_NOASK; + + else if (*s == '?') /* "?device" ? */ + askCommand |= ASK_ASK; + + else + { + UBYTE ch = *s - (UBYTE)'0'; + if (ch <= 9) /* "123?device" ? */ + { + PCStr p = s; + unsigned digits = 0; + do + { + digits |= 1 << ch; + ch = *++p - (UBYTE)'0'; + } while (ch <= 9); + + if (*p != '?') + break; + + s = p; + line_choices = digits; + all_choices |= digits; + } + else + break; + } /* else */ + } /* for */ + + s = scanword(s, d); + + if (*s == '?') /* "device?" ? */ + { + askCommand |= ASK_ASK; + s++; + } + return s; } /* Yet another change for true portability (PJV) */ @@ -1591,31 +1554,36 @@ STATIC char toupper(char c) } /* Convert string s to uppercase */ -STATIC VOID strupr(char *s) +static PStr strupr(PStr s) { - while (*s) { - *s = toupper(*s); - s++; + PStr d = s; + for (;; d++) + { + char ch = *d; + if (ch == '\0') + break; + *d = toupper(ch); } + return s; } /* The following code is 8086 dependant */ #if 1 /* ifdef KERNEL */ -STATIC VOID mcb_init_copy(UCOUNT seg, UWORD size, mcb *near_mcb) +STATIC void mcb_init_copy(seg_t seg, size_t size, mcb *near_mcb) { - near_mcb->m_size = size; - fmemcpy(MK_FP(seg, 0), near_mcb, sizeof(mcb)); + near_mcb->m_size = size - 1; + fmemcpy(MK_SEG_PTR(mcb, seg), near_mcb, sizeof(mcb)); } -STATIC VOID mcb_init(UCOUNT seg, UWORD size, BYTE type) +STATIC void mcb_init(seg_t seg, size_t size, BYTE type) { static mcb near_mcb BSS_INIT({0}); near_mcb.m_type = type; mcb_init_copy(seg, size, &near_mcb); } -STATIC VOID mumcb_init(UCOUNT seg, UWORD size) +STATIC void mumcb_init(seg_t seg, size_t size) { static mcb near_mcb = { MCB_NORMAL, @@ -1627,25 +1595,27 @@ STATIC VOID mumcb_init(UCOUNT seg, UWORD size) } #endif -char *strcat(register char * d, register const char * s) +static PStr strcat(PStr d, PCStr s) { strcpy(d + strlen(d), s); return d; } /* compare two ASCII strings ignoring case */ -STATIC char strcaseequal(const char * d, const char * s) +STATIC char strcasediff(PCStr d, PCStr s) { - char ch; - while ((ch = toupper(*s++)) == toupper(*d++)) - if (ch == '\0') - return 1; - return 0; + while (toupper(*s) == toupper(*d)) + { + if (*s == '\0') + return 0; + s++, d++; + } + return 1; } /* moved from BLOCKIO.C here. - that saves some relocation problems + that saves some relocation problems */ STATIC void config_init_buffers(int wantedbuffers) @@ -1653,29 +1623,27 @@ STATIC void config_init_buffers(int wantedbuffers) struct buffer FAR *pbuffer; unsigned buffers = 0; - /* fill HMA with buffers if BUFFERS count >=0 and DOS in HMA */ + /* fill HMA with buffers if BUFFERS count >=0 and DOS in HMA */ if (wantedbuffers < 0) wantedbuffers = -wantedbuffers; else if (HMAState == HMA_DONE) buffers = (0xfff0 - HMAFree) / sizeof(struct buffer); - if (wantedbuffers < 6) /* min 6 buffers */ + if (wantedbuffers < 6) /* min 6 buffers */ wantedbuffers = 6; - if (wantedbuffers > 99) /* max 99 buffers */ + if (wantedbuffers > 99) /* max 99 buffers */ { printf("BUFFERS=%u not supported, reducing to 99\n", wantedbuffers); wantedbuffers = 99; } - if (wantedbuffers > buffers) /* more specified than available -> get em */ + if (buffers < wantedbuffers) /* not less than requested */ buffers = wantedbuffers; LoL->nbuffers = buffers; LoL->inforecptr = &LoL->firstbuf; { size_t bytes = sizeof(struct buffer) * buffers; - pbuffer = HMAalloc(bytes); - - if (pbuffer == NULL) + if ((pbuffer = HMAalloc(bytes)) == NULL) { pbuffer = KernelAlloc(bytes, 'B', 0); if (HMAState == HMA_DONE) @@ -1684,15 +1652,16 @@ STATIC void config_init_buffers(int wantedbuffers) else { LoL->bufloc = LOC_HMA; - /* space in HMA beyond requested buffers available as user space */ + + /* space in HMA beyond requested buffers available as user space */ firstAvailableBuf = pbuffer + wantedbuffers; } } LoL->deblock_buf = DiskTransferBuffer; LoL->firstbuf = pbuffer; - DebugPrintf(("init_buffers (size %u) at", sizeof(struct buffer))); - DebugPrintf((" (%p)", LoL->firstbuf)); + DebugPrintf(("init_buffers (size %u) at (%p)", + sizeof(struct buffer), pbuffer)); buffers--; pbuffer->b_prev = FP_OFF(pbuffer + buffers); @@ -1703,20 +1672,13 @@ STATIC void config_init_buffers(int wantedbuffers) pbuffer->b_next = FP_OFF(pbuffer + 1); pbuffer++; pbuffer->b_prev = FP_OFF(pbuffer - 1); - } - while (--i); + } while (--i); } pbuffer->b_next = FP_OFF(pbuffer - buffers); - /* now, we can have quite some buffers in HMA - -- up to 50 for KE38616. - so we fill the HMA with buffers - but not if the BUFFERS count is negative ;-) - */ - DebugPrintf((" done\n")); - if (FP_SEG(pbuffer) == 0xffff) + if (FP_SEG(pbuffer) == /*HMASEG*/0xFFFF) { buffers++; printf("Kernel: allocated %d Diskbuffers = %u Bytes in HMA\n", @@ -1740,267 +1702,239 @@ STATIC void config_init_fnodes(int f_nodes_cnt) } /* - Undocumented feature: - - ANYDOS + Undocumented feature: + Format: ANYDOS [=] will report to MSDOS programs just the version number they expect. be careful with it! */ - -STATIC VOID SetAnyDos(BYTE * pLine) +STATIC void SetAnyDos(PCStr p) { - UNREFERENCED_PARAMETER(pLine); + if (*p) /* garbage at line end? */ + { + CfgFailure(p); + return; + } ReturnAnyDosVersionExpected = TRUE; } -STATIC VOID CfgIgnore(BYTE * pLine) +/* Format: EECHO string */ +STATIC void CfgMenuEsc(PCStr p) { - UNREFERENCED_PARAMETER(pLine); + char ch; + do + { + ch = *p; p++; + if (ch == '\0') + ch = '\n'; + if (ch == '$') /* translate $ to ESC */ + ch = ESC; + printf("%c", ch); + } while (ch != '\n'); } /* - 'MENU'ing stuff - - although it's worse then MSDOS's , its better then nothing - + 'MENU'ing stuff + although it's worse then MSDOS's , its better then nothing + Menu selection bar struct: + x pos, y pos, string */ -STATIC void ClearScreen(unsigned char attr); -STATIC VOID CfgMenu(BYTE * pLine) +static struct MenuSelector { - int nLen; - BYTE *pNumber = pLine; + unsigned x, y; + UBYTE len; + char text[80]; +} MenuStruct[10] BSS_INIT({0}); - printf("%s\n",pLine); - if (MenuColor == -1) - return; +static unsigned nextMenuRow BSS_INIT(0); - pLine = skipwh(pLine); +/* Format: MENU string */ +/* Format: ECHO string */ +STATIC void CfgMenu(PCStr p) +{ + struct MenuSelector *menu; + UBYTE ch; + unsigned len; + int spaces; - /* skip drawing characters in cp437, which is what we'll have - just after booting! */ - while ((unsigned char)*pLine >= 0xb0 && (unsigned char)*pLine < 0xe0) - pLine++; + say2("%s\n", p); + nextMenuRow++; - pLine = skipwh(pLine); /* skip more whitespaces... */ - - /* now I'm expecting a number here if this is a menu-choice line. */ - if (isnum(pLine[0])) + /* find digit */ + for (len = 0;; p++, len++) { - struct MenuSelector *menu = &MenuStruct[pLine[0]-'0']; - - menu->x = (pLine-pNumber); /* xpos is at start of number */ - menu->y = nMenuLine; - /* copy menu text: */ - nLen = findend(pLine); /* length is until cr/lf, null or three spaces */ - - /* max 40 chars including nullterminator - (change struct at top of file if you want more...) */ - if (nLen > MENULINEMAX-1) - nLen = MENULINEMAX-1; - memcpy(menu->Text, pLine, nLen); - menu->Text[nLen] = 0; /* nullTerminate */ + ch = *p; + if (ch == '\0') + return; + ch -= (UBYTE)'0'; + if (ch <= 9) + break; } - nMenuLine++; + + menu = &MenuStruct[ch]; + menu->x = len; /* start position of digit */ + menu->y = nextMenuRow - 1; + + /* copy menu text (up to null or 10+ spaces) */ + len = 0; + do + { + ch = *p; + if (ch == '\0') + break; + menu->text[len] = ch; + p++, len++; + if (ch > ' ') + { + menu->len = len; + spaces = 11; + } + } while (--spaces && len < sizeof menu->text - 1); + menu->text[menu->len] = '\0'; } -STATIC VOID CfgMenuEsc(BYTE * pLine) +STATIC void SelectLine(unsigned i) { - BYTE * check; - for (check = pLine; check[0]; check++) - if (check[0] == '$') check[0] = 27; /* translate $ to ESC */ - printf("%s\n",pLine); + struct MenuSelector *menu = MenuStruct; + do + { + if (menu->len) + { + UBYTE attr = MenuColor; + if (i == 0) /* selected line? */ + /* swap colors and clear blinking attribute */ + attr = ((attr << 4) | (attr >> 4)) & 0x7f; + + /* redraw line */ + ClearScreenArea(attr, menu->x, menu->y, menu->len, 1); + say2("%s", menu->text); + } + menu++, i--; + } while (menu < ENDOF(MenuStruct)); +} + +static unsigned show_choices(unsigned choicey) +{ + unsigned x; + UBYTE i; + + gotoxy(2, choicey); + say("Enter a choice: ["); + x = 19; /* =strlen(" Enter a choice: [") */ + i = 0; + do + { + if (testbit(all_choices, i)) + { + if (i < last_choice) + x++; + printf("%c", (UBYTE)'0' + i); + } + i++; + } while (i <= 9); + say("]"); + return x; } STATIC VOID DoMenu(void) { - iregs r; - int key = -1; - if (Menus == 0) - return; + unsigned choicey; + say("\n\n\n"); /* make sure there are 3 free lines */ + choicey = screeny() - 2; - InitKernelConfig.SkipConfigSeconds = -1; - - if (MenuColor == -1) - Menus |= 1 << 0; /* '0' Menu always allowed */ - - nMenuLine+=2; /* use this to position "select menu" text (ypos): */ + gotoxy(0, screenbottom()); + say2("F5=Bypass startup files F8=Confirm each line of %s/AUTOEXEC.BAT", + configfile); for (;;) { - int i, j; + unsigned key; + UBYTE c; -RestartInput: + gotoxy(75, screenbottom()); + say(askCommand & ASK_TRACE ? "[Y]" : "[N]"); - if (MenuColor != -1) - { - SelectLine(MenuSelected); /* select current line. */ - - /* set new cursor position: */ - r.a.b.h = 0x02; - r.b.b.h = 0; - r.d.b.l = 3; - r.d.b.h = nMenuLine; - - init_call_intr(0x10, &r); /* set cursor pos */ - } - - printf("Select from Menu ["); - - for (i = 0, j = 1; i <= 9; i++, j<<=1) - if (Menus & j) - printf("%c", '0' + i); - printf("], or press [ENTER]"); - - if (MenuColor != -1) - printf(" (Selection=%d) ", MenuSelected); + if (MenuColor && nextMenuRow + 1 == choicey) + SelectLine(last_choice); /* invert color of selected line */ if (MenuTimeout >= 0) - printf("- %d \b", MenuTimeout); - else - printf(" \b\b\b\b\b"); - - if (MenuColor != -1) - printf("\r\n\n "); - else - printf(" -"); - - printf(" Singlestepping (F8) is: %s \r", singleStep ? "ON " : "OFF"); - - key = GetBiosKey(MenuTimeout >= 0 ? 1 : -1); - - if (key == -1) /* timeout, take default */ { - if (MenuTimeout > 0) + show_choices(choicey); + printf(" Time remainig: %d ", MenuTimeout); + + gotoxy(show_choices(choicey), choicey); + key = GetBiosKey(1); /* poll keyboard 1 second */ + if (key == 0) { + if (MenuTimeout == 0) + break; /* timeout, take default */ MenuTimeout--; - goto RestartInput; + continue; } - break; - } - else + MenuTimeout = -1; + clearrow(); /* clear "Time remaining" */ + } - if (key == 0x3f00) /* F5 */ + gotoxy(show_choices(choicey), choicey); + key = GetBiosKey(-1); /* remove key from buffer */ + + if (key == K_F5) /* F5 */ { - SkipAllConfig = TRUE; + askCommand |= ASK_SKIPALL; break; } - if (key == 0x4200) /* F8 */ + if (key == K_F8) /* F8 */ + askCommand ^= ASK_TRACE; + + c = last_choice; + + if (key == K_Up || key == K_Left) + while (c > 0 && !testbit(all_choices, --c)); + + else if (key == K_Down || key == K_Right) + while (c < 9 && !testbit(all_choices, ++c)); + + else { - singleStep = !singleStep; - } - else if(key == 0x4800 && MenuColor != -1) /* arrow up */ - { - if(MenuSelected>=1 && (Menus & (1 << (MenuSelected-1))) ) - { - MenuSelected--; - } - } - else if(key == 0x5000 && MenuColor != -1) /* arrow down */ - { - if(MenuSelected 10) + last_choice = 10;*/ + MenuTimeout = numarg; } } -STATIC void ClearScreen(unsigned char attr) +/* Format: MENUCOLOR [=] foreground [, background] */ +STATIC void CfgMenuColor(PCStr p) { - /* scroll down (newlines): */ - iregs r; - unsigned char rows; - - /* clear */ - r.a.x = 0x0600; - r.b.b.h = attr; - r.c.x = 0; - r.d.b.l = peekb(0x40, 0x4a) - 1; /* columns */ - rows = peekb(0x40, 0x84); - if (rows == 0) rows = 24; - r.d.b.h = rows; - init_call_intr(0x10, &r); - - /* move cursor to pos 0,0: */ - r.a.b.h = 0x02; /* set cursorpos */ - r.b.b.h = 0; /* displaypage: */ - r.d.x = 0; /* pos 0,0 */ - init_call_intr(0x10, &r); - MenuColor = attr; -} - -/** - MENUCOLOR[=] fg[, bg] -*/ -STATIC void CfgMenuColor(BYTE * pLine) -{ - int num = 0; - unsigned char fg, bg = 0; - - pLine = skipwh(pLine); - - if ('=' == *pLine) - pLine = skipwh(pLine + 1); - - pLine = GetNumArg(pLine, &num); - if (pLine == 0) - return; - fg = (unsigned char)num; - - pLine = skipwh(pLine); - - if (*pLine == ',') + if (GetNumArg2(p, 0)) { - pLine = GetNumArg(skipwh(pLine+1), &num); - if (pLine == 0) - return; - bg = (unsigned char)num; + UBYTE attr = (UBYTE)((numarg << 4) | numarg1); + if (attr == 0) + attr = 0x07; /* white on black */ + MenuColor = attr; } - ClearScreen((bg << 4) | fg); } /********************************************************************************* @@ -2010,606 +1944,231 @@ STATIC void CfgMenuColor(BYTE * pLine) *********************************************************************************/ #define _DATE_MDY 0 /* mm/dd/yy */ -#define _DATE_DMY 1 /* dd.mm.yy */ -#define _DATE_YMD 2 /* yy/mm/dd */ +#define _DATE_DMY 1 /* dd.mm.yy */ +#define _DATE_YMD 2 /* yy/mm/dd */ #define _TIME_12 0 #define _TIME_24 1 struct CountrySpecificInfo specificCountriesSupported[] = { - - /* US */ { - 1, /* = W1 W437 # Country ID & Codepage */ - 437, - _DATE_MDY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "$", /* '$' ,'EUR' */ - ",", /* ',' # Thousand's separator */ - ".", /* '.' # Decimal point */ - "/", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_12 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* Canadian French */ ,{ - 2, /* = W1 W437 # Country ID & Codepage */ - 863, - _DATE_YMD, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "$", /* '$' ,'EUR' */ - ",", /* ',' # Thousand's separator */ - ".", /* '.' # Decimal point */ - "-", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* Latin America */ ,{ - 3, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_MDY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "$", /* '$' ,'EUR' */ - ",", /* ',' # Thousand's separator */ - ".", /* '.' # Decimal point */ - "/", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_12 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* Russia - by arkady */ ,{ - 7, /* = W1 W437 # Country ID & Codepage */ - 866, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "RUB", /* '$' ,'EUR' */ - /* should be "\xE0", but as no codepage - support exists (yet), better to leave it as 'Rubels' - */ - " ", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - ".", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 3, /* Currency format : currency follows, after blank */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* DUTCH */ ,{ - 31, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "EUR", /* '$' ,'EUR' */ - ".", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - "-", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* Belgium */ ,{ - 32, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "EUR", /* '$' ,'EUR' */ - ".", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - "-", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* France */ ,{ - 33, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "EUR", /* '$' ,'EUR' */ - ".", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - "-", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* Spain */ ,{ - 33, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "EUR", /* '$' ,'EUR' */ - ".", /* ',' # Thousand's separator */ - "'", /* Decimal point - by aitor */ - "-", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* Hungary */ ,{ - 36, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "$HU", /* '$' ,'EUR' */ - ".", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - "-", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* Yugoslavia */ ,{ - 38, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "$YU", /* '$' ,'EUR' */ - ".", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - "-", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* Italy */ ,{ - 39, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "EUR", /* '$' ,'EUR' */ - ".", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - "-", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* Switzerland */ ,{ - 41, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "SF", /* '$' ,'EUR' */ - ".", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - ".", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* Czechoslovakia */ ,{ - 42, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_YMD, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "$YU", /* '$' ,'EUR' */ - ".", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - ".", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* UK */ ,{ - 44, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "\x9c", /* Pound sign */ - ".", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - "/", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* Denmark */ ,{ - 45, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "DKK", /* */ - ".", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - "-", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - /* Sweden */ ,{ - 46, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_YMD, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "SEK", /* */ - ",", /* ',' # Thousand's separator */ - ".", /* '.' # Decimal point */ - "-", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* Norway */ ,{ - 47, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "NOK", /* */ - ",", /* ',' # Thousand's separator */ - ".", /* '.' # Decimal point */ - ".", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* Poland */ ,{ - 48, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_YMD, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "PLN", /* michael tyc: PLN means PoLish New zloty, I think) */ - ",", /* ',' # Thousand's separator */ - ".", /* '.' # Decimal point */ - ".", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* GERMAN */ ,{ - 49, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "EUR", /* '$' ,'EUR' */ - ".", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - ".", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 1, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* Argentina */ ,{ - 54, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "$ar", /* '$' ,'EUR' */ - ".", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - "/", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 1, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_12 /* = 0 # time format: 0/1: 12/24 houres */ - } - /* Brazil */ ,{ - 55, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "$ar", /* '$' ,'EUR' */ - ".", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - "/", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 1, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* International English */ ,{ - 61, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_MDY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "$", /* '$' ,'EUR' */ - ".", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - "/", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } +/* table rewritten by Bernd Blaauw +Country ID : international numbering +Codepage : codepage to use by default +Date format : M = Month, D = Day, Y = Year (4digit); 0=USA, 1=Europe, 2=Japan +Currency : $ = dollar, EUR = EURO (ALT-128), United Kingdom uses the pound sign +Thousands : separator for thousands (1,000,000 bytes; Dutch: 1.000.000 bytes) +Decimals : separator for decimals (2.5KB; Dutch: 2,5KB) +Datesep : Date separator (2/4/2004 or 2-4-2004 for example) +Timesep : usually ":" is used to separate hours, minutes and seconds +Currencyf : Currency format (bit array) +Currencyp : Currency precision +Timeformat : 0=12 hour format (AM/PM), 1=24 hour format (16:12 means 4:12 PM) - /* Japan - Yuki Mitsui */ ,{ - 81, /* = W1 W437 # Country ID & Codepage */ - 932, - _DATE_YMD, /* Date format: 0/1/2:U.S.A./Europe/Japan */ - "\x81\x8f", /* '$' ,'EUR' */ - ",", /* ',' # Thousand's separator */ - ".", /* '.' # Decimal point */ - "/", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_12 /* = 0 # time format: 0/1: 12/24 houres - */ - } + ID CP Date currency 1000 0.1 date time C digit time Locale/Country contributor +------------------------------------------------------------------------------------------------------------- */ +{ 1,437,_DATE_MDY,"$" ,",",".", "/", ":", 0 , 2,_TIME_12}, /* United States */ +{ 2,863,_DATE_YMD,"$" ,",",".", "-", ":", 0 , 2,_TIME_24}, /* Canadian French */ +{ 3,850,_DATE_MDY,"$" ,",",".", "/", ":", 0 , 2,_TIME_12}, /* Latin America */ +{ 7,866,_DATE_DMY,"RUB" ," ",",", ".", ":", 3 , 2,_TIME_24}, /* Russia Arkady V. Belousov */ +{ 31,850,_DATE_DMY,"EUR" ,".",",", "-", ":", 0 , 2,_TIME_24}, /* Dutch Bart Oldeman */ +{ 32,850,_DATE_DMY,"EUR" ,".",",", "-", ":", 0 , 2,_TIME_24}, /* Belgium */ +{ 33,850,_DATE_DMY,"EUR" ,".",",", "-", ":", 0 , 2,_TIME_24}, /* France */ +{ 34,850,_DATE_DMY,"EUR" ,".","'", "-", ":", 0 , 2,_TIME_24}, /* Spain Aitor Santamaria Merino */ +{ 36,850,_DATE_DMY,"$HU" ,".",",", "-", ":", 0 , 2,_TIME_24}, /* Hungary */ +{ 38,850,_DATE_DMY,"$YU" ,".",",", "-", ":", 0 , 2,_TIME_24}, /* Yugoslavia */ +{ 39,850,_DATE_DMY,"EUR" ,".",",", "-", ":", 0 , 2,_TIME_24}, /* Italy */ +{ 41,850,_DATE_DMY,"SF" ,".",",", ".", ":", 0 , 2,_TIME_24}, /* Switserland */ +{ 42,850,_DATE_YMD,"$YU" ,".",",", ".", ":", 0 , 2,_TIME_24}, /* Czech & Slovakia */ +{ 44,850,_DATE_DMY,"\x9c" ,".",",", "/", ":", 0 , 2,_TIME_24}, /* United Kingdom */ +{ 45,850,_DATE_DMY,"DKK" ,".",",", "-", ":", 0 , 2,_TIME_24}, /* Denmark */ +{ 46,850,_DATE_YMD,"SEK" ,",",".", "-", ":", 0 , 2,_TIME_24}, /* Sweden */ +{ 47,850,_DATE_DMY,"NOK" ,",",".", ".", ":", 0 , 2,_TIME_24}, /* Norway */ +{ 48,850,_DATE_YMD,"PLN" ,",",".", ".", ":", 0 , 2,_TIME_24}, /* Poland Michael H.Tyc */ +{ 49,850,_DATE_DMY,"EUR" ,".",",", ".", ":", 1 , 2,_TIME_24}, /* German Tom Ehlert */ +{ 54,850,_DATE_DMY,"$ar" ,".",",", "/", ":", 1 , 2,_TIME_12}, /* Argentina */ +{ 55,850,_DATE_DMY,"$ar" ,".",",", "/", ":", 1 , 2,_TIME_24}, /* Brazil */ +{ 61,850,_DATE_MDY,"$" ,".",",", "/", ":", 0 , 2,_TIME_24}, /* Int. English */ +{ 81,932,_DATE_YMD,"\x81\x8f",",",".", "/", ":", 0 , 2,_TIME_12}, /* Japan Yuki Mitsui */ +{351,850,_DATE_DMY,"EUR" ,".",",", "-", ":", 0 , 2,_TIME_24}, /* Portugal */ +{358,850,_DATE_DMY,"EUR" ," ",",", ".", ":",0x3, 2,_TIME_24}, /* Finland wolf */ +{359,855,_DATE_DMY,"BGL" ," ",",", ".", ":", 3 , 2,_TIME_24}, /* Bulgaria Luchezar Georgiev */ +{380,848,_DATE_DMY,"UAH" ," ",",", ".", ":", 3 , 2,_TIME_24}, /* Ukraine Oleg Deribas */ +}; - /* Portugal */ ,{ - 351, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "EUR", /* '$' ,'EUR' */ - ".", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - "-", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0, /* = 0 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 houres */ - } - - /* Finland - by wolf */ ,{ - 358, /* = W1 W437 # Country ID & Codepage */ - 850, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "EUR", /* '$' ,'EUR' */ - " ", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - ".", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 0x3, /* # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 hours */ - } - - /* Bulgaria - by Luchezar Georgiev */ ,{ - 359, /* = W1 W437 # Country ID & Codepage */ - 855, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "BGL", /* '$' ,'EUR' */ - " ", /* ',' # Thousand's separator */ - ",", /* '.' # Decimal point */ - ".", /* '-' DateSeparator */ - ":", /* ':' TimeSeparator */ - 3, /* # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 0 # time format: 0/1: 12/24 hours */ - } - - /* Ukraine - by Oleg Deribas */ ,{ - 380, /* = W380 W848 # Country ID & Codepage */ - 848, - _DATE_DMY, /* Date format: 0/1/2: U.S.A./Europe/Japan */ - "UAH", /* Currency */ - " ", /* ' ' # Thousand's separator */ - ",", /* ',' # Decimal point */ - ".", /* '.' DateSeparator */ - ":", /* ':' TimeSeparator */ - 3, /* = 3 # Currency format (bit array) */ - 2, /* = 2 # Currency precision */ - _TIME_24 /* = 1 # time format: 0/1: 12/24 houres */ - } - -}; - - -/* contributors to above table: - - tom ehlert (GER) - bart oldeman (NL) - wolf (FIN) - Michael H.Tyc (POL) - Oleg Deribas (UKR) - Arkady Belousov (RUS) - Luchezar Georgiev (BUL) - Yuki Mitsui (JAP) - Aitor Santamar­a Merino (SP) -*/ - -STATIC int LoadCountryInfoHardCoded(char *filename, COUNT ctryCode, COUNT codePage) +STATIC void LoadCountryInfoHardCoded(CStr filename, int ccode, int cpage) { struct CountrySpecificInfo *country; - UNREFERENCED_PARAMETER(codePage); + UNREFERENCED_PARAMETER(cpage); UNREFERENCED_PARAMETER(filename); - /* printf("cntry: %u, CP%u, file=\"%s\"\n", ctryCode, codePage, filename); */ - - + /* printf("cntry: %u, CP%u, file=\"%s\"\n", ccode, cpage, filename); */ for (country = specificCountriesSupported; - country < specificCountriesSupported + LENGTH(specificCountriesSupported); + country < ENDOF(specificCountriesSupported); country++) { - if (country->CountryID == ctryCode) + if (country->CountryID == ccode) { int codepagesaved = nlsCountryInfoHardcoded.C.CodePage; - - fmemcpy(&nlsCountryInfoHardcoded.C.CountryID, + fmemcpy(&nlsCountryInfoHardcoded.C, country, min(nlsCountryInfoHardcoded.TableSize, sizeof *country)); - nlsCountryInfoHardcoded.C.CodePage = codepagesaved; - - return 0; + return; } } printf("could not find country info for country ID %u\n" - "current supported countries are ", ctryCode); + "current supported countries are ", ccode); for (country = specificCountriesSupported; - country < specificCountriesSupported + LENGTH(specificCountriesSupported); + country < ENDOF(specificCountriesSupported); country++) { printf("%u ", country->CountryID); } - printf("\n"); - - return 1; + say("\n"); } - /* **************************************************************** -** implementation of INSTALL=NANSI.COM /P /X /BLA +** implementation of INSTALL=NANSI.COM /P /X /BLA */ -int numInstallCmds BSS_INIT(0); -struct instCmds { - char buffer[128]; - int mode; -} InstallCommands[10] BSS_INIT({0}); - -#ifdef DEBUG -#define InstallPrintf(x) printf x -#else -#define InstallPrintf(x) -#endif - -STATIC VOID _CmdInstall(BYTE * pLine,int mode) -{ - struct instCmds *cmd; - - InstallPrintf(("Installcmd %d:%s\n",numInstallCmds,pLine)); - - if (numInstallCmds > LENGTH(InstallCommands)) - { - printf("Too many Install commands given (%d max)\n",LENGTH(InstallCommands)); - CfgFailure(pLine); - return; - } - cmd = &InstallCommands[numInstallCmds]; - memcpy(cmd->buffer,pLine,127); - cmd->buffer[127] = 0; - cmd->mode = mode; - numInstallCmds++; -} -STATIC VOID CmdInstall(BYTE * pLine) -{ - _CmdInstall(pLine,0); -} -STATIC VOID CmdInstallHigh(BYTE * pLine) -{ - _CmdInstall(pLine,0x80); /* load high, if possible */ -} - -STATIC VOID InstallExec(struct instCmds *icmd) -{ - BYTE filename[128], *args, *d, *cmd = icmd->buffer; - exec_blk exb; - - InstallPrintf(("installing %s\n",cmd)); - - cmd=skipwh(cmd); - - for (args = cmd, d = filename; ;args++,d++) - { - *d = *args; - if (*d <= 0x020 || *d == '/') - break; - } - *d = 0; - - args--; - *args = strlen(&args[1]); - args[*args+1] = '\r'; - args[*args+2] = 0; - - exb.exec.env_seg = 0; - exb.exec.cmd_line = (CommandTail FAR *) args; - exb.exec.fcb_1 = exb.exec.fcb_2 = (fcb FAR *) 0xfffffffful; - - - InstallPrintf(("cmd[%s] args [%u,%s]\n",filename,*args,args+1)); - - if (init_DosExec(icmd->mode, &exb, filename) != SUCCESS) - { - CfgFailure(cmd); - } -} - -STATIC void free(seg segment) +STATIC void free(seg_t seg) { iregs r; - - r.a.b.h = 0x49; /* free memory */ - r.es = segment; + r.ES = seg; + r.AH = 0x49; /* free memory */ init_call_intr(0x21, &r); } /* set memory allocation strategy */ -STATIC void set_strategy(unsigned char strat) +STATIC void set_strategy(UBYTE strat) { iregs r; - - r.a.x = 0x5801; - r.b.b.l = strat; + r.BL = strat; + r.AX = 0x5801; init_call_intr(0x21, &r); } +/* Format: INSTALL [=] command */ +/* Format: INSTALLHIGH [=] command */ +STATIC void _CmdInstall(PCStr p, int mode) +{ + CommandTail args; + PStr pf; + unsigned len; + exec_blk exb; + + for (pf = szBuf;; p++, pf++) + { + UBYTE ch = *p; + if (ch <= ' ' || ch == '/') + break; + *pf = ch; + } + *pf = '\0'; + + len = strlen(p); + if (len > sizeof args.ctBuffer - 2) + len = sizeof args.ctBuffer - 2; /* trim too long line */ + args.ctCount = (UBYTE)len; + args.ctBuffer[len] = '\r'; + args.ctBuffer[len+1] = 0; + memcpy(args.ctBuffer, p, len); + + set_strategy(mode); + exb.exec.env_seg = DOS_PSP + 8; + exb.exec.cmd_line = &args; + /*exb.exec.fcb_1 = exb.exec.fcb_2 = NULL;*/ /* unimportant */ + + DebugPrintf(("cmd[%s] args [%u,%s]\n", szBuf, args.ctCount, args.ctBuffer)); + + if (init_DosExec(mode, &exb, szBuf) != SUCCESS) + CfgFailure(p); +} + +STATIC void CmdInstall(PCStr p) { _CmdInstall(p, 0); } + +STATIC void CmdInstallHigh(PCStr p) { _CmdInstall(p, 0x80); } + VOID DoInstall(void) { - int i; - unsigned short installMemory; - struct instCmds *cmd; + seg_t kernel; - if (numInstallCmds == 0) - return; - - InstallPrintf(("Installing commands now\n")); - - /* grab memory for this install code - we KNOW, that we are executing somewhere at top of memory - we need to protect the INIT_CODE from other programs - that will be executing soon + /* grab memory for this install code: + we are executing somewhere at top of memory and need to protect + the INIT_CODE from other programs that will be executing soon */ set_strategy(LAST_FIT); - installMemory = allocmem(((unsigned)_init_end + ebda_size + 15) / 16); + kernel = allocmem(((unsigned)_init_end + ebda_size + 15) / 16); - InstallPrintf(("allocated memory at %x\n",installMemory)); + DebugPrintf(("Installing commands now (kernel at %X)\n", kernel)); + + DoConfig_(); - for (i = 0, cmd = InstallCommands; i < numInstallCmds; i++, cmd++) - { - InstallPrintf(("%d:%s\n",i,cmd->buffer)); - set_strategy(cmd->mode); - InstallExec(cmd); - } set_strategy(FIRST_FIT); - free(installMemory); - - InstallPrintf(("Done with installing commands\n")); - return; + free(kernel); + + DebugPrintf(("Done with installing commands\n")); } -STATIC VOID CmdSet(BYTE *pLine) +/* master_env copied over command line area in + DOS_PSP, thus its size limited to 128 bytes */ +static char master_env[128] BSS_INIT({0}); +static PStr envp = master_env; + +/* Format: SET var = string */ +STATIC void CmdSet(PCStr p) { - pLine = GetStringArg(pLine, szBuf); - pLine = skipwh(pLine); /* scan() stops at the equal sign or space */ - if (*pLine == '=') /* equal sign is required */ + PStr q; + p = skipwh(scanword(p, szBuf)); + if (*p != '=') /* equal sign is required */ { - int size; - strupr(szBuf); /* all environment variables must be uppercase */ - strcat(szBuf, "="); - pLine = skipwh(++pLine); - strcat(szBuf, pLine); /* append the variable value (may include spaces) */ - size = strlen(szBuf); - if (size < master_env + sizeof(master_env) - envp - 1) - { /* must end with two consequtive zeros */ - strcpy(envp, szBuf); - envp += size + 1; /* add next variables starting at the second zero */ - } - else - printf("Master environment is full - can't add \"%s\"\n", szBuf); + CfgFailure(p); + return; } - else - printf("Invalid SET command: \"%s\"\n", szBuf); + + /* environment variables must be uppercase */ + strcat(strupr(szBuf), "="); + + { + PStr pm = master_env; /* find duplication */ + for (q = pm; pm < envp; q = pm) + { + PCStr v = szBuf; + while (*v == *pm) /* compare variables */ + v++, pm++; + while (*++pm); /* find end of definition */ + pm++; + if (*v == '\0') /* variable found? */ + { + while (pm < envp) + *q++ = *pm++; /* remove duplication */ + break; + } + } /* for */ + } + + p = skipwh(p + 1); + if (*p) /* add new definition? */ + { + size_t sz = strlen(strcat(szBuf, p)) + 1; + + /* environment ends by empty ASCIIZ (one null character) */ + if (sz >= master_env + sizeof master_env - q) + { + CfgFailure(p); + say("Out of environment space\n"); + return; + } + strcpy(q, szBuf); + q += sz; + } + + envp = q; + *q = '\0'; /* "add" empty ASCIIZ string */ + fmemcpy(MK_PTR(char, DOS_PSP + 8, 0), master_env, q + 1 - master_env); } diff --git a/kernel/config.h b/kernel/config.h index 50dff68..f940411 100644 --- a/kernel/config.h +++ b/kernel/config.h @@ -29,26 +29,17 @@ struct config { /* Configuration variables */ UBYTE cfgDosDataUmb; - BYTE cfgBuffers; /* number of buffers in the system */ + BYTE cfgBuffers; /* number of buffers in the system */ UBYTE cfgFiles; /* number of available files */ UBYTE cfgFilesHigh; UBYTE cfgFcbs; /* number of available FCBs */ UBYTE cfgProtFcbs; /* number of protected FCBs */ - BYTE *cfgInit; /* init of command.com */ - BYTE *cfgInitTail; /* command.com's tail */ + char cfgShell[256]; /* SHELL= line */ UBYTE cfgLastdrive; /* last drive */ UBYTE cfgLastdriveHigh; - BYTE cfgStacks; /* number of stacks */ - BYTE cfgStacksHigh; + BYTE cfgStacks; /* number of stacks */ + BYTE cfgStacksHigh; UWORD cfgStackSize; /* stacks size for each stack */ - /* COUNTRY= - * In Pass #1 these information is collected and in PostConfig() - * the NLS package is loaded into memory. -- 2000/06/11 ska - */ - WORD cfgCSYS_cntry; /* country ID to be loaded */ - UWORD cfgCSYS_cp; /* requested codepage; NLS_DEFAULT if default */ - WORD cfgCSYS_memory; /* # of bytes required for the NLS pkg; 0 if none */ - VOID FAR *cfgCSYS_data; /* where the loaded data is for PostConfig() */ UBYTE cfgP_0_startmode; /* load command.com high or not */ unsigned ebda2move; /* value for switches=/E:nnnn */ }; diff --git a/kernel/dsk.c b/kernel/dsk.c index 96368dc..39acd12 100644 --- a/kernel/dsk.c +++ b/kernel/dsk.c @@ -39,34 +39,33 @@ static BYTE *dskRcsId = #define DebugPrintf(x) #endif -/* #define STATIC */ - -BOOL ASMPASCAL fl_reset(WORD); -COUNT ASMPASCAL fl_diskchanged(WORD); - -COUNT ASMPASCAL fl_format(WORD, WORD, WORD, WORD, WORD, UBYTE FAR *); -COUNT ASMPASCAL fl_read(WORD, WORD, WORD, WORD, WORD, UBYTE FAR *); -COUNT ASMPASCAL fl_write(WORD, WORD, WORD, WORD, WORD, UBYTE FAR *); -COUNT ASMPASCAL fl_verify(WORD, WORD, WORD, WORD, WORD, UBYTE FAR *); -COUNT ASMPASCAL fl_setdisktype(WORD, WORD); -COUNT ASMPASCAL fl_setmediatype(WORD, WORD, WORD); -VOID ASMPASCAL fl_readkey(VOID); -extern COUNT ASMPASCAL fl_lba_ReadWrite(BYTE drive, WORD mode, - struct _bios_LBA_address_packet FAR - * dap_p); +void ASMPASCAL fl_readkey(void); +int ASMPASCAL fl_reset(UBYTE drive); +int ASMPASCAL fl_diskchanged(UBYTE drive); +int ASMPASCAL fl_setdisktype(UBYTE drive, WORD type); +int ASMPASCAL fl_setmediatype(UBYTE drive, WORD tracks, WORD sectors); +int ASMPASCAL fl_read (UBYTE drive, WORD, WORD, WORD, WORD, void FAR *); +int ASMPASCAL fl_write (UBYTE drive, WORD, WORD, WORD, WORD, void FAR *); +int ASMPASCAL fl_verify(UBYTE drive, WORD, WORD, WORD, WORD, void FAR *); +int ASMPASCAL fl_format(UBYTE drive, WORD, WORD, WORD, WORD, void FAR *); +int ASMPASCAL fl_lba_ReadWrite(UBYTE drive, WORD mode, + struct _bios_LBA_address_packet FAR *); #ifdef __WATCOMC__ +#pragma aux (pascal) fl_readkey modify exact [ax] #pragma aux (pascal) fl_reset modify exact [ax dx] #pragma aux (pascal) fl_diskchanged modify exact [ax dx] -#pragma aux (pascal) fl_setdisktype modify exact [ax bx dx] -#pragma aux (pascal) fl_readkey modify exact [ax] +#pragma aux (pascal) fl_setdisktype modify exact [ax dx bx] +#pragma aux (pascal) fl_setmediatype modify exact [ax cx dx bx es] +#pragma aux (pascal) fl_read modify exact [ax cx dx bx es] +#pragma aux (pascal) fl_write modify exact [ax cx dx bx es] +#pragma aux (pascal) fl_format modify exact [ax cx dx bx es] +#pragma aux (pascal) fl_verify modify exact [ax cx dx bx es] #pragma aux (pascal) fl_lba_ReadWrite modify exact [ax dx] #endif STATIC int LBA_Transfer(ddt * pddt, UWORD mode, VOID FAR * buffer, ULONG LBA_address, unsigned total, UWORD * transferred); -#define NENTRY 26 /* total size of dispatch table */ - #define LBA_READ 0x4200 #define LBA_WRITE 0x4300 UWORD LBA_WRITE_VERIFY = 0x4302; @@ -92,74 +91,64 @@ extern struct DynS ASM Dyn; /*TE - array access functions */ ddt *getddt(int dev) { - return &(((ddt *) Dyn.Buffer)[dev]); + return (ddt*)Dyn.Buffer + dev; } -STATIC VOID tmark(ddt *pddt) -{ - pddt->ddt_fh.ddt_lasttime = ReadPCClock(); -} +#define getddt0() ((ddt*)Dyn.Buffer) + +#define tmark(pddt) ((pddt)->ddt_fh.ddt_lasttime = ReadPCClock()) STATIC BOOL tdelay(ddt *pddt, ULONG ticks) { return ReadPCClock() - pddt->ddt_fh.ddt_lasttime >= ticks; } -#define N_PART 4 /* number of partitions per - table partition */ +#define N_PART 4 /* number of partitions per partition table */ #define PARTOFF 0x1be -#ifdef PROTO -typedef WORD dsk_proc(rqptr rq, ddt * pddt); -#else -typedef WORD dsk_proc(); -#endif +typedef WORD dsk_proc(rqptr, ddt*); STATIC dsk_proc mediachk, bldbpb, blockio, IoctlQueblk, Genblkdev, Getlogdev, Setlogdev, blk_Open, blk_Close, - blk_Media, blk_noerr, blk_nondr, blk_error; + blk_Media, blk_noerr, blk_nondr; -STATIC WORD getbpb(ddt * pddt); -#ifdef PROTO +STATIC WORD getbpb(ddt*); STATIC WORD dskerr(COUNT); -#else -STATIC WORD dskerr(); -#endif /* */ /* the function dispatch table */ /* */ -static dsk_proc * const dispatch[NENTRY] = +static dsk_proc * const dispatch [] = { - /* disk init is done in diskinit.c, so this should never be called */ - blk_error, /* Initialize */ - mediachk, /* Media Check */ - bldbpb, /* Build BPB */ - blk_error, /* Ioctl In */ - blockio, /* Input (Read) */ - blk_nondr, /* Non-destructive Read */ - blk_noerr, /* Input Status */ - blk_noerr, /* Input Flush */ - blockio, /* Output (Write) */ - blockio, /* Output with verify */ - blk_noerr, /* Output Status */ - blk_noerr, /* Output Flush */ - blk_error, /* Ioctl Out */ - blk_Open, /* Device Open */ - blk_Close, /* Device Close */ - blk_Media, /* Removable Media */ - blk_noerr, /* Output till busy */ - blk_error, /* undefined */ - blk_error, /* undefined */ - Genblkdev, /* Generic Ioctl Call */ - blk_error, /* undefined */ - blk_error, /* undefined */ - blk_error, /* undefined */ - Getlogdev, /* Get Logical Device */ - Setlogdev, /* Set Logical Device */ - IoctlQueblk /* Ioctl Query */ + /* disk init is done in initdisk.c, so this should never be called */ + NULL, /* 0x00 Initialize */ + mediachk, /* 0x01 Media Check */ + bldbpb, /* 0x02 Build BPB */ + NULL, /* 0x03 Ioctl In */ + blockio, /* 0x04 Input (Read) */ + blk_nondr, /* 0x05 Non-destructive Read */ + blk_noerr, /* 0x06 Input Status */ + blk_noerr, /* 0x07 Input Flush */ + blockio, /* 0x08 Output (Write) */ + blockio, /* 0x09 Output with verify */ + blk_noerr, /* 0x0A Output Status */ + blk_noerr, /* 0x0B Output Flush */ + NULL, /* 0x0C Ioctl Out */ + blk_Open, /* 0x0D Device Open */ + blk_Close, /* 0x0E Device Close */ + blk_Media, /* 0x0F Removable Media */ + blk_noerr, /* 0x10 Output till busy */ + NULL, /* 0x11 undefined */ + NULL, /* 0x12 undefined */ + Genblkdev, /* 0x13 Generic Ioctl Call */ + NULL, /* 0x14 undefined */ + NULL, /* 0x15 undefined */ + NULL, /* 0x16 undefined */ + Getlogdev, /* 0x17 Get Logical Device */ + Setlogdev, /* 0x18 Set Logical Device */ + IoctlQueblk /* 0x19 Ioctl Query */ }; #define hd(x) ((x) & DF_FIXED) @@ -168,61 +157,61 @@ static dsk_proc * const dispatch[NENTRY] = /* F U N C T I O N S --------------------------------------------------- */ /* ----------------------------------------------------------------------- */ -COUNT ASMCFUNC FAR blk_driver(rqptr rp) +int ASMCFUNC FAR blk_driver(rqptr rp) { - if (rp->r_unit >= blk_dev.dh_name[0] && rp->r_command != C_INIT) - return failure(E_UNIT); - if (rp->r_command > NENTRY) + if (rp->r_command >= LENGTH (dispatch)) + return failure(E_FAILURE); /* general failure */ { - return failure(E_FAILURE); /* general failure */ + dsk_proc *const proc = dispatch [rp->r_command]; + if (proc == NULL) + { + rp->r_count = 0; + return failure(E_FAILURE); /* general failure */ + } + if (rp->r_unit >= blk_dev.dh_name[0]) + return failure(E_UNIT); + return proc (rp, getddt(rp->r_unit)); } - else - return ((*dispatch[rp->r_command]) (rp, getddt(rp->r_unit))); } -STATIC char template_string[] = "Remove diskette in drive X:\n"; -#define DRIVE_POS (sizeof(template_string) - 4) +STATIC char template_string[] = + "\nInsert diskette for drive :: and press any key when ready\n\n"; +/* 012345678901234567890123456^ */ +#define DRIVE_POS 27 STATIC WORD play_dj(ddt * pddt) { + UBYTE i; + ddt *pddt2; + + if ((pddt->ddt_descflags & (DF_MULTLOG | DF_CURLOG)) != DF_MULTLOG) + return M_NOT_CHANGED; + /* play the DJ ... */ - if ((pddt->ddt_descflags & (DF_MULTLOG | DF_CURLOG)) == DF_MULTLOG) + pddt2 = getddt0() - 1; + i = blk_dev.dh_name[0] + 1; + do { - int i; - ddt *pddt2 = getddt(0); - for (i = 0; i < blk_dev.dh_name[0]; i++, pddt2++) + pddt2++, i--; + if (i == 0) { - if (pddt->ddt_driveno == pddt2->ddt_driveno && - (pddt2->ddt_descflags & (DF_MULTLOG | DF_CURLOG)) == - (DF_MULTLOG | DF_CURLOG)) - break; + put_string("Error in the DJ mechanism!\n"); /* should not happen! */ + return M_CHANGED; } - if (i == blk_dev.dh_name[0]) - { - put_string("Error in the DJ mechanism!\n"); /* should not happen! */ - } - else - { - template_string[DRIVE_POS] = 'A' + pddt2->ddt_logdriveno; - put_string(template_string); - put_string("Insert"); - template_string[DRIVE_POS] = 'A' + pddt->ddt_logdriveno; - put_string(template_string + 6); - put_string("Press the any key to continue ... \n"); - fl_readkey(); - pddt2->ddt_descflags &= ~DF_CURLOG; - pddt->ddt_descflags |= DF_CURLOG; - pokeb(0, 0x504, pddt->ddt_logdriveno); - } - return M_CHANGED; - } - return M_NOT_CHANGED; + } while (pddt->ddt_driveno != pddt2->ddt_driveno || + (~pddt2->ddt_descflags & (DF_MULTLOG | DF_CURLOG))); + + template_string[DRIVE_POS] = 'A' + pddt->ddt_logdriveno; + put_string(template_string); + fl_readkey(); + pddt2->ddt_descflags &= ~DF_CURLOG; + pddt->ddt_descflags |= DF_CURLOG; + pokeb(0, 0x504, pddt->ddt_logdriveno); + return M_CHANGED; } STATIC WORD diskchange(ddt * pddt) { - COUNT result; - /* if it's a hard drive, media never changes */ if (hd(pddt->ddt_descflags)) return M_NOT_CHANGED; @@ -232,15 +221,18 @@ STATIC WORD diskchange(ddt * pddt) if (pddt->ddt_descflags & DF_CHANGELINE) /* if we can detect a change ... */ { - if ((result = fl_diskchanged(pddt->ddt_driveno)) == 1) + int ret = fl_diskchanged(pddt->ddt_driveno); + if (ret == 1) /* check if it has changed... */ return M_CHANGED; - else if (result == 0) + if (ret == 0) return M_NOT_CHANGED; } /* can not detect or error... */ - return tdelay(pddt, 37ul) ? M_DONT_KNOW : M_NOT_CHANGED; + if (tdelay(pddt, 37)) + return M_DONT_KNOW; + return M_NOT_CHANGED; } STATIC WORD mediachk(rqptr rp, ddt * pddt) @@ -256,19 +248,15 @@ STATIC WORD mediachk(rqptr rp, ddt * pddt) pddt->ddt_descflags &= ~DF_DISKCHANGE; rp->r_mcretcode = M_DONT_KNOW; } - else + else if ((rp->r_mcretcode = diskchange(pddt)) == M_DONT_KNOW) { - rp->r_mcretcode = diskchange(pddt); - if (rp->r_mcretcode == M_DONT_KNOW) - { - /* don't know but can check serial number ... */ - ULONG serialno = pddt->ddt_serialno; - COUNT result = getbpb(pddt); - if (result != 0) - return (result); - if (serialno != pddt->ddt_serialno) - rp->r_mcretcode = M_CHANGED; - } + /* don't know but can check serial number ... */ + ULONG serialno = pddt->ddt_serialno; + int ret = getbpb(pddt); + if (ret) + return ret; + if (serialno != pddt->ddt_serialno) + rp->r_mcretcode = M_CHANGED; } return S_DONE; } @@ -276,13 +264,10 @@ STATIC WORD mediachk(rqptr rp, ddt * pddt) /* * Read Write Sector Zero or Hard Drive Dos Bpb */ -STATIC WORD RWzero(ddt * pddt, UWORD mode) +STATIC int RWzero(ddt * pddt, UWORD mode) { UWORD done; - - return LBA_Transfer(pddt, mode, - (UBYTE FAR *) & DiskTransferBuffer, - pddt->ddt_offset, 1, &done); + return LBA_Transfer(pddt, mode, DiskTransferBuffer, 0, 1, &done); } /* @@ -291,36 +276,32 @@ STATIC WORD RWzero(ddt * pddt, UWORD mode) */ STATIC WORD Getlogdev(rqptr rp, ddt * pddt) { - int i; - ddt *pddt2; - - if (!(pddt->ddt_descflags & DF_MULTLOG)) { - rp->r_unit = 0; - return S_DONE; - } - - pddt2 = getddt(0); - for (i = 0; i < blk_dev.dh_name[0]; i++, pddt2++) + UBYTE unit = 0; + if (pddt->ddt_descflags & DF_MULTLOG) { - if (pddt->ddt_driveno == pddt2->ddt_driveno && - (pddt2->ddt_descflags & (DF_MULTLOG | DF_CURLOG)) == - (DF_MULTLOG | DF_CURLOG)) - break; + ddt *pddt2 = getddt0() - 1; + do + pddt2++, unit++; + while (unit < blk_dev.dh_name[0] && + (pddt->ddt_driveno != pddt2->ddt_driveno || + (~pddt2->ddt_descflags & (DF_MULTLOG | DF_CURLOG)))); } - - rp->r_unit = i+1; + rp->r_unit = unit; return S_DONE; } STATIC WORD Setlogdev(rqptr rp, ddt * pddt) { - unsigned char unit = rp->r_unit; + UBYTE unit = rp->r_unit + 1; Getlogdev(rp, pddt); - if (rp->r_unit == 0) - return S_DONE; - getddt(rp->r_unit - 1)->ddt_descflags &= ~DF_CURLOG; - pddt->ddt_descflags |= DF_CURLOG; - rp->r_unit = unit + 1; + if (rp->r_unit) + { + getddt(rp->r_unit - 1)->ddt_descflags &= ~DF_CURLOG; + pddt->ddt_descflags |= DF_CURLOG; + /* UNDOCUMENTED: MS-DOS sets r_unit field both for */ + /* 0x17 (Getlogdev()) and 0x18 (Setlogdev()) functions. */ + rp->r_unit = unit; + } return S_DONE; } @@ -354,48 +335,42 @@ STATIC WORD blk_Media(rqptr rp, ddt * pddt) if (hd(pddt->ddt_descflags)) return S_BUSY | S_DONE; /* Hard Drive */ - else - return S_DONE; /* Floppy */ + return S_DONE; /* Floppy */ } STATIC WORD getbpb(ddt * pddt) { - ULONG count; - bpb *pbpbarray = &pddt->ddt_bpb; - unsigned secs_per_cyl; - WORD ret; - - /* pddt->ddt_descflags |= DF_NOACCESS; + /* pddt->ddt_descflags |= DF_NOACCESS; * disabled for now - problems with FORMAT ?? */ /* set drive to not accessible and changed */ if (diskchange(pddt) != M_NOT_CHANGED) pddt->ddt_descflags |= DF_DISKCHANGE; - ret = RWzero(pddt, LBA_READ); - if (ret != 0) - return (dskerr(ret)); + { + int ret = RWzero(pddt, LBA_READ); + if (ret) + return ret; + } - pbpbarray->bpb_nbyte = getword(&DiskTransferBuffer[BT_BPB]); - - if (DiskTransferBuffer[0x1fe] != 0x55 - || DiskTransferBuffer[0x1ff] != 0xaa || pbpbarray->bpb_nbyte != 512) + if (getword(DiskTransferBuffer + 0x1fe) != 0xaa55 || + getword(DiskTransferBuffer + BT_BPB) != 512) /* bpb_nbyte */ { /* copy default bpb to be sure that there is no bogus data */ - memcpy(pbpbarray, &pddt->ddt_defbpb, sizeof(bpb)); + memcpy(&pddt->ddt_bpb, &pddt->ddt_defbpb, sizeof pddt->ddt_bpb); return S_DONE; } - pddt->ddt_descflags &= ~DF_NOACCESS; /* set drive to accessible */ + pddt->ddt_descflags &= ~DF_NOACCESS; /* set drive to accessible */ /*TE ~ 200 bytes*/ - memcpy(pbpbarray, &DiskTransferBuffer[BT_BPB], sizeof(bpb)); + memcpy(&pddt->ddt_bpb, DiskTransferBuffer + BT_BPB, sizeof pddt->ddt_bpb); /*?? */ /* 2b is fat16 volume label. if memcmp, then offset 0x36. - if (fstrncmp((BYTE *) & DiskTransferBuffer[0x36], "FAT16",5) == 0 || - fstrncmp((BYTE *) & DiskTransferBuffer[0x36], "FAT12",5) == 0) { + if (memcmp(DiskTransferBuffer + 0x36, "FAT16", 5) == 0 || + memcmp(DiskTransferBuffer + 0x36, "FAT12", 5) == 0) TE: I'm not sure, what the _real_ decision point is, however MSDN 'A_BF_BPB_SectorsPerFAT The number of sectors per FAT. @@ -405,7 +380,7 @@ STATIC WORD getbpb(ddt * pddt) { struct FS_info *fs = (struct FS_info *)&DiskTransferBuffer[0x27]; #ifdef WITHFAT32 - if (pbpbarray->bpb_nfsect == 0) + if (pddt->ddt_bpb.bpb_nfsect == 0) { /* FAT32 boot sector */ fs = (struct FS_info *)&DiskTransferBuffer[0x43]; @@ -417,37 +392,49 @@ STATIC WORD getbpb(ddt * pddt) } #ifdef DSK_DEBUG - printf("BPB_NBYTE = %04x\n", pbpbarray->bpb_nbyte); - printf("BPB_NSECTOR = %02x\n", pbpbarray->bpb_nsector); - printf("BPB_NRESERVED = %04x\n", pbpbarray->bpb_nreserved); - printf("BPB_NFAT = %02x\n", pbpbarray->bpb_nfat); - printf("BPB_NDIRENT = %04x\n", pbpbarray->bpb_ndirent); - printf("BPB_NSIZE = %04x\n", pbpbarray->bpb_nsize); - printf("BPB_MDESC = %02x\n", pbpbarray->bpb_mdesc); - printf("BPB_NFSECT = %04x\n", pbpbarray->bpb_nfsect); + printf("BPB_NBYTE = %04x\n" + "BPB_NSECTOR = %02x\n" + "BPB_NRESERVED = %04x\n" + "BPB_NFAT = %02x\n" + "BPB_NDIRENT = %04x\n" + "BPB_NSIZE = %04x\n" + "BPB_MDESC = %02x\n" + "BPB_NFSECT = %04x\n", + pddt->ddt_bpb.bpb_nbyte, + pddt->ddt_bpb.bpb_nsector, + pddt->ddt_bpb.bpb_nreserved, + pddt->ddt_bpb.bpb_nfat, + pddt->ddt_bpb.bpb_ndirent, + pddt->ddt_bpb.bpb_nsize, + pddt->ddt_bpb.bpb_mdesc, + pddt->ddt_bpb.bpb_nfsect); #endif - count = - pbpbarray->bpb_nsize == 0 ? - pbpbarray->bpb_huge : pbpbarray->bpb_nsize; - secs_per_cyl = pbpbarray->bpb_nheads * pbpbarray->bpb_nsecs; - - if (secs_per_cyl == 0) - { - tmark(pddt); - return failure(E_FAILURE); - } - /* this field is problematic for partitions > 65535 cylinders, - in general > 512 GiB. However: we are not using it ourselves. */ - pddt->ddt_ncyl = (UWORD)((count + (secs_per_cyl - 1)) / secs_per_cyl); - tmark(pddt); + { + unsigned secs_per_cyl = pddt->ddt_bpb.bpb_nheads * pddt->ddt_bpb.bpb_nsecs; + if (secs_per_cyl == 0) + return failure(E_FAILURE); + + /* this field is problematic for partitions > 65535 cylinders, + in general > 512 GiB. However: we are not using it ourselves. */ + { + unsigned nsize = pddt->ddt_bpb.bpb_nsize; + pddt->ddt_ncyl = (UWORD)(((nsize ? nsize : pddt->ddt_bpb.bpb_huge) - 1) + / secs_per_cyl) + 1; + } + } + #ifdef DSK_DEBUG - printf("BPB_NSECS = %04x\n", pbpbarray->bpb_nsecs); - printf("BPB_NHEADS = %04x\n", pbpbarray->bpb_nheads); - printf("BPB_HIDDEN = %08lx\n", pbpbarray->bpb_hidden); - printf("BPB_HUGE = %08lx\n", pbpbarray->bpb_huge); + printf("BPB_NSECS = %04x\n" + "BPB_NHEADS = %04x\n" + "BPB_HIDDEN = %08lx\n" + "BPB_HUGE = %08lx\n", + pddt->ddt_bpb.bpb_nsecs, + pddt->ddt_bpb.bpb_nheads, + pddt->ddt_bpb.bpb_hidden, + pddt->ddt_bpb.bpb_huge); #endif return 0; @@ -455,11 +442,9 @@ STATIC WORD getbpb(ddt * pddt) STATIC WORD bldbpb(rqptr rp, ddt * pddt) { - WORD result; - - if ((result = getbpb(pddt)) != 0) - return result; - + int ret = getbpb(pddt); + if (ret) + return ret; rp->r_bpptr = &pddt->ddt_bpb; return S_DONE; } @@ -469,49 +454,44 @@ STATIC WORD IoctlQueblk(rqptr rp, ddt * pddt) UNREFERENCED_PARAMETER(pddt); #ifdef WITHFAT32 - if (rp->r_cat == 8 || rp->r_cat == 0x48) + if ((UBYTE)(~0x40 & rp->r_cat) != 8 || /* 0x08,0x48 */ #else - if (rp->r_cat == 8) + if (rp->r_cat != 8 || #endif - { - switch (rp->r_fun) - { - case 0x46: - case 0x47: - case 0x60: - case 0x66: - case 0x67: - return S_DONE; - } - } - return failure(E_CMD); + (rp->r_fun != 0x60 && + (UBYTE)(~0x21 & rp->r_fun) != 0x46)) /* 0x46,0x47,0x66,0x67 */ + return failure(E_CMD); + return S_DONE; } STATIC COUNT Genblockio(ddt * pddt, UWORD mode, WORD head, WORD track, WORD sector, WORD count, VOID FAR * buffer) { - UWORD transferred; + UWORD done; - /* apparently sector is ZERO, not ONE based !!! */ + /* apparently here sector is ZERO, not ONE based !!! */ return LBA_Transfer(pddt, mode, buffer, - ((ULONG) track * pddt->ddt_bpb.bpb_nheads + head) * - (ULONG) pddt->ddt_bpb.bpb_nsecs + - pddt->ddt_offset + sector, count, &transferred); + ((ULONG) track * pddt->ddt_bpb.bpb_nheads + + head) * pddt->ddt_bpb.bpb_nsecs + sector, + count, &done); } STATIC WORD Genblkdev(rqptr rp, ddt * pddt) { - int ret; unsigned descflags = pddt->ddt_descflags; #ifdef WITHFAT32 - int extended = 0; + unsigned copy_size = sizeof (bpb); - if (rp->r_cat == 0x48) - extended = 1; - else -#endif + if (rp->r_cat != 0x48) + { + if (rp->r_cat != 8) + return failure(E_CMD); + copy_size = BPB_SIZEOF; + } +#else if (rp->r_cat != 8) return failure(E_CMD); +#endif switch (rp->r_fun) { @@ -521,80 +501,68 @@ STATIC WORD Genblkdev(rqptr rp, ddt * pddt) bpb *pbpb; pddt->ddt_type = gblp->gbio_devtype; - pddt->ddt_descflags = (descflags & ~3) | (gblp->gbio_devattrib & 3) - | (DF_DPCHANGED | DF_REFORMAT); + pddt->ddt_descflags = (descflags & ~3) | + (gblp->gbio_devattrib & 3) | + (DF_DPCHANGED | DF_REFORMAT); pddt->ddt_ncyl = gblp->gbio_ncyl; /* use default dpb or current bpb? */ - pbpb = - (gblp->gbio_spcfunbit & 0x01) == - 0 ? &pddt->ddt_defbpb : &pddt->ddt_bpb; + pbpb = (gblp->gbio_spcfunbit & 1) ? &pddt->ddt_bpb : &pddt->ddt_defbpb; #ifdef WITHFAT32 - fmemcpy(pbpb, &gblp->gbio_bpb, - extended ? sizeof(gblp->gbio_bpb) : BPB_SIZEOF); + fmemcpy(pbpb, &gblp->gbio_bpb, copy_size); #else fmemcpy(pbpb, &gblp->gbio_bpb, sizeof(gblp->gbio_bpb)); #endif - /*pbpb->bpb_nsector = gblp->gbio_nsecs; */ + /*pbpb->bpb_nsector = gblp->gbio_nsecs;*/ break; } case 0x41: /* write track */ { struct gblkrw FAR *rw = rp->r_rw; - ret = Genblockio(pddt, LBA_WRITE, rw->gbrw_head, rw->gbrw_cyl, - rw->gbrw_sector, rw->gbrw_nsecs, rw->gbrw_buffer); - if (ret != 0) - return dskerr(ret); + int ret = Genblockio(pddt, LBA_WRITE, rw->gbrw_head, rw->gbrw_cyl, + rw->gbrw_sector, rw->gbrw_nsecs, rw->gbrw_buffer); + if (ret) + return ret; + break; } - break; case 0x42: /* format/verify track */ { struct gblkfv FAR *fv = rp->r_fv; - COUNT tracks; - struct thst { - UBYTE track, head, sector, type; - } *addrfield, afentry; + int ret; pddt->ddt_descflags &= ~DF_DPCHANGED; if (hd(descflags)) { /* XXX no low-level formatting for hard disks implemented */ - fv->gbfv_spcfunbit = 1; /* "not supported by bios" */ - return S_DONE; + fv->gbfv_spcfunbit = 1; /* "not supported by bios" */ + break; } - if (descflags & DF_DPCHANGED) + + /* first try newer setmediatype function */ + if ((descflags & DF_DPCHANGED) && + (ret = fl_setmediatype(pddt->ddt_driveno, pddt->ddt_ncyl, + pddt->ddt_bpb.bpb_nsecs)) != 0) { - /* first try newer setmediatype function */ - ret = fl_setmediatype(pddt->ddt_driveno, pddt->ddt_ncyl, - pddt->ddt_bpb.bpb_nsecs); if (ret == 0xc) { /* specified tracks, sectors/track not allowed for drive */ fv->gbfv_spcfunbit = 2; + return failure(E_NOTFND); /*dskerr(0xc)*/ + } + if (ret == 0x80 || + (fv->gbfv_spcfunbit & 1) && + (ret = fl_read(pddt->ddt_driveno, 0, 0, 1, 1, + DiskTransferBuffer)) != 0) + { + fv->gbfv_spcfunbit = 3; /* no disk in drive */ return dskerr(ret); } - else if (ret == 0x80) + /* otherwise, setdisktype */ { - fv->gbfv_spcfunbit = 3; /* no disk in drive */ - return dskerr(ret); - } - else if (ret != 0) - /* otherwise, setdisktype */ - { - unsigned char type; - unsigned tracks, secs; - if ((fv->gbfv_spcfunbit & 1) && - (ret = - fl_read(pddt->ddt_driveno, 0, 0, 1, 1, - DiskTransferBuffer)) != 0) - { - fv->gbfv_spcfunbit = 3; /* no disk in drive */ - return dskerr(ret); - } /* type 1: 320/360K disk in 360K drive */ /* type 2: 320/360K disk in 1.2M drive */ - tracks = pddt->ddt_ncyl; - secs = pddt->ddt_bpb.bpb_nsecs; - type = pddt->ddt_type + 1; + unsigned tracks = pddt->ddt_ncyl; + unsigned secs = pddt->ddt_bpb.bpb_nsecs; + UBYTE type = pddt->ddt_type + 1; if (!(tracks == 40 && (secs == 9 || secs == 8) && type < 3)) { /* type 3: 1.2M disk in 1.2M drive */ @@ -607,85 +575,98 @@ STATIC WORD Genblkdev(rqptr rp, ddt * pddt) { /* specified tracks, sectors/track not allowed for drive */ fv->gbfv_spcfunbit = 2; - return dskerr(0xc); + return failure(E_NOTFND); /*dskerr(0xc)*/ } } fl_setdisktype(pddt->ddt_driveno, type); } } if (fv->gbfv_spcfunbit & 1) - return S_DONE; - - afentry.type = 2; /* 512 byte sectors */ - afentry.track = fv->gbfv_cyl; - afentry.head = fv->gbfv_head; - - for (tracks = fv->gbfv_spcfunbit & 2 ? fv->gbfv_ntracks : 1; - tracks > 0; tracks--) { - addrfield = (struct thst *)DiskTransferBuffer; - - if (afentry.track > pddt->ddt_ncyl) - return failure(E_FAILURE); - - for (afentry.sector = 1; - afentry.sector <= pddt->ddt_bpb.bpb_nsecs; afentry.sector++) - memcpy(addrfield++, &afentry, sizeof(afentry)); - - ret = - Genblockio(pddt, LBA_FORMAT, afentry.head, afentry.track, 0, - pddt->ddt_bpb.bpb_nsecs, DiskTransferBuffer); - if (ret != 0) - return dskerr(ret); + fv->gbfv_spcfunbit = 0; /* success */ + break; } - afentry.head++; - if (afentry.head >= pddt->ddt_bpb.bpb_nheads) + { - afentry.head = 0; - afentry.track++; + unsigned cyl = fv->gbfv_cyl; + unsigned head = fv->gbfv_head; + unsigned tracks = fv->gbfv_spcfunbit & 2 ? fv->gbfv_ntracks : 1; + + for (; tracks; tracks--) + { + if (cyl >= pddt->ddt_ncyl) /* ??? remove --avb */ + return failure(E_FAILURE); + { + struct thst { + UBYTE cyl, head, sector, type; + } *addrfield = (struct thst *)DiskTransferBuffer; + unsigned sector = 0; + do + { + sector++; + addrfield->type = 2; /* 512 byte sectors */ + addrfield->cyl = cyl; + addrfield->head = head; + addrfield->sector = sector; + addrfield++; + } while (sector < pddt->ddt_bpb.bpb_nsecs); + } + { + int ret = Genblockio(pddt, LBA_FORMAT, head, cyl, 0, + pddt->ddt_bpb.bpb_nsecs, DiskTransferBuffer); + if (ret) + return ret; + } + if (++head >= pddt->ddt_bpb.bpb_nheads) + { + head = 0; + cyl++; + } + } } + + fv->gbfv_spcfunbit >>= 1; /* move bit 1 to bit 0 */ } - /* fall through to verify */ case 0x62: /* verify track */ { struct gblkfv FAR *fv = rp->r_fv; - - ret = Genblockio(pddt, LBA_VERIFY, fv->gbfv_head, fv->gbfv_cyl, 0, - (fv->gbfv_spcfunbit ? - fv->gbfv_ntracks * pddt->ddt_defbpb.bpb_nsecs : - pddt->ddt_defbpb.bpb_nsecs), DiskTransferBuffer); - if (ret != 0) - return dskerr(ret); + int ret = Genblockio(pddt, LBA_VERIFY, fv->gbfv_head, fv->gbfv_cyl, 0, + (fv->gbfv_spcfunbit & 1) + ? fv->gbfv_ntracks * pddt->ddt_defbpb.bpb_nsecs + : pddt->ddt_defbpb.bpb_nsecs, + DiskTransferBuffer); + /* !!! ret should be analyzed to fill fv->gbfv_spcfunbit by + 1=function not supported by BIOS + 2=specified tracks, sector/track not allowed for drive + 3=no disk in drive + --avb + */ + if (ret) + return ret; fv->gbfv_spcfunbit = 0; /* success */ + break; } - break; case 0x46: /* set volume serial number */ { - struct Gioc_media FAR *gioc = rp->r_gioc; struct FS_info *fs; - - ret = getbpb(pddt); - if (ret != 0) - return (ret); - - fs = (struct FS_info *)&DiskTransferBuffer - [(pddt->ddt_bpb.bpb_nfsect != 0 ? 0x27 : 0x43)]; - fs->serialno = gioc->ioc_serialno; - pddt->ddt_serialno = fs->serialno; - + int ret = getbpb(pddt); + if (ret) + return ret; + fs = (struct FS_info *)(pddt->ddt_bpb.bpb_nfsect + ? DiskTransferBuffer + 0x27 + : DiskTransferBuffer + 0x43); + pddt->ddt_serialno = fs->serialno = rp->r_gioc->ioc_serialno; ret = RWzero(pddt, LBA_WRITE); - if (ret != 0) - return (dskerr(ret)); + if (ret) + return ret; + break; } - break; case 0x47: /* set access flag */ - { - struct Access_info FAR *ai = rp->r_ai; - pddt->ddt_descflags = (descflags & ~DF_NOACCESS) | - (ai->AI_Flag ? 0 : DF_NOACCESS); - } + pddt->ddt_descflags |= DF_NOACCESS; + if (rp->r_ai->AI_Flag) + pddt->ddt_descflags &= ~DF_NOACCESS; break; case 0x60: /* get device parameters */ { @@ -698,45 +679,39 @@ STATIC WORD Genblkdev(rqptr rp, ddt * pddt) gblp->gbio_media = (pddt->ddt_type == 1) && (pddt->ddt_ncyl == 40); gblp->gbio_ncyl = pddt->ddt_ncyl; /* use default dpb or current bpb? */ - pbpb = - (gblp->gbio_spcfunbit & 0x01) == - 0 ? &pddt->ddt_defbpb : &pddt->ddt_bpb; + pbpb = (gblp->gbio_spcfunbit & 1) ? &pddt->ddt_bpb : &pddt->ddt_defbpb; #ifdef WITHFAT32 - fmemcpy(&gblp->gbio_bpb, pbpb, - extended ? sizeof(gblp->gbio_bpb) : BPB_SIZEOF); + fmemcpy(&gblp->gbio_bpb, pbpb, copy_size); #else fmemcpy(&gblp->gbio_bpb, pbpb, sizeof(gblp->gbio_bpb)); #endif - /*gblp->gbio_nsecs = pbpb->bpb_nsector; */ + /*gblp->gbio_nsecs = pbpb->bpb_nsector;*/ break; } case 0x61: /* read track */ { struct gblkrw FAR *rw = rp->r_rw; - ret = Genblockio(pddt, LBA_READ, rw->gbrw_head, rw->gbrw_cyl, - rw->gbrw_sector, rw->gbrw_nsecs, rw->gbrw_buffer); - if (ret != 0) - return dskerr(ret); + int ret = Genblockio(pddt, LBA_READ, rw->gbrw_head, rw->gbrw_cyl, + rw->gbrw_sector, rw->gbrw_nsecs, rw->gbrw_buffer); + if (ret) + return ret; + break; } - break; case 0x66: /* get volume serial number */ { - struct Gioc_media FAR *gioc = rp->r_gioc; - - ret = getbpb(pddt); - if (ret != 0) - return (ret); + struct Gioc_media FAR *gioc; + int ret = getbpb(pddt); + if (ret) + return ret; + gioc = rp->r_gioc; gioc->ioc_serialno = pddt->ddt_serialno; - fmemcpy(gioc->ioc_volume, pddt->ddt_volume, 11); - fmemcpy(gioc->ioc_fstype, pddt->ddt_fstype, 8); + fmemcpy(gioc->ioc_volume, pddt->ddt_volume, sizeof gioc->ioc_volume); + fmemcpy(gioc->ioc_fstype, pddt->ddt_fstype, sizeof gioc->ioc_fstype); + break; } - break; case 0x67: /* get access flag */ - { - struct Access_info FAR *ai = rp->r_ai; - ai->AI_Flag = descflags & DF_NOACCESS ? 0 : 1; /* bit 9 */ - } + rp->r_ai->AI_Flag = (descflags / DF_NOACCESS) & 1; /* bit 9 */ break; default: return failure(E_CMD); @@ -746,12 +721,8 @@ STATIC WORD Genblkdev(rqptr rp, ddt * pddt) STATIC WORD blockio(rqptr rp, ddt * pddt) { - ULONG start, size; - WORD ret; - UWORD done; - + ULONG start; int action; - bpb *pbpb; switch (rp->r_command) { @@ -773,35 +744,24 @@ STATIC WORD blockio(rqptr rp, ddt * pddt) tmark(pddt); start = (rp->r_start != HUGECOUNT ? rp->r_start : rp->r_huge); - pbpb = hd(pddt->ddt_descflags) ? &pddt->ddt_defbpb : &pddt->ddt_bpb; - size = (pbpb->bpb_nsize ? pbpb->bpb_nsize : pbpb->bpb_huge); - - if (start >= size || start + rp->r_count > size) { - return 0x0408; + const bpb *pbpb = hd(pddt->ddt_descflags) ? &pddt->ddt_defbpb : &pddt->ddt_bpb; + ULONG size = (pbpb->bpb_nsize ? pbpb->bpb_nsize : pbpb->bpb_huge); + if (start >= size || rp->r_count > size - start) + return 0x0408; } - start += pddt->ddt_offset; - ret = LBA_Transfer(pddt, action, - rp->r_trans, - start, rp->r_count, &done); - rp->r_count = done; - - if (ret != 0) { - return dskerr(ret); + UWORD done; + int ret = LBA_Transfer(pddt, action, rp->r_trans, + start, rp->r_count, &done); + rp->r_count = done; + if (ret) + return ret; } return S_DONE; } -STATIC WORD blk_error(rqptr rp, ddt * pddt) -{ - UNREFERENCED_PARAMETER(pddt); - - rp->r_count = 0; - return failure(E_FAILURE); /* general failure */ -} - STATIC WORD blk_noerr(rqptr rp, ddt * pddt) { UNREFERENCED_PARAMETER(rp); @@ -818,13 +778,9 @@ STATIC WORD dskerr(COUNT code) { case 1: /* invalid command - general failure */ if (code & 0x08) - return S_ERROR | E_NOTRDY; /* failure(E_NOTRDY); at least on yhe INT25 route, - 0x8002 is returned */ - else - return failure(E_CMD); - - case 2: /* address mark not found - general failure */ - return failure(E_FAILURE); + return S_ERROR | E_NOTRDY; /* failure(E_NOTRDY); at least on the + INT25 route, 0x8002 is returned */ + return failure(E_CMD); case 3: /* write protect */ return failure(E_WRPRT); @@ -832,14 +788,15 @@ STATIC WORD dskerr(COUNT code) default: if (code & 0x80) /* time-out */ return failure(E_NOTRDY); - else if (code & 0x40) /* seek error */ + if (code & 0x40) /* seek error */ return failure(E_SEEK); - else if (code & 0x10) /* CRC error */ + if (code & 0x10) /* CRC error */ return failure(E_CRC); - else if (code & 0x04) + if (code & 0x04) return failure(E_NOTFND); - else - return failure(E_FAILURE); + + case 2: /* address mark not found - general failure */ + return failure(E_FAILURE); } } @@ -898,42 +855,22 @@ STATIC unsigned DMA_max_transfer(void FAR * buffer, unsigned count) UWORD *transferred sectors actually transferred Read/Write/Write+verify some sectors, using LBA addressing. - - + This function handles all the minor details, including: - retry in case of errors - crossing the 64K DMA boundary - translation to CHS addressing if necessary - - crossing track boundaries (necessary for some BIOS's - + crossing track boundaries (necessary for some BIOS's) High memory doesn't work very well, use internal buffer - write with verify details for LBA - */ STATIC int LBA_Transfer(ddt * pddt, UWORD mode, VOID FAR * buffer, ULONG LBA_address, unsigned totaltodo, UWORD * transferred) { - static struct _bios_LBA_address_packet dap = { - 16, 0, 0, 0, 0, 0, 0 - }; - - unsigned count; - unsigned error_code = 0; - struct CHS chs; - void FAR *transfer_address; - unsigned char driveno = pddt->ddt_driveno; - - int num_retries; - *transferred = 0; - + /* only low-level format floppies for now ! */ if (mode == LBA_FORMAT && hd(pddt->ddt_descflags)) return 0; @@ -943,136 +880,106 @@ STATIC int LBA_Transfer(ddt * pddt, UWORD mode, VOID FAR * buffer, if (!hd(pddt->ddt_descflags)) { - UBYTE FAR *int1e_ptr = (UBYTE FAR *)getvec(0x1e); - unsigned char nsecs = (unsigned char)(pddt->ddt_bpb.bpb_nsecs); - + UBYTE FAR *int1e_ptr = (UBYTE FAR *)getvec(0x1e); + UBYTE nsecs = (UBYTE)pddt->ddt_bpb.bpb_nsecs; if (int1e_ptr[4] != nsecs) { int1e_ptr[4] = nsecs; - fl_reset(driveno); + fl_reset(pddt->ddt_driveno); } } - -/* + + LBA_address += pddt->ddt_offset; +/* if (LBA_address+totaltodo > pddt->total_sectors) { printf("LBA-Transfer error : address overflow = %lu > %lu max\n",LBA_address+totaltodo,driveParam->total_sectors); - return 1; + return failure(E_CMD); // dskerr(1) } */ buffer = adjust_far(buffer); - for (; totaltodo != 0;) + while (totaltodo) { - /* avoid overflowing 64K DMA boundary */ - count = DMA_max_transfer(buffer, totaltodo); + int num_retries; + /* avoid overflowing 64K DMA boundary */ + void FAR *transfer_address = buffer; + unsigned count = DMA_max_transfer(buffer, totaltodo); if (FP_SEG(buffer) >= 0xa000 || count == 0) { transfer_address = DiskTransferBuffer; count = 1; - if ((mode & 0xff00) == (LBA_WRITE & 0xff00)) - { fmemcpy(DiskTransferBuffer, buffer, 512); - } - } - else - { - transfer_address = buffer; } - for (num_retries = 0; num_retries < N_RETRY; num_retries++) + for (num_retries = N_RETRY;;) { - if ((pddt->ddt_descflags & DF_LBA) && mode != LBA_FORMAT) + unsigned error_code; + if (mode != LBA_FORMAT && (pddt->ddt_descflags & DF_LBA)) { + UWORD m; + static struct _bios_LBA_address_packet dap = { + 16, 0, 0, 0, 0, 0, 0 + }; dap.number_of_blocks = count; - dap.buffer_address = transfer_address; - + dap.block_address = LBA_address; dap.block_address_high = 0; /* clear high part */ - dap.block_address = LBA_address; /* clear high part */ - /* Load the registers and call the interrupt. */ - - if ((pddt->ddt_descflags & DF_WRTVERIFY) || mode != LBA_WRITE_VERIFY) - { - error_code = fl_lba_ReadWrite(driveno, mode, &dap); - } - else + m = mode; + if (mode == LBA_WRITE_VERIFY && !(pddt->ddt_descflags & DF_WRTVERIFY)) { /* verify requested, but not supported */ - error_code = - fl_lba_ReadWrite(driveno, LBA_WRITE, &dap); - + error_code = fl_lba_ReadWrite(pddt->ddt_driveno, LBA_WRITE, &dap); if (error_code == 0) { - error_code = - fl_lba_ReadWrite(driveno, LBA_VERIFY, &dap); + m = LBA_VERIFY; + error_code = fl_lba_ReadWrite(pddt->ddt_driveno, m, &dap); } } + else + error_code = fl_lba_ReadWrite(pddt->ddt_driveno, m, &dap); } else { /* transfer data, using old bios functions */ - + struct CHS chs; if (LBA_to_CHS(LBA_address, &chs, pddt)) - return 1; + return failure(E_CMD); /*dskerr(1)*/ /* avoid overflow at end of track */ - - if (chs.Sector + count > (unsigned)pddt->ddt_bpb.bpb_nsecs + 1) - { - count = pddt->ddt_bpb.bpb_nsecs + 1 - chs.Sector; - } + if (count > pddt->ddt_bpb.bpb_nsecs + 1 - chs.Sector) + count = pddt->ddt_bpb.bpb_nsecs + 1 - chs.Sector; error_code = (mode == LBA_READ ? fl_read : mode == LBA_VERIFY ? fl_verify : - mode == - LBA_FORMAT ? fl_format : fl_write) (driveno, - chs.Head, - chs.Cylinder, - chs.Sector, - count, - transfer_address); - + mode == LBA_FORMAT ? fl_format : fl_write) + (pddt->ddt_driveno, chs.Head, chs.Cylinder, + chs.Sector, count, transfer_address); if (error_code == 0 && mode == LBA_WRITE_VERIFY) - { - error_code = fl_verify(driveno, chs.Head, chs.Cylinder, + error_code = fl_verify(pddt->ddt_driveno, chs.Head, chs.Cylinder, chs.Sector, count, transfer_address); - } } if (error_code == 0) break; - fl_reset(driveno); - - } /* end of retries */ - - if (error_code) - { - return error_code; - } + fl_reset(pddt->ddt_driveno); + if (--num_retries == 0) + return dskerr(error_code); + } /* end of retries */ /* copy to user buffer if nesessary */ if (transfer_address == DiskTransferBuffer && (mode & 0xff00) == (LBA_READ & 0xff00)) - { fmemcpy(buffer, DiskTransferBuffer, 512); - } *transferred += count; LBA_address += count; totaltodo -= count; - buffer = adjust_far((char FAR *)buffer + count * 512); + buffer = adjust_far((char FAR *)buffer + count * 512u); } - return (error_code); + return 0; } - -/* - * Revision 1.17 2001/05/13 tomehlert - * Added full support for LBA hard drives - * initcode moved (mostly) to initdisk.c - * lower interface partly redesigned - */ diff --git a/kernel/entry.asm b/kernel/entry.asm index d0610fd..f7fe4c5 100644 --- a/kernel/entry.asm +++ b/kernel/entry.asm @@ -314,7 +314,7 @@ int21_2: inc byte [_InDOS] or ah,ah jz int21_3 cmp ah,0ch - jle int21_normalentry + jbe int21_normalentry int21_3: call dos_crit_sect diff --git a/kernel/globals.h b/kernel/globals.h index b99f195..dc16b57 100644 --- a/kernel/globals.h +++ b/kernel/globals.h @@ -235,7 +235,7 @@ Freeman Publishing, Lawrence KS, USA (ISBN 0-87930-436-7).\n\ extern UWORD ASM NetBios; extern BYTE * ASM net_name; extern BYTE ASM net_set_count; -extern BYTE ASM NetDelay, ASM NetRetry; +extern UWORD ASM NetDelay, ASM NetRetry; extern UWORD ASM first_mcb, /* Start of user memory */ ASM uppermem_root; /* Start of umb chain (usually 9fff) */ @@ -360,8 +360,7 @@ extern UWORD ASM f_nodes_cnt; /* number of allocated f_nodes */ /* Process related functions - not under automatic generation. */ /* Typically, these are in ".asm" files. */ -VOID ASMCFUNC FAR cpm_entry(VOID) -/*INRPT FAR handle_break(VOID) */ ; +VOID ASMCFUNC FAR cpm_entry(VOID); COUNT ASMCFUNC CriticalError(COUNT nFlag, COUNT nDrive, COUNT nError, struct dhdr FAR * lpDevice); @@ -371,7 +370,6 @@ VOID ASMCFUNC FAR CharMapSrvc(VOID); VOID ASMCFUNC FAR set_stack(VOID); VOID ASMCFUNC FAR restore_stack(VOID); #endif -/*VOID INRPT FAR handle_break(VOID); */ ULONG ASMPASCAL ReadPCClock(VOID); VOID ASMPASCAL WriteATClock(BYTE *, BYTE, BYTE, BYTE); diff --git a/kernel/init-mod.h b/kernel/init-mod.h index aab7476..c7b3459 100644 --- a/kernel/init-mod.h +++ b/kernel/init-mod.h @@ -124,36 +124,32 @@ intvec getvec(unsigned char intno); /* config.c */ extern struct config Config; VOID PreConfig(VOID); -VOID PreConfig2(VOID); -VOID DoConfig(int pass); +void DoConfig(void); VOID PostConfig(VOID); VOID configDone(VOID); -VOID FAR * KernelAlloc(size_t nBytes, char type, int mode); -void FAR * KernelAllocPara(size_t nPara, char type, char *name, int mode); -char *strcat(char * d, const char * s); -BYTE * GetStringArg(BYTE * pLine, BYTE * pszString); +#ifdef I86 +void _seg * alignNextPara(CVFP); +#else +#define alignNextPara(x) ((const VOID *)x) +#endif +void _seg * KernelAlloc(size_t nBytes, UBYTE type, int mode); +void _seg * KernelAllocPara(size_t nPara, UBYTE type, CStr name, int mode); void DoInstall(void); -UWORD GetBiosKey(int timeout); +unsigned GetBiosKey(int timeout); /* diskinit.c */ COUNT dsk_init(VOID); /* int2f.asm */ -COUNT ASMPASCAL Umb_Test(void); -COUNT ASMPASCAL UMB_get_largest(void FAR * driverAddress, - UCOUNT * seg, UCOUNT * size); + +int ASMPASCAL UMB_get_largest(CVFP driverAddress, seg_t *, size_t *); #ifdef __WATCOMC__ -#pragma aux (pascal) UMB_get_largest modify exact [ax bx cx dx] +# pragma aux (pascal) UMB_get_largest modify exact [ax bx cx dx] #endif /* inithma.c */ int MoveKernelToHMA(void); -VOID FAR * HMAalloc(COUNT bytesToAllocate); - -/* initoem.c */ -unsigned init_oem(void); -void movebda(size_t bytes, unsigned new_seg); -unsigned ebdasize(void); +VFP HMAalloc(COUNT bytesToAllocate); /* intr.asm */ @@ -164,7 +160,7 @@ int ASMPASCAL close(int fd); int ASMPASCAL dup2(int oldfd, int newfd); seg ASMPASCAL allocmem(UWORD size); void ASMPASCAL init_PSPSet(seg psp_seg); -int ASMPASCAL init_DosExec(int mode, exec_blk * ep, char * lp); +int ASMPASCAL init_DosExec(int mode, exec_blk *, CStr); int ASMPASCAL init_setdrive(int drive); int ASMPASCAL init_switchar(int chr); void ASMPASCAL keycheck(void); @@ -208,15 +204,22 @@ VOID ASMCFUNC FAR int2f_handler(void); VOID ASMCFUNC FAR cpm_entry(void); /* kernel.asm */ -VOID ASMCFUNC FAR init_call_p_0(struct config FAR *Config); /* P_0, actually */ + +void ASMCFUNC FAR init_call_p_0(const struct config FAR *); /* P_0, actually */ +#ifdef __WATCOMC__ +# pragma aux (cdecl) init_call_p_0 aborts +#endif /* main.c */ -VOID ASMCFUNC FreeDOSmain(void); -BOOL init_device(struct dhdr FAR * dhp, char * cmdLine, - COUNT mode, char FAR **top); -VOID init_fatal(BYTE * err_msg); + +void ASMCFUNC FreeDOSmain(void); +BOOL init_device(struct dhdr FAR *, PCStr cmdLine, int mode, VFP *top); +#ifdef __WATCOMC__ +# pragma aux (cdecl) FreeDOSmain aborts +#endif /* prf.c */ + int VA_CDECL init_printf(const char * fmt, ...); int VA_CDECL init_sprintf(char * buff, const char * fmt, ...); @@ -231,12 +234,17 @@ extern UWORD HMAFree; /* first byte in HMA not yet used */ extern unsigned CurrentKernelSegment; extern struct _KernelConfig FAR ASM LowKernelConfig; extern WORD days[2][13]; -extern BYTE FAR *lpTop; +extern VFP lpTop; extern BYTE ASM _ib_start[], ASM _ib_end[], ASM _init_end[]; -extern UWORD ram_top; /* How much ram in Kbytes */ -extern char singleStep; -extern char SkipAllConfig; -extern char master_env[128]; + +enum { ASK_ASK = 0x01, /* ?device= device?= */ + ASK_NOASK = 0x02, /* !files= */ + ASK_TRACE = 0x04, /* F8 processing */ + ASK_SKIPALL = 0x08, /* F5 processing */ + ASK_YESALL = 0x10, /* Esc while trace */ +}; + +extern UBYTE askCommand; extern struct lol FAR *LoL; @@ -312,4 +320,3 @@ ULONG ASMCFUNC FAR MULULUL(ULONG mul1, ULONG mul2); /* MULtiply ULong by ULo ULONG ASMCFUNC FAR DIVULUS(ULONG mul1, UWORD mul2); /* DIVide ULong by UShort */ ULONG ASMCFUNC FAR DIVMODULUS(ULONG mul1, UWORD mul2, UWORD * rem); /* DIVide ULong by UShort */ #endif - diff --git a/kernel/initoem.c b/kernel/initoem.c index d07b3f9..e69de29 100644 --- a/kernel/initoem.c +++ b/kernel/initoem.c @@ -1,72 +0,0 @@ -/****************************************************************/ -/* */ -/* initoem.c */ -/* */ -/* OEM Initializattion Functions */ -/* */ -/* Copyright (c) 1995 */ -/* Pasquale J. Villani */ -/* All Rights Reserved */ -/* */ -/* This file is part of DOS-C. */ -/* */ -/* DOS-C is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version */ -/* 2, or (at your option) any later version. */ -/* */ -/* DOS-C is distributed in the hope that it will be useful, but */ -/* WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ -/* the GNU General Public License for more details. */ -/* */ -/* You should have received a copy of the GNU General Public */ -/* License along with DOS-C; see the file COPYING. If not, */ -/* write to the Free Software Foundation, 675 Mass Ave, */ -/* Cambridge, MA 02139, USA. */ -/* */ -/****************************************************************/ - -#include "portab.h" -#include "init-mod.h" - -#ifdef VERSION_STRINGS -static BYTE *RcsId = - "$Id$"; -#endif - -#define EBDASEG 0x40e -#define RAMSIZE 0x413 - -unsigned init_oem(void) -{ - iregs r; - init_call_intr(0x12, &r); - return r.a.x; -} - -void movebda(size_t bytes, unsigned new_seg) -{ - unsigned old_seg = peek(0, EBDASEG); - fmemcpy(MK_FP(new_seg, 0), MK_FP(old_seg, 0), bytes); - poke(0, EBDASEG, new_seg); - poke(0, RAMSIZE, ram_top); -} - -unsigned ebdasize(void) -{ - unsigned ebdaseg = peek(0, EBDASEG); - unsigned ramsize = ram_top; - - if (ramsize * 64 == ebdaseg && ramsize < 640 && peek(0, RAMSIZE) == ramsize) - { - unsigned ebdasz = peekb(ebdaseg, 0); - - /* sanity check: is there really no more than 63 KB? - * must be at 640k (all other values never seen and are untested) - */ - if (ebdasz <= 63 && ramsize + ebdasz == 640) - return ebdasz * 1024U; - } - return 0; -} diff --git a/kernel/int2f.asm b/kernel/int2f.asm index 895e378..73369ab 100644 --- a/kernel/int2f.asm +++ b/kernel/int2f.asm @@ -106,10 +106,9 @@ DriverSysCal: mov di, _Dyn+2 jmp short Int2f?iret - -;*********************************************************** -; internal doscalls INT2F/11xx - handled through C -;*********************************************************** +;********************************************************************** +; internal dos calls INT2F/12xx and INT2F/4A01,4A02 - handled through C +;********************************************************************** IntDosCal: ; set up register frame ;struct int2f12regs diff --git a/kernel/inthndlr.c b/kernel/inthndlr.c index 6cf6ab7..72e577e 100644 --- a/kernel/inthndlr.c +++ b/kernel/inthndlr.c @@ -1240,13 +1240,12 @@ dispatch: case 0x5f: if (lr.AL == 7 || lr.AL == 8) { - struct cds FAR *cdsp; - if (lr.DL >= lastdrive) + struct cds FAR *cdsp = &CDSp[lr.DL]; + if (lr.DL >= lastdrive || FP_OFF(cdsp->cdsDpb) == 0) { rc = DE_INVLDDRV; goto error_exit; } - cdsp = &CDSp[lr.DL]; if (lr.AL == 7) cdsp->cdsFlags |= CDSPHYSDRV; else diff --git a/kernel/intr.asm b/kernel/intr.asm index 895ce62..7318522 100644 --- a/kernel/intr.asm +++ b/kernel/intr.asm @@ -94,7 +94,9 @@ segment HMA_TEXT -;; COUNT ASMPASCAL res_DosExec(COUNT mode, exec_blk * ep, BYTE * lp) +; +; int ASMPASCAL res_DosExec(int mode, exec_blk * ep, const char * lp); +; global RES_DOSEXEC RES_DOSEXEC: pop es ; ret address @@ -106,12 +108,13 @@ RES_DOSEXEC: push ds pop es ; es = ds int 21h - jc short no_exec_error - xor ax, ax -no_exec_error: + sbb dx,dx ; CF=0? + and ax,dx ; then ax=0, else ax=error code ret -;; UCOUNT ASMPASCAL res_read(int fd, void *buf, UCOUNT count); +; +; unsigned ASMPASCAL res_read(int fd, void *buf, unsigned count); +; global RES_READ RES_READ: pop ax ; ret address @@ -121,23 +124,20 @@ RES_READ: push ax ; ret address mov ah, 3fh int 21h - jnc no_read_error - mov ax, -1 -no_read_error: + sbb dx,dx ; CF=1? + or ax,dx ; then ax=-1, else ax=bytes read ret segment INIT_TEXT ; -; void init_call_intr(nr, rp) -; REG int nr -; REG struct REGPACK *rp +; unsigned ASMPASCAL init_call_intr(int nr, iregs * rp); ; global INIT_CALL_INTR INIT_CALL_INTR: INTR ; -; int init_call_XMScall( (WORD FAR * driverAddress)(), WORD AX, WORD DX) +; int ASMPASCAL init_call_XMScall(void FAR * driverAddress, UWORD ax, UWORD dx); ; ; this calls HIMEM.SYS ; @@ -154,8 +154,10 @@ INIT_CALL_XMSCALL: push es ; driver address ("jmp es:cx") push cx retf - -; void FAR *DetectXMSDriver(VOID) + +; +; void FAR * ASMPASCAL DetectXMSDriver(VOID); +; global DETECTXMSDRIVER DETECTXMSDRIVER: mov ax, 4300h @@ -163,8 +165,8 @@ DETECTXMSDRIVER: cmp al, 80h je detected - xor ax, ax - xor dx, dx + xor ax,ax + cwd ret detected: @@ -179,13 +181,18 @@ detected: pop es ret +; +; void ASMPASCAL keycheck(void); +; global KEYCHECK KEYCHECK: mov ah, 1 int 16h ret -;; int open(const char *pathname, int flags); +; +; int ASMPASCAL open(const char *pathname, int flags); +; global INIT_DOSOPEN INIT_DOSOPEN: ;; init calling DOS through ints: @@ -198,12 +205,14 @@ INIT_DOSOPEN: common_int21: int 21h - jnc common_no_error - mov ax, -1 -common_no_error: + jnc common_ret ; CF=1? + sbb ax,ax ; then ax=-1, else ax unchanged +common_ret: ret -;; int close(int fd); +; +; int ASMPASCAL close(int fd); +; global CLOSE CLOSE: pop ax ; ret address @@ -212,7 +221,9 @@ CLOSE: mov ah, 3eh jmp short common_int21 -;; UCOUNT read(int fd, void *buf, UCOUNT count); +; +; unsigned ASMPASCAL read(int fd, void *buf, unsigned count); +; global READ READ: pop ax ; ret address @@ -223,7 +234,9 @@ READ: mov ah, 3fh jmp short common_int21 -;; int dup2(int oldfd, int newfd); +; +; int ASMPASCAL dup2(int oldfd, int newfd); +; global DUP2 DUP2: pop ax ; ret address @@ -233,7 +246,9 @@ DUP2: mov ah, 46h jmp short common_int21 -;; VOID init_PSPSet(seg psp_seg) +; +; void ASMPASCAL init_PSPSet(seg psp_seg); +; global INIT_PSPSET INIT_PSPSET: pop ax ; ret address @@ -243,7 +258,9 @@ INIT_PSPSET: int 21h ret -;; COUNT init_DosExec(COUNT mode, exec_blk * ep, BYTE * lp) +; +; int ASMPASCAL init_DosExec(int mode, exec_blk * ep, const char * lp); +; global INIT_DOSEXEC INIT_DOSEXEC: pop es ; ret address @@ -255,12 +272,13 @@ INIT_DOSEXEC: push ds pop es ; es = ds int 21h - jc short exec_no_error - xor ax, ax -exec_no_error: + sbb dx,dx ; CF=0? + and ax,dx ; then ax=0, else ax=error code ret -;; int init_setdrive(int drive) +; +; int ASMPASCAL init_setdrive(int drive); +; global INIT_SETDRIVE INIT_SETDRIVE: mov ah, 0x0e @@ -271,7 +289,9 @@ common_dl_int21: int 21h ret -;; int init_switchar(int char) +; +; int ASMPASCAL init_switchar(int chr); +; global INIT_SWITCHAR INIT_SWITCHAR: mov ax, 0x3701 @@ -287,11 +307,13 @@ ALLOCMEM: push ax ; ret address mov ah, 48h int 21h - sbb bx, bx ; carry=1 -> ax=-1 - or ax, bx ; segment + sbb bx,bx ; CF=1? + or ax,bx ; then ax=-1, else ax=segment ret -;; void set_DTA(void far *dta) +; +; void ASMPASCAL set_DTA(void far *dta); +; global SET_DTA SET_DTA: pop ax ; ret address diff --git a/kernel/ioctl.c b/kernel/ioctl.c index bb9a753..3ad15af 100644 --- a/kernel/ioctl.c +++ b/kernel/ioctl.c @@ -56,17 +56,124 @@ static BYTE *RcsId = COUNT DosDevIOctl(lregs * r) { - sft FAR *s; - struct dpb FAR *dpbp; - COUNT nMode; - unsigned attr; - unsigned char al = r->AL; + static UBYTE cmds [] = { + 0, 0, + /* 0x02 */ C_IOCTLIN, + /* 0x03 */ C_IOCTLOUT, + /* 0x04 */ C_IOCTLIN, + /* 0x05 */ C_IOCTLOUT, + /* 0x06 */ C_ISTAT, + /* 0x07 */ C_OSTAT, + /* 0x08 */ C_REMMEDIA, + 0, 0, 0, + /* 0x0c */ C_GENIOCTL, + /* 0x0d */ C_GENIOCTL, + /* 0x0e */ C_GETLDEV, + /* 0x0f */ C_SETLDEV, + /* 0x10 */ C_IOCTLQRY, + /* 0x11 */ C_IOCTLQRY, + }; + static UWORD required_attr [] = { + 0, 0, + /* 0x02 */ ATTR_IOCTL, + /* 0x03 */ ATTR_IOCTL, + /* 0x04 */ ATTR_IOCTL, + /* 0x05 */ ATTR_IOCTL, + 0, 0, + /* 0x08 */ ATTR_EXCALLS, + 0, 0, 0, + /* 0x0c */ ATTR_GENIOCTL, + /* 0x0d */ ATTR_GENIOCTL, + /* 0x0e */ ATTR_GENIOCTL, + /* 0x0f */ ATTR_GENIOCTL, + /* 0x10 */ ATTR_QRYIOCTL, + /* 0x11 */ ATTR_QRYIOCTL, + }; - if (al > 0x11) + sft FAR *s; + struct dhdr FAR *dev; + unsigned attr, flags; + UBYTE cmd; + + switch (r->AL) + { + default: /* 0x12+ */ + return DE_INVLDFUNC; + + case 0x0b: + if (r->DX) /* skip, it's a special case */ + NetRetry = r->DX; + NetDelay = r->CX; + return SUCCESS; + + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x06: + case 0x07: + case 0x0a: + case 0x0c: + case 0x10: + /* Test that the handle is valid and */ + /* get the SFT block that contains the SFT */ + if ((s = get_sft(r->BX)) == (sft FAR *)-1) + return DE_INVLDHNDL; + flags = s->sft_flags; + dev = s->sft_dev; + attr = dev->dh_attr; + break; + + case 0x04: + case 0x05: + case 0x08: + case 0x09: + case 0x0d: + case 0x0e: + case 0x0f: + case 0x11: + { + struct dpb FAR *dpbp; +/* + Line below previously returned the deviceheader at r->bl. But, + DOS numbers its drives starting at 1, not 0. A=1, B=2, and so + on. Changed this line so it is now zero-based. --SRM + */ +/* changed to use default drive if drive=0. --JPP */ +/* Fixed it. --JT */ + +#define NDN_HACK +#ifdef NDN_HACK +/* NDN feeds the actual ASCII drive letter to this function */ + UBYTE unit = (r->BL & 0x1f) - 1; +#else + UBYTE unit = r->BL - 1; +#endif + if (unit == 0xff) + unit = default_drive; + CharReqHdr.r_unit = unit; + + if ((dpbp = get_dpb(unit)) == NULL) + { + if (r->AL != 0x09) + return DE_INVLDDRV; + attr = ATTR_REMOTE; + } + else + { + dev = dpbp->dpb_device; + attr = dev->dh_attr; + } + } + } /* switch */ + + /* required_attr[] may be zero and in this case attr ignored */ + if (~attr & required_attr [r->AL]) return DE_INVLDFUNC; /* commonly used, shouldn't harm to do front up */ - if (al == 0x0C || al == 0x0D || al >= 0x10) /* generic or query */ + CharReqHdr.r_command = cmd = cmds [r->AL]; + if (cmd == C_GENIOCTL || cmd == C_IOCTLQRY) { CharReqHdr.r_cat = r->CH; /* category (major) code */ CharReqHdr.r_fun = r->CL; /* function (minor) code */ @@ -82,47 +189,16 @@ COUNT DosDevIOctl(lregs * r) switch (r->AL) { - case 0x0b: - /* skip, it's a special case. */ - NetDelay = r->CX; - if (r->DX) - NetRetry = r->DX; - break; - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x06: - case 0x07: - case 0x0a: - case 0x0c: - case 0x10: - { - unsigned flags; - - /* Test that the handle is valid and */ - /* get the SFT block that contains the SFT */ - if ((s = get_sft(r->BX)) == (sft FAR *) - 1) - return DE_INVLDHNDL; - - attr = s->sft_dev->dh_attr; - flags = s->sft_flags; - - switch (r->AL) - { - case 0x00: /* Get the flags from the SFT */ + r->DX = flags; if (flags & SFT_FDEVICE) - r->AX = (attr & 0xff00) | (flags & 0xff); - else - r->AX = flags; + r->DH = attr >> 8; /* Undocumented result, Ax = Dx seen using Pcwatch */ - r->DX = r->AX; + r->AX = r->DX; break; - case 0x01: - /* sft_flags is a file, return an error because you */ + case 0x01: /* can't set the status of a file. */ if (!(flags & SFT_FDEVICE)) return DE_INVLDFUNC; @@ -132,205 +208,95 @@ COUNT DosDevIOctl(lregs * r) if (r->DH != 0) return DE_INVLDDATA; - /* Undocumented: AL should get the old value */ - r->AL = s->sft_flags_lo; /* Set it to what we got in the DL register from the */ /* user. */ s->sft_flags_lo = SFT_FDEVICE | r->DL; + /* Undocumented: AL should get the old value */ + r->AL = (UBYTE)flags; break; - case 0x02: - nMode = C_IOCTLIN; - goto IoCharCommon; - - case 0x03: - nMode = C_IOCTLOUT; - goto IoCharCommon; - - case 0x06: - if (flags & SFT_FDEVICE) - { - nMode = C_ISTAT; - goto IoCharCommon; - } - r->AL = s->sft_posit >= s->sft_size ? 0 : 0xFF; - break; - - case 0x07: - if (flags & SFT_FDEVICE) - { - nMode = C_OSTAT; - goto IoCharCommon; - } - r->AL = 0; - break; - - case 0x0a: + case 0x0a: r->DX = flags; - r->AX = 0; + r->AX = 0; /* ??? RBIL doesn't says that AX changed --avb */ break; - case 0x0c: - nMode = C_GENIOCTL; - goto IoCharCommon; - - default: /* 0x10 */ - nMode = C_IOCTLQRY; - IoCharCommon: - if ((flags & SFT_FDEVICE) && - ( (r->AL <= 0x03 && (attr & ATTR_IOCTL)) - || r->AL == 0x06 || r->AL == 0x07 - || (r->AL == 0x10 && (attr & ATTR_QRYIOCTL)) - || (r->AL == 0x0c && (attr & ATTR_GENIOCTL)))) + case 0x06: + if (!(flags & SFT_FDEVICE)) { - CharReqHdr.r_unit = 0; - CharReqHdr.r_command = nMode; - 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 <= 0x03) - r->AX = CharReqHdr.r_count; - else if (r->AL <= 0x07) - r->AX = CharReqHdr.r_status & S_BUSY ? 0000 : 0x00ff; - else /* 0x0c or 0x10 */ - r->AX = CharReqHdr.r_status; + r->AL = s->sft_posit >= s->sft_size ? (UBYTE)0 : (UBYTE)0xFF; break; } - return DE_INVLDFUNC; - } - break; - } + /* fall through */ - default: /* block IOCTL: 4, 5, 8, 9, d, e, f, 11 */ - -/* - This line previously returned the deviceheader at r->bl. But, - DOS numbers its drives starting at 1, not 0. A=1, B=2, and so - on. Changed this line so it is now zero-based. - - -SRM - */ -/* JPP - changed to use default drive if drive=0 */ -/* JT Fixed it */ - -#define NDN_HACK -/* NDN feeds the actual ASCII drive letter to this function */ -#ifdef NDN_HACK - CharReqHdr.r_unit = ((r->BL & 0x1f) == 0 ? default_drive : - (r->BL & 0x1f) - 1); -#else - CharReqHdr.r_unit = (r->BL == 0 ? default_drive : r->BL - 1); -#endif - - dpbp = get_dpb(CharReqHdr.r_unit); - if (dpbp) - attr = dpbp->dpb_device->dh_attr; - else if (r->AL != 9) - return DE_INVLDDRV; - - switch (r->AL) - { - case 0x04: - nMode = C_IOCTLIN; - goto IoBlockCommon; - case 0x05: - nMode = C_IOCTLOUT; - goto IoBlockCommon; - case 0x08: - if (attr & ATTR_EXCALLS) + case 0x07: + if (!(flags & SFT_FDEVICE)) { - nMode = C_REMMEDIA; - goto IoBlockCommon; + r->AL = 0; + break; } - return DE_INVLDFUNC; - case 0x09: + /* fall through */ + + case 0x02: + case 0x03: + case 0x0c: + case 0x10: + if (!(flags & SFT_FDEVICE)) + return DE_INVLDFUNC; + CharReqHdr.r_unit = 0; /* ??? not used for devices --avb */ + goto execrequest; + + case 0x09: { - struct cds FAR *cdsp = get_cds(CharReqHdr.r_unit); - r->AX = S_DONE | S_BUSY; - if (cdsp != NULL && dpbp == NULL) - { - r->DX = ATTR_REMOTE; - } - else - { - if (!dpbp) - { - return DE_INVLDDRV; - } - r->DX = attr; - } + const struct cds FAR *cdsp = get_cds(CharReqHdr.r_unit); + if (cdsp == NULL) + return DE_INVLDDRV; if (cdsp->cdsFlags & CDSSUBST) - { - r->DX |= ATTR_SUBST; - } + attr |= ATTR_SUBST; + r->DX = attr; + r->AX = S_DONE | S_BUSY; /* ??? S_* values only for driver interface; + RBIL doesn't says that AX changed --avb */ break; } - case 0x0d: - nMode = C_GENIOCTL; - goto IoBlockCommon; - case 0x11: - nMode = C_IOCTLQRY; - IoBlockCommon: - if (r->AL == 0x0D && (r->CX & ~(0x486B-0x084A)) == 0x084A) + + case 0x0d: + if ((r->CX & ~0x4021) == 0x084A) { /* 084A/484A, 084B/484B, 086A/486A, 086B/486B */ r->AX = 0; /* (lock/unlock logical/physical volume) */ break; /* simulate success for MS-DOS 7+ SCANDISK etc. --LG */ } - if ((r->AL <= 0x05 && !(attr & ATTR_IOCTL)) - || (r->AL == 0x11 && !(attr & ATTR_QRYIOCTL)) - || (r->AL == 0x0d && !(attr & ATTR_GENIOCTL))) - { - return DE_INVLDFUNC; - } - - CharReqHdr.r_command = nMode; - execrh((request FAR *) & CharReqHdr, dpbp->dpb_device); + /* fall through */ + case 0x04: + case 0x05: + case 0x08: + case 0x11: + execrequest: + execrh(&CharReqHdr, dev); if (CharReqHdr.r_status & S_ERROR) { CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13; return DE_DEVICE; } - if (r->AL <= 0x05) + + if (r->AL <= 0x05) /* 0x02, 0x03, 0x04, 0x05 */ r->AX = CharReqHdr.r_count; - else if (r->AL == 0x08) - r->AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0; - else /* 0x0d or 0x11 */ + else if (r->AL <= 0x07) /* 0x06, 0x07 */ + r->AX = (CharReqHdr.r_status & S_BUSY) ? 0000 : 0x00ff; + else if (r->AL == 0x08) /* 0x08 */ + r->AX = (CharReqHdr.r_status / S_BUSY) & 1u; + else /* 0x0c, 0x0d, 0x10, 0x11 */ r->AX = CharReqHdr.r_status; break; - case 0x0e: - nMode = C_GETLDEV; - goto IoLogCommon; - default: /* 0x0f */ - nMode = C_SETLDEV; - IoLogCommon: - if (attr & ATTR_GENIOCTL) + case 0x0e: + default: /* 0x0f */ + execrh(&CharReqHdr, dev); + if (CharReqHdr.r_status & S_ERROR) { - - CharReqHdr.r_command = nMode; - execrh((request FAR *) & CharReqHdr, 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; - return SUCCESS; - } + CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13; + return DE_ACCESS; } - return DE_INVLDFUNC; - } - break; - } + r->AL = CharReqHdr.r_unit; + } /* switch */ return SUCCESS; } - diff --git a/kernel/main.c b/kernel/main.c index 0e13d42..cddb299 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -45,12 +45,12 @@ static char copyright[] = struct _KernelConfig InitKernelConfig BSS_INIT({0}); -STATIC VOID InitIO(void); +STATIC VOID init_internal_devices(void); STATIC VOID update_dcb(struct dhdr FAR *); STATIC VOID init_kernel(VOID); STATIC VOID signon(VOID); -STATIC VOID kernel(VOID); +STATIC VOID init_shell(VOID); STATIC VOID FsConfig(VOID); STATIC VOID InitPrinters(VOID); STATIC VOID InitSerialPorts(VOID); @@ -69,11 +69,8 @@ __segment DosTextSeg = 0; struct lol FAR *LoL = &DATASTART; -VOID ASMCFUNC FreeDOSmain(void) +void ASMCFUNC FreeDOSmain(void) { - unsigned char drv; - unsigned char FAR *p; - #ifdef _MSC_VER extern FAR prn_dev; DosDataSeg = (__segment) & DATASTART; @@ -89,24 +86,25 @@ VOID ASMCFUNC FreeDOSmain(void) at 50:e0 */ - drv = LoL->BootDrive + 1; - p = MK_FP(0, 0x5e0); - if (fmemcmp(p+2,"CONFIG",6) == 0) /* UPX */ { - fmemcpy(&InitKernelConfig, p+2, sizeof(InitKernelConfig)); + UBYTE drv; + UBYTE FAR *p = MK_PTR(UBYTE, 0, 0x5e2); + if (fmemcmp(p, "CONFIG", 6) == 0) /* UPXed */ + drv = p[-2]; /* boot drive was stored there by stub from exeflat.c */ + else + { + drv = LoL->BootDrive; + p[-2] = drv; /* used by initdisk.c:ReadAllPartitionTables() */ + p = (UBYTE FAR*)&LowKernelConfig; + } - drv = *p + 1; - *(DWORD FAR *)(p+2) = 0; - } - else - { - *p = drv - 1; - fmemcpy(&InitKernelConfig, &LowKernelConfig, sizeof(InitKernelConfig)); - } + drv++; + if (drv > 0x80) + drv = 3; /* C: */ + LoL->BootDrive = drv; - if (drv >= 0x80) - drv = 3; /* C: */ - LoL->BootDrive = drv; + fmemcpy(&InitKernelConfig, p, sizeof InitKernelConfig); + } setup_int_vectors(); @@ -114,22 +112,14 @@ VOID ASMCFUNC FreeDOSmain(void) signon(); init_kernel(); + init_shell(); -#ifdef DEBUG - /* Non-portable message kludge alert! */ - printf("KERNEL: Boot drive = %c\n", 'A' + LoL->BootDrive - 1); -#endif - - DoInstall(); - - kernel(); + init_call_p_0(&Config); /* execute process 0 (the shell) */ } /* InitializeAllBPBs() - or MakeNortonDiskEditorHappy() - it has been determined, that FDOS's BPB tables are initialized, only when used (like DIR H:). at least one known utility (norton DE) seems to access them directly. @@ -149,62 +139,47 @@ void InitializeAllBPBs(VOID) STATIC void PSPInit(void) { - psp far *p = MK_FP(DOS_PSP, 0); + psp _seg *p = MK_SEG_PTR(psp, DOS_PSP); - /* Clear out new psp first */ - fmemset(p, 0, sizeof(psp)); + fmemset(p, 0, sizeof(psp)); /* Clear out new psp first */ - /* initialize all entries and exits */ - /* CP/M-like exit point */ - p->ps_exit = 0x20cd; - - /* CP/M-like entry point - call far to special entry */ - p->ps_farcall = 0x9a; - p->ps_reentry = MK_FP(0, 0x30 * 4); - /* unix style call - 0xcd 0x21 0xcb (int 21, retf) */ - p->ps_unix[0] = 0xcd; - p->ps_unix[1] = 0x21; + /* initialize all entries and exits */ + p->ps_exit = 0x20cd; /* CP/M-like exit point: */ + /* INT 20 opcode */ + /* CP/M-like entry point: */ + p->ps_farcall = 0x9a; /* FAR CALL opcode... */ + p->ps_reentry = MK_FP(0, 0x30 * 4); /* ...entry address */ + p->ps_unix[0] = 0xcd; /* unix style call: */ + p->ps_unix[1] = 0x21; /* INT 21/RETF opcodes */ p->ps_unix[2] = 0xcb; - /* Now for parent-child relationships */ - /* parent psp segment */ - p->ps_parent = FP_SEG(p); - /* previous psp pointer */ - p->ps_prevpsp = MK_FP(0xffff,0xffff); + /* parent-child relationships */ + /*p->ps_parent = 0;*/ /* parent psp segment */ + p->ps_prevpsp = (VFP)-1l; /* previous psp address */ - /* Environment and memory useage parameters */ - /* memory size in paragraphs */ - /* p->ps_size = 0; clear from above */ - /* environment paragraph */ - p->ps_environ = DOS_PSP + 8; - /* terminate address */ - p->ps_isv22 = getvec(0x22); - /* break address */ - p->ps_isv23 = getvec(0x23); - /* critical error address */ - p->ps_isv24 = getvec(0x24); + /* Environment and memory useage parameters */ + /*p->ps_size = 0;*/ /* segment of memory beyond */ + /* memory allocated to program */ + /*p->ps_environ = 0;*/ /* environment paragraph */ - /* user stack pointer - int 21 */ - /* p->ps_stack = NULL; clear from above */ + /*p->ps_isv22 = NULL;*/ /* terminate handler */ + /*p->ps_isv23 = NULL;*/ /* break handler */ + /*p->ps_isv24 = NULL;*/ /* critical error handler */ - /* File System parameters */ - /* maximum open files */ - p->ps_maxfiles = 20; - fmemset(p->ps_files, 0xff, 20); + /*p->ps_stack = NULL;*/ /* user stack pointer - int 21 */ - /* open file table pointer */ - p->ps_filetab = p->ps_files; + /* File System parameters */ + p->ps_maxfiles = sizeof p->ps_files; /* size of file table */ + fmemset(p->ps_filetab = p->ps_files, 0xff, sizeof p->ps_files); - /* first command line argument */ - /* p->ps_fcb1.fcb_drive = 0; already set */ - fmemset(p->ps_fcb1.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE); - /* second command line argument */ - /* p->ps_fcb2.fcb_drive = 0; already set */ - fmemset(p->ps_fcb2.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE); + /*p->ps_fcb1.fcb_drive = 0;*/ /* 1st command line argument */ + /*fmemset(p->ps_fcb1.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE);*/ + /*p->ps_fcb2.fcb_drive = 0;*/ /* 2nd command line argument */ + /*fmemset(p->ps_fcb2.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE);*/ - /* local command line */ - /* p->ps_cmd.ctCount = 0; command tail, already set */ - p->ps_cmd.ctBuffer[0] = 0xd; /* command tail */ + /* this area reused for master environment */ + /*p->ps_cmd.ctCount = 0;*/ /* local command line */ + /*p->ps_cmd.ctBuffer[0] = '\r';*/ /* command tail */ } #ifndef __WATCOMC__ @@ -255,7 +230,7 @@ STATIC void setup_int_vectors(void) for (i = 0x23; i <= 0x3f; i++) setvec(i, empty_handler); - for (pvec = vectors; pvec < vectors + (sizeof vectors/sizeof *pvec); pvec++) + for (pvec = vectors; pvec < ENDOF(vectors); pvec++) setvec(pvec->intno, (intvec)MK_FP(FP_SEG(empty_handler), pvec->handleroff)); pokeb(0, 0x30 * 4, 0xea); pokel(0, 0x30 * 4 + 1, (ULONG)cpm_entry); @@ -272,9 +247,6 @@ STATIC void init_kernel(void) LoL->os_setver_major = LoL->os_major = MAJOR_RELEASE; LoL->os_setver_minor = LoL->os_minor = MINOR_RELEASE; - /* Init oem hook - returns memory size in KB */ - ram_top = init_oem(); - /* move kernel to high conventional RAM, just below the init code */ #ifdef __WATCOMC__ lpTop = MK_FP(_CS, 0); @@ -283,16 +255,17 @@ STATIC void init_kernel(void) #endif MoveKernel(FP_SEG(lpTop)); + /* lpTop should be para-aligned */ lpTop = MK_FP(FP_SEG(lpTop) - 0xfff, 0xfff0); /* Initialize IO subsystem */ - InitIO(); + init_internal_devices(); InitPrinters(); InitSerialPorts(); - init_PSPSet(DOS_PSP); set_DTA(MK_FP(DOS_PSP, 0x80)); PSPInit(); + init_PSPSet(DOS_PSP); Init_clk_driver(); @@ -300,7 +273,6 @@ STATIC void init_kernel(void) /* we can read config.sys later. */ LoL->lastdrive = Config.cfgLastdrive; - /* init_device((struct dhdr FAR *)&blk_dev, NULL, 0, &ram_top); */ blk_dev.dh_name[0] = dsk_init(); PreConfig(); @@ -313,14 +285,7 @@ STATIC void init_kernel(void) FsConfig(); /* Now process CONFIG.SYS */ - DoConfig(0); - DoConfig(1); - - /* initialize near data and MCBs */ - PreConfig2(); - /* and process CONFIG.SYS one last time for device drivers */ - DoConfig(2); - + DoConfig(); /* Close all (device) files */ for (i = 0; i < 20; i++) @@ -331,10 +296,12 @@ STATIC void init_kernel(void) /* Init the file system one more time */ FsConfig(); - + configDone(); InitializeAllBPBs(); + + DoInstall(); } STATIC VOID FsConfig(VOID) @@ -346,21 +313,15 @@ STATIC VOID FsConfig(VOID) for (i = 0; i < LoL->lastdrive; i++) { struct cds FAR *pcds_table = &LoL->CDSp[i]; - fmemcpy(pcds_table->cdsCurrentPath, "A:\\\0", 4); - pcds_table->cdsCurrentPath[0] += i; - - if (i < LoL->nblkdev && (ULONG) dpb != 0xffffffffl) + pcds_table->cdsFlags = 0; + if (i < LoL->nblkdev && (LONG) dpb != -1l) { pcds_table->cdsDpb = dpb; pcds_table->cdsFlags = CDSPHYSDRV; dpb = dpb->dpb_next; } - else - { - pcds_table->cdsFlags = 0; - } pcds_table->cdsStrtClst = 0xffff; pcds_table->cdsParam = 0xffff; pcds_table->cdsStoreUData = 0xffff; @@ -428,135 +389,89 @@ STATIC VOID signon() MAJOR_RELEASE, MINOR_RELEASE, copyright); } -STATIC void kernel() +STATIC void init_shell() { - CommandTail Cmd; - - if (master_env[0] == '\0') /* some shells panic on empty master env. */ - strcpy(master_env, "PATH=."); - fmemcpy(MK_FP(DOS_PSP + 8, 0), master_env, sizeof(master_env)); - - /* process 0 */ - /* Execute command.com from the drive we just booted from */ - memset(Cmd.ctBuffer, 0, sizeof(Cmd.ctBuffer)); - strcpy(Cmd.ctBuffer, Config.cfgInitTail); - - for (Cmd.ctCount = 0; Cmd.ctCount < sizeof(Cmd.ctBuffer); Cmd.ctCount++) - if (Cmd.ctBuffer[Cmd.ctCount] == '\r') - break; - - /* if stepping CONFIG.SYS (F5/F8), tell COMMAND.COM about it */ - - /* 3 for string + 2 for "\r\n" */ - if (Cmd.ctCount < sizeof(Cmd.ctBuffer) - 5) + /* if stepping CONFIG.SYS (F5/F8), tell COMMAND.COM about it */ + /* (insert /D, /Y as first argument) */ + if (askCommand & (ASK_TRACE | ASK_SKIPALL)) { - char *insertString = NULL; + PStr p = Config.cfgShell - 1; /* find end of command name */ - if (singleStep) - insertString = " /Y"; /* single step AUTOEXEC */ + /* too long line -> truncate it to make space for "/Y \0" */ + Config.cfgShell[sizeof Config.cfgShell - 4] = '\0'; - if (SkipAllConfig) - insertString = " /D"; /* disable AUTOEXEC */ + do p++; while ((UBYTE)*p > ' ' && *p != '/'); + + if (*p == ' ' || *p == '\t') + p++; /* place option after space */ - if (insertString) { - - /* insert /D, /Y as first argument */ - char *p, *q; - - for (p = Cmd.ctBuffer; p < &Cmd.ctBuffer[Cmd.ctCount]; p++) + PStr q = p; + while (*q++); /* find end of command line */ + /* shift tail to right by 3 to make room for option */ + do { - if (*p == ' ' || *p == '\t' || *p == '\r') - { - for (q = &Cmd.ctBuffer[Cmd.ctCount + 1]; q >= p; q--) - q[3] = q[0]; - memcpy(p, insertString, 3); - break; - } - } - /* save buffer -- on the stack it's fine here */ - Config.cfgInitTail = Cmd.ctBuffer; + q--; + q[3] = q[0]; + } while (q > p); } + + p[0] = '/', p[1] = 'Y', p[2] = ' '; /* single step AUTOEXEC */ + if (askCommand & ASK_SKIPALL) + p[1] = 'D'; /* disable AUTOEXEC */ } - init_call_p_0(&Config); /* go execute process 0 (the shell) */ } -/* check for a block device and update device control block */ +/* check for a block device and update device control block */ STATIC VOID update_dcb(struct dhdr FAR * dhp) { - REG COUNT Index; - COUNT nunits = dhp->dh_name[0]; - struct dpb FAR *dpb; + int nunits = dhp->dh_name[0]; + struct dpb FAR *dpb = LoL->DPBp; - if (LoL->nblkdev == 0) - dpb = LoL->DPBp; - else + if (LoL->nblkdev) { - for (dpb = LoL->DPBp; (ULONG) dpb->dpb_next != 0xffffffffl; - dpb = dpb->dpb_next) - ; + while ((LONG) dpb->dpb_next != -1l) + dpb = dpb->dpb_next; dpb = dpb->dpb_next = KernelAlloc(nunits * sizeof(struct dpb), 'E', Config.cfgDosDataUmb); } - for (Index = 0; Index < nunits; Index++) { - dpb->dpb_next = dpb + 1; - dpb->dpb_unit = LoL->nblkdev; - dpb->dpb_subunit = Index; - dpb->dpb_device = dhp; - dpb->dpb_flags = M_CHANGED; - if ((LoL->CDSp != 0) && (LoL->nblkdev < LoL->lastdrive)) + int i = 0; + do { - LoL->CDSp[LoL->nblkdev].cdsDpb = dpb; - LoL->CDSp[LoL->nblkdev].cdsFlags = CDSPHYSDRV; - } - ++dpb; - ++LoL->nblkdev; + dpb->dpb_next = dpb + 1; + dpb->dpb_unit = LoL->nblkdev; + if (LoL->nblkdev < LoL->lastdrive && LoL->CDSp) + { + LoL->CDSp[LoL->nblkdev].cdsDpb = dpb; + LoL->CDSp[LoL->nblkdev].cdsFlags = CDSPHYSDRV; + } + LoL->nblkdev++; + dpb->dpb_subunit = i; + dpb->dpb_device = dhp; + dpb->dpb_flags = M_CHANGED; + dpb++; + i++; + } while (i < nunits); } - (dpb - 1)->dpb_next = (void FAR *)0xFFFFFFFFl; + (dpb - 1)->dpb_next = (VFP)-1l; } -/* If cmdLine is NULL, this is an internal driver */ - -BOOL init_device(struct dhdr FAR * dhp, char *cmdLine, COUNT mode, - char FAR **r_top) +/* If r_top is NULL, this is an internal driver */ +BOOL init_device(struct dhdr FAR * dhp, PCStr cmdLine, int mode, VFP *r_top) { request rq; - char name[8]; - - if (cmdLine) { - char *p, *q, ch; - int i; - - p = q = cmdLine; - for (;;) - { - ch = *p; - if (ch == '\0' || ch == ' ' || ch == '\t') - break; - p++; - if (ch == '\\' || ch == '/' || ch == ':') - q = p; /* remember position after path */ - } - for (i = 0; i < 8; i++) { - ch = '\0'; - if (p != q && *q != '.') - ch = *q++; - /* copy name, without extension */ - name[i] = ch; - } - } rq.r_unit = 0; rq.r_status = 0; rq.r_command = C_INIT; rq.r_length = sizeof(request); - rq.r_endaddr = *r_top; - rq.r_bpbptr = (void FAR *)(cmdLine ? cmdLine : "\n"); + rq.r_endaddr = r_top ? *r_top : lpTop; + rq.r_bpbptr = (VFP)cmdLine; rq.r_firstunit = LoL->nblkdev; - execrh((request FAR *) & rq, dhp); + execrh(&rq, dhp); /* * Added needed Error handle @@ -564,7 +479,7 @@ BOOL init_device(struct dhdr FAR * dhp, char *cmdLine, COUNT mode, if ((rq.r_status & (S_ERROR | S_DONE)) == S_ERROR) return TRUE; - if (cmdLine) + if (r_top) { /* Don't link in device drivers which do not take up memory */ if (rq.r_endaddr == (BYTE FAR *) dhp) @@ -578,8 +493,35 @@ BOOL init_device(struct dhdr FAR * dhp, char *cmdLine, COUNT mode, if (FP_OFF(dhp->dh_next) == 0xffff) { - KernelAllocPara(FP_SEG(rq.r_endaddr) + (FP_OFF(rq.r_endaddr) + 15)/16 - - FP_SEG(dhp), 'D', name, mode); + char name[8]; + PCStr q; + { + UBYTE ch; + PCStr p = cmdLine; + q = p; /* position after path */ + do /* find driver name after path */ + { + ch = *p; + p++; + if (ch == ':' || ch == '\\' || ch == '/') + q = p; + } while (ch > ' '); + } + { + int i = 0; + do /* extract driver name */ + { + UBYTE ch = *q; + if (ch <= ' ' || ch == '.') + ch = '\0'; /* copy name, without extension */ + name[i] = ch; + if (ch == '\0') + break; + i++, q++; + } while (i < sizeof name); + } + KernelAllocPara(FP_SEG(alignNextPara(rq.r_endaddr)) - FP_SEG(dhp), + 'D', name, mode); } /* Another fix for multisegmented device drivers: */ @@ -589,7 +531,7 @@ BOOL init_device(struct dhdr FAR * dhp, char *cmdLine, COUNT mode, /* last INIT call which will then be passed as the end address */ /* for the next INIT call. */ - *r_top = (char FAR *)rq.r_endaddr; + *r_top = rq.r_endaddr; } if (!(dhp->dh_attr & ATTR_CHAR) && (rq.r_nunits != 0)) @@ -606,28 +548,21 @@ BOOL init_device(struct dhdr FAR * dhp, char *cmdLine, COUNT mode, return FALSE; } -STATIC void InitIO(void) +STATIC void init_internal_devices(void) { struct dhdr far *device = &LoL->nul_dev; /* Initialize driver chain */ do { - init_device(device, NULL, 0, &lpTop); + /* ??? is cmdLine "\n" for internal devices required? --avb */ + init_device(device, "\n", 0, NULL); device = device->dh_next; } while (FP_OFF(device) != 0xffff); } -/* issue an internal error message */ -VOID init_fatal(BYTE * err_msg) -{ - printf("\nInternal kernel error - %s\nSystem halted\n", err_msg); - for (;;) ; -} - /* Initialize all printers - this should work. IMHO, this might also be done on first use of printer, as I never liked the noise by a resetting printer, and I usually much more often reset my system, then I print :-) @@ -674,50 +609,43 @@ STATIC VOID InitSerialPorts(VOID) remove the floppy/bootable CD from the drive. user has some seconds to hit ANY key to continue - to boot from floppy/cd, else the system is + to boot from floppy/cd, else the system is booted from HD */ -EmulatedDriveStatus(int drive,char statusOnly) +static int EmulatedDriveStatus(int drive,char statusOnly) { iregs r; char buffer[0x13]; buffer[0] = 0x13; - r.a.b.h = 0x4b; /* bootable CDROM - get status */ - r.a.b.l = statusOnly; - r.d.b.l = (char)drive; - r.si = (int)buffer; - init_call_intr(0x13, &r); - - if (r.flags & 1) - return FALSE; - - return TRUE; + r.AH = 0x4b; /* bootable CDROM - get status */ + r.AL = statusOnly; + r.DL = (char)drive; + r.SI = (int)buffer; + init_call_intr(0x13, &r); + return r.FLAGS & 1; /* carry flag */ } STATIC void CheckContinueBootFromHarddisk(void) { char *bootedFrom = "Floppy/CD"; - iregs r; - int key; - if (InitKernelConfig.BootHarddiskSeconds == 0) + if (InitKernelConfig.BootHarddiskSeconds <= 0) return; if (LoL->BootDrive >= 3) { #if 0 - if (!EmulatedDriveStatus(0x80,1)) + if (EmulatedDriveStatus(0x80,1)) #endif - { /* already booted from HD */ return; - } } - else { + else + { #if 0 - if (!EmulatedDriveStatus(0x00,1)) + if (EmulatedDriveStatus(0x00,1)) #endif bootedFrom = "Floppy"; } @@ -729,34 +657,30 @@ STATIC void CheckContinueBootFromHarddisk(void) " Hit 'H' or wait %d seconds to boot from Harddisk\n", InitKernelConfig.BootHarddiskSeconds, bootedFrom, - InitKernelConfig.BootHarddiskSeconds - ); + InitKernelConfig.BootHarddiskSeconds); - key = GetBiosKey(InitKernelConfig.BootHarddiskSeconds); - - if (key != -1 && (key & 0xff) != 'h' && (key & 0xff) != 'H') + if (GetBiosKey(InitKernelConfig.BootHarddiskSeconds)) { - /* user has hit a key, continue to boot from floppy/CD */ - printf("\n"); - return; + unsigned key = GetBiosKey(-1); /* remove key from buffer */ + if ((UBYTE)key != 'h' && (UBYTE)key != 'H') + /* user has hit a key, continue to boot from floppy/CD */ + return; } /* reboot from harddisk */ EmulatedDriveStatus(0x00,0); EmulatedDriveStatus(0x80,0); - /* now jump and run */ - r.a.x = 0x0201; - r.c.x = 0x0001; - r.d.x = 0x0080; - r.b.x = 0x7c00; - r.es = 0; - - init_call_intr(0x13, &r); - { - void (far *reboot)(void) = (void (far*)(void)) MK_FP(0x0,0x7c00); - - (*reboot)(); + iregs r; + r.AX = 0x0201; + r.CX = 0x0001; + r.DX = 0x0080; + r.BX = 0x7c00; + r.ES = 0; + init_call_intr(0x13, &r); } + + /* now jump and run */ + ((void (far*)(void)) MK_FP(0,0x7c00))(); /* jump to boot sector */ } diff --git a/kernel/makefile b/kernel/makefile index 0b67948..4d7adc4 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -1,5 +1,5 @@ # -# Makefile for Borland C++ 3.1 for kernel.sys +# makefile for kernel.sys # # $Id$ # @@ -9,10 +9,12 @@ LIBS=..\lib\device.lib ..\lib\libm.lib HDR=../hdr/ -# *List Macros* +# List Macros ########################################################## # Only 8 files per definition; this is limitation of DOS batch # files (only 9 directly accessible parameters). +# Order of linking is important: first kernel.asm, last INIT code. + OBJS1=kernel.obj entry.obj io.obj console.obj serial.obj printer.obj dsk.obj \ sysclk.obj OBJS2=asmsupt.obj execrh.obj nlssupt.obj procsupt.obj dosidle.obj int2f.obj \ @@ -27,98 +29,87 @@ OBJS7=main.obj config.obj initoem.obj inithma.obj dyninit.obj iprf.obj \ initdisk.obj initclk.obj OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS6) $(OBJS7) -# *Explicit Rules* +# Explicit Rules ####################################################### -production: ..\bin\$(TARGET).sys +all: ..\bin\$(TARGET).sys -..\bin\$(TARGET).sys: kernel.sys - copy kernel.sys ..\bin - copy kernel.sys ..\bin\$(TARGET).sys - copy kernel.map ..\bin\$(TARGET).map - -kernel.sys: kernel.exe ..\utils\exeflat.exe - $(XUPX) kernel.exe - ..\utils\exeflat kernel.exe kernel.sys 0x60 -S0x10 -S0x8B $(UPXOPT) - -kernel.exe: $(TARGET).lnk $(OBJS) $(LIBS) +..\bin\$(TARGET).sys: $(TARGET).lnk $(OBJS) $(LIBS) ..\utils\exeflat.exe $(LINK) @$(TARGET).lnk; - -clobber: clean - -$(RM) kernel.exe kernel.sys status.me - -clean: - -$(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.cod *.err *.lnk + $(XUPX) kernel.exe + ..\utils\exeflat kernel.exe $*.sys 0x60 -S0x10 -S0x8B $(UPXOPT) + copy $*.sys ..\bin\kernel.sys # 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 +# inability of Turbo `make' 2.0 to perform command line redirection. --ror4 ECHOTO=..\utils\echoto -$(TARGET).lnk: turboc.cfg makefile ..\mkfiles\generic.mak ..\mkfiles\$(COMPILER).mak - -$(RM) *.lnk - $(ECHOTO) $(TARGET).lnk $(OBJS1)+ - $(ECHOTO) $(TARGET).lnk $(OBJS2)+ - $(ECHOTO) $(TARGET).lnk $(OBJS3)+ - $(ECHOTO) $(TARGET).lnk $(OBJS4)+ - $(ECHOTO) $(TARGET).lnk $(OBJS5)+ - $(ECHOTO) $(TARGET).lnk $(OBJS6)+ - $(ECHOTO) $(TARGET).lnk $(OBJS7) - $(ECHOTO) $(TARGET).lnk kernel.exe - $(ECHOTO) $(TARGET).lnk kernel.map - $(ECHOTO) $(TARGET).lnk $(LIBS) +$(TARGET).lnk: $(DEPENDS) *.cfg + -$(RM) *.lnk *.obj + $(ECHOTO) $*.lnk $(OBJS1)+ + $(ECHOTO) $*.lnk $(OBJS2)+ + $(ECHOTO) $*.lnk $(OBJS3)+ + $(ECHOTO) $*.lnk $(OBJS4)+ + $(ECHOTO) $*.lnk $(OBJS5)+ + $(ECHOTO) $*.lnk $(OBJS6)+ + $(ECHOTO) $*.lnk $(OBJS7) + $(ECHOTO) $*.lnk kernel + $(ECHOTO) $*.lnk ..\bin\$* + $(ECHOTO) $*.lnk $(LIBS) -# *Individual File Dependencies* -apisupt.obj: apisupt.asm segs.inc $(TARGET).lnk -asmsupt.obj: asmsupt.asm segs.inc $(TARGET).lnk -console.obj: console.asm io.inc $(TARGET).lnk -dosidle.obj: dosidle.asm segs.inc $(TARGET).lnk -entry.obj: entry.asm segs.inc $(HDR)stacks.inc $(TARGET).lnk -execrh.obj: execrh.asm segs.inc $(TARGET).lnk -int2f.obj: int2f.asm segs.inc $(HDR)stacks.inc $(TARGET).lnk -intr.obj: intr.asm segs.inc $(TARGET).lnk -io.obj: io.asm segs.inc $(HDR)stacks.inc $(TARGET).lnk -irqstack.obj: irqstack.asm segs.inc $(TARGET).lnk -kernel.obj: kernel.asm segs.inc ludivmul.inc $(TARGET).lnk -nls_hc.obj: nls_hc.asm segs.inc $(TARGET).lnk -nlssupt.obj: nlssupt.asm segs.inc $(HDR)stacks.inc $(TARGET).lnk -printer.obj: printer.asm io.inc $(TARGET).lnk -procsupt.obj: procsupt.asm segs.inc $(HDR)stacks.inc $(TARGET).lnk -serial.obj: serial.asm io.inc $(TARGET).lnk +# Individual File Dependencies ######################################### + +apisupt.obj: apisupt.asm segs.inc +asmsupt.obj: asmsupt.asm segs.inc +console.obj: console.asm io.inc +dosidle.obj: dosidle.asm segs.inc +entry.obj: entry.asm segs.inc $(HDR)stacks.inc +execrh.obj: execrh.asm segs.inc +int2f.obj: int2f.asm segs.inc $(HDR)stacks.inc +intr.obj: intr.asm segs.inc +io.obj: io.asm segs.inc $(HDR)stacks.inc +irqstack.obj: irqstack.asm segs.inc +kernel.obj: kernel.asm segs.inc ludivmul.inc +nls_hc.obj: nls_hc.asm segs.inc +nlssupt.obj: nlssupt.asm segs.inc $(HDR)stacks.inc +printer.obj: printer.asm io.inc +procsupt.obj: procsupt.asm segs.inc $(HDR)stacks.inc +serial.obj: serial.asm io.inc HDRS=\ $(HDR)portab.h $(HDR)device.h $(HDR)mcb.h $(HDR)pcb.h \ $(HDR)fat.h $(HDR)fcb.h $(HDR)tail.h $(HDR)time.h $(HDR)process.h \ - $(HDR)dcb.h $(HDR)sft.h $(HDR)cds.h $(HDR)exe.h $(HDR)fnode.h \ - $(HDR)dirmatch.h $(HDR)file.h $(HDR)clock.h $(HDR)kbd.h $(HDR)error.h \ + $(HDR)dcb.h $(HDR)sft.h $(HDR)cds.h $(HDR)exe.h $(HDR)fnode.h \ + $(HDR)dirmatch.h $(HDR)file.h $(HDR)clock.h $(HDR)kbd.h $(HDR)error.h \ $(HDR)version.h dyndata.h HEADERS=$(HDRS) globals.h proto.h INITHEADERS=$(HDRS) init-mod.h init-dat.h -blockio.obj: blockio.c $(HEADERS) $(TARGET).lnk -break.obj: break.c $(HEADERS) $(TARGET).lnk -chario.obj: chario.c $(HEADERS) $(TARGET).lnk -dosfns.obj: dosfns.c $(HEADERS) $(TARGET).lnk -dosnames.obj: dosnames.c $(HEADERS) $(TARGET).lnk -dsk.obj: dsk.c $(HEADERS) $(TARGET).lnk -error.obj: error.c $(HEADERS) $(TARGET).lnk -fatdir.obj: fatdir.c $(HEADERS) $(TARGET).lnk -fatfs.obj: fatfs.c $(HEADERS) $(TARGET).lnk -fattab.obj: fattab.c $(HEADERS) $(TARGET).lnk -fcbfns.obj: fcbfns.c $(HEADERS) $(TARGET).lnk -inthndlr.obj: inthndlr.c $(HEADERS) $(TARGET).lnk -ioctl.obj: ioctl.c $(HEADERS) $(TARGET).lnk -memmgr.obj: memmgr.c $(HEADERS) $(TARGET).lnk -misc.obj: misc.c $(HEADERS) $(TARGET).lnk -lfnapi.obj: lfnapi.c $(HEADERS) $(TARGET).lnk -newstuff.obj: newstuff.c $(HEADERS) $(TARGET).lnk -network.obj: network.c $(HEADERS) $(TARGET).lnk -nls.obj: nls.c $(HEADERS) $(TARGET).lnk -prf.obj: prf.c $(HDR)portab.h $(TARGET).lnk -strings.obj: strings.c $(TARGET).lnk -sysclk.obj: sysclk.c $(HEADERS) $(TARGET).lnk -syspack.obj: syspack.c $(HEADERS) $(TARGET).lnk -systime.obj: systime.c $(HEADERS) $(TARGET).lnk -task.obj: task.c $(HEADERS) $(TARGET).lnk +blockio.obj: blockio.c $(HEADERS) +break.obj: break.c $(HEADERS) +chario.obj: chario.c $(HEADERS) +dosfns.obj: dosfns.c $(HEADERS) +dosnames.obj: dosnames.c $(HEADERS) +dsk.obj: dsk.c $(HEADERS) +error.obj: error.c $(HEADERS) +fatdir.obj: fatdir.c $(HEADERS) +fatfs.obj: fatfs.c $(HEADERS) +fattab.obj: fattab.c $(HEADERS) +fcbfns.obj: fcbfns.c $(HEADERS) +inthndlr.obj: inthndlr.c $(HEADERS) +ioctl.obj: ioctl.c $(HEADERS) +lfnapi.obj: lfnapi.c $(HEADERS) +memmgr.obj: memmgr.c $(HEADERS) +misc.obj: misc.c $(HEADERS) +network.obj: network.c $(HEADERS) +newstuff.obj: newstuff.c $(HEADERS) +nls.obj: nls.c $(HEADERS) +prf.obj: prf.c $(HDR)portab.h +strings.obj: strings.c +sysclk.obj: sysclk.c $(HEADERS) +syspack.obj: syspack.c $(HEADERS) +systime.obj: systime.c $(HEADERS) +task.obj: task.c $(HEADERS) # now the funny stuff :-) # Files in the INIT segment @@ -126,39 +117,49 @@ task.obj: task.c $(HEADERS) $(TARGET).lnk # XXX: Special handling for initialization modules -- this is required because # TC 2.01 cannot handle `#pragma option' like TC 3 can. -- ror4 -config.obj: config.c $(INITHEADERS) $(TARGET).lnk - $(CC) $(INITCFLAGS) $*.c - $(INITPATCH) $*.obj +config.obj: config.c $(INITHEADERS) + $(CC) $(INITCFLAGS) $*.c + $(INITPATCH) $*.obj -initoem.obj: initoem.c $(INITHEADERS) $(TARGET).lnk - $(CC) $(INITCFLAGS) $*.c - $(INITPATCH) $*.obj +dyninit.obj: dyninit.c $(INITHEADERS) + $(CC) $(INITCFLAGS) $*.c + $(INITPATCH) $*.obj -main.obj: main.c $(INITHEADERS) $(TARGET).lnk - $(CC) $(INITCFLAGS) $*.c - $(INITPATCH) $*.obj +initclk.obj: initclk.c $(INITHEADERS) + $(CC) $(INITCFLAGS) $*.c + $(INITPATCH) $*.obj -inithma.obj: inithma.c $(INITHEADERS) $(TARGET).lnk - $(CC) $(INITCFLAGS) $*.c - $(INITPATCH) $*.obj +initdisk.obj: initdisk.c $(INITHEADERS) + $(CC) $(INITCFLAGS) $*.c + $(INITPATCH) $*.obj -dyninit.obj: dyninit.c $(INITHEADERS) $(TARGET).lnk - $(CC) $(INITCFLAGS) $*.c - $(INITPATCH) $*.obj +inithma.obj: inithma.c $(INITHEADERS) + $(CC) $(INITCFLAGS) $*.c + $(INITPATCH) $*.obj -initdisk.obj: initdisk.c $(INITHEADERS) $(TARGET).lnk - $(CC) $(INITCFLAGS) $*.c - $(INITPATCH) $*.obj +initoem.obj: initoem.c $(INITHEADERS) + $(CC) $(INITCFLAGS) $*.c + $(INITPATCH) $*.obj -initclk.obj: initclk.c $(INITHEADERS) $(TARGET).lnk - $(CC) $(INITCFLAGS) $*.c - $(INITPATCH) $*.obj +main.obj: main.c $(INITHEADERS) + $(CC) $(INITCFLAGS) $*.c + $(INITPATCH) $*.obj -#the string functions for INIT_TEXT -iasmsupt.obj: asmsupt.asm $(TARGET).lnk - $(NASM) -D$(COMPILER) -D_INIT $(NASMFLAGS) -f obj -o iasmsupt.obj asmsupt.asm +# the string functions for INIT_TEXT -#the printf for INIT_TEXT - yet another special case, this file includes prf.c -iprf.obj: iprf.c prf.c $(HDR)portab.h $(TARGET).lnk - $(CC) $(INITCFLAGS) $*.c - $(INITPATCH) $*.obj +iasmsupt.obj: asmsupt.asm + $(NASM) $(NASMFLAGS) -D_INIT asmsupt.asm -o$*.obj + +# the printf for INIT_TEXT - yet another special case, this file includes prf.c + +iprf.obj: iprf.c prf.c $(HDR)portab.h + $(CC) $(INITCFLAGS) $*.c + $(INITPATCH) $*.obj + +######################################################################## + +clean: + -$(RM) *.bak *.cod *.crf *.err *.lnk *.lst *.map *.obj *.xrf + +clobber: clean + -$(RM) kernel.exe status.me diff --git a/kernel/msc.cfg b/kernel/msc.cfg new file mode 100644 index 0000000..af2a42c --- /dev/null +++ b/kernel/msc.cfg @@ -0,0 +1,5 @@ +-batch -nologo -WX +-Zlp1 +-f- -Osb1V4e -Gsry +-Fc +-I..\hdr diff --git a/kernel/nls.c b/kernel/nls.c index ee5455a..6810dbe 100644 --- a/kernel/nls.c +++ b/kernel/nls.c @@ -502,7 +502,7 @@ VOID DosUpFString(char FAR * str) COUNT DosGetData(int subfct, UWORD cp, UWORD cntry, UWORD bufsize, VOID FAR * buf) { - struct nlsPackage FAR *nls; /* NLS package to use to return the info from */ + struct nlsPackage FAR *nls; /* NLS package to use to return the info from */ log(("NLS: GetData(): subfct=%x, cp=%u, cntry=%u, bufsize=%u\n", subfct, cp, cntry, bufsize)); @@ -513,19 +513,21 @@ COUNT DosGetData(int subfct, UWORD cp, UWORD cntry, UWORD bufsize, return DE_INVLDFUNC; /* nls := NLS package of cntry/codepage */ - if ((nls = searchPackage(cp, cntry)) == NULL - || (nls->flags & NLS_FLAG_DIRECT_GETDATA) == 0) + if ((nls = searchPackage(cp, cntry)) != NULL) { - /* If the NLS pkg is not loaded into memory or the - direct-access flag is disabled, the request must - be passed through MUX */ - return (subfct == NLS_DOS_38) - ? mux38(nls->cp, nls->cntry, bufsize, buf) - : mux65(subfct, nls->cp, nls->cntry, bufsize, buf); + /* matching NLS package found */ + if (nls->flags & NLS_FLAG_DIRECT_GETDATA) + /* Direct access to the data */ + return nlsGetData(nls, subfct, buf, bufsize); + cp = nls->cp; + cntry = nls->cntry; } - /* Direct access to the data */ - return nlsGetData(nls, subfct, buf, bufsize); + /* If the NLS pkg is not loaded into memory or the direct-access + flag is disabled, the request must be passed through MUX */ + return (subfct == NLS_DOS_38) + ? mux38(cp, cntry, bufsize, buf) + : mux65(subfct, cp, cntry, bufsize, buf); } /* diff --git a/kernel/procsupt.asm b/kernel/procsupt.asm index 432972c..6fc3352 100644 --- a/kernel/procsupt.asm +++ b/kernel/procsupt.asm @@ -47,17 +47,12 @@ segment HMA_TEXT ; ; void exec_user(iregs far *irp, int disable_a20) ; - global _exec_user + global _exec_user _exec_user: - -; PUSH$ALL -; mov ds,[_DGROUP_] -; cld -; -; -; - pop ax ; return address (unused) - +%ifndef WATCOM +; exec_user declared with attribute `aborts' + pop ax ; return address (unused) +%endif pop ax ; irp (user ss:sp) pop dx pop cx ; disable A20? @@ -280,10 +275,13 @@ _spawn_int23: ; prepare to call process 0 (the shell) from P_0() in C - global reloc_call_p_0 + global reloc_call_p_0 reloc_call_p_0: +%ifndef WATCOM +; reloc_call_p_0 declared with attribute `aborts' pop ax ; return address (32-bit, unused) pop ax +%endif pop ax ; fetch parameter 0 (32-bit) from the old stack pop dx mov ds,[cs:_DGROUP_] @@ -293,4 +291,9 @@ reloc_call_p_0: sti push dx ; pass parameter 0 onto the new stack push ax - call _P_0 ; no return, allow parameter fetch from C +%ifndef WATCOM + call _P_0 ; no return, allow parameter fetch from C +%else +; P_0 declared with attribute `aborts' + jmp _P_0 ; no return, allow parameter fetch from C +%endif diff --git a/kernel/proto.h b/kernel/proto.h index 524d5a8..f72c898 100644 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -132,9 +132,14 @@ VOID ASMCFUNC DosIdle_int(void); int ParseDosName(const char *, char *, BOOL); /* error.c */ + VOID dump(void); VOID panic(BYTE * s); VOID fatal(BYTE * err_msg); +#ifdef __WATCOMC__ +# pragma aux panic aborts +# pragma aux fatal aborts +#endif /* fatdir.c */ VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart); @@ -225,21 +230,20 @@ void FcbCloseAll(void); UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First); /* intr.asm */ -COUNT ASMPASCAL res_DosExec(COUNT mode, exec_blk * ep, BYTE * lp); -UCOUNT ASMPASCAL res_read(int fd, void *buf, UCOUNT count); + +int ASMPASCAL res_DosExec(int mode, exec_blk *, PCStr); +unsigned ASMPASCAL res_read(int fd, void *buf, unsigned count); #ifdef __WATCOMC__ -#pragma aux (pascal) res_DosExec modify exact [ax bx dx es] -#pragma aux (pascal) res_read modify exact [ax bx cx dx] +# pragma aux (pascal) res_DosExec modify exact [ax bx dx es] +# pragma aux (pascal) res_read modify exact [ax bx cx dx] #endif /* ioctl.c */ COUNT DosDevIOctl(lregs * r); /* memmgr.c */ -seg far2para(VOID FAR * p); -seg long2para(ULONG size); -void FAR *add_far(void FAR * fp, unsigned off); -VOID FAR *adjust_far(const void FAR * fp); + +VFP adjust_far(CVFP); COUNT DosMemAlloc(UWORD size, COUNT mode, seg * para, UWORD * asize); COUNT DosMemLargest(UWORD * size); COUNT DosMemFree(UWORD para); @@ -364,12 +368,16 @@ const UWORD *is_leap_year_monthdays(UWORD year); UWORD DaysFromYearMonthDay(UWORD Year, UWORD Month, UWORD DayOfMonth); /* task.c */ -VOID new_psp(seg para, seg cur_psp); -VOID child_psp(seg para, seg cur_psp, int psize); -VOID return_user(void); + +void new_psp(seg_t para, seg_t cur_psp); +void child_psp(seg_t para, seg_t cur_psp, seg_t beyond); +void return_user(void); COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp); ULONG SftGetFsize(int sft_idx); VOID InitPSP(VOID); +#ifdef __WATCOMC__ +# pragma aux return_user aborts +#endif /* newstuff.c */ int SetJFTSize(UWORD nHandles); @@ -391,7 +399,11 @@ UWORD get_machine_name(BYTE FAR * netname); VOID set_machine_name(BYTE FAR * netname, UWORD name_num); /* procsupt.asm */ -VOID ASMCFUNC exec_user(iregs FAR * irp, int disable_a20); + +void ASMCFUNC exec_user(iregs FAR *, int disable_a20); +#ifdef __WATCOMC__ +# pragma aux (cdecl) exec_user aborts +#endif /* new by TE */ @@ -403,5 +415,4 @@ VOID ASMCFUNC exec_user(iregs FAR * irp, int disable_a20); ASSERT_CONST( (BYTE FAR *)x->fcb_ext - (BYTE FAR *)x->fcbname == 8) */ -#define ASSERT_CONST(x) { typedef struct { char _xx[x ? 1 : -1]; } xx ; } - +#define ASSERT_CONST(x) { typedef struct { char _[(x) ? 1 : -1]; } _; } diff --git a/kernel/segs.inc b/kernel/segs.inc index ba6e123..5e88c19 100644 --- a/kernel/segs.inc +++ b/kernel/segs.inc @@ -59,8 +59,12 @@ segment _FIXED_DATA class=FDATA align=16 segment _BSS class=BSS align=2 segment _DATA class=DATA align=2 segment _DATAEND class=DATA align=1 -;for WATCOM +%ifdef MSC +segment CONST class=CONST align=2 +%else segment CONST class=DATA align=2 +%endif +;for WATCOM segment CONST2 class=DATA align=2 ;for MSC segment DCONST class=DCONST align=2 diff --git a/kernel/task.c b/kernel/task.c index 2a173bb..1d5b6bd 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -34,8 +34,6 @@ static BYTE *RcsId = "$Id$"; #endif -#define toupper(c) ((c) >= 'a' && (c) <= 'z' ? (c) + ('A' - 'a') : (c)) - #define LOADNGO 0 #define LOAD 1 #define OVERLAY 3 @@ -49,6 +47,7 @@ static BYTE *RcsId = #define ExeHeader (*(exe_header *)(SecPathName + 0)) #define TempExeBlock (*(exec_blk *)(SecPathName + sizeof(exe_header))) #define Shell (SecPathName + sizeof(exe_header) + sizeof(exec_blk)) +#define sizeofShell (sizeof SecPathName - sizeof(exe_header) - sizeof(exec_blk)) #ifdef __TURBOC__ /* this is a Borlandism and doesn't work elsewhere */ #if sizeof(SecPathName) < sizeof(exe_header) + sizeof(exec_blk) + NAMEMAX @@ -56,20 +55,17 @@ static BYTE *RcsId = #endif #endif -#define CHUNK 32256 -#define MAXENV 32768u -#define ENV_KEEPFREE 83 /* keep unallocated by environment variables */ - /* The '65' added to nEnvSize does not cover the additional stuff: - + 2 bytes: number of strings - + 80 bytes: maximum absolute filename - + 1 byte: '\0' - -- 1999/04/21 ska */ +#define CHUNK 32256u /* =8000h-512; this value allows to combine + in one int value negative error codes + and positive read counters + */ +#define MAXENV 32768u /* maximum environment size */ intvec getvec(unsigned char intno) { intvec iv; disable(); - iv = *(intvec FAR *)MK_FP(0,4 * (intno)); + iv = *MK_PTR(intvec, 0, 4 * intno); enable(); return iv; } @@ -77,13 +73,13 @@ intvec getvec(unsigned char intno) void setvec(unsigned char intno, intvec vector) { disable(); - *(intvec FAR *)MK_FP(0,4 * intno) = vector; + *MK_PTR(intvec, 0, 4 * intno) = vector; enable(); } ULONG SftGetFsize(int sft_idx) { - sft FAR *s = idx_to_sft(sft_idx); + const sft FAR *s = idx_to_sft(sft_idx); /* Get the SFT block that contains the SFT */ if (FP_OFF(s) == (size_t) -1) @@ -99,258 +95,243 @@ ULONG SftGetFsize(int sft_idx) return dos_getfsize(s->sft_status); } -STATIC COUNT ChildEnv(exec_blk * exp, UWORD * pChildEnvSeg, char far * pathname) +/* create a new environment for the process */ +STATIC int ChildEnv(seg_t env_seg, seg_t *penv_seg, const char far *path) { - BYTE FAR *pSrc; - BYTE FAR *pDest; - UWORD nEnvSize; - COUNT RetCode; -/* UWORD MaxEnvSize; not used -- 1999/04/21 ska */ - psp FAR *ppsp = MK_FP(cu_psp, 0); + size_t env_sz, path_sz; + int rc; - /* create a new environment for the process */ - /* copy parent's environment if exec.env_seg == 0 */ - - pSrc = exp->exec.env_seg ? - MK_FP(exp->exec.env_seg, 0) : MK_FP(ppsp->ps_environ, 0); - -#if 0 /* Every process requires an environment because of argv[0] - -- 1999/04/21 ska */ - */if (!pSrc) /* no environment to copy */ + -- 1999/04/21 ska + */ + + /* make complete pathname */ + if ((rc = truename(path, PriPathName, CDS_MODE_SKIP_PHYSICAL)) < SUCCESS) + return rc; + + /* get parent's environment if exec.env_seg == 0 */ + if (env_seg == 0) + env_seg = MK_SEG_PTR(const psp, cu_psp)->ps_environ; + + /* count size of environment */ + path_sz = strlen(PriPathName) + 5; + env_sz = 0; + if (env_seg && *MK_PTR(const char, env_seg, 0)) { - *pChildEnvSeg = 0; - return SUCCESS; - } -#endif - - nEnvSize = 1; - /* This loop had not counted the very last '\0' - -- 1999/04/21 ska */ - if (pSrc) - { /* if no environment is available, one byte is required */ - - for (nEnvSize = 0;; nEnvSize++) + do { - /* Test env size and abort if greater than max */ - if (nEnvSize >= MAXENV - ENV_KEEPFREE) + env_sz++; + if (env_sz + path_sz > MAXENV) return DE_INVLDENV; - - if (*(UWORD FAR *) (pSrc + nEnvSize) == 0) - break; - } - nEnvSize += 2; /* account for trailing \0\0 */ + } while (*MK_PTR(const UWORD, env_seg, env_sz)); } - /* allocate enough space for env + path */ - if ((RetCode = DosMemAlloc((nEnvSize + ENV_KEEPFREE + 15)/16, - mem_access_mode, pChildEnvSeg, - NULL /*(UWORD FAR *) MaxEnvSize ska */ )) < 0) - return RetCode; - pDest = MK_FP(*pChildEnvSeg + 1, 0); - - /* fill the new env and inform the process of its */ - /* location throught the psp */ - - /* copy the environment */ - if (pSrc) + /* allocate space for env + path */ { - fmemcpy(pDest, pSrc, nEnvSize); - pDest += nEnvSize; + UWORD tmp; + if ((rc = DosMemAlloc((env_sz + path_sz + 15) / 16, + mem_access_mode, penv_seg, &tmp)) != SUCCESS) + return rc; } - else - *pDest++ = '\0'; /* create an empty environment */ - - /* initialize 'extra strings' count */ - *((UWORD FAR *) pDest) = 1; - pDest += sizeof(UWORD) / sizeof(BYTE); - - /* copy complete pathname */ - if ((RetCode = truename(pathname, PriPathName, CDS_MODE_SKIP_PHYSICAL)) < SUCCESS) { - return RetCode; + seg_t dst_seg = *penv_seg + 1; + + /* enviornment contains: + - 0 or more ASCIIZ strings (with variable definitions); + - empty ASCIIZ string (one null character); + - 16-bit counter (usually 1); + - ASCIIZ string with path. + */ + /* UNDOCUMENTED: with none variables before empty ASCIIZ string, + environment should get additional null character (ie. empty + environment contains two null characters). --avb + */ + fmemcpy(MK_SEG_PTR(char, dst_seg), MK_SEG_PTR(const char, env_seg), env_sz); + *MK_PTR(UWORD, dst_seg, env_sz) = 0; + *MK_PTR(UWORD, dst_seg, env_sz + 2) = 1; + fstrcpy(MK_PTR(char, dst_seg, env_sz + 4), PriPathName); } - fstrcpy(pDest, PriPathName); - - /* Theoretically one could either: - + resize the already allocated block to best-fit behind the pathname, or - + generate the filename into a temporary buffer to allocate only the - minimum required environment -- 1999/04/21 ska */ - return SUCCESS; } -/* The following code is 8086 dependant */ -void new_psp(seg para, seg cur_psp) +/* The following code is 8086 dependant */ +void new_psp(seg_t para, seg_t cur_psp) { - psp FAR *p = MK_FP(para, 0); + psp _seg *p = MK_SEG_PTR(psp, para); - fmemcpy(p, MK_FP(cur_psp, 0), sizeof(psp)); + fmemcpy(p, MK_SEG_PTR(psp, cur_psp), sizeof(psp)); - /* terminate address */ - p->ps_isv22 = getvec(0x22); - /* break address */ - p->ps_isv23 = getvec(0x23); - /* critical error address */ - p->ps_isv24 = getvec(0x24); - /* parent psp segment set to 0 (see RBIL int21/ah=26) */ - p->ps_parent = 0; + /* initialize all entries and exits */ + p->ps_exit = 0x20cd; /* CP/M-like exit point: */ + /* INT 20 opcode */ + /* CP/M-like entry point: */ + p->ps_farcall = 0x9a; /* FAR CALL opcode... */ + p->ps_reentry = MK_FP(0xf01d,0xfef0); /* ...entry address */ + + /* entry address should point to 0:c0 (INT 30 vector), but + low word of ps_reentry should also contain "size of first + segment for .COM file" while preserving the far call; + in MS-DOS this is F01D:FEF0 --avb */ + + p->ps_unix[0] = 0xcd; /* unix style call: */ + p->ps_unix[1] = 0x21; /* INT 21/RETF opcodes */ + p->ps_unix[2] = 0xcb; + + /* parent-child relationships */ + p->ps_prevpsp = (VFP)-1l; /* previous psp address */ + + p->ps_isv22 = getvec(0x22); /* terminate handler */ + p->ps_isv23 = getvec(0x23); /* break handler */ + p->ps_isv24 = getvec(0x24); /* critical error handler */ + + /* File System parameters */ + p->ps_maxfiles = sizeof p->ps_files; /* size of file table */ + p->ps_filetab = p->ps_files; /* file table address */ } -void child_psp(seg para, seg cur_psp, int psize) +/* !!! cur_psp always equal to cu_psp --avb */ +void child_psp(seg_t para, seg_t cur_psp, seg_t beyond) { - psp FAR *p = MK_FP(para, 0); - psp FAR *q = MK_FP(cur_psp, 0); - int i; + psp _seg *p; new_psp(para, cur_psp); + p = MK_SEG_PTR(psp, para); - /* Now for parent-child relationships */ - /* parent psp segment */ - p->ps_parent = cu_psp; - /* previous psp pointer */ - p->ps_prevpsp = q; + /* parent-child relationships */ + p->ps_parent = cu_psp; /* parent psp segment */ - /* Environment and memory useage parameters */ - /* memory size in paragraphs */ - p->ps_size = psize; + /* Environment and memory useage parameters */ + p->ps_size = beyond; /* segment of memory beyond */ + /* memory allocated to program */ - /* File System parameters */ - /* maximum open files */ - p->ps_maxfiles = 20; - fmemset(p->ps_files, 0xff, 20); - - /* open file table pointer */ - p->ps_filetab = p->ps_files; - - /* clone the file table -- 0xff is unused */ - for (i = 0; i < 20; i++) - if (CloneHandle(i) >= 0) - p->ps_files[i] = q->ps_filetab[i]; - - /* first command line argument */ - p->ps_fcb1.fcb_drive = 0; - fmemset(p->ps_fcb1.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE); - /* second command line argument */ - p->ps_fcb2.fcb_drive = 0; - fmemset(p->ps_fcb2.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE); - - /* local command line */ - p->ps_cmd.ctCount = 0; - p->ps_cmd.ctBuffer[0] = 0xd; /* command tail */ -} - -STATIC UBYTE chkdrv(unsigned drive) /* from FCB: 0 = default, 1 = A:, ... */ -{ - if (drive) - drive--; /* 0 = A:, 1 = B:, ... */ - else - drive = default_drive; - return get_cds(drive) ? 0 : 0xff; /* return 0 if drive is valid, else 0xff */ -} - -STATIC UWORD patchPSP(UWORD pspseg, UWORD envseg, exec_blk FAR * exb, - BYTE FAR * fnam) -{ - psp FAR *psp; - mcb FAR *pspmcb; - int i; - BYTE FAR *np; - - pspmcb = MK_FP(pspseg, 0); - ++pspseg; - psp = MK_FP(pspseg, 0); - - /* complete the psp by adding the command line and FCBs */ - fmemcpy(&psp->ps_cmd, exb->exec.cmd_line, sizeof(CommandTail)); - if (FP_OFF(exb->exec.fcb_1) != 0xffff) + /* File System parameters */ { - fmemcpy(&psp->ps_fcb1, exb->exec.fcb_1, 16); - fmemcpy(&psp->ps_fcb2, exb->exec.fcb_2, 16); + psp _seg *q = MK_SEG_PTR(psp, cur_psp); + int i; + /* clone the file table, 0xff=unused */ + for (i = 0; i < sizeof p->ps_files; i++) + p->ps_files[i] = CloneHandle(i) != SUCCESS ? 0xff : q->ps_filetab[i]; + } +} + +struct cds FAR *get_cds1(unsigned drv) +{ + if (drv-- == 0) /* 0 = A:, 1 = B:, ... */ + drv = default_drive; + return get_cds(drv); +} + +STATIC void makePSP(seg_t pspseg, seg_t envseg, size_t asize, const char FAR * path) +{ + psp _seg *p = MK_SEG_PTR(psp, pspseg); + mcb _seg *pspmcb = MK_SEG_PTR(mcb, FP_SEG(p) - 1); + + /* identify the mcb as this functions' */ + pspmcb->m_psp = FP_SEG(p); + + /* copy the file name less extension into MCB */ + { + const char FAR *np; + int i; + for (np = path;;) /* find program name after path */ + { + char ch = *path; + if (ch == '\0') + break; + path++; + if (ch == ':' || ch == '\\' || ch == '/') + np = path; /* remember position after path */ + } + i = 0; + do /* extract program name */ + { + UBYTE ch = *np; + if (ch == '.' || ch == '\0') + { + pspmcb->m_name[i] = '\0'; + break; + } + if (ch >= 'a' && ch <= 'z') + ch -= (UBYTE)('a' - 'A'); + pspmcb->m_name[i] = ch; /* copy name, without extension */ + i++, np++; + } while (i < 8); } - /* identify the mcb as this functions' */ - pspmcb->m_psp = pspseg; - /* Patch in environment segment, if present, also adjust its MCB */ + setvec(0x22, (intvec)MK_FP(user_r->CS, user_r->IP)); + child_psp(FP_SEG(p), cu_psp, FP_SEG(p) + asize); + + /* Patch in env segment, if present, also adjust its MCB */ if (envseg) { - ((mcb FAR *) MK_FP(envseg, 0))->m_psp = pspseg; + MK_SEG_PTR(mcb, envseg)->m_psp = FP_SEG(p); envseg++; } - psp->ps_environ = envseg; - - /* use the file name less extension - left adjusted and */ - np = fnam; - for (;;) - { - switch (*fnam++) - { - case '\0': - goto set_name; - case ':': - case '/': - case '\\': - np = fnam; - } - } -set_name: - for (i = 0; i < 8 && np[i] != '.' && np[i] != '\0'; i++) - { - pspmcb->m_name[i] = toupper(np[i]); - } - if (i < 8) - pspmcb->m_name[i] = '\0'; - - /* return value: AX value to be passed based on FCB values */ - return chkdrv(psp->ps_fcb1.fcb_drive) | - (chkdrv(psp->ps_fcb2.fcb_drive) << 8); + p->ps_environ = envseg; } -int load_transfer(UWORD ds, exec_blk *exp, UWORD fcbcode, COUNT mode) +static void load_transfer(seg_t ds, exec_blk *ep, int mode) { - psp FAR *p = MK_FP(ds, 0); - psp FAR *q = MK_FP(cu_psp, 0); - - /* Transfer control to the executable */ - p->ps_parent = cu_psp; - p->ps_prevpsp = q; - q->ps_stack = (BYTE FAR *)user_r; + UWORD fcbcode; + psp _seg *p = MK_SEG_PTR(psp, ds); + { + psp _seg *q = MK_SEG_PTR(psp, cu_psp); + p->ps_parent = FP_SEG(q); + p->ps_prevpsp = q; + q->ps_stack = (BYTE FAR *)user_r; + } user_r->FLAGS &= ~FLG_CARRY; - - cu_psp = ds; + + cu_psp = FP_SEG(p); /* process dta */ dta = &p->ps_cmd; - + + /* complete the psp by adding the command line and FCBs */ + /* UNDOCUMENTED: MS-DOS copies sizeof(CommandTail) bytes without + checking memory contents and fixing wrong (>7Fh) length field; + FCBs also copied without checking address validness --avb + */ + fmemcpy(&p->ps_fcb1, ep->exec.fcb_1, 12); /* drive+name+ext */ + fmemcpy(&p->ps_fcb2, ep->exec.fcb_2, 12); + fmemcpy(&p->ps_cmd, ep->exec.cmd_line, sizeof(CommandTail)); + + /* AX value to be passed based on FCB values */ + fcbcode = (get_cds1(p->ps_fcb1.fcb_drive) ? 0 : 0xff) | + (get_cds1(p->ps_fcb2.fcb_drive) ? 0 : 0xff00); + + /* Transfer control to the executable */ if (mode == LOADNGO) { - iregs FAR *irp; - /* build the user area on the stack */ - irp = (iregs FAR *)(exp->exec.stack - sizeof(iregs)); - + iregs FAR *irp = (iregs FAR *)(ep->exec.stack - sizeof(iregs)); + /* start allocating REGs (as in MS-DOS - some demos expect them so --LG) */ /* see http://www.beroset.com/asm/showregs.asm */ - irp->DX = irp->ES = irp->DS = ds; - irp->CS = FP_SEG(exp->exec.start_addr); - irp->SI = irp->IP = FP_OFF(exp->exec.start_addr); - irp->DI = FP_OFF(exp->exec.stack); + irp->AX = + irp->BX = fcbcode; + irp->DX = + irp->ES = + irp->DS = FP_SEG(p); + irp->CS = FP_SEG(ep->exec.start_addr); + irp->SI = + irp->IP = FP_OFF(ep->exec.start_addr); + irp->DI = FP_OFF(ep->exec.stack); irp->BP = 0x91e; /* this is more or less random but some programs expect 0x9 in the high byte of BP!! */ - irp->AX = irp->BX = fcbcode; irp->CX = 0xFF; irp->FLAGS = 0x200; - + if (InDOS) --InDOS; exec_user(irp, 1); - - /* We should never be here - fatal("KERNEL RETURNED!!!"); */ + + /* We should never be here + panic("KERNEL RETURNED!!!"); */ } + /* mode == LOAD */ - exp->exec.stack -= 2; - *((UWORD FAR *)(exp->exec.stack)) = fcbcode; - return SUCCESS; + ep->exec.stack -= sizeof(UWORD); + *(UWORD FAR *)ep->exec.stack = fcbcode; } /* Now find out how many paragraphs are available @@ -413,10 +394,8 @@ STATIC int ExecMemAlloc(UWORD size, seg *para, UWORD *asize) COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd) { UWORD mem; - UWORD env, asize = 0; - - { - UWORD com_size; + UWORD env, asize; + UWORD com_size; { ULONG com_size_long = SftGetFsize(fd); /* maximally 64k - 256 bytes stack - @@ -436,20 +415,15 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd) DosUmbLink(1); /* link in UMB's */ } - rc = ChildEnv(exp, &env, namep); - /* COMFILES will always be loaded in largest area. is that true TE */ /* yes, see RBIL, int21/ah=48 -- Bart */ - - if (rc == SUCCESS) - rc = ExecMemLargest(&asize, com_size); - - if (rc == SUCCESS) - /* Allocate our memory and pass back any errors */ - rc = ExecMemAlloc(asize, &mem, &asize); - - if (rc != SUCCESS) - DosMemFree(env); + if ((rc = ChildEnv(exp->exec.env_seg, &env, namep)) == SUCCESS) + { + if ((rc = ExecMemLargest(&asize, com_size)) != SUCCESS || + /* Allocate our memory and pass back any errors */ + (rc = ExecMemAlloc(asize, &mem, &asize)) != SUCCESS) + DosMemFree(env); + } if (mode & 0x80) { @@ -461,46 +435,27 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd) if (rc != SUCCESS) return rc; - ++mem; - } - else - mem = exp->load.load_seg; - } - #ifdef DEBUG printf("DosComLoader. Loading '%S' at %04x\n", namep, mem); #endif + ++mem; + } + /* Now load the executable */ - { - BYTE FAR *sp; - - if (mode == OVERLAY) /* memory already allocated */ - sp = MK_FP(mem, 0); - else /* test the filesize against the allocated memory */ - sp = MK_FP(mem, sizeof(psp)); - - /* MS DOS always only loads the very first 64KB - sizeof(psp) bytes. - -- 1999/04/21 ska */ - /* rewind to start */ SftSeek(fd, 0, 0); + /* MS DOS always only loads the very first 64KB - sizeof(psp) bytes. + -- 1999/04/21 ska */ /* read everything, but at most 64K - sizeof(PSP) */ - DosRWSft(fd, 0xff00, sp, XFR_READ); + /* !!! should be added check for reading success --avb */ + DosRWSft(fd, 0xff00, mode == OVERLAY /* memory already allocated */ + ? MK_FP(exp->load.load_seg, 0) + : MK_FP(mem, sizeof(psp)), XFR_READ); DosCloseSft(fd, FALSE); - } - if (mode == OVERLAY) - return SUCCESS; - + if (mode != OVERLAY) { - UWORD fcbcode; - psp FAR *p; - - /* point to the PSP so we can build it */ - setvec(0x22, (intvec)MK_FP(user_r->CS, user_r->IP)); - child_psp(mem, cu_psp, mem + asize); - - fcbcode = patchPSP(mem - 1, env, exp, namep); + makePSP(mem, env, asize, namep); /* set asize to end of segment */ if (asize > 0x1000) asize = 0x1000; @@ -510,27 +465,21 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd) /* CP/M compatibility--size of first segment for .COM files while preserving the far call to 0:00c0 + copy in HMA at ffff:00d0 */ - p = MK_FP(mem, 0); - p->ps_reentry = MK_FP(0xc - asize, asize << 4); + MK_SEG_PTR(psp, mem)->ps_reentry = MK_FP(0xc - asize, asize << 4); asize <<= 4; asize += 0x10e; exp->exec.stack = MK_FP(mem, asize); exp->exec.start_addr = MK_FP(mem, 0x100); - *((UWORD FAR *) MK_FP(mem, asize)) = (UWORD) 0; - load_transfer(mem, exp, fcbcode, mode); + *MK_PTR(UWORD, mem, asize) = 0; + load_transfer(mem, exp, mode); } return SUCCESS; } -VOID return_user(void) +void return_user(void) { - psp FAR *p, FAR * q; - REG COUNT i; - iregs FAR *irp; -/* long j;*/ - /* restore parent */ - p = MK_FP(cu_psp, 0); + psp _seg *p = MK_SEG_PTR(psp, cu_psp); /* When process returns - restore the isv */ setvec(0x22, p->ps_isv22); @@ -544,34 +493,31 @@ VOID return_user(void) if (!tsr) { + REG COUNT i; network_redirector(REM_CLOSEALL); for (i = 0; i < p->ps_maxfiles; i++) { DosClose(i); } FcbCloseAll(); - FreeProcessMem(cu_psp); + FreeProcessMem(FP_SEG(p)); } - cu_psp = p->ps_parent; - q = MK_FP(cu_psp, 0); + { + iregs FAR *irp = (iregs FAR *)MK_SEG_PTR(psp, cu_psp = p->ps_parent)->ps_stack; + irp->CS = FP_SEG(p->ps_isv22); + irp->IP = FP_OFF(p->ps_isv22); - irp = (iregs FAR *) q->ps_stack; - - irp->CS = FP_SEG(p->ps_isv22); - irp->IP = FP_OFF(p->ps_isv22); - - if (InDOS) - --InDOS; - exec_user((iregs FAR *) q->ps_stack, 0); + if (InDOS) + --InDOS; + exec_user(irp, 0); + } } COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd) { - UWORD mem, env, start_seg, asize = 0; - UWORD exe_size; - { - UWORD image_size; + UWORD mem, env, start_seg, asize; + UWORD image_size; /* compute image size by removing the offset from the */ /* number pages scaled to bytes plus the remainder and */ @@ -581,10 +527,11 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd) return DE_INVLDDATA; /* we're not able to get >=1MB in dos memory */ image_size = ExeHeader.exPages * 32 - ExeHeader.exHeaderSize; - /* We should not attempt to allocate - memory if we are overlaying the current process, because the new - process will simply re-use the block we already have allocated. - Jun 11, 2000 - rbc */ + /* We should not attempt to allocate memory if we are overlaying + the current process, because the new process will simply re-use + the block we already have allocated. This was causing execl() to + fail in applications which use it to overlay (replace) the current + exe file with a new one. Jun 11, 2000 --rbc */ if ((mode & 0x7f) != OVERLAY) { @@ -592,10 +539,6 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd) UBYTE orig_mem_access = mem_access_mode; COUNT rc; - /* and finally add in the psp size */ - image_size += sizeof(psp) / 16; /*TE 03/20/01 */ - exe_size = image_size + ExeHeader.exMinAlloc; - /* Clone the environement and create a memory arena */ if (mode & 0x80) { @@ -603,38 +546,35 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd) mem_access_mode |= 0x80; } - rc = ChildEnv(exp, &env, namep); - - if (rc == SUCCESS) + if ((rc = ChildEnv(exp->exec.env_seg, &env, namep)) == SUCCESS) + { + image_size += sizeof(psp) / 16; /*TE 03/20/01 */ /* Now find out how many paragraphs are available */ - rc = ExecMemLargest(&asize, exe_size); - - exe_size = image_size + ExeHeader.exMaxAlloc; - /* second test is for overflow (avoiding longs) -- - exMaxAlloc can be high */ - if (exe_size > asize || exe_size < image_size) - exe_size = asize; - - /* TE if ExeHeader.exMinAlloc == ExeHeader.exMaxAlloc == 0, - DOS will allocate the largest possible memory area - and load the image as high as possible into it. - discovered (and after that found in RBIL), when testing NET */ - - if ((ExeHeader.exMinAlloc | ExeHeader.exMaxAlloc) == 0) - exe_size = asize; - - /* Allocate our memory and pass back any errors */ - if (rc == SUCCESS) - rc = ExecMemAlloc(exe_size, &mem, &asize); - - if (rc != SUCCESS) - DosMemFree(env); + if ((rc = ExecMemLargest(&asize, image_size + ExeHeader.exMinAlloc)) == SUCCESS) + { + unsigned max_size = image_size + ExeHeader.exMaxAlloc; + /* second test is for overflow (avoiding longs) -- + exMaxAlloc can be high */ + if (max_size > asize || max_size < image_size || + /* TE if ExeHeader.exMinAlloc == ExeHeader.exMaxAlloc == 0, + DOS will allocate the largest possible memory area + and load the image as high as possible into it. + discovered (and after that found in RBIL), when testing NET */ + (ExeHeader.exMinAlloc | ExeHeader.exMaxAlloc) == 0) + max_size = asize; + /* Allocate our memory and pass back any errors */ + rc = ExecMemAlloc(max_size, &mem, &asize); + } + if (rc != SUCCESS) + DosMemFree(env); + } if (mode & 0x80) { mem_access_mode = orig_mem_access; /* restore old situation */ DosUmbLink(UMBstate); /* restore link state */ } + if (rc != SUCCESS) return rc; @@ -643,20 +583,7 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd) #ifdef DEBUG printf("DosExeLoader. Loading '%S' at %04x\n", namep, mem); #endif - /* memory found large enough - continue processing */ - ++mem; - -/* /// Added open curly brace and "else" clause. We should not attempt - to allocate memory if we are overlaying the current process, because - the new process will simply re-use the block we already have allocated. - This was causing execl() to fail in applications which use it to - overlay (replace) the current exe file with a new one. - Jun 11, 2000 - rbc */ - } - else /* !!OVERLAY */ - { - mem = exp->load.load_seg; } /* Now load the executable */ @@ -665,75 +592,57 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd) { if (mode != OVERLAY) { - DosMemFree(--mem); + DosMemFree(mem); DosMemFree(env); } return DE_INVLDDATA; } /* create the start seg for later computations */ - start_seg = mem; - exe_size = image_size; + start_seg = exp->load.load_seg; if (mode != OVERLAY) { - exe_size -= sizeof(psp) / 16; - start_seg += sizeof(psp) / 16; - if (exe_size > 0 && (ExeHeader.exMinAlloc | ExeHeader.exMaxAlloc) == 0) - { - mcb FAR *mp = MK_FP(mem - 1, 0); - + start_seg = mem + 1 + sizeof(psp) / 16; + if ((ExeHeader.exMinAlloc | ExeHeader.exMaxAlloc) == 0) /* then the image should be placed as high as possible */ - start_seg += mp->m_size - image_size; - } + start_seg += MK_SEG_PTR(const mcb, mem)->m_size - image_size; + image_size -= sizeof(psp) / 16; } - } /* read in the image in 32256 chunks */ { - int nBytesRead, toRead = CHUNK; - seg sp = start_seg; - - while (1) + seg_t sp = start_seg; + do { - if (exe_size < CHUNK/16) - toRead = exe_size*16; - nBytesRead = (int)DosRWSft(fd, toRead, MK_FP(sp, 0), XFR_READ); - if (nBytesRead < toRead || exe_size <= CHUNK/16) + int toRead = CHUNK; + if (image_size < CHUNK/16) + { + toRead = image_size*16; + image_size = CHUNK/16; + } + if ((int)DosRWSft(fd, toRead, MK_FP(sp, 0), XFR_READ) < toRead) break; sp += CHUNK/16; - exe_size -= CHUNK/16; - } + } while (image_size -= CHUNK/16); } - { /* relocate the image for new segment */ - COUNT i; - UWORD reloc[2]; - seg FAR *spot; - - SftSeek(fd, ExeHeader.exRelocTable, 0); - for (i = 0; i < ExeHeader.exRelocItems; i++) + /* relocate the image for new segment */ + SftSeek(fd, ExeHeader.exRelocTable, 0); + { + unsigned i; + for (i = ExeHeader.exRelocItems; i; i--) { - if (DosRWSft - (fd, sizeof(reloc), (VOID FAR *) & reloc[0], XFR_READ) != sizeof(reloc)) + UWORD reloc[2]; + if (DosRWSft(fd, sizeof reloc, reloc, XFR_READ) != sizeof reloc) { if (mode != OVERLAY) { - DosMemFree(--mem); + DosMemFree(mem); DosMemFree(env); } return DE_INVLDDATA; } - if (mode == OVERLAY) - { - spot = MK_FP(reloc[1] + mem, reloc[0]); - *spot += exp->load.reloc; - } - else - { - /* spot = MK_FP(reloc[1] + mem + 0x10, reloc[0]); */ - spot = MK_FP(reloc[1] + start_seg, reloc[0]); - *spot += start_seg; - } + *MK_PTR(seg_t, reloc[1] + start_seg, reloc[0]) += start_seg; } } @@ -741,24 +650,17 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd) DosCloseSft(fd, FALSE); /* exit here for overlay */ - if (mode == OVERLAY) - return SUCCESS; - + if (mode != OVERLAY) { - UWORD fcbcode; - - /* point to the PSP so we can build it */ - setvec(0x22, (intvec)MK_FP(user_r->CS, user_r->IP)); - child_psp(mem, cu_psp, mem + asize); - - fcbcode = patchPSP(mem - 1, env, exp, namep); + mem++; + makePSP(mem, env, asize, namep); exp->exec.stack = MK_FP(ExeHeader.exInitSS + start_seg, ExeHeader.exInitSP); exp->exec.start_addr = MK_FP(ExeHeader.exInitCS + start_seg, ExeHeader.exInitIP); /* Transfer control to the executable */ - load_transfer(mem, exp, fcbcode, mode); + load_transfer(mem, exp, mode); } return SUCCESS; } @@ -786,7 +688,7 @@ COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp) return DE_FILENOTFND; } - rc = (int)DosRWSft(fd, sizeof(exe_header), (BYTE FAR *)&ExeHeader, XFR_READ); + rc = (int)DosRWSft(fd, sizeof(exe_header), &ExeHeader, XFR_READ); if (rc == sizeof(exe_header) && (ExeHeader.exSignature == MAGIC || ExeHeader.exSignature == OLD_MAGIC)) @@ -809,44 +711,65 @@ COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp) #include "config.h" /* config structure definition */ /* start process 0 (the shell) */ -VOID ASMCFUNC P_0(struct config FAR *Config) -{ - BYTE *tailp, *endp; - exec_blk exb; - UBYTE mode = Config->cfgP_0_startmode; - - /* build exec block and save all parameters here as init part will vanish! */ - exb.exec.fcb_1 = exb.exec.fcb_2 = (fcb FAR *)-1L; - exb.exec.env_seg = DOS_PSP + 8; - fstrcpy(Shell, MK_FP(FP_SEG(Config), Config->cfgInit)); - /* join name and tail */ - fstrcpy(Shell + strlen(Shell), MK_FP(FP_SEG(Config), Config->cfgInitTail)); - endp = Shell + strlen(Shell); - - for ( ; ; ) /* endless shell load loop - reboot or shut down to exit it! */ - { - BYTE *p; - /* if there are no parameters, point to end without "\r\n" */ - if((tailp = strchr(Shell,'\t')) == NULL && - (tailp = strchr(Shell, ' ')) == NULL) - tailp = endp - 2; - /* shift tail to right by 2 to make room for '\0', ctCount */ - for (p = endp - 1; p >= tailp; p--) - *(p + 2) = *p; - /* terminate name and tail */ - *tailp = *(endp + 2) = '\0'; - /* ctCount: just past '\0' do not count the "\r\n" */ - exb.exec.cmd_line = (CommandTail *)(tailp + 1); - exb.exec.cmd_line->ctCount = endp - tailp - 2; -#ifdef DEBUG - printf("Process 0 starting: %s%s\n\n", Shell, tailp + 2); +void ASMCFUNC P_0(const struct config FAR *); +#ifdef __WATCOMC__ +# pragma aux (cdecl) P_0 aborts #endif - res_DosExec(mode, &exb, Shell); - put_string("Bad or missing Command Interpreter: "); /* failure _or_ exit */ + +void ASMCFUNC P_0(const struct config FAR *Config) +{ + int mode = Config->cfgP_0_startmode; + + const char FAR *p = MK_PTR(const char, FP_SEG(Config), Config->cfgShell); + PStr endp = Shell; + while ((*endp = *p++) != '\0' && + ++endp < Shell + sizeofShell - 4); /* 4 for 0,ctCount and "\r\0" */ + + for (;;) /* endless shell load loop - reboot or shut down to exit it! */ + { + PStr tailp = Shell - 1; + + *endp = '\r', endp[1] = '\0'; /* terminate command line */ + endp += 2; + + /* find end of command name */ + do tailp++; while ((UBYTE)*tailp > ' ' && *tailp != '/'); + + /* shift tail to right by 2 to make room for '\0' and ctCount */ + { + PStr p = endp; + do + { + p--; + p[2] = p[0]; + } while (p > tailp); + } + + /* terminate name */ + *tailp = '\0'; + + /* init length of command line tail (ctCount field) */ + tailp++; + *tailp = (UBYTE)(endp - tailp - 1); /* without "\r\0" */ + + { + exec_blk exb; + exb.exec.env_seg = DOS_PSP + 8; + exb.exec.cmd_line = (CommandTail *)tailp; + /*exb.exec.fcb_1 = exb.exec.fcb_2 = NULL;*/ /* unimportant */ + +#ifdef DEBUG + printf("Process 0 starting: %s%s\n\n", Shell, tailp + 1); +#endif + res_DosExec(mode, &exb, Shell); + } + + /* failure or exit */ + put_string("\nBad or missing Command Interpreter\n" + "Enter the full shell command line:\n"); put_string(Shell); - put_string(tailp + 2); - put_string(" Enter the full shell command line: "); - endp = Shell + res_read(STDIN, Shell, NAMEMAX); - *endp = '\0'; /* terminate string for strchr */ + *endp = '\n'; /* replace "\r\0" by "\n\0" */ + put_string(++tailp); + endp = Shell + res_read(STDIN, Shell, sizeofShell) - 2; /* exclude "\r\n" */ } } diff --git a/kernel/tci.cfg b/kernel/tci.cfg new file mode 100644 index 0000000..946e794 --- /dev/null +++ b/kernel/tci.cfg @@ -0,0 +1,7 @@ +-zCINIT_TEXT +-zRID +-zTID +-zSI_GROUP +-zDIB +-zBIB +-zGI_GROUP diff --git a/kernel/turboc.cfg b/kernel/turboc.cfg index f07a6c1..413e8f7 100644 --- a/kernel/turboc.cfg +++ b/kernel/turboc.cfg @@ -1,15 +1,11 @@ --f- --ff- --O --Z -d +-f- -k- --vi- --wpro --weas --wpre --w --g1 --I..\hdr +-O -Z -p --v- -I. -D__STDC__=0 -DKERNEL -DI86 -DPROTO -DASMSUPT +-v- +-w -g1 +-I..\hdr +-DI86 + +-zCHMA_TEXT diff --git a/kernel/vc.cfg b/kernel/vc.cfg new file mode 100644 index 0000000..af2a42c --- /dev/null +++ b/kernel/vc.cfg @@ -0,0 +1,5 @@ +-batch -nologo -WX +-Zlp1 +-f- -Osb1V4e -Gsry +-Fc +-I..\hdr diff --git a/kernel/wc.cfg b/kernel/wc.cfg new file mode 100644 index 0000000..53e3092 --- /dev/null +++ b/kernel/wc.cfg @@ -0,0 +1,9 @@ +-e5 -we -wx +-j +-os -s +-r -zgf -zff +-zq -zl -zp1 +-d1 +-I..\hdr + +-ntHMA_TEXT diff --git a/kernel/wci.cfg b/kernel/wci.cfg new file mode 100644 index 0000000..0559116 --- /dev/null +++ b/kernel/wci.cfg @@ -0,0 +1,11 @@ +-e5 -we -wx +-j +-os -s +-r -zgf -zff +-zq -zl -zp1 +-d1 +-I..\hdr + +-ntINIT_TEXT +-gTGROUP +-ndI diff --git a/lib/makefile b/lib/makefile index 91e2792..e93f02e 100644 --- a/lib/makefile +++ b/lib/makefile @@ -4,21 +4,23 @@ # $Id$ # - !include "../mkfiles/generic.mak" +######################################################################## -libm.lib: $(CLIB) - -$(RM) libm.lib - $(LIBUTIL) $(CLIB) $(MATH_EXTRACT) $(LIBTERM) - $(COMSPEC) /c for %i in (*.obj) do ..\utils\patchobj CODE=LCODE %i - $(LIBUTIL) libm $(MATH_INSERT) $(LIBTERM) - -$(RM) *.OBJ +all: libm.lib +libm.lib: $(CLIB) $(DEPENDS) + -$(RM) $*.lib + $(LIBUTIL) $(CLIB) $(MATH_EXTRACT) $(LIBTERM) + $(COMSPEC) /c for %i in (*.obj) do ..\utils\patchobj CODE=LCODE %i + $(LIBUTIL) $* $(MATH_INSERT) $(LIBTERM) + -$(RM) *.obj -clobber: clean - -$(RM) status.me +######################################################################## clean: - -$(RM) *.obj *.bak libm.lib + -$(RM) *.bak *.cod *.crf *.err *.las *.lst *.map *.obj *.xrf +clobber: clean + -$(RM) libm.lib status.me diff --git a/mkfiles/bc.mak b/mkfiles/bc.mak new file mode 100644 index 0000000..9cb252a --- /dev/null +++ b/mkfiles/bc.mak @@ -0,0 +1,10 @@ +# +# BC.MAK - kernel copiler options for Borland C++ +# + +!include "..\mkfiles\tcpp.mak" + +TARGET=KBC + +CC=$(BINPATH)\bcc -c +CL=$(BINPATH)\bcc diff --git a/mkfiles/bc5.mak b/mkfiles/bc5.mak index 64408fd..0a98b9d 100644 --- a/mkfiles/bc5.mak +++ b/mkfiles/bc5.mak @@ -2,52 +2,9 @@ # BC5.MAK - kernel copiler options for Borland C++ # -# Use these for Borland C++ - -COMPILERPATH=$(BC5_BASE) -COMPILERBIN=$(COMPILERPATH)\bin -CC=$(COMPILERBIN)\bcc -c -CL=$(COMPILERBIN)\bcc -INCLUDEPATH=$(COMPILERPATH)\include -LIBUTIL=$(COMPILERBIN)\tlib -LIBPATH=$(COMPILERPATH)\lib -LIBTERM= -LIBPLUS=+ - -TINY=-lt -CFLAGST=-L$(LIBPATH) -mt -a- -k- -f- -ff- -O -Z -d -CFLAGSC=-L$(LIBPATH) -a- -mc +!include "..\mkfiles\turbocpp.mak" TARGET=KBC -# used for building the library - -CLIB=$(COMPILERPATH)\lib\cs.lib -MATH_EXTRACT=*H_LDIV *H_LLSH *H_LURSH *F_LXMUL -MATH_INSERT=+H_LDIV +H_LLSH +H_LURSH +F_LXMUL - -# -# heavy stuff - building the kernel -# 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" - -# -# ALLCFLAGS specified by turbo.cfg and config.mak -# -ALLCFLAGS=$(TARGETOPT) -zCHMA_TEXT $(ALLCFLAGS) -INITCFLAGS=$(ALLCFLAGS) -zCINIT_TEXT -zDIB -zRID -zTID -zBIB -zGI_GROUP -zSI_GROUP -CFLAGS=$(ALLCFLAGS) +CC=$(BINPATH)\bcc -c +CL=$(BINPATH)\bcc diff --git a/mkfiles/generic.mak b/mkfiles/generic.mak index 5e97ea2..e70533a 100644 --- a/mkfiles/generic.mak +++ b/mkfiles/generic.mak @@ -1,43 +1,67 @@ # These are generic definitions -#********************************************************************** -#* TARGET : we create a %TARGET%.sys file -#* TARGETOPT : options, handled down to the compiler -#********************************************************************** - -TARGETOPT=-1- +# TARGET : we create a $(TARGET).sys file +!if $(XCPU)0 == 0 +XCPU=86 +!endif +CPUOPT= !if $(XCPU) == 186 -TARGETOPT=-1 +CPUOPT=-1 !endif !if $(XCPU) == 386 -TARGETOPT=-3 +CPUOPT=-3 !endif +!if $(XFAT)0 == 0 +XFAT=32 +!endif !if $(XFAT) == 32 -ALLCFLAGS=$(ALLCFLAGS) -DWITHFAT32 -NASMFLAGS=$(NASMFLAGS) -DWITHFAT32 +ALLCFLAGS=-DWITHFAT32 $(ALLCFLAGS) +NASMFLAGS=-DWITHFAT32 $(NASMFLAGS) !endif -NASM=$(XNASM) -NASMFLAGS = $(NASMFLAGS) -i../hdr/ -DXCPU=$(XCPU) - -LINK=$(XLINK) +NASMFLAGS=-fobj -i../hdr/ -D$(COMPILER) -DXCPU=$(XCPU) $(NASMFLAGS) +BINPATH=$(BASE)\bin +INCLUDEPATH=$(BASE)\include +LIBPATH=$(BASE)\lib INITPATCH=@rem +UPXOPT=-U +!if $(__MAKE__)0 == 0 # NMAKE/WMAKE +!if "$(XUPX)" == "" # TC doesn't supports this +XUPX=rem # NMAKE doesn't supports @ in macro +UPXOPT= +!endif +!else # TC/BC MAKE +!if !$d(XUPX) # NMAKE/WMAKE doesn't supports $d() +XUPX=@rem +UPXOPT= +!endif +!endif + !include "..\mkfiles\$(COMPILER).mak" TARGET=$(TARGET)$(XCPU)$(XFAT) +INITCFLAGS=$(INITCFLAGS) $(ALLCFLAGS) +CFLAGS=$(CFLAGS) $(ALLCFLAGS) RM=..\utils\rmfiles +DEPENDS=makefile ..\*.bat ..\mkfiles\*.* -.asm.obj : - $(NASM) -D$(COMPILER) $(NASMFLAGS) -f obj $*.asm +# Implicit Rules ####################################################### -# *Implicit Rules* -.c.obj : - $(CC) $(CFLAGS) $*.c +.asm.obj: + $(NASM) $(NASMFLAGS) $< -.cpp.obj : - $(CC) $(CFLAGS) $*.cpp +.c.obj: + $(CC) $(CFLAGS) $< +.cpp.obj: + $(CC) $(CFLAGS) $< + +.c.com: + $(CL) $(CFLAGST) $< + +.c.exe: + $(CL) $(CFLAGSC) $< diff --git a/mkfiles/msc.mak b/mkfiles/msc.mak new file mode 100644 index 0000000..3c8945c --- /dev/null +++ b/mkfiles/msc.mak @@ -0,0 +1,31 @@ +# +# MSC.MAK - kernel copiler options for MS VC 1.5x (MS CL 8.x) +# + +TARGET=KMS + +CC=$(BINPATH)\cl -batch -nologo -c +CL=$(BINPATH)\cl -batch -nologo + +# used for building the library + +CLIB=$(LIBPATH)\slibce.lib +MATH_EXTRACT=*aflmul *aFlshl *aFNauldi *aFulrem *aFulshr *aFuldiv *aFlrem *aFldiv *aFNaulsh +MATH_INSERT =+aflmul +aFlshl +aFNauldi +aFulrem +aFulshr +aFuldiv +aFlrem +aFldiv +aFNaulsh + +# + +!if $(XCPU) == 186 +CPUOPT=-G1 +!endif +!if $(XCPU) == 386 +CPUOPT=-G3 +!endif + +ALLCFLAGS=@msc.cfg -I$(INCLUDEPATH) $(CPUOPT) $(ALLCFLAGS) +INITCFLAGS=-NTINIT_TEXT +CFLAGS =-NTHMA_TEXT +INITPATCH=..\utils\patchobj _DATA=IDATA DATA=ID BSS=ID DGROUP=I_GROUP CONST=IC + +CFLAGST=-I..\hdr -I$(INCLUDEPATH) /Fm /AT /Os /Zp1 +CFLAGSC=-I..\hdr -I$(INCLUDEPATH) /Fm /AL /Os /Zp1 diff --git a/mkfiles/mscl8.mak b/mkfiles/mscl8.mak index cd5c53b..a398c4d 100644 --- a/mkfiles/mscl8.mak +++ b/mkfiles/mscl8.mak @@ -1,47 +1,31 @@ # -# MSCL8.MAK - kernel copiler options for MS CL8 = MSVC1.52 +# MSCL8.MAK - kernel copiler options for MS CL8 = MS VC 1.52 # -# Use these for MSCV 1.52 -COMPILERPATH=$(MS_BASE) -COMPILERBIN=$(COMPILERPATH)\bin -INCLUDEPATH=$(COMPILERPATH)\include -CC=$(COMPILERBIN)\cl -c -CL=$(COMPILERBIN)\cl -TINY= -CFLAGST=/Fm /AT /Os /Zp1 -CFLAGSC=/Fm /AL /Os /Zp1 -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 - -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 -!endif -!if $(XCPU) == 386 -TARGETOPT=-G3 -!endif - TARGET=KMS +CC=$(BINPATH)\cl -batch -nologo -c +CL=$(BINPATH)\cl -batch -nologo + +# used for building the library + +CLIB=$(LIBPATH)\slibce.lib +MATH_EXTRACT=*aflmul *aFlshl *aFNauldi *aFulrem *aFulshr *aFuldiv *aFlrem *aFldiv *aFNaulsh +MATH_INSERT =+aflmul +aFlshl +aFNauldi +aFulrem +aFulshr +aFuldiv +aFlrem +aFldiv +aFNaulsh + # -# heavy stuff - building +!if $(XCPU) == 186 +CPUOPT=-G1 +!endif +!if $(XCPU) == 386 +CPUOPT=-G3 +!endif -ALLCFLAGS=-I..\hdr $(TARGETOPT) $(ALLCFLAGS) -nologo -Zl -Fc -WX -Gr -f- -Os -Gs -Ob1 -OV4 -Gy -Oe -Zp1 +ALLCFLAGS=@vc.cfg -I$(INCLUDEPATH) $(CPUOPT) $(ALLCFLAGS) +INITCFLAGS=-NTINIT_TEXT +CFLAGS =-NTHMA_TEXT +INITPATCH=..\utils\patchobj _DATA=IDATA DATA=ID BSS=ID DGROUP=I_GROUP CONST=IC -INITCFLAGS=$(ALLCFLAGS) -NTINIT_TEXT -CFLAGS=$(ALLCFLAGS) -NTHMA_TEXT -INITPATCH = ..\utils\patchobj _DATA=IDATA DATA=ID BSS=ID DGROUP=I_GROUP CONST=IC +CFLAGST=-I..\hdr -I$(INCLUDEPATH) /Fm /AT /Os /Zp1 +CFLAGSC=-I..\hdr -I$(INCLUDEPATH) /Fm /AL /Os /Zp1 diff --git a/mkfiles/tc.mak b/mkfiles/tc.mak new file mode 100644 index 0000000..856b65f --- /dev/null +++ b/mkfiles/tc.mak @@ -0,0 +1,16 @@ +# +# TC.MAK - kernel copiler options for Turbo C 2.01 +# + +BINPATH=$(BASE) + +!include "..\mkfiles\tcpp.mak" + +TARGET=KTC + +MATH_EXTRACT=*LDIV *LXMUL *LURSH *LLSH *LRSH +MATH_INSERT =+LDIV +LXMUL +LURSH +LLSH +LRSH + +# TCC doesn't support responce file + +INITCFLAGS=-zCINIT_TEXT -zRID -zTID -zSI_GROUP -zDIB -zBIB -zGI_GROUP diff --git a/mkfiles/tc2.mak b/mkfiles/tc2.mak index c5e5213..1d5c32c 100644 --- a/mkfiles/tc2.mak +++ b/mkfiles/tc2.mak @@ -1,53 +1,16 @@ # -# TURBOC.MAK - kernel copiler options for TURBOC +# TC2.MAK - kernel copiler options for Turbo C 2.01 # -# Use these for Turbo C 2.01 +BINPATH=$(BASE) -COMPILERPATH=$(TC2_BASE) -COMPILERBIN=$(COMPILERPATH) -CC=$(COMPILERBIN)\tcc -c -CL=$(COMPILERBIN)\tcc -INCLUDEPATH=$(COMPILERPATH)\include -LIBUTIL=$(COMPILERBIN)\tlib -LIBPATH=$(COMPILERPATH)\lib -LIBTERM= -LIBPLUS=+ - -TINY=-lt -CFLAGST=-L$(LIBPATH) -mt -a- -k- -f- -ff- -O -Z -d -w -CFLAGSC=-L$(LIBPATH) -a- -mc +!include "..\mkfiles\turbocpp.mak" TARGET=KTC -# used for building the library - -CLIB=$(COMPILERPATH)\lib\cs.lib MATH_EXTRACT=*LDIV *LXMUL *LURSH *LLSH *LRSH -MATH_INSERT=+LDIV +LXMUL +LURSH +LLSH +LRSH +MATH_INSERT =+LDIV +LXMUL +LURSH +LLSH +LRSH -# -# heavy stuff - building the kernel -# 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" +# TCC 2.0 doesn't support responce file -# -# ALLCFLAGS specified by turbo.cfg and config.mak -# -ALLCFLAGS=$(TARGETOPT) -zCHMA_TEXT $(ALLCFLAGS) -INITCFLAGS=$(ALLCFLAGS) -zCINIT_TEXT -zDIB -zRID -zTID -zBIB -zGI_GROUP -zSI_GROUP -CFLAGS=$(ALLCFLAGS) +INITCFLAGS=-zCINIT_TEXT -zRID -zTID -zSI_GROUP -zDIB -zBIB -zGI_GROUP diff --git a/mkfiles/tc3.mak b/mkfiles/tc3.mak index 1ac6986..a387fe5 100644 --- a/mkfiles/tc3.mak +++ b/mkfiles/tc3.mak @@ -1,53 +1,7 @@ # -# TC3.MAK - kernel copiler options for Turbo C 3.0 +# TC3.MAK - kernel copiler options for Turbo C++ 3.0 # -# Use these for Turbo C 3.0 - -COMPILERPATH=$(TC3_BASE) -COMPILERBIN=$(COMPILERPATH)\bin -CC=$(COMPILERBIN)\tcc -c -CL=$(COMPILERBIN)\tcc -INCLUDEPATH=$(COMPILERPATH)\include -LIBUTIL=$(COMPILERBIN)\tlib -LIBPATH=$(COMPILERPATH)\lib -LIBTERM= -LIBPLUS=+ - -TINY=-lt -CFLAGST=-L$(LIBPATH) -mt -a- -k- -f- -ff- -O -Z -d -CFLAGSC=-L$(LIBPATH) -a- -mc +!include "..\mkfiles\turbocpp.mak" TARGET=KT3 - -# used for building the library - -CLIB=$(COMPILERPATH)\lib\cs.lib -MATH_EXTRACT=*H_LDIV *H_LLSH *H_LURSH *F_LXMUL -MATH_INSERT=+H_LDIV +H_LLSH +H_LURSH +F_LXMUL - -# -# heavy stuff - building the kernel -# 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" - -# -# ALLCFLAGS specified by turbo.cfg and config.mak -# -ALLCFLAGS=$(TARGETOPT) -zCHMA_TEXT $(ALLCFLAGS) -INITCFLAGS=$(ALLCFLAGS) -zCINIT_TEXT -zDIB -zRID -zTID -zBIB -zGI_GROUP -zSI_GROUP -CFLAGS=$(ALLCFLAGS) diff --git a/mkfiles/tcpp.mak b/mkfiles/tcpp.mak new file mode 100644 index 0000000..e3afc34 --- /dev/null +++ b/mkfiles/tcpp.mak @@ -0,0 +1,42 @@ +# +# TCPP.MAK - kernel copiler options for Turbo C++ 1.01 +# + +TARGET=KTP + +CC=$(BINPATH)\tcc -c +CL=$(BINPATH)\tcc + +# used for building the library + +CLIB=$(LIBPATH)\cs.lib +MATH_EXTRACT=*H_LDIV *H_LLSH *H_LURSH *F_LXMUL +MATH_INSERT =+H_LDIV +H_LLSH +H_LURSH +F_LXMUL + +# +# Compiler options for Turbo/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" + +# +# Common options specified in turboc.cfg instead ALLCFLAGS +# + +ALLCFLAGS=-I..\hdr;$(INCLUDEPATH) $(CPUOPT) $(ALLCFLAGS) +INITCFLAGS=@tci.cfg + +CFLAGST=-I..\hdr;$(INCLUDEPATH) -L$(LIBPATH) -mt -lt +CFLAGSC=-I..\hdr;$(INCLUDEPATH) -L$(LIBPATH) -mc diff --git a/mkfiles/tcpp3.mak b/mkfiles/tcpp3.mak new file mode 100644 index 0000000..c1a448b --- /dev/null +++ b/mkfiles/tcpp3.mak @@ -0,0 +1,7 @@ +# +# TCPP3.MAK - kernel copiler options for Turbo C++ 3.0 +# + +!include "..\mkfiles\tcpp.mak" + +TARGET=KT3 diff --git a/mkfiles/turbocpp.mak b/mkfiles/turbocpp.mak index db33118..0522de0 100644 --- a/mkfiles/turbocpp.mak +++ b/mkfiles/turbocpp.mak @@ -1,34 +1,20 @@ # -# TURBOCPP.MAK - kernel copiler options for TCPP 1.01 +# TURBOCPP.MAK - kernel copiler options for Turbo C++ 1.01 # -# Use these for Turbo CPP 1.01 - -COMPILERPATH=$(TP1_BASE) -COMPILERBIN=$(COMPILERPATH)\bin -CC=$(COMPILERBIN)\tcc -c -CL=$(COMPILERBIN)\tcc -INCLUDEPATH=$(COMPILERPATH)\include -LIBUTIL=$(COMPILERBIN)\tlib -LIBPATH=$(COMPILERPATH)\lib -LIBTERM= -LIBPLUS=+ - -TINY=-lt -CFLAGST=-L$(LIBPATH) -mt -a- -k- -f- -ff- -O -Z -d -CFLAGSC=-L$(LIBPATH) -a- -mc - TARGET=KTP +CC=$(BINPATH)\tcc -c +CL=$(BINPATH)\tcc + # used for building the library -CLIB=$(COMPILERPATH)\lib\cs.lib +CLIB=$(LIBPATH)\cs.lib MATH_EXTRACT=*H_LDIV *H_LLSH *H_LURSH *F_LXMUL -MATH_INSERT=+H_LDIV +H_LLSH +H_LURSH +F_LXMUL +MATH_INSERT =+H_LDIV +H_LLSH +H_LURSH +F_LXMUL # -# heavy stuff - building the kernel -# Compiler and Options for Borland C++ +# Compiler options for Turbo/Borland C # ------------------------------------ # # -zAname ¦ ¦ Code class @@ -46,8 +32,12 @@ MATH_INSERT=+H_LDIV +H_LLSH +H_LURSH +F_LXMUL # -zX ¦«¦ Use default name for "X" # -# ALLCFLAGS specified by turbo.cfg and config.mak +# Common options specified in turboc.cfg instead ALLCFLAGS # -ALLCFLAGS=$(TARGETOPT) -zCHMA_TEXT $(ALLCFLAGS) -INITCFLAGS=$(ALLCFLAGS) -zCINIT_TEXT -zDIB -zRID -zTID -zBIB -zGI_GROUP -zSI_GROUP -CFLAGS=$(ALLCFLAGS) + +ALLCFLAGS=-I..\hdr;$(INCLUDEPATH) $(CPUOPT) $(ALLCFLAGS) +INITCFLAGS=@..\mkfiles\tci.cfg +CFLAGS =-zCHMA_TEXT + +CFLAGST=-I..\hdr;$(INCLUDEPATH) -L$(LIBPATH) -mt -lt # -ff- +CFLAGSC=-I..\hdr;$(INCLUDEPATH) -L$(LIBPATH) -mc diff --git a/mkfiles/watcom.mak b/mkfiles/watcom.mak index 77a2615..95cda19 100644 --- a/mkfiles/watcom.mak +++ b/mkfiles/watcom.mak @@ -1,67 +1,50 @@ # -# WATCOM.MAK - kernel copiler options for WATCOM C 11.0c +# WATCOM.MAK - kernel copiler options for WATCOM C/OpenWatcom # -# Use these for WATCOM 11.0c -COMPILERPATH=$(WATCOM) -CC=*wcc -CL=wcl -INCLUDEPATH=$(COMPILERPATH)\H -INCLUDE=$(COMPILERPATH)\h -EDPATH=$(COMPILERPATH)\EDDAT - -!if $(XCPU) != 186 -!if $(XCPU) != 386 -TARGETOPT=-0 -!endif -!endif - -LIBPATH=$(COMPILERPATH)\lib286 -LIBUTIL=wlib -q -LIBPLUS= -LIBTERM= - -TINY=-mt -CFLAGST=-zq-zp1-os-s-we-e3-wx -CFLAGSC=-mc-zq-zp1-os-s-we-e3-wx - TARGET=KWC +BINPATH=$(BASE)\binw +INCLUDEPATH=$(BASE)\h +LIBPATH=$(BASE)\lib286 + +CC=$(BINPATH)\wcc +CL=$(BINPATH)\wcl + # used for building the library -CLIB=$(COMPILERPATH)\lib286\dos\clibm.lib - -# we use our own ones, which override these ones when linking. -# - +CLIB=$(LIBPATH)\dos\clibm.lib MATH_EXTRACT=*i4m -MATH_INSERT=+i4m - +MATH_INSERT =+i4m # -# heavy stuff - building +# Compiler options for Watcom +# --------------------------- # # -e= set limit on number of error messages +# -w= set warning level number +# -we treat all warnings as errors +# -zq operate quietly +# +# -j change char default from unsigned to signed # -ms small memory model (small code/small data) -# -j change char default from unsigned to signed -#-nc= set code class name -#-nd= set data segment name -#-nm= set module name -#-nt= set name of text segment -# -g= set code group name # -os -> favor code size over execution time in optimizations -# -s remove stack overflow checks -# -w= set warning level number -# -we treat all warnings as errors +# -s remove stack overflow checks # -ze enable extensions (i.e., near, far, export, etc.) # -zl remove default library information # -zp= pack structure members with alignment {1,2,4,8,16} -# -zq operate quietly # -# -3 optimization for 386 - given in CONFIG.MAK, not here +# -3 optimization for 386 - given in $(CPUOPT) +# -g= set code group name +# -nc= set code class name +# -nd= set data segment name +# -nm= set module name +# -nt= set name of text segment # -ALLCFLAGS=-I..\hdr $(TARGETOPT) $(ALLCFLAGS)-zq-os-s-e5-j-zl-zp1-wx-we-zgf-zff-r -INITCFLAGS=$(ALLCFLAGS)-ntINIT_TEXT-gTGROUP-ndI -CFLAGS=$(ALLCFLAGS)-ntHMA_TEXT +ALLCFLAGS=-I$(INCLUDEPATH) $(CPUOPT)$(ALLCFLAGS) +INITCFLAGS=@wci.cfg +CFLAGS =@wc.cfg +CFLAGST=-I..\hdr;$(INCLUDEPATH) -e3-we-wx-zq-os-s-zp1-mt +CFLAGSC=-I..\hdr;$(INCLUDEPATH) -e3-we-wx-zq-os-s-zp1-mc diff --git a/sys/fdkrncfg.c b/sys/fdkrncfg.c index 941e196..36648bd 100644 --- a/sys/fdkrncfg.c +++ b/sys/fdkrncfg.c @@ -50,7 +50,7 @@ unsigned long lseek(int fildes, unsigned long offset, int whence); #define FAR far #include "kconfig.h" -KernelConfig cfg = { 0 }; +KernelConfig cfg; /* static memory zeroed automatically */ typedef unsigned char byte; typedef signed char sbyte; diff --git a/sys/makefile b/sys/makefile index ed4aad9..d2324f0 100644 --- a/sys/makefile +++ b/sys/makefile @@ -6,55 +6,36 @@ !include "../mkfiles/generic.mak" -CFLAGS = -I$(INCLUDEPATH) -I..\hdr -DFORSYS -DWITHFAT32 $(CFLAGST) -NASMFLAGS = -DSYS=1 +SYS_C=sys.c fdkrncfg.c ..\kernel\prf.c talloc.c +DEPENDS=$(DEPENDS) *.cfg -# *List Macros* +######################################################################## -SYS_EXE_dependencies = \ - sys.obj \ - fdkrncfg.obj \ - prf.obj \ - talloc.obj +all: bin2c.com ..\bin\sys.com -# *Explicit Rules* -production: bin2c.com ..\bin\sys.com +bin2c.com: bin2c.c $(DEPENDS) -bin2c.com: bin2c.c - $(CL) $(CFLAGS) $(TINY) bin2c.c +fat12com.h: ..\boot\fat12.bin bin2c.com + bin2c ..\boot\fat12.bin $*.h $* -..\bin\sys.com: sys.com - copy sys.com ..\bin - -fat12com.h: ..\boot\fat12com.bin bin2c.com - .\bin2c ..\boot\fat12com.bin fat12com.h fat12com - -fat16com.h: ..\boot\fat16com.bin bin2c.com - .\bin2c ..\boot\fat16com.bin fat16com.h fat16com +fat16com.h: ..\boot\fat16.bin bin2c.com + bin2c ..\boot\fat16.bin $*.h $* fat32chs.h: ..\boot\fat32chs.bin bin2c.com - .\bin2c ..\boot\fat32chs.bin fat32chs.h fat32chs + bin2c ..\boot\$*.bin $*.h $* fat32lba.h: ..\boot\fat32lba.bin bin2c.com - .\bin2c ..\boot\fat32lba.bin fat32lba.h fat32lba + bin2c ..\boot\$*.bin $*.h $* -prf.obj: ..\kernel\prf.c - $(CC) $(CFLAGS) ..\kernel\prf.c +..\bin\sys.com: $(SYS_C) ..\hdr\*.h fat12com.h fat16com.h fat32chs.h fat32lba.h + $(CL) $(CFLAGST) -DFORSYS -DWITHFAT32 $(SYS_C) + copy sys.com ..\bin + del sys.com -fdkrncfg.obj: fdkrncfg.c ..\hdr\kconfig.h - -talloc.obj: talloc.c - -sys.com: $(SYS_EXE_dependencies) - $(CL) $(CFLAGST) $(TINY) $(SYS_EXE_dependencies) - -clobber: clean - -$(RM) bin2c.com sys.com fat*.h +######################################################################## clean: - -$(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.las *.cod *.err status.me - -# *Individual File Dependencies* -sys.obj: sys.c ..\hdr\portab.h ..\hdr\device.h fat12com.h fat16com.h fat32chs.h fat32lba.h - $(CC) $(CFLAGS) $*.c + -$(RM) *.bak *.cod *.crf *.err *.las *.lst *.map *.obj *.xrf +clobber: clean + -$(RM) bin2c.com fat*.h status.me diff --git a/sys/turboc.cfg b/sys/turboc.cfg new file mode 100644 index 0000000..84faa4c --- /dev/null +++ b/sys/turboc.cfg @@ -0,0 +1,7 @@ +-d +-f- +-k- +-O -Z +-v- +-w -g1 +-I..\hdr diff --git a/utils/echoto.bat b/utils/echoto.bat index 31758d9..f3fe60d 100755 --- a/utils/echoto.bat +++ b/utils/echoto.bat @@ -1 +1 @@ -@echo %2 %3 %4 %5 %6 %7 %8 %9 >> %1 \ No newline at end of file +@echo %2 %3 %4 %5 %6 %7 %8 %9>>%1 \ No newline at end of file diff --git a/utils/exeflat.c b/utils/exeflat.c index 91dde71..e0b822c 100644 --- a/utils/exeflat.c +++ b/utils/exeflat.c @@ -52,8 +52,6 @@ large portions copied from task.c #define BUFSIZE 32768u -#define LENGTH(x) (sizeof(x)/sizeof(x[0])) - typedef struct { UWORD off, seg; } farptr; @@ -260,7 +258,7 @@ int main(int argc, char **argv) } /* this assumes <= 0xfe00 code in kernel */ - *(short *)&JumpBehindCode[0x1e] += size; + *(short *)&JumpBehindCode[0x1e] += (short)size; fwrite(JumpBehindCode, 1, 0x20, dest); } @@ -282,31 +280,33 @@ int main(int argc, char **argv) if (UPX) { /* UPX trailer */ - /* hand assembled - so this remains ANSI C ;-) */ - static char trailer[] = { /* shift down everything by sizeof JumpBehindCode */ - 0xE8, 0x00, 0x00, /* call 103 */ - 0x59, /* pop cx */ - 0x0E, /* push cs */ - 0x1F, /* pop ds */ - 0x8c, 0xc8, /* mov ax,cs */ - 0x48, /* dec ax */ - 0x48, /* dec ax */ - 0x8e, 0xc0, /* mov es,ax */ - 0x31, 0xFF, /* xor di,di */ - 0xBE, 0x00, 0x00, /* mov si,0x00 */ - 0xFC, /* cld */ - 0xF3, 0xA4, /* rep movsb */ - 0x26, 0x88, 0x1e, 0x00, 0x00, /* mov es:[0],bl */ - 0xB8, 0x00, 0x00, /* mov ax,0000h */ - 0x8E, 0xD0, /* mov ss,ax */ - 0xBC, 0x00, 0x00, /* mov sp,0000h */ - 0x31, 0xC0, /* xor ax,ax */ - 0x50, /* push ax */ - 0xC3 /* ret */ + /* hand assembled - so this remains ANSI C ;-) */ + /* move kernel down to place CONFIG-block, which added above, + at 0x5e:0 instead 0x60:0 and store there boot drive number + from BL; kernel.asm will then check presence of additional + CONFIG-block at this address. */ + static char trailer[] = { + 0x0E, /* 0 push cs */ + 0x1F, /* 1 pop ds ; =0x60 */ + 0xBF,0x5E,0x00, /* 2 mov di,0x5E */ + 0x8E,0xC7, /* 5 mov es,di */ + 0xFC, /* 7 cld */ + 0x33,0xFF, /* 8 xor di,di */ + 0x93, /* 10 xchg ax,bx ; mov al,bl */ + 0xAA, /* 11 stosb ; mov [es:0],al */ + 0x8B,0xF7, /* 12 mov si,di */ + 0xB9,0x00,0x00, /* 14 mov cx,offset trailer */ + 0xF3,0xA4, /* 17 rep movsb */ + 0xBF,0x00,0x00, /* 19 mov di,... */ + 0x8E,0xD7, /* 22 mov ss,di */ + 0xBC,0x00,0x00, /* 24 mov sp,... */ + 0x33,0xFF, /* 27 xor di,di */ + 0xFF,0xE7, /* 29 jmp di ; jmp 0 */ }; - *(short *)&trailer[26] = start_seg + header.exInitSS; - *(short *)&trailer[31] = header.exInitSP; - fwrite(trailer, 1, sizeof(trailer), dest); + *(short *)&trailer[15] = (short)size + 0x20; + *(short *)&trailer[20] = start_seg + header.exInitSS; + *(short *)&trailer[25] = header.exInitSP; + fwrite(trailer, 1, sizeof trailer, dest); } fclose(dest); printf("\nProcessed %d relocations, %d not shown\n", diff --git a/utils/makefile b/utils/makefile index 7be6ec7..5a26e97 100644 --- a/utils/makefile +++ b/utils/makefile @@ -1,19 +1,19 @@ !include "../mkfiles/generic.mak" -CFLAGS = -I$(INCLUDEPATH) -I..\hdr +DEPENDS=$(DEPENDS) *.cfg -production: patchobj.com exeflat.exe +######################################################################## -patchobj.com: patchobj.c - $(CL) $(CFLAGST) $(TINY) $(CFLAGS) patchobj.c +all: patchobj.com exeflat.exe -exeflat.exe: exeflat.c ../hdr/exe.h - $(CL) $(CFLAGSC) $(CFLAGS) exeflat.c +patchobj.com: patchobj.c $(DEPENDS) +exeflat.exe: exeflat.c ../hdr/exe.h $(DEPENDS) -clobber: clean +######################################################################## clean: - $(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.las *.cod *.err status.me - $(RM) exeflat.exe patchobj.com + -$(RM) *.bak *.cod *.crf *.err *.las *.lst *.map *.obj *.xrf +clobber: clean + -$(RM) patchobj.com exeflat.exe status.me diff --git a/utils/rmfiles.bat b/utils/rmfiles.bat index a4a052e..e2423fd 100644 --- a/utils/rmfiles.bat +++ b/utils/rmfiles.bat @@ -7,4 +7,3 @@ shift goto loop_commandline :done_with_commandline - diff --git a/utils/turboc.cfg b/utils/turboc.cfg new file mode 100644 index 0000000..84faa4c --- /dev/null +++ b/utils/turboc.cfg @@ -0,0 +1,7 @@ +-d +-f- +-k- +-O -Z +-v- +-w -g1 +-I..\hdr diff --git a/utils/wlinker.bat b/utils/wlinker.bat index 9d25845..30d39eb 100755 --- a/utils/wlinker.bat +++ b/utils/wlinker.bat @@ -1,4 +1,4 @@ @echo off -ms2wlink %1 %2 %3 %4 %5 %6 %7 %8 %9 ,,,, > kernel.lnk -echo op map,statics,verbose >> kernel.lnk -call wlink @kernel.lnk +%BASE%\binw\ms2wlink %1 %2 %3 %4 %5 %6 %7 %8 %9>kernel.lnk +echo op map,statics,verbose,eliminate,vfremoval>>kernel.lnk +%BASE%\binw\wlink @kernel.lnk