Compare commits

...

No commits in common. "master" and "svn-trunk" have entirely different histories.

182 changed files with 7651 additions and 23275 deletions

6
.gitattributes vendored
View File

@ -1,6 +0,0 @@
* text eol=crlf
*.up -text
*.UP -text
ci_*.sh text eol=lf
.github/workflows/*.yml text eol=lf
test/** binary diff

View File

@ -1,48 +0,0 @@
name: Build
on:
pull_request:
types:
- opened
- ready_for_review
- reopened
- synchronize
push:
workflow_dispatch:
jobs:
build:
if: contains(github.event.head_commit.message, '[skip ci]') == false
runs-on: ubuntu-22.04
steps:
- name: Checkout repository and submodules
uses: actions/checkout@v4
with:
submodules: recursive
- name: Package install
run: ./ci_prereq.sh
- name: build
run: ./ci_build.sh
- name: test
run: ./ci_test.sh
- name: make snapshot name
id: snapshotname
run: |
(
today=`date -u +%F | tr '\n' '-'`
s_sha=`echo -n ${GITHUB_SHA} | cut -c1-8`
printf "fname=snapshot-%s%s\n" $today $s_sha >> $GITHUB_OUTPUT
)
- name: upload
if: github.repository == 'FDOS/kernel' &&
(github.event_name == 'push' || github.event.pull_request.merged == true)
uses: actions/upload-artifact@v4
with:
name: ${{ steps.snapshotname.outputs.fname }}
path: _output/*/*.???

48
.gitignore vendored
View File

@ -1,59 +1,11 @@
# Object Files
*.OBJ
*.obj
# List Files
*.LST
*.lst
# Map files
*.MAP
*.map
*.SYM
*.sym
# Executable files
*.EXE
*.exe
*.COM
*.com
# Bin files
*.BIN
*.bin
# Libraries
*.LIB
*.lib
# generated text files
sys/*.h
sys/*.H
kernel/*.lnk
kernel/*.LNK
# FreeDOS build tools configuration
config.bat
config.mak
kernel/*.SYS
kernel/*.sys
bin/[kK]*.SYS
bin/[kK]*.sys
bin/COMMAND.COM
bin/command.com
bin/COUNTRY.SYS
bin/country.sys
bin/SETVER.SYS
bin/setver.sys
# backup files
*.orig
*~
*.diff
*.rej
# CI build
_downloads/**
_output/**
_watcom/**

7
.gitmodules vendored
View File

@ -1,7 +0,0 @@
[submodule "share"]
path = share
url = https://github.com/FDOS/share.git
ignore = untracked
[submodule "country"]
path = country
url = https://github.com/FDOS/country.git

View File

@ -1,123 +0,0 @@
@ECHO OFF
IF "%1"=="" GOTO USAGE
REM assumes ran in same directory as this file, ie base of kernel source
SET BASEPATH=%CD%
CD ..
REM setup command aliases
SET ZIPIT=7z.exe a -tzip -mx9 -mm=deflate -mpass15 -r
REM when called from RELEASE.BAT assume clean source exported from version control
IF "%2"=="RELEASE" GOTO PACK
ECHO create source copy
if EXIST SOURCE RMDIR /S /Q SOURCE > NUL
MKDIR SOURCE
ECHO \.svn>SOURCE\SKIPLIST
ECHO .git>>SOURCE\SKIPLIST
ECHO .yml>>SOURCE\SKIPLIST
ECHO CNAME>>SOURCE\SKIPLIST
XCOPY %BASEPATH% SOURCE\ke%1 /S /V /I /Q /G /H /R /Y /EXCLUDE:SOURCE\SKIPLIST
DEL SOURCE\SKIPLIST > NUL
ECHO ensuring clean
PUSHD .
CD SOURCE\ke%1
CALL clobber.bat
POPD
:PACK
SET VERSION=%1
SET LSMRET=SRC
SET LSMFILE=SOURCE\ke%1\docs\fdkernel.lsm
GOTO LSM
:SRC
REM remove CONFIG.BAT if exists, such as building packages from develoment directory
IF EXIST SOURCE\ke%1\CONFIG.BAT DEL SOURCE\ke%1\CONFIG.BAT > NUL
ECHO zipping source
%ZIPIT% ke%1s.zip SOURCE\*
ECHO gathering source and creating APPINFO and expected packaging dir structure
REM FreeDOS package format, has APPINFO, BIN, DOC\KERNEL, SOURCE\KERNEL\
MKDIR PACKAGE
MKDIR PACKAGE\SOURCE
XCOPY /S /I /Q SOURCE\ke%1 PACKAGE\SOURCE\KERNEL
MKDIR PACKAGE\DOC
MKDIR PACKAGE\DOC\KERNEL
COPY /N SOURCE\ke%1\DOCS\* PACKAGE\DOC\KERNEL\
COPY SOURCE\ke%1\COPYING PACKAGE\DOC\KERNEL\COPYING
MKDIR PACKAGE\APPINFO
MOVE PACKAGE\DOC\KERNEL\fdkernel.lsm PACKAGE\APPINFO\KERNEL.LSM
MKDIR PACKAGE\BIN
ECHO using working configuration file
COPY %BASEPATH%\CONFIG.BAT SOURCE\ke%1\ > NUL
CD SOURCE\ke%1
ECHO build and packaging
SET VERSION=%1 (FAT12/FAT16)
SET FAT=16
SET CPU=86
SET BZKRET=F16
GOTO BZK
:F16
SET VERSION=%1 (FAT12/FAT16/FAT32)
SET FAT=32
SET CPU=386
SET BZKRET=F32
GOTO BZK
:F32
ECHO building FreeDOS package
CD ..\..\PACKAGE
%ZIPIT% ..\kernel.zip APPINFO BIN DOC SOURCE
ECHO clean up
CD ..
RMDIR /S /Q SOURCE > NUL
RMDIR /S /Q PACKAGE > NUL
ECHO Done.
SET BZKRET=
GOTO DONE
:BZK
ECHO build kernel %VERSION%
CALL build.bat /D KERNEL_VERSION /V "%1 " %CPU% win upx fat%FAT%
DEL BIN\K*86??.sys
SET LSMRET=BZK_2
SET LSMFILE=docs\fdkernel.lsm
GOTO LSM
:BZK_2
SET LSMRET=
ECHO zipping FAT%FAT% release version
%ZIPIT% ..\..\ke%1_%CPU%f%FAT%.zip BIN\* DOCS\*
ECHO storing binaries for FreeDOS package
COPY BIN\KERNEL.SYS ..\..\PACKAGE\BIN\KERNL%CPU%.SYS
COPY /B /Y BIN\country.sys ..\..\PACKAGE\BIN\COUNTRY.SYS
COPY /B /Y BIN\setver.sys ..\..\PACKAGE\BIN\SETVER.SYS
COPY /B /Y BIN\sys.com ..\..\PACKAGE\BIN\SYS.COM
IF EXIST BIN\share.com COPY /B /Y BIN\share.com ..\..\PACKAGE\BIN\SHARE.COM
ECHO cleaning up between builds
CALL clobber.bat
GOTO %BZKRET%
:LSM
ECHO Begin3>%LSMFILE%
ECHO Title: The FreeDOS Kernel>>%LSMFILE%
ECHO Version: %VERSION%>>%LSMFILE%
ECHO Entered-date: %DATE%>>%LSMFILE%
ECHO Description: The FreeDOS Kernel>>%LSMFILE%
ECHO Keywords: kernel, FreeDOS, DOS, MSDOS>>%LSMFILE%
ECHO Author: (developers: can be reached on the freedos-kernel mailing list)>>%LSMFILE%
ECHO Maintained-by: freedos-kernel@lists.sourceforge.net>>%LSMFILE%
ECHO Primary-site: http://github.com/fdos/kernel>>%LSMFILE%
ECHO Alternate-site: http://www.fdos.org/kernel/>>%LSMFILE%
ECHO Alternate-site: http://freedos.sourceforge.net/kernel/>>%LSMFILE%
ECHO Original-site: http://www.gcfl.net/pub/FreeDOS/kernel>>%LSMFILE%
ECHO Platforms: DOS, FreeDOS, DOSEMU (OpenWatcom/Borland/GCC-ia16, NASM, UPX)>>%LSMFILE%
ECHO Copying-policy: GPL2>>%LSMFILE%
ECHO End>>%LSMFILE%
SET LSMFILE=
SET VERSION=
GOTO %LSMRET%
:USAGE
ECHO Build kernel packages (interim builds or release without tagging) - usage: %0 {VERSION} e.g. %0 2039 or %0 git
:DONE
CD %BASEPATH%
SET BASEPATH=
SET ZIPIT=

View File

@ -1,17 +1,4 @@
fdkernel
=========
========
FreeDOS kernel - current 0xFD version is 2.43 (2043)
http://www.fdos.org/kernel/
The FreeDOS kernel implements the core MS/PC-DOS (R) compatible functions. It is derived from Pat Villani's DOS-C kernel and released under the GPL v2. Please see http://www.freedos.org/ for more details about the FreeDOS (TM) Project. This was originally a branch based on 2042 SVN 0xFD kernel; the full svn history has since been added to git (see other branches) and current development of release kernels are available here. Please fork and submit a Pull Request!
Compiled kernels ready to use (just copy kernel.sys over an existing install) are available at http://www.fdos.org/kernel/testing/git/ - also available are the source archive and fdpkg compatible packages. *** TODO update links/upload archives
This version of the kernel is intended only for 8086+ or 80386+ IBM compatible computers in continuation of the goals of the FreeDOS Project. Please see http://www.fdos.org/kernel for my 0xDC kernel that is work on merging back in some of the original portability aspects and other supported features at the cost of some compatibility with older hardware/software.
Please feel free to email me - PerditionC@gmail.com
Now with automatic builds and soon tests [![Build](../../workflows/Build/badge.svg)](../../actions)
FreeDOS kernel

View File

@ -1,30 +1,92 @@
@ECHO OFF
IF "%1"=="" GOTO USAGE
REM assume ran in root directory of kernel checkout, e.g. C:\fdos\source\kernel\
REM goto to just below trunk and tags directory, assume ran in trunk directory
CD ..
ECHO tag git with release version -
git tag -a -m "Tag kernel release %1" ke%1 HEAD
ECHO get a clean tree
if EXIST ..\SOURCE RMDIR /S /Q ..\SOURCE > NUL
::git clone -v --local --branch ke%1 . ..\SOURCE\ke%1\
git clone -v --local . ..\SOURCE\ke%1\
ECHO tag SVN with release version - svn copy trunk/ tags/ke%1
svn copy https://freedos.svn.sourceforge.net/svnroot/freedos/kernel/trunk/ https://freedos.svn.sourceforge.net/svnroot/freedos/kernel/tags/ke%1 -m "Tag kernel release %1"
PAUSE
ECHO svn export to get clean tree
if EXIST SOURCE RMDIR /S /Q SOURCE > NUL
svn export https://freedos.svn.sourceforge.net/svnroot/freedos/kernel/tags/ke%1 SOURCE\ke%1
REM svn export https://freedos.svn.sourceforge.net/svnroot/freedos/kernel/trunk SOURCE\ke%1
REM delete files to exclude
RD /S /Q ..\SOURCE\ke%1\.git > NUL
RD /S /Q ..\SOURCE\ke%1\.github > NUL
DEL /Q ..\SOURCE\ke%1\.git* > NUL
DEL /Q ..\SOURCE\ke%1\*.yml > NUL
DEL /Q ..\SOURCE\ke%1\ci*.sh > NUL
DEL /Q ..\SOURCE\ke%1\docs\*.yml > NUL
DEL /Q ..\SOURCE\ke%1\docs\CNAME > NUL
pause
SET VERSION=%1
SET LSMRET=SRC
SET LSMFILE=SOURCE\ke%1\docs\fdkernel.lsm
GOTO LSM
:SRC
ECHO zipping source
7z.exe a -tzip -mx9 -mpass15 -r ke%1s.zip SOURCE\*
ECHO creating APPINFO and expected packaging dir structure
ECHO using working configuration file
COPY trunk\CONFIG.BAT SOURCE\ke%1 > NUL
CD SOURCE\ke%1
ECHO %CD%
CALL MAKEPKGS.BAT %1 RELEASE
ECHO build and packaging
SET VERSION=%1 (FAT12/FAT16)
SET FAT=16
SET BZKRET=F16
GOTO BZK
:F16
SET VERSION=%1 (FAT12/FAT16/FAT32)
SET FAT=32
SET BZKRET=F32
GOTO BZK
:F32
ECHO clean up
CD ..\..
RMDIR /S /Q SOURCE > NUL
ECHO Done.
SET BZKRET=
GOTO DONE
:BZK
ECHO build kernel %VERSION%
CALL build.bat /D KERNEL_VERSION /V "%1 " 86 upx fat%FAT%
DEL BIN\K??86??.sys
SET LSMRET=BZK_2
SET LSMFILE=docs\fdkernel.lsm
GOTO LSM
:BZK_2
SET LSMRET=
ECHO zipping FAT%FAT% release version
7z.exe a -tzip -mx9 -mpass15 -r ..\..\ke%1_86f%FAT%.zip BIN\* DOCS\*
ECHO restructuring and zipping update package
DEL BIN\K??86??.* > NUL
MKDIR DOC
MKDIR DOC\KERNEL
COPY DOCS\* DOC\KERNEL\
MKDIR APPINFO
MOVE DOC\KERNEL\*.lsm APPINFO\
7z.exe a -tzip -mx9 -mpass15 -r ..\..\kernel%FAT%.zip APPINFO\* BIN\* DOC\*
ECHO cleaning up between builds
CALL clobber.bat
RMDIR /S /Q DOC
RMDIR /S /Q APPINFO
GOTO %BZKRET%
:LSM
ECHO Begin3>%LSMFILE%
ECHO Title: The FreeDOS Kernel>>%LSMFILE%
ECHO Version: %VERSION%>>%LSMFILE%
ECHO Entered-date: %DATE%>>%LSMFILE%
ECHO Description: The FreeDOS Kernel>>%LSMFILE%
ECHO Keywords: kernel, FreeDOS, DOS, MSDOS>>%LSMFILE%
ECHO Author: (developers: can be reached on the freedos-kernel mailing list)>>%LSMFILE%
ECHO Maintained-by: freedos-kernel@lists.sourceforge.net>>%LSMFILE%
ECHO Primary-site: http://freedos.sourceforge.net/kernel/>>%LSMFILE%
ECHO Alternate-site: http://www.fdos.org/kernel/>>%LSMFILE%
ECHO Alternate-site: https://freedos.svn.sourceforge.net/svnroot/freedos>>%LSMFILE%
ECHO Original-site: http://www.gcfl.net/pub/FreeDOS/kernel>>%LSMFILE%
ECHO Platforms: DOS, FreeDOS, DOSEMU (OpenWatcom C or Turbo C, NASM, UPX)>>%LSMFILE%
ECHO Copying-policy: GPL2>>%LSMFILE%
ECHO End>>%LSMFILE%
SET LSMFILE=
SET VERSION=
GOTO %LSMRET%
:USAGE
ECHO Tag and build release kernels - usage: RELEASE {VERSION} e.g. RELEASE 2039
:DONE
ECHO Please git push the tag to origin and upload the archives.
ECHO E.g. git push origin ke%1

View File

@ -24,73 +24,40 @@
; License along with DOS-C; see the file COPYING. If not,
; write to the Free Software Foundation, 675 Mass Ave,
; Cambridge, MA 02139, USA.
; Memory layout for the FreeDOS FAT12/FAT16 boot process:
;
; ...
; |-------| 1FE0h:7E00h = 27C00h (159 KiB)
; |BOOTSEC| loader relocates itself here first thing,
; |RELOC. | before loading root directory/FAT/kernel file
; |-------| 1FE0h:7C00h = 27A00h (158 KiB)
; | gap | PARAMS live here
; |LBA PKT| LBA disk packet
; |-------| 1FE0h:7BC0h = 279C0h (158 KiB)
; | gap | READADDR_* live here
; |-------| 1FE0h:7BA0h = 279A0h (158 KiB)
; | STACK | below relocated loader, above sector buffer (size 5.9 KiB)
; ...
; |-------| 1FE0h:6400h = 26200h (152 KiB)
; |SEC.BUF| sector buffer, to avoid crossing 64 KiB DMA boundary (size 8 KiB)
; |-------| 1FE0h:4400h = 24200h (144 KiB)
; ...
; |-------| 1FE0h:4380h = 24182h (144 KiB)
; |CLUSTER| built from FAT, listing every cluster of the kernel file.
; | LIST | file <= 134 KiB, cluster >= 32 Byte, hence <= 8578 B list.
; |-------| 1FE0h:2200h = 22000h (136 KiB)
; ...
; |-------| 0000h:7E00h = 07E00h (31.5 KiB)
; |BOOTSEC| possibly overwritten by the FAT (<= 128 KiB) and the kernel,
; |ORIGIN | so the bootsector relocates itself up...
; |-------| 0000h:7C00h = 07C00h (31 KiB)
; ...
; |-------|
; |KERNEL | maximum size 128 KiB (overwrites bootsec origin)
; |LOADED | (holds directory then FAT before kernel file load)
; |-------| 0060h:0000h = 00600h (1.5 KiB)
; ...
; The entire root directory is loaded to the kernel load address
; to scan for the kernel file. It is assumed to fit into 128 KiB.
; Typical root directory size is up to 512 entries = 16 KiB.
; Further, it is assumed that at least one root directory entry
; starts with a NUL byte to signify the end of the directory.
; After the directory entry is found, the entire FAT is loaded to
; the kernel load address. It is assumed that the size of the FAT
; in sectPerFat will not lead to a FAT larger than 128 KiB, which
; is the maximum size a FAT16 may fully utilise.
; The kernel load segment may be patched using the SYS /L switch.
; We support values between 0x60 and 0x200 here, with file size
; of up to 128 KiB (rounded to cluster size). Default is 0x60.
; This loader traditionally supports file sizes up to 134 KiB,
; assuming the default segment of 0x60. This does require a
; cluster size of 4 KiB (leads to maximum 132 KiB) or 2 KiB or
; lower (maximum 134 KiB). A more portable maximum is 128 KiB,
; which works with cluster sizes up to 128 KiB.
;
; +--------+ 1FE0:7E00
; |BOOT SEC|
; |RELOCATE|
; |--------| 1FE0:7C00
; |LBA PKT |
; |--------| 1FE0:7BC0
; |--------| 1FE0:7BA0
; |BS STACK|
; |--------|
; |4KBRDBUF| used to avoid crossing 64KB DMA boundary
; |--------| 1FE0:63A0
; | |
; |--------| 1FE0:3000
; | CLUSTER|
; | LIST |
; |--------| 1FE0:2000
; | |
; |--------| 0000:7E00
; |BOOT SEC| overwritten by max 128k FAT buffer
; |ORIGIN | and later by max 134k loaded kernel
; |--------| 0000:7C00
; | |
; |--------|
; |KERNEL | also used as max 128k FAT buffer
; |LOADED | before kernel loading starts
; |--------| 0060:0000
; | |
; +--------+
;%define ISFAT12 1
;%define ISFAT16 1
;verify one and only one of ISFAT12 or ISFAT16 is defined
%ifdef ISFAT12
%ifdef ISFAT16
%error Must select one FS
%endif
%elifndef ISFAT16
%error Must select one FS
%endif
; NOTE: sys must be updated if magic offsets change
%assign ISFAT1216DUAL 1
%include "magic.mac"
segment .text
@ -124,8 +91,8 @@ Entry: jmp short real_start
%define LOADSEG 0x0060
%define CLUSTLIST 0x2200 ; offset of temporary buffer for FAT
; chain cluster list
%define FATBUF 0x2000 ; offset of temporary buffer for FAT
; chain
; Some extra variables
@ -133,16 +100,7 @@ Entry: jmp short real_start
;-----------------------------------------------------------------------
times 36h - ($ - $$) db 0
; The filesystem ID is used by lDOS's instsect (by ecm)
; by default to validate that the filesystem matches.
%ifdef ISFAT12
%define FATFS "FAT12"
%elifdef ISFAT16
%define FATFS "FAT16"
%endif
db FATFS
times 3Eh - ($ - $$) db 32
times 0x3E-$+$$ db 0
; using bp-Entry+loadseg_xxx generates smaller code than using just
; loadseg_xxx, where bp is initialized to Entry, so bp-Entry equals 0
@ -159,9 +117,9 @@ Entry: jmp short real_start
%define LBA_SECTOR_32 word [LBA_PACKET+12]
%define LBA_SECTOR_48 word [LBA_PACKET+14]
%define READBUF 0x4400 ; max 8 KiB buffer
%define READADDR_OFF word BP-0x60 ; pointer within user buffer
%define READADDR_SEG word BP-0x60+2
%define READBUF 0x63A0 ; max 4KB buffer (min 2KB stack), == stacktop-0x1800
%define READADDR_OFF BP-0x60-0x1804 ; pointer within user buffer
%define READADDR_SEG BP-0x60-0x1802
%define PARAMS LBA_PACKET+0x10
;%define RootDirSecs PARAMS+0x0 ; # of sectors root dir uses
@ -203,7 +161,6 @@ real_start:
jmp word 0x1FE0:cont
loadseg_off dw 0
magicoffset "loadseg", 5Ch, 5Ch
loadseg_seg dw LOADSEG
cont:
@ -216,7 +173,6 @@ cont:
; in DL, however we work around this in SYS.COM by NOP'ing out the use of DL
; (formerly we checked for [drive]==0xff; update sys.c if code moves)
;
magicoffset "set unit", 66h, 66h
mov [drive], dl ; rely on BIOS drive number in DL
mov LBA_SIZE, 10h
@ -293,7 +249,7 @@ next_entry: mov cx, 11
cmp byte [es:di], 0 ; if the first byte of the name is 0,
jnz next_entry ; there is no more files in the directory
jmp boot_error ; fail if not found
jc boot_error ; fail if not found
ffDone:
push ax ; store first cluster number
@ -321,7 +277,7 @@ ffDone:
push ds
pop es
mov ds, [loadseg_60]
mov di, CLUSTLIST
mov di, FATBUF
next_clust: stosw ; store cluster number
mov si, ax ; SI = cluster number
@ -378,7 +334,7 @@ finished: ; Mark end of FAT chain with 0, so we have a single
les bx, [loadsegoff_60] ; set ES:BX to load address 60:0
mov si, CLUSTLIST ; set DS:SI to the FAT chain
mov si, FATBUF ; set DS:SI to the FAT chain
cluster_next: lodsw ; AX = next cluster to read
or ax, ax ; EOF?
@ -390,9 +346,7 @@ load_next: dec ax ; cluster numbers start with 2
dec ax
mov di, word [bsSecPerClust]
dec di ; minus one if 256 spc
and di, 0xff ; DI = sectors per cluster - 1
inc di ; = spc
and di, 0xff ; DI = sectors per cluster
mul di
add ax, [data_start]
adc dx, [data_start+2] ; DX:AX = first sector to read
@ -401,19 +355,18 @@ load_next: dec ax ; cluster numbers start with 2
; shows text after the call to this function.
show.do_show:
mov ah, 0Eh ; show character
int 10h ; via "TTY" mode
show: pop si
lodsb ; get character
push si ; stack up potential return address
cmp al, 0 ; end of string?
jne .do_show ; until done
mov ah,0x0E ; show character
int 0x10 ; via "TTY" mode
cmp al,'.' ; end of string?
jne show ; until done
ret
boot_error: call show
; db "Error! Hit a key to reboot.",0
db "Error!",0
; db "Error! Hit a key to reboot."
db "Error!."
xor ah,ah
int 0x13 ; reset floppy
@ -437,12 +390,8 @@ readDisk: push si
mov word [READADDR_SEG], es
mov word [READADDR_OFF], bx
%ifndef QUIET
call show
db ".",0
%else ; ensure code after this still at same location
times 5 nop
%endif
db "."
read_next:
;******************** LBA_READ *******************************
@ -453,7 +402,7 @@ read_next:
mov bx,055aah ;
mov dl, [drive]
magicoffset "LBA detection", 17Bh, 178h
; NOTE: sys must be updated if location changes!!!
test dl,dl ; don't use LBA addressing on A:
jz read_normal_BIOS ; might be a (buggy)
; CDROM-BOOT floppy emulation
@ -557,7 +506,6 @@ do_int13_read:
times 0x01f1-$+$$ db 0
magicoffset "kernel name", 1F1h, 1F1h
filename db "KERNEL SYS",0,0
sign dw 0xAA55

View File

@ -1,37 +1,34 @@
; Memory layout for the FreeDOS FAT32 single stage boot process:
;
; ...
; |-------| 1FE0h:7E00h = 27C00h (159 KiB)
; |BOOTSEC| loader relocates itself here first thing,
; |RELOC. | before loading root directory/FAT/kernel file
; |-------| 1FE0h:7C00h = 27A00h (158 KiB)
; | STACK | below relocated loader, above FAT sector (size 22 KiB)
; ...
; |-------| 2200h:2000h = 24000h (144 KiB)
; | FAT | (only 1 sector buffered, maximum sector size 8 KiB)
; |-------| 2200h:0000h = 22000h (136 KiB)
; ...
; |-------| 0000h:7E00h = 07E00h (31.5 KiB)
; |BOOTSEC| overwritten by the kernel, so the
; |ORIGIN | bootsector relocates itself up...
; |-------| 0000h:7C00h = 07C00h (31 KiB)
; ...
; |-------|
; |KERNEL | maximum size 128 KiB (overwrites bootsec origin)
; |LOADED | (holds 1 sector directory buffer before kernel file load)
; |-------| 0060h:0000h = 00600h (1.5 KiB)
; ...
; The kernel load segment may be patched using the SYS /L switch.
; We support values between 0x60 and 0x200 here, with file size
; of up to 128 KiB (rounded to cluster size). Default is 0x60.
; +--------+
; | |
; | |
; |--------| 4000:0000
; | |
; | FAT |
; | |
; |--------| 2000:0000
; |BOOT SEC|
; |RELOCATE|
; |--------| 1FE0:0000
; | |
; | |
; | |
; | |
; |--------|
; |BOOT SEC|
; |ORIGIN | 07C0:0000
; |--------|
; | |
; | |
; | |
; |--------|
; |KERNEL |
; |LOADED |
; |--------| 0060:0000
; | |
; +--------+
;%define MULTI_SEC_READ 1
; NOTE: sys must be updated if magic offsets change
%assign ISFAT1216DUAL 0
%include "magic.mac"
segment .text
@ -60,16 +57,11 @@ Entry: jmp short real_start
%define xrootClst bp+0x2c ; Starting cluster of root directory
%define drive bp+0x40 ; Drive number
times 52h - ($ - $$) db 0
; The filesystem ID is used by lDOS's instsect (by ecm)
; by default to validate that the filesystem matches.
db "FAT32"
times 5Ah - ($ - $$) db 32
times 0x5a-$+$$ db 0
%define LOADSEG 0x0060
%define FATSEG 0x2200
%define FATSEG 0x2000
%define fat_sector bp+0x48 ; last accessed sector of the FAT
@ -100,14 +92,12 @@ real_start: cld
jmp word 0x1FE0:cont
loadseg_off dw 0
magicoffset "loadseg", 78h
loadseg_seg dw LOADSEG
cont: mov ds, ax
mov ss, ax
lea sp, [bp-0x20]
sti
magicoffset "set unit", 82h
mov [drive], dl ; BIOS passes drive number in DL
; call print
@ -149,7 +139,7 @@ secshift: inc ax
shr cx, 1
cmp cx, 1
jne secshift
mov word [fat_secshift], ax
mov byte [fat_secshift], al
dec cx
; FINDFILE: Searches for the file in the root directory.
@ -221,10 +211,6 @@ c6:
jmp short c5
boot_error:
mov ax, 0E00h | '!'
int 10h ; display the error sign
mov al, 07h
int 10h ; beep
xor ah,ah
int 0x16 ; wait for a key
int 0x19 ; reboot the machine
@ -245,7 +231,8 @@ next_cluster:
cn_loop:
shr dx,1
rcr ax,1
loop cn_loop ; DX:AX fat sector where our
dec cx
jnz cn_loop ; DX:AX fat sector where our
; cluster resides
; DI - cluster index in this
; sector
@ -278,8 +265,7 @@ cn_exit:
boot_success:
mov dl, [drive] ; for Enhanced DR-DOS load
mov bl, dl ; for FreeDOS load
mov bl, [drive]
jmp far [loadsegoff_60]
; Convert cluster to the absolute sector
@ -303,9 +289,7 @@ c3:
sub ax, 2
sbb cx, byte 0 ; CX:AX == cluster - 2
mov bl, [bsSecPerClust]
dec bx ; bl = spc - 1, 0FFh if 256 spc
sub bh, bh ; bx = spc - 1
inc bx ; bx = spc
sub bh, bh
xchg cx, ax ; AX:CX == cluster - 2
mul bx ; first handle high word
; DX must be 0 here
@ -316,7 +300,6 @@ c3:
adc dx, [data_start + 2]
ret
%if 0
; prints text after call to this function.
print_1char:
@ -329,7 +312,6 @@ print1: lodsb ; get token
cmp al, 0 ; end of string?
jne print_1char ; until done
ret ; and jump to it
%endif
;input:
; DX:AX - 32-bit DOS sector number
@ -399,15 +381,12 @@ read_ok:
mov es, cx
no_incr_es:
inc ax
jnz .no_carry
inc dx
.no_carry:
add ax,byte 1
adc dx,byte 0
ret
times 0x01f1-$+$$ db 0
magicoffset "kernel name", 1F1h
filename db "KERNEL SYS",0,0
sign dw 0xAA55

View File

@ -27,36 +27,27 @@
; Memory layout for the FreeDOS FAT32 single stage boot process:
;
; ...
; |-------| 1FE0h:7E00h = 27C00h (159 KiB)
; |BOOTSEC| loader relocates itself here first thing,
; |RELOC. | before loading root directory/FAT/kernel file
; |-------| 1FE0h:7C00h = 27A00h (158 KiB)
; | STACK | below relocated loader, above FAT sector (size 22 KiB)
; |-------| 1FE0:7E00
; |BOOTSEC|
; |RELOC. |
; |-------| 1FE0:7C00
; ...
; |-------| 2200h:2000h = 24000h (144 KiB)
; | FAT | (only 1 sector buffered, maximum sector size 8 KiB)
; |-------| 2200h:0000h = 22000h (136 KiB)
; |-------| 2000:0200
; | FAT | (only 1 sector buffered)
; |-------| 2000:0000
; ...
; |-------| 0000h:7E00h = 07E00h (31.5 KiB)
; |-------| 0000:7E00
; |BOOTSEC| overwritten by the kernel, so the
; |ORIGIN | bootsector relocates itself up...
; |-------| 0000h:7C00h = 07C00h (31 KiB)
; |-------| 0000:7C00
; ...
; |-------|
; |KERNEL | maximum size 128 KiB (overwrites bootsec origin)
; |LOADED | (holds 1 sector directory buffer before kernel file load)
; |-------| 0060h:0000h = 00600h (1.5 KiB)
; |KERNEL | maximum size 134k (overwrites bootsec origin)
; |LOADED | (holds 1 sector directory buffer before kernel load)
; |-------| 0060:0000
; ...
; The kernel load segment may be patched using the SYS /L switch.
; We support values between 0x60 and 0x200 here, with file size
; of up to 128 KiB (rounded to cluster size). Default is 0x60.
; NOTE: sys must be updated if magic offsets change
%assign ISFAT1216DUAL 0
%include "magic.mac"
segment .text
@ -94,7 +85,7 @@ Entry: jmp short real_start
%define LOADSEG 0x0060
%define FATSEG 0x2200
%define FATSEG 0x2000
%define fat_secshift fat_afterss-1 ; each fat sector describes 2^??
; clusters (db) (selfmodifying)
@ -105,11 +96,7 @@ Entry: jmp short real_start
%define data_start bp+0x4c ; first data sector (dd)
; (overwriting unused bytes)
times 52h - ($ - $$) db 0
; The filesystem ID is used by lDOS's instsect (by ecm)
; by default to validate that the filesystem matches.
db "FAT32"
times 5Ah - ($ - $$) db 32
times 0x5a-$+$$ db 0
; not used: [0x42] = byte 0x29 (ext boot param flag)
; [0x43] = dword serial
; [0x47] = label (padded with 00, 11 bytes)
@ -134,9 +121,7 @@ real_start: cld
rep movsw ; move boot code to the 0x1FE0:0x0000
jmp word 0x1FE0:cont
loadseg_off dw 0
magicoffset "loadseg", 78h
dw LOADSEG
loadseg_off dw 0, LOADSEG
; -------------
@ -144,15 +129,10 @@ cont: mov ds, ax
mov ss, ax ; stack and BP-relative moves up, too
lea sp, [bp-0x20]
sti
magicoffset "set unit", 82h
mov [drive], dl ; BIOS passes drive number in DL
%ifndef QUIET
mov si, msg_LoadFreeDOS
call print ; modifies AX BX SI
%else ; ensure code after this still at same location
times 6 nop
%endif
; -------------
@ -254,9 +234,7 @@ rk_walk_fat: pop eax
;-----------------------------------------------------------------------
boot_success:
mov dl, [drive] ; for Enhanced DR-DOS load
mov bl, dl ; for FreeDOS load
boot_success: mov bl, [drive]
jmp far [loadsegoff_60]
;-----------------------------------------------------------------------
@ -331,8 +309,6 @@ convert_cluster:
dec eax
movzx edx, byte [bsSecPerClust]
dec dl ; spc - 1
inc dx ; spc
push edx
mul edx
pop edx
@ -421,7 +397,6 @@ msg_BootError db "No "
; currently, only "kernel.sys not found" gives a message,
; but read errors in data or root or fat sectors do not.
magicoffset "kernel name", 1F1h
filename db "KERNEL SYS"
sign dw 0, 0xAA55

View File

@ -1,76 +0,0 @@
; Public Domain 2024 by E. C. Masloch
%macro _appenddigitstrdef 2.nolist
%substr %%ii "0123456789ABCDEF" (%2) + 1
%strcat _%1 _%1,%%ii
%endmacro
; %1 = name of single-line macro to set. will be prefixed by underscore
; %2 = number to write
; %3 = minimal number of hexits, 0..8. defaults to 1
; (setting it to 0 with a number of 0 defines macro to "")
%macro _autohexitsstrdef 2-3.nolist 1
%if %3 > 8
%error Minimal number of hexits 9 or more: %3
%endif
%define _%1 ""
%if (%2) >= 1_0000_0000h
%error Number has to use 9 or more hexits: %2
%endif
%if (%2) >= 1000_0000h || %3 >= 8
_appenddigitstrdef %1, (%2 >> (7 * 4)) & 0Fh
%endif
%if (%2) >= 100_0000h || %3 >= 7
_appenddigitstrdef %1, (%2 >> (6 * 4)) & 0Fh
%endif
%if (%2) >= 10_0000h || %3 >= 6
_appenddigitstrdef %1, (%2 >> (5 * 4)) & 0Fh
%endif
%if (%2) >= 1_0000h || %3 >= 5
_appenddigitstrdef %1, (%2 >> (4 * 4)) & 0Fh
%endif
%if (%2) >= 1000h || %3 >= 4
_appenddigitstrdef %1, (%2 >> (3 * 4)) & 0Fh
%endif
%if (%2) >= 100h || %3 >= 3
_appenddigitstrdef %1, (%2 >> (2 * 4)) & 0Fh
%endif
%if (%2) >= 10h || %3 >= 2
_appenddigitstrdef %1, (%2 >> (1 * 4)) & 0Fh
%endif
%if (%2) >= 1h || %3 >= 1
_appenddigitstrdef %1, (%2 >> (0 * 4)) & 0Fh
%endif
%endmacro
%macro magicoffset 2-4.nolist ,0
%if ISFAT1216DUAL
%ifdef ISFAT12
%define SYSOFFSET %2
%elifdef ISFAT16
%define SYSOFFSET %3
%else
%define SYSOFFSET 0
; Just a placeholder, so the proper error message
; will be shown when assembling without either
; of the ISFATx defines.
%endif
%else
%define SYSOFFSET %2
%ifnempty %3
%error Not in dual mode
%endif
%endif
%assign NEWOFFSET $ + %4 - Entry
%if NEWOFFSET != SYSOFFSET
_autohexitsstrdef NEWOFFSETHEX, NEWOFFSET
%strcat _NEWOFFSETHEX _NEWOFFSETHEX,'h'
%deftok NEWOFFSET _NEWOFFSETHEX
%if ISFAT1216DUAL
%error Magic offset %1 changed for FATFS, old=SYSOFFSET, new=NEWOFFSET
%else
%error Magic offset %1 changed, old=SYSOFFSET, new=NEWOFFSET
%endif
%endif
%endmacro

View File

@ -7,23 +7,23 @@
production: fat12com.bin fat16com.bin fat32chs.bin fat32lba.bin oemfat12.bin oemfat16.bin
fat12com.bin: boot.asm magic.mac
$(NASM) -dISFAT12 $(NASMBOOTFLAGS) boot.asm -lfat12com.lst -ofat12com.bin
fat12com.bin: boot.asm
$(NASM) -dISFAT12 boot.asm -l$*.lst -ofat12com.bin
fat16com.bin: boot.asm magic.mac
$(NASM) -dISFAT16 $(NASMBOOTFLAGS) boot.asm -lfat16com.lst -ofat16com.bin
fat16com.bin: boot.asm
$(NASM) -dISFAT16 boot.asm -l$*.lst -ofat16com.bin
fat32chs.bin: boot32.asm magic.mac
$(NASM) $(NASMBOOTFLAGS) boot32.asm -lfat32chs.lst -ofat32chs.bin
fat32chs.bin: boot32.asm
$(NASM) boot32.asm -l$*.lst -ofat32chs.bin
fat32lba.bin: boot32lb.asm magic.mac
$(NASM) $(NASMBOOTFLAGS) boot32lb.asm -lfat32lba.lst -ofat32lba.bin
fat32lba.bin: boot32lb.asm
$(NASM) boot32lb.asm -l$*.lst -ofat32lba.bin
oemfat12.bin: oemboot.asm magic.mac
$(NASM) -dISFAT12 $(NASMBOOTFLAGS) oemboot.asm -loemfat12.lst -ooemfat12.bin
oemfat12.bin: oemboot.asm
$(NASM) -dISFAT12 oemboot.asm -l$*.lst -ooemfat12.bin
oemfat16.bin: oemboot.asm magic.mac
$(NASM) -dISFAT16 $(NASMBOOTFLAGS) oemboot.asm -loemfat16.lst -ooemfat16.bin
oemfat16.bin: oemboot.asm
$(NASM) -dISFAT16 oemboot.asm -l$*.lst -ooemfat16.bin
clobber: clean
-$(RM) *.bin status.me

View File

@ -116,11 +116,6 @@
; |IVT | Interrupt Vector Table
; +--------+ 0000:0000
; NOTE: sys must be updated if magic offsets change
%assign ISFAT1216DUAL 1
%include "magic.mac"
CPU 8086 ; enable assembler warnings to limit instruction set
;%define ISFAT12 1 ; only 1 of these should be set,
@ -148,7 +143,7 @@ segment .text
%define FATBUF bp-0x7500 ; offset of temporary buffer for FAT
; chain 0:FATBUF = 0:0700 = LOADSEG:0
%define ROOTDIR 0x7C00-0x7700 ; offset to buffer for root directory
%define ROOTDIR bp-0x7700 ; offset to buffer for root directory
; entry of kernel 0:ROOTDIR
%define CLUSTLIST bp+0x0300 ; zero terminated list of clusters
; that the kernel occupies
@ -228,22 +223,7 @@ Entry: jmp short real_start
db 0x29 ; extended boot record id
dd 0x12345678 ; volume serial number
db 'NO NAME '; volume label
times 36h - ($ - $$) db 0
; The filesystem ID is used by lDOS's instsect (by ecm)
; by default to validate that the filesystem matches.
%ifdef ISFAT12
%define FATFS "FAT12"
%ifdef ISFAT16
%error Must select one FS
%endif
%elifdef ISFAT16
%define FATFS "FAT16"
%else
%define FATFS "unknown"
%error Must select one FS
%endif
db FATFS ; filesystem id
times 3Eh - ($ - $$) db 32
db 'FAT12 ' ; filesystem id
;-----------------------------------------------------------------------
; ENTRY
@ -289,7 +269,6 @@ real_start:
; in DL, however we work around this in SYS.COM by NOP'ing out the use of DL
; (formerly we checked for [drive]==0xff; update sys.c if code moves)
;
magicoffset "set unit", 4Fh, 4Fh
mov [drive], dl ; rely on BIOS drive number in DL
@ -340,11 +319,11 @@ real_start:
pop di ; mov di, word [RootDirSecs]
pop ax ; mov ax, word [root_dir_start]
pop dx ; mov dx, word [root_dir_start+2]
mov bx, ROOTDIR ; es:bx = 0:0500
lea bx, [ROOTDIR] ; es:bx = 0:0500
push es ; save pointer to ROOTDIR
call readDisk
pop es ; restore pointer to ROOTDIR
mov si, ROOTDIR ; ds:si = 0:0500
lea si, [ROOTDIR] ; ds:si = 0:0500
; Search for kernel file name, and find start cluster.
@ -361,7 +340,6 @@ next_entry: mov cx, 11
jc boot_error ; fail if not found and si wraps
cmp byte [si], 0 ; if the first byte of the name is 0,
jnz next_entry ; there are no more files in the directory
jmp boot_error
ffDone:
mov [first_cluster], ax ; store first cluster number
@ -369,7 +347,7 @@ ffDone:
%ifdef SETROOTDIR
; copy over this portion of root dir to 0x0:500 for PC-DOS
; (this may allow IBMBIO.COM to start in any directory entry)
mov di, ROOTDIR ; es:di = 0:0500
lea di, [ROOTDIR] ; es:di = 0:0500
mov cx, 32 ; limit to this 1 entry (rest don't matter)
rep movsw
%endif
@ -421,12 +399,11 @@ fat_12: add si, si ; multiply cluster number by 3...
; value is in bits 4-15, and must be shifted right 4 bits. If
; the number was odd, CF was set in the last shift instruction.
mov cl, 4 ; always initialise shift counter
jc fat_odd ; is odd, only shift down -->
shl ax, cl ; shift up (effectively masks off
; the highest 4 bits)
fat_odd:
jnc fat_even
mov cl, 4
shr ax, cl
fat_even: and ah, 0x0f ; mask off the highest 4 bits
cmp ax, 0x0ff8 ; check for EOF
jb next_clust ; continue if not EOF
@ -478,14 +455,13 @@ cluster_next: lodsw ; AX = next cluster to read
%else
jmp LOADSEG:0000 ; yes, pass control to kernel
%endif
magicoffset "load jump ofs", 11Ah, 118h, -4
; failed to boot
boot_error:
call show
; db "Error! Hit a key to reboot.",0
db "):",0
; db "Error! Hit a key to reboot."
db "):."
%ifdef LOOPONERR
jmp $
%else
@ -502,9 +478,7 @@ load_next: dec ax ; cluster numbers start with 2
dec ax
mov di, word [bsSecPerClust]
dec di ; minus one if 256 spc
and di, 0xff ; DI = sectors per cluster - 1
inc di ; = spc
and di, 0xff ; DI = sectors per cluster
mul di
add ax, [data_start]
adc dx, [data_start+2] ; DX:AX = first sector to read
@ -514,14 +488,13 @@ load_next: dec ax ; cluster numbers start with 2
; shows text after the call to this function.
show.do_show:
mov ah, 0Eh ; show character
int 10h ; via "TTY" mode
show: pop si
lodsb ; get character
push si ; stack up potential return address
cmp al, 0 ; end of string?
jne .do_show ; until done
mov ah,0x0E ; show character
int 0x10 ; via "TTY" mode
cmp al,'.' ; end of string?
jne show ; until done
ret
@ -543,7 +516,7 @@ readDisk: push si ; preserve cluster #
mov word [LBA_OFF], bx
call show
db ".",0
db "."
read_next:
; initialize constants
@ -664,8 +637,6 @@ read_skip:
ret
times 0x01f1-$+$$ db 0
magicoffset "kernel name", 1F1h, 1F1h
%ifdef MSCOMPAT
filename db "IO SYS"
%else

View File

@ -25,6 +25,7 @@ if not exist config.bat goto abort
call config.bat
:-if "%LAST%" == "" goto noenv
set dos4g=quiet
:-----------------------------------------------------------------------
:- following is command line handling
@ -50,7 +51,6 @@ if "%1" == "x86" goto setCPU
if "%1" == "upx" set XUPX=upx --8086 --best
if "%1" == "debug" set ALLCFLAGS=%ALLCFLAGS% -DDEBUG
if "%1" == "lfn" set ALLCFLAGS=%ALLCFLAGS% -DWITHLFNAPI
if "%1" == "lfnapi" set ALLCFLAGS=%ALLCFLAGS% -DWITHLFNAPI
if "%1" == "win" set ALLCFLAGS=%ALLCFLAGS% -DWIN31SUPPORT
@ -117,20 +117,6 @@ cd ..\kernel
%MAKE% production
if errorlevel 1 goto abort-cd
echo.
echo Process COUNTRY +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
echo.
cd ..\country
%MAKE% DIRSEP=\ CP=copy production
if errorlevel 1 goto abort-cd
echo.
echo Process SETVER +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
echo.
cd ..\setver
%MAKE% production
if errorlevel 1 goto abort-cd
cd ..
set XERROR=
@ -169,8 +155,6 @@ if "%1" == "" goto abort
if "%2" == "/V" goto :setDefineWithValue
set ALLCFLAGS=%ALLCFLAGS% -D%1
set NASMFLAGS=%NASMFLAGS% -D%1
REM $(NASMBOOTFLAGS) are extra flags only used when building boot sectors
set NASMBOOTFLAGS=%NASMBOOTFLAGS% -d%1
goto nextOption
:setDefineWithValue

View File

@ -15,6 +15,7 @@ set onerror=if not "%XERROR%" == "" goto daswarwohlnix
:***** MSCL kernels
call config.bat
set dos4g=quiet
if "%MS_BASE%" == "" goto no_ms
call build -r msc 386 fat16
@ -46,7 +47,7 @@ call build -r tc 86 fat32
:***** (Open) Watcom kernels
if not "%COMPILER%" == "WATCOM" goto no_wc
if "%WATCOM%" == "" goto no_wc
call build -r wc 386 fat32
%ONERROR%
call build -r wc 386 fat16

View File

@ -1,117 +0,0 @@
#!/bin/sh
set -e
if [ -z "${BUILD_DIR}" ] ; then
BUILD_DIR=$(pwd)
fi
echo BUILD_DIR is \"${BUILD_DIR}\"
# Output directory
rm -rf _output
mkdir _output
# GCC
mkdir _output/gcc
git clean -x -d -f -e test -e _output -e _downloads -e _watcom
make -C country clean
make all COMPILER=gcc
mv -n bin/KGC*.map bin/KGC*.sys _output/gcc/.
mv -n bin/country.sys _output/gcc/.
# GCC share
(
cd share
git submodule update --init --recursive
git clean -x -d -f
env COMPILER=gcc ./build.sh
)
mv -n share/src/share.com _output/gcc/.
mv -n share/src/share.map _output/gcc/.
# Watcom
OWTAR=ow-snapshot.tar.xz
if [ ! -d _watcom ] ; then
mkdir -p _downloads
mkdir _watcom
if [ ! -f _downloads/$OWTAR ] ; then
(cd _downloads && wget --no-verbose https://github.com/open-watcom/open-watcom-v2/releases/download/Last-CI-build/$OWTAR)
fi
(cd _watcom && tar -xf ../_downloads/$OWTAR)
fi
export WATCOM=$BUILD_DIR/_watcom
export PATH=$BUILD_DIR/bin:$PATH:$WATCOM/binl64
mkdir _output/wc
git clean -x -d -f -e test -e _output -e _downloads -e _watcom
make -C country clean
make all COMPILER=owlinux
mv -n bin/KWC*.map bin/KWC*.sys _output/wc/.
mv -n bin/country.sys _output/wc/.
## DOS (GCC)
#mkdir _output/gcc_dos
#git clean -x -d -f -e test -e _output -e _downloads -e _watcom
#{
# echo set COMPILER=GCC
# echo set MAKE=make
# echo set XCPU=386
# echo set XFAT=32
# echo set XNASM='C:\\devel\\nasm\\nasm'
# echo set OLDPATH=%PATH%
# echo set PATH='C:\\devel\\i16gnu\\bin;C:\\bin;%OLDPATH%'
#} | unix2dos > config.bat
#dosemu -td -q -K . -E "build.bat"
# DOS (Watcom)
mkdir _output/wc_dos
git clean -x -d -f -e test -e _output -e _downloads -e _watcom
{
echo set COMPILER=WATCOM
echo set WATCOM='C:\\devel\\watcomc'
echo set MAKE=wmake /ms
echo set XCPU=386
echo set XFAT=32
echo set XNASM='C:\\devel\\nasm\\nasm'
echo set XUPX=upx --8086 --best
echo set OLDPATH=%PATH%
echo set PATH='%WATCOM%\\binw;C:\\bin;%OLDPATH%'
echo set DOS4G=QUIET
} | unix2dos > config.bat
dosemu -td -q -K . -E "build.bat"
mv -n bin/KWC*.map bin/KWC*.sys _output/wc_dos/.
mv -n bin/country.sys _output/wc_dos/.
# DOS (Turbo C 2.01)
if [ -d ${HOME}/.dosemu/drive_c/tc201 ] ; then
mkdir _output/tc_dos
git clean -x -d -f -e test -e _output -e _downloads -e _watcom
{
echo set COMPILER=TC2
echo set TC2_BASE='C:\\tc201'
echo set MAKE=make
echo set XCPU=386
echo set XFAT=32
echo set XNASM=nasm
echo set OLDPATH=%PATH%
echo set PATH='%TC2_BASE%;C:\\devel\\nasm;C:\\bin;%OLDPATH%'
} | unix2dos > config.bat
dosemu -td -q -K . -E "build.bat lfn"
mv -n bin/KTC*.map bin/KTC*.sys _output/tc_dos/.
mv -n bin/country.sys _output/tc_dos/.
# TC share
(
cd share
git submodule update --init --recursive
git clean -x -d -f
env COMPILER=tcc2-emu ./build.sh
)
mv -n share/src/share.com _output/tc_dos/.
mv -n share/src/share.map _output/tc_dos/.
fi
echo done

View File

@ -1,82 +0,0 @@
#!/bin/sh
set -e
sudo add-apt-repository -y ppa:tkchia/build-ia16
sudo add-apt-repository -y ppa:dosemu2/ppa
sudo apt update
# for cross building
sudo apt install gcc-ia16-elf libi86-ia16-elf nasm upx qemu-system-x86 mtools util-linux bash
# for building with DOS using an emulator
sudo apt install dosemu2 dos2unix
# Perhaps later we should build using Freecom from published package
mkdir -p _downloads
cd _downloads
HERE=$(pwd)
#IBIBLIO_PATH='http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.2/repos'
IBIBLIO_PATH='https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/repositories/1.3'
BASE=${IBIBLIO_PATH}/base
# get FreeDOS kernel
[ -f kernel.zip ] || wget --no-verbose ${BASE}/kernel.zip
# get FreeCOM
[ -f freecom.zip ] || wget --no-verbose ${BASE}/freecom.zip
DEVEL=${IBIBLIO_PATH}/devel
# get gnumake for DOS
[ -f djgpp_mk.zip ] || wget --no-verbose ${DEVEL}/djgpp_mk.zip
# get nasm for DOS
[ -f nasm.zip ] || wget --no-verbose ${DEVEL}/nasm.zip
# get upx for DOS
[ -f upx.zip ] || wget --no-verbose ${DEVEL}/upx.zip
# grab ia16-gcc from ibiblio.org
#[ -f i16gcc.zip ] || wget --no-verbose ${DEVEL}/i16gcc.zip
#[ -f i16newli.zip ] || wget --no-verbose ${DEVEL}/i16newli.zip
#[ -f i16butil.zip ] || wget --no-verbose ${DEVEL}/i16butil.zip
#[ -f i16lbi86.zip ] || wget --no-verbose ${DEVEL}/i16lbi86.zip
# get watcom for DOS
[ -f watcomc.zip ] || wget --no-verbose ${DEVEL}/watcomc.zip
mkdir -p ${HOME}/.dosemu/drive_c
cd ${HOME}/.dosemu/drive_c && (
mkdir -p bin
# Boot files
unzip -L -q ${HERE}/kernel.zip
cp -p bin/kernl386.sys ./kernel.sys
unzip -L -q ${HERE}/freecom.zip
cp -p bin/command.com ./command.com
cp -p /usr/share/dosemu/dosemu2-cmds-0.3/c/fdconfig.sys .
# Development files
unzip -L -q ${HERE}/djgpp_mk.zip
cp -p devel/djgpp/bin/make.exe bin/.
unzip -L -q ${HERE}/upx.zip
cp -p devel/upx/upx.exe bin/.
echo PATH to make and upx binaries is 'c:/bin'
unzip -L -q ${HERE}/nasm.zip
echo PATH to nasm binary is 'c:/devel/nasm'
# unzip -L -q ${HERE}/i16gcc.zip
# unzip -L -q ${HERE}/i16newli.zip
# unzip -L -q ${HERE}/i16butil.zip
# unzip -L -q ${HERE}/i16lbi86.zip
# echo PATH to ia16 binaries is 'c:/devel/i16gnu/bin'
unzip -L -q ${HERE}/watcomc.zip
echo PATH to watcom binaries is 'c:/devel/watcomc/binw'
)

View File

@ -1,52 +0,0 @@
#! /bin/bash
KVER=8632
if [ ! -f _output/gcc/KGC${KVER}.sys ] ; then
echo GCC built kernel not present
exit 1
fi
if [ ! -f _output/wc/KWC${KVER}.sys ] ; then
echo Watcom built kernel not present
exit 1
fi
if [ ! -f _output/wc_dos/KWC38632.sys ] ; then
echo Watcom DOS built kernel not present
exit 1
fi
if [ ! -f _output/tc_dos/KTC38632.sys ] && [ -d ${HOME}/.dosemu/drive_c/tc201 ] ; then
echo Turbo C 2.01 built kernel not present
exit 1
fi
echo Kernels have all been built
find _output -ls
cd test
if ! ./test.sh ../_output/gcc/KGC${KVER}.sys diskgc bootgc 'boot gcc: '
then
echo GCC boot test failed
exit 2
fi
if ! ./test.sh ../_output/wc/KWC${KVER}.sys diskwc bootwc 'boot wc: '
then
echo OpenWatcom boot test failed
exit 2
fi
if ! ./test.sh ../_output/wc_dos/KWC38632.sys diskwcd bootwcd 'boot wcd: '
then
echo 'OpenWatcom(DOS) boot test failed'
exit 2
fi
if [ -d ${HOME}/.dosemu/drive_c/tc201 ] ; then
if ! ./test.sh ../_output/tc_dos/KTC38632.sys disktcd boottcd 'boot tcd: '
then
echo 'Turbo C 2.01 boot test failed'
exit 2
fi
fi
cd ..
exit 0

View File

@ -27,9 +27,6 @@ cd ..\sys
cd ..\kernel
%MAKE% clean
cd ..\setver
%MAKE% clean
cd ..\hdr
if exist *.bak del *.bak

View File

@ -27,20 +27,12 @@ cd ..\sys
cd ..\kernel
%MAKE% clobber
cd ..\setver
%MAKE% clobber
cd ..\hdr
if exist *.bak del *.bak
cd ..\bin
if exist sys.com del sys.com
if exist country.sys del country.sys
cd ..
if exist *.bak del *.bak
if exist status.me del status.me
:end
default.bat clearset

View File

@ -19,41 +19,35 @@
:-**********************************************************************
:-- define NASM executable - remember - it should not be protected
:- mode DJGPP version if you're using Windows NT/2k/XP to compile
:- because DJGPP-nasm crashes when using protected mode Borland's
:- make under Windows NT/2k/XP
:- also: DJGPP-nasm crashes when using protected mode Borland's make
:-**********************************************************************
set XNASM=nasm
set XNASM=c:\bin\nasm16
:**********************************************************************
:- define your COMPILER type here, pick one of them
:**********************************************************************
:- Turbo C 2.01
:- set COMPILER=TC2
set COMPILER=TC2
:- Turbo C++ 1.01
:- set COMPILER=TURBOCPP
:- Turbo C 3.0
:- set COMPILER=TC3
:- Borland C 3.1
set COMPILER=BC3
:- Borland C
:- set COMPILER=BC5
:- Microsoft C
:- set COMPILER=MSCL8
:- Watcom C (for DOS)
:- Watcom C
:- set COMPILER=WATCOM
:- Watcom C (for Windows)
:- set COMPILER=OWWIN
:-**********************************************************************
:-- where is the BASE dir of your compiler(s) ??
:-**********************************************************************
:- set TC2_BASE=c:\tc201
set TC2_BASE=c:\tc201
:- set TP1_BASE=c:\tcpp
:- set TC3_BASE=c:\tc3
set BC3_BASE=c:\bc
:- set BC5_BASE=c:\bc5
:- set MS_BASE=c:\msvc
@ -62,7 +56,6 @@ set BC3_BASE=c:\bc
:- if not \%WATCOM% == \ goto watcom_defined
:- set WATCOM=c:\watcom
:- set PATH=%PATH%;%WATCOM%\binw
:- set DOS4G=QUIET
:watcom_defined
:-**********************************************************************
@ -108,12 +101,12 @@ set XUPX=upx --8086 --best
:* select your default target: required CPU and what FAT system to support
:**********************************************************************
:- set XCPU=86
set XCPU=86
:- set XCPU=186
set XCPU=386
:- set XCPU=386
:- set XFAT=16
set XFAT=32
set XFAT=16
:- set XFAT=32
:- Give extra compiler DEFINE flags here
:- such as -DDEBUG : extra DEBUG output

View File

@ -52,12 +52,12 @@ XUPX=upx --8086 --best
# select your default target: required CPU and what FAT system to support
#*********************************************************************
# XCPU=86
XCPU=86
# XCPU=186
XCPU=386
# XCPU=386
# XFAT=16
XFAT=32
XFAT=16
# XFAT=32
# Give extra compiler DEFINE flags here
# such as -DDEBUG : extra DEBUG output

@ -1 +0,0 @@
Subproject commit 13587a32d6fda6cf1a1ce9bd9c3da7d3ae5a8dd5

View File

@ -23,10 +23,8 @@ 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%" == "BC3" set MAKE=%BC3_BASE%\bin\make
if "%COMPILER%" == "BC5" set MAKE=%BC5_BASE%\bin\make
if "%COMPILER%" == "WATCOM" set MAKE=wmake /ms /h
if "%COMPILER%" == "OWWIN" set MAKE=wmake /ms /h
if "%COMPILER%" == "MSCL8" set MAKE=%MS_BASE%\bin\nmake /nologo
echo Make is %MAKE%.
@ -40,10 +38,8 @@ 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%" == "BC3" set XLINK=%BC3_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%" == "OWWIN" set XLINK=..\utils\wlinker /ma/nologo
if "%COMPILER%" == "MSCL8" set XLINK=%MS_BASE%\bin\link /ONERROR:NOEXE /ma /nologo
echo Linker is %XLINK%.
@ -75,12 +71,10 @@ set XLINK=
set TC2_BASE=
set TP1_BASE=
set TC3_BASE=
set BC3_BASE=
set BC5_BASE=
set MS_BASE=
set XNASM=
set NASMFLAGS=
set NASMBOOTFLAGS=
set XUPX=
set UPXOPT=
set LOADSEG=

View File

@ -1 +0,0 @@
kernel.fdos.org

View File

@ -1,4 +0,0 @@
theme: jekyll-theme-tactile
title: "FreeDOS kernel"
description: "Implementation of the core DOS API for FreeDOS, kernel.sys"
show_downloads: "true"

View File

@ -15,11 +15,6 @@ kernel come out, you can extract them over your previous source, and
not have to worry about resetting up your configuration because your
CONFIG.BAT file will not get replaced!
For example to build your custom branded kernel for 386+ with FAT32
support using OpenWatcom compilers use a command such as:
BUILD.BAT 386 ow fat32 upx /D CUSTOM_BRANDING /V "MyDOS"
Building on Linux:
==================
@ -38,16 +33,6 @@ make clean
- to clobber (delete everything that was generated):
make clobber
You can now also cross compile with T.K. Chia's fork of ia16-elf-gcc,
which is available at https://github.com/tkchia/gcc-ia16, using
make all COMPILER=gcc
or by setting COMPILER=gcc in config.mak. If you are using Ubuntu
Linux 20.04 LTS (Focal Fossa), 18.04 (Bionic Beaver), or 16.04 LTS
(Xenial Xerus), there are precompiled ia16-elf-gcc packages at
https://launchpad.net/~tkchia/+archive/ubuntu/build-ia16/.
Otherwise, for now ia16-elf-gcc needs to be compiled from source.
Only releases 20180708 and later are supported.
Notes:
======
The recommended compiler and assembler at the time of writing (2009/05/19)

View File

@ -305,12 +305,8 @@ Example: switchar=-
SWITCHES
Usage: switches=/E[:xxx] /F /K /N /W
Adjusts boot time processing behaviour.
/E specifies how to handle moving of EBDA (Extended BIOS Data Area),
if a size in bytes is specified [xxx, in range of 48-1024]
then the EBDA will be moved from the top of conventional memory
to a lower address (allowing for potentially larger free block
of conventional memory if video memory at A0000 is available).
without a size, the EBDA will not be moved
/E enables moving of EBDA (Extended BIOS Data Area), optionally a
size in kilobytes may be specified [xxx, in range of 48-1024]
/F skips the delay checking for F5/F8 keystroke before processing
config.sys [equivalent to SYS CONFIG skipconfigseconds=0]
F5 and F8 are only processed if pressed before DOS boots but
@ -320,14 +316,9 @@ Adjusts boot time processing behaviour.
handling for 102/105 key keyboards.
/N disables F5/F8 support [equivalent to kernel config (SYS CONFIG,
run SYS CONFIG /? for explanations) skipconfigseconds=-1]
F5 (skip config) and F8 (single step config.sys) key presses
are ignored (note: with /F a well timed F5/F8 still works, whereas
/N completely disables).
F5 (skip config) and F8 (single step config.sys) are ignored.
/W is NOT supported in FreeDOS. This option in MS DOS would set a flag
for Windows 3.0 to skip loading wina20.386 from the root directory,
used when \WINA20.386 is moved into a subdirectory, a device line
with proper path must be added to Microsoft (R) Windows SYSTEM.INI
[386Enhanced] section. --- may be ignored for compatibility
for Windows 3.0 to skip loading wina20.386 from the root directory.
VERSION
Usage: version=x.y

View File

@ -31,7 +31,6 @@ Michal Bakowski (mb@orad.pl)
Ron Cemer (roncemer@gte.net)
"ror4" (ror4@angelfire.com)
Rune Espeseth (re@icd.no)
sava (lpproj@gmail.com)
Steffen Kaiser (Steffen.Kaiser@fh-rhein-sieg.de)
Steve Miller (SMiller@dsfx.com)
Tom Ehlert (te@drivesnapshot.de)

View File

@ -1,15 +1,13 @@
Begin3
Title: The FreeDOS Kernel
Version: git
Version: SVN
Entered-date: N/A
Description: The FreeDOS Kernel
Keywords: kernel, FreeDOS, DOS, MSDOS
Author: (developers: can be reached on the freedos-kernel mailing list)
Maintained-by: freedos-kernel@lists.sourceforge.net
Primary-site: http://github.com/fdos/kernel
Alternate-site: http://www.fdos.org/kernel/
Alternate-site: http://freedos.sourceforge.net/kernel/
Primary-site: http://freedos.sourceforge.net/kernel/
Original-site: http://www.gcfl.net/pub/FreeDOS/kernel
Platforms: DOS, FreeDOS, DOSEMU (OpenWatcom/Borland/GCC-ia16, NASM, UPX)
Platforms: DOS, FreeDOS, DOSEMU (OpenWatcom C or Turbo C, NASM, optionally UPX)
Copying-policy: GPL2
End

View File

@ -10,144 +10,6 @@ http://freedos.svn.sf.net/viewvc/freedos?view=rev&sortby=rev&revision=NUMBER
Changelog items can list SVN revision rNUMBER and bugzilla bug NUMBER.
2023 ?? - Build 2045
-------- Jeremy Davis
+ Changes Jeremy Davis and Tom Ehlert
* initial GPT partition support
2023 December 2? - Build 2044
-------- Jeremy Davis
+ Changes Jeremy Davis, Andrew Bird, Tee-Kiah Chia (tkchia), Sava (lpproj),
Stas Sergeev (stsp), C. Masloch, Jiri Malak, Bernd Böckmann
* support determining kernel file version without booting it
* only print messages once, not each time processing partitions
* fix for Format GitHub issue #1 - format divide by 0 due to kernel function 440D, subfunction 60 returning a zero for logical_sectors_per_fat as initdisk overflows and calculates incorrect value
* From bzt, initialize drive parameter head & sector values to avoid potential divisions by 0
* config: allow to delete variable with empty SET command
* truename: fix array overrun (pick from fdpp)
* main: insure master environment starts out empty
* config: make sure word marker trailing in environment is zero
* inthndlr: align hma size to para
* DosGetExtFree: Use new redirector function 11a3
* sys: detect small FAT32 as FAT32 (zero in word SPF)
* boot: enable loading from file systems with 256 sectors per cluster
* fatfs.c: allow bpbSectorsPerCluster == 0 to mean 256
* FCB (int 21h func 29h): should not accept field separator as "drive letter"
* FCB (int 21h func 29h): should keep parsing name even if drive letter invalid
* exeflat: update usage screen with -E, -D, and -U switches
* upxentry, upxdevic: add header comments
* exeflat: improve compressed stub handling, fixes, update documentation, various other updates
* kernel: optimise A20 check and enable/disable calls
* improve/fix gcc and OpenWatcom build support
* task: return Invalid format on empty executable (fixes #70)
* fdkrncfg: bugfix, version info check should not include signature
* fix 2nd parameter of "DOS=" statement in config.sys does not take effect in some cases:
* dosfns, int2f: make SHARE uninstallable
* CI: improvements
* Fix incorrect date format for Czech and Slovak Republic. Both Countries use DD.MM.YYYY date format. Microsoft DOS also use this format.
* dosfns: Check share table before delete/rename
* various build updates and move share and country to submodules
* FCB: Rename should support asterisk wildcards - based on dosemu fdpp, fixes issue #43
* add tests for FCB rename - based on tests from andrewbird
* allow opening a character device prefixed with invalid drive letter (e.g. "@:NUL") but not with invalid path
* add test for opening character devices (all pass on DOS 5,6, NT VDM, @:dev fail currently on FD kernel)
* initial implementation of extended seek (0x7142 - LONG LSEEK with 64-bit file position)
* add implementation of int 0x2F function 0x1f build CDS from dosemu2/fdpp
* add skeleton for LFN API, includes 0x71a6 implementation (call to redirector only) from dosemu2/fdpp
* ensure offset to critical patch tables doesn't change
* From Tom Ehlert: don't split disk transfers crossing DMA boundary if BIOS indicates can handle transparently
* fcbfns: Fix for FcbFindFirstNext [fixes #40]
* task: don't zero parent_psp on 0x26
* boot, oemboot: fix to abort properly on file not found
* oemboot: optimise FAT12 entry loading (picked from lDOS boot)
* adjust padding to be same as in PC-DOS (90h/nop)
* from RBIL int 21h/4400h (table 01423) add definition for bit 11 if SFT is not for a device (for a file) - media not removable, currently unused
* from dosemu2/fdpp - zero out critical patch list Personal NetWare Server really writes to these addresses, so putting 0x0d0c the way DOS does, is not safe.
* int 21h/4400h only return low byte of SFT flags if not a device, part of dosemu2/fdpp bug #147 fix
* check for unsupported function call in console - from dosemu2/fdpp bug# 101 fix
* improve support for Windows 3 Enhanced mode
2021 May 13 - Build 2043
-------- Jeremy Davis
+ Changes Bart Oldeman, Jeremy Davis, Andrew Bird, Tee-Kiah Chia (tkchia), Sava (lpproj),
Stas Sergeev (stsp), C. Masloch, Jiri Malak, Piotr Durlej, Ricardo Hanke
* update for releases using git instead of svn
* Update README.md
* add support for building with ia16-elf-gcc, including multiple updates/fixes
* SYS: Reduce verbosity when the verbose flag is not set
* add safety check to FAT12/16 boot sector to warn about breaking sys if boot code updated
* Implement version table support for int21/ah=4b, subfunctions 0 and 1
* CI: Add Github Action to automatically build and minimal test kernel on commit
* FATFS: rmdir of read only directories is valid
* boot: allow instsect to match the filesystem ID string
* boot: fix Int10.0E expected not to alter al (SBC188)
* Fix Func 2Dh (Set System Time) sets wrong time
* Fix func 0Bh (Get STDIN Status) always returns AL=FFh with some alternative CON drivers:
* Fix Func 30h (Get DOS Version) return version 0.0 in config.sys
* int2f: fix call interface around syscall_MUX14( ) (inthndlr.c)
* int2f: fix call interface around int2F_12_handler( )
* int2f: Allow 1217h function to return new CDS entry
* from Mondgestein, Function 30h (Get DOS Version): Get DOS version from PSP
* Fix func 36h (Get free disk space) fails in some redirectors:
* dosfns.c: only copy to current_ldt if pointer is valid
* inthndlr.c: in Int21.43FF, dispatch DosMkRmdir on CL not AH
* EXEC (func 0x4b): fix: do not crash if exMinAlloc == 0xffff
* FCB: Rename return value lost
* Fix division for some large numbers such as 0xFFFF01FF/0x10101FF
* Fix comments (Gerd Grosse, https://sourceforge.net/p/freedos/bugs/106/)
* FCB: Rename return value lost
* Fix compilation with TC2 and MSVC 1.52c.
* disk: fix sectors count truncation for CHS [fixes #10]
* implement CHAIN directive for config.sys
* add some initial (minimal) tests
* Fix memory break in NUL device
* Fix initial DTA
* Implement Int 2F/AX=120Bh based on RBIL description
* Implement Int 2F/AX=120Ah based on RBIL description - untested!
* From Evelyn, CPU unsupported message missing loading error msg address (pop si)
* Copy FCB-format filename from PriPathName (some redirectors require FCB-format filename stored in SDA+22Bh DirEntBuffer)
* Fix an error at opening a character device prefixed with invalid drive letter (e.g. "@:NUL") (some application use it for opening character device driver)
* Fix incompletion on loading huge (more than 65280 bytes) binary device driver
* On creating child PSP (func 0x55), copy command line parameters from the parent (required for some device loaders)
* Improve support for older BPB based volumes lacking extended fields. (Based on lpproj's nec98:Fix for DOS 3.x partitions)
2016 May 16 - Build 2042
-------- Jeremy Davis, Sava
+ Changes Jeremy
* support determining kernel file version without booting it
* from Christian Masloch, display error on unsupported CPU
* improve memdisk CONFIG.SYS processing support
* ensure top of RAM correctly adjusted after moving EBDA
* fix reading from NULL
* merge creation date & time from old dev branch
* use absolute not relative disk read/writes
(allows syslinux DOS installer to work correctly)
* Fix FCB parse filename (int21h func 29h)
* Improve support for older BPB based volumes lacking extended fields.
(Based on lpproj's nec98:Fix for DOS 3.x partitions)
* Int 2F/AX=120Ah & AX=120Bh based on RBIL, untested
+ Changes Sava (lpproj)
* add cross-compile capability on Windows with OW and mingw32-make
* Fix pointer of DBCS table (int 0x21, func 0x6300)
* Enable to load DBCS table from COUNTRY.SYS
* Return current country code (func 0x38)
* Fix broken decompression on loading FAT16 kernel (compressed in dos/sys)
* On creating child PSP (func 0x55), copy command line parameters
from the parent (required for some device loaders)
* Fix incomplete loading of huge (more than 65280 bytes) binary device driver
* Fix an error at opening a character device prefixed with invalid
drive letter (e.g. "@:NUL")
* Copy FCB-format filename from PriPathName (some redirectors require
FCB-format filename stored in SDA+22Bh DirEntBuffer)
2012 Feb 07 - Build 2041
-------- Jeremy Davis

View File

@ -1,37 +0,0 @@
INTRODUCTION
------------
The release archives contains the current FreeDOS Kernel, also
known as DOS-C, originally written by Pasquale J. Villani.
The FreeDOS Kernel is available from https://github.com/FDOS/kernel/
(formally http://freedos.sourceforge.net/ ).
It's also available from http://www.dosemu.org/ (somewhere on there).
The FreeDOS Kernel is also available through the FreeDOS Project at
http://www.freedos.org/
See the DOCS directory for more documentation and information about
the FreeDOS Kernel.
Contents of zip files:
* [ke20xx_f16.zip](https://github.com/FDOS/kernel/releases/download/ke2043/ke2043_86f16.zip) : binaries for 8086, FAT12 and FAT16 only
* [ke20xx_f32.zip](https://github.com/FDOS/kernel/releases/download/ke2043/ke2043_86f32.zip) : binaries for 8086, FAT12, FAT16, and FAT32
* [ke20xxs.zip](https://github.com/FDOS/kernel/releases/download/ke2043/ke2043s.zip) : sources for the kernel
BUG REPORTS
-----------
If you have found a bug, think you have found a bug, or would just
like to make a suggestion, go to the bug tracking web page at
https://github.com/FDOS/kernel/issues
(Previously at http://sourceforge.net/tracker/?group_id=5109&atid=105109, and
even earlier archive of old (Bugzilla) items is at www.freedos.org/bugzilla/ )
Copyright
---------
DOS-C is (c) Copyright 1995, 1996 by Pasquale J. Villani
All Rights Reserved.

View File

@ -1,94 +0,0 @@
FreeDOS kernel with memdisk support compiled in:
When enabled one can supplement (or replace) CONFIG.SYS from the memdisk
command line. The kernel upon booting will verify running on a 386+ and
then check for memdisk using int 13h call with magic values. If found
then the memdisk command line is processed and simulated CONFIG.SYS lines
are evaluated left to right as though they logically followed the last
line in CONFIG.SYS (or FDCONFIG.SYS).
Example syslinux.cfg section:
LABEL FreeDOS
KERNEL memdisk
MENU LABEL FreeDOS example
INITRD FDSTD.img
APPEND {ECHO Booting FreeDOS}{ECHO This is the second line.}
FreeDOS config lines are denoted by surrounding the line in curly braces {}
thus allowing multiple simulated lines on a single APPEND line. However,
the closing brace } may be omitted if it would be immediately followed by
an opening brace { or end of the APPEND line. Anything on the memdisk line
outside of the curly braces {} is ignored. The lines may be preceeded by
FD= to be compatible with earlier FD kernel release or any other key= to
specify the environment variable generated by getargs utility. All simulated
config lines (text between the { and }) are evaluated by the kernel asis
except the final line (the line within final {}).
The final } is optional which results in the memdisk options initrd= and
BOOT_IMAGE= to appear as part of the config.sys line. To avoid issues
several memdisk options are ignored if after the last opening brace {.
Note that the syslinux/memdisk options are case sensitive. Currently
ignored options are: initrd, BOOT_IMAGE, floppy, harddisk, and iso.
Additionally, to simplify passing and overriding arguments when syslinux
is booting, any key=value pairs seen after any memdisk options will cause
all corresponding key=??? prior to any memdisk options to be cleared on
the resulting config line.
For example if the final assembled memdisk line appears to the kernel as:
{ECHO HI{ECHO X=1 X=2 Y=1 Z=1 initrd=FDSTD10.img BOOT_IMAGE=memdisk X=386
then the following two lines will evaluated by the kernel after processing
any CONFIG.SYS lines.
ECHO HI
ECHO Y=1 Z=1 X=386
The following APPEND lines are all treated identically by the kernel.
APPEND floppy FD={ECHO Welcome}{ECHO 2nd line}{ECHO third}
APPEND floppy FD={ECHO Welcome{ECHO 2nd line{ECHO third
APPEND {ECHO Welcome} {ECHO 2nd line} {ECHO third} floppy
APPEND {ECHO Welcome{Echo 2nd line} {ECHO third floppy
resulting in the following equivalent three CONFIG.SYS lines
ECHO Welcome
ECHO 2nd line
ECHO third
The following complete example syslinux.cfg and FreeDOS configuration files
could be used to boot various kernel options avoiding the use of the FreeDOS
kernel menu in addition to the Sylinux menu.
# CONFIG.SYS
REM always executed, in common with all choices
FILES=20
LASTDRIVE=Z
SHELLHIGH=\COMMAND.COM /E:256 /P
#AUTOEXEC.BAT
@ECHO OFF
CLS
ECHO Welcome to FreeDOS (http://www.freedos.org)!
ECHO User selected menu %CONFIG%
# SYSLINUX.CFG
UI vesamenu.c32
DEFAULT clean
LABEL clean
MENU LABEL FreeDOS with no drivers
KERNEL memdisk
INITRD /fdos0360.img
APPEND floppy FD={SET config=0}
LABEL jemm
MENU LABEL FreeDOS with memory manager
KERNEL memdisk
INITRD /fdos0360.img
APPEND floppy FD={SET config=1}{DEVICE?=JEMMEX.EXE
Syslinux boot-prompt (when vesamenu not used):
jemm
or
jemm NOEMS

View File

@ -13,7 +13,7 @@ http://www.freedos.org/
See the DOCS directory for more documentation and information about
the FreeDOS Kernel.
Contents of release zip files:
Contents of zip files:
ke20xx_16.zip : binaries for 8086, FAT16
ke20xx_32.zip : binaries for 8086, FAT16, FAT32
ke20xxsrc.zip : sources for the kernel
@ -22,22 +22,17 @@ BUG REPORTS
-----------
If you have found a bug, think you have found a bug, or would just
like to make a suggestion or feature request, then add an issue to
the kernel's GitHub site:
https://github.com/FDOS/kernel/issues
Note: bugs (or feature requests) reported at the old bug tracking
web page http://sourceforge.net/tracker/?group_id=5109&atid=105109
and http://sourceforge.net/tracker/?atid=355109&group_id=5109&func=browse
will still be reviewed, but not actively.
like to make a suggestion, go to the bug tracking web page at
http://sourceforge.net/tracker/?group_id=5109&atid=105109
An archive of old (Bugzilla) items is at www.freedos.org/bugzilla/
There is also a feature request tracker on our SourceForge pages at
http://sourceforge.net/tracker/?atid=355109&group_id=5109&func=browse
Copyright
---------
DOS-C is (c) Copyright 1995, 1996 by Pasquale J. Villani
All Rights Reserved.
Portions of FreeDOS kernel copyright others, 199?-2021

View File

@ -1,4 +1,4 @@
FreeDOS System Installer v3.6f - Nov 20, 2024
FreeDOS System Installer v3.6e - Nov 13, 2009
documentation by:
Jeremy Davis
Bart Oldeman
@ -23,18 +23,12 @@ Usage: SYS [source] drive: [bootsect] [{option}]
/BOOTONLY: do *not* copy kernel / shell, only update boot sector or image
/UPDATE : copy kernel and update boot sector (do *not* copy shell)
/OEM : indicates boot sector, filenames, and load segment to use
/OEM:FD FreeDOS settings
/OEM:EDR Enhanced DR-DOS (DRBIO.SYS and DRDOS.SYS)
/OEM:LEDRPACK Enhanced DR-DOS (EDRPACK.SYS, lDOS drload)
/OEM:LEDR Enhanced DR-DOS (EDRDOS.COM, lDOS iniload)
/OEM:LMSPACK OSS MS-DOS (LMSPACK.SYS, lDOS drload)
/OEM:LMS OSS MS-DOS (LMSDOS.COM, lDOS iniload)
/OEM:OPENDOS Caldera OpenDOS 7.01 (and Novell DOS 7),
DR-DOS 7.02 - 7.03, 7.01.01 - 7.01.06
/OEM:PC PC-DOS, DR DOS 5 - Novell DOS 7
/OEM:MS MS-DOS
/OEM:W9x MS Win9x DOS
default is /OEM[:AUTO], select DOS based on existing files
/OEM:FD use FreeDOS compatible settings
/OEM:DR use DR DOS 7+ compatible settings (same as /OEM)
/OEM:PC use PC-DOS compatible settings
/OEM:MS use MS-DOS compatible settings
/OEM:W9x use MS Win9x DOS compatible settings
default is /OEM:AUTO, select DOS based on existing files
/K name : name of kernel to use in boot sector instead of KERNEL.SYS
/L segm : hex load segment to use in boot sector instead of 0x60
/B btdrv : hex BIOS # of boot drive set in bs, 0=A:, 80=1st hd,...
@ -108,12 +102,6 @@ even 1st floppy drive attempts to use LBA support
(note that CHS may still be used if LBA check fails)
and /FORCE:CHS will always bypass use of LBA extensions.
SYS by default installs the FreeDOS kernel KERNEL.SYS.
If KERNEL.SYS is not found, it may install a different
kernel, like an Enhanced DR-DOS kernel, provided it
finds one. You may explicitly tell SYS which kernel
flavour to install via the /OEM argument.
Kernel Configuration Options:

View File

@ -29,7 +29,6 @@
;
%include "../kernel/segs.inc"
%include "../hdr/stacks.inc"
segment HMA_TEXT
;
@ -113,8 +112,7 @@ fl_common:
push bp ; setup stack frame
mov bp,sp
arg drive, head, track, sector, count, {buffer,4}
mov cx,[.track] ; cylinder number
mov cx,[bp+0Ch] ; cylinder number
mov al,1 ; this should be an error code
cmp ch,3 ; this code can't write above 3FFh=1023
@ -123,13 +121,13 @@ arg drive, head, track, sector, count, {buffer,4}
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,[.sector] ; or in the sector number (bits 0-5)
or cl,[bp+0Ah] ; or in the sector number (bits 0-5)
mov al,[.count] ; count of sectors to read/write/...
les bx,[.buffer] ; Load 32 bit buffer ptr into ES:BX
mov al,[bp+08h] ; count of sectors to read/write/...
les bx,[bp+04h] ; Load 32 bit buffer ptr into ES:BX
mov dl,[.drive] ; drive (if or'ed 80h its a hard drive)
mov dh,[.head] ; get the head number
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
@ -154,10 +152,9 @@ FL_LBA_READWRITE:
push ds
push si ; wasn't in kernel < KE2024Bo6!!
arg drive, mode, {dap_p,4}
mov dl,[.drive] ; drive (if or'ed with 80h a hard drive)
mov ax,[.mode] ; get the command
lds si,[.dap_p] ; get far dap pointer
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
@ -185,7 +182,8 @@ FL_READKEY: xor ah, ah
global FL_SETDISKTYPE
FL_SETDISKTYPE:
pop bx ; return address
popargs dx,ax ; drive number(dl),disk format type(al)
pop ax ; disk format type (al)
pop dx ; drive number (dl)
push bx ; restore stack
mov ah,17h ; floppy set disk type for format
int 13h
@ -200,7 +198,9 @@ ret_AH:
global FL_SETMEDIATYPE
FL_SETMEDIATYPE:
pop ax ; return address
popargs dx,cx,bx ; drive number,#tracks,sectors/track
pop bx ; sectors/track
pop cx ; number of tracks
pop dx ; drive number
push ax ; restore stack
push di

View File

@ -24,7 +24,7 @@
OBJS = floppy.obj rdpcclk.obj wrpcclk.obj wratclk.obj
LIBOBJS= $(LIBPLUS)floppy.obj $(LIBPLUS)rdpcclk.obj $(LIBPLUS)wrpcclk.obj $(LIBPLUS)wratclk.obj
LIBOBJS= +floppy.obj +rdpcclk.obj +wrpcclk.obj +wratclk.obj
@ -45,5 +45,5 @@ clean:
device.lib : $(OBJS)
-$(RM) device.lib
$(LIBUTIL) $(LIBFLAGS) device.lib $(LIBOBJS) $(LIBTERM)
$(LIBUTIL) $(LIBFLAGS) device $(LIBOBJS) $(LIBTERM)

View File

@ -29,7 +29,6 @@
;
%include "../kernel/segs.inc"
%include "../hdr/stacks.inc"
segment HMA_TEXT
@ -48,14 +47,13 @@ WRITEATCLOCK:
; bcdMinutes = 6
; bcdHours = 8
; bcdDays = 10
arg bcdDays, bcdHours, bcdMinutes, bcdSeconds
mov ch,byte [.bcdHours]
mov cl,byte [.bcdMinutes]
mov dh,byte [.bcdSeconds]
mov ch,byte [bp+8] ;bcdHours
mov cl,byte [bp+6] ;bcdMinutes
mov dh,byte [bp+4] ;bcdSeconds
mov dl,0
mov ah,3
int 1ah
mov bx,word [.bcdDays]
mov bx,word [bp+10] ;bcdDays
mov dx,word [bx]
mov cx,word [bx+2]
mov ah,5

View File

@ -28,7 +28,6 @@
; $Header$
;
%include "../kernel/segs.inc"
%include "../hdr/stacks.inc"
segment HMA_TEXT
@ -41,7 +40,8 @@ segment HMA_TEXT
WRITEPCCLOCK:
; Ticks = 4
pop ax ; return address
popargs {cx,dx} ; Ticks
pop dx
pop cx ; Ticks
push ax ; restore stack
mov ah,1
int 1ah

View File

@ -34,11 +34,10 @@
*/*/hdr/buffer.h
*/*/hdr/cds.h
*/*/hdr/clock.h
*/*/hdr/date.h
*/*/hdr/dcb.h
*/*/hdr/ddate.h
*/*/hdr/device.h
*/*/hdr/dirmatch.h
*/*/hdr/dtime.h
*/*/hdr/error.h
*/*/hdr/exe.h
*/*/hdr/fat.h
@ -57,6 +56,7 @@
*/*/hdr/sft.h
*/*/hdr/stacks.inc
*/*/hdr/tail.h
*/*/hdr/time.h
*/*/hdr/version.h
*/*/hdr/xstructs.h
*/*/kernel/nls/001-437.hc

View File

@ -1,6 +1,6 @@
/****************************************************************/
/* */
/* ddate.h */
/* date.h */
/* */
/* DOS General Date Structure */
/* */
@ -51,7 +51,7 @@ static BYTE *date_hRcsId =
#define EPOCH_DAY 1 /* 1 for January 1 */
#define EPOCH_YEAR 1980 /* for Tues 1-1-80 epoch */
typedef UWORD ddate;
typedef UWORD date;
#endif

View File

@ -152,13 +152,13 @@ typedef struct {
UWORD bpb_nreserved; /* # Reserved Sectors */
UBYTE bpb_nfat; /* # FATs */
UWORD bpb_ndirent; /* # Root Directory entries */
UWORD bpb_nsize; /* Total volume Size in sectors */
UWORD bpb_nsize; /* Size in sectors */
UBYTE bpb_mdesc; /* MEDIA Descriptor Byte */
UWORD bpb_nfsect; /* FAT size in sectors */
UWORD bpb_nsecs; /* Sectors per track */
UWORD bpb_nheads; /* Number of heads */
ULONG bpb_hidden; /* Hidden sectors */
ULONG bpb_huge; /* Total volume Size in sectors if*/
ULONG bpb_huge; /* Size in sectors if */
/* bpb_nsize == 0 */
#ifdef WITHFAT32
ULONG bpb_xnfsect; /* FAT size in sectors if */
@ -253,7 +253,6 @@ typedef struct ddtstruct {
/* freedos specific flag bits */
#define DF_LBA 0x400
#define DF_WRTVERIFY 0x800
#define DF_DMA_TRANSPARENT 0x1000 /* DMA boundary errors are handled transparently */
/* typedef struct ddtstruct ddt;*/
@ -496,7 +495,7 @@ WORD ASMCFUNC FAR clk_driver(rqptr rp);
/* execrh.asm */
#if defined(__WATCOMC__) && _M_IX86 >= 300
WORD execrh(request FAR *, struct dhdr FAR *);
#pragma aux execrh "^" __parm __reverse __routine [] __modify [__ax __bx __cx __dx __es __fs __gs]
#pragma aux execrh "^" parm reverse routine [] modify [ax bx cx dx es fs gs]
#else
WORD ASMPASCAL execrh(request FAR *, struct dhdr FAR *);
#endif

View File

@ -47,8 +47,8 @@ typedef struct {
UWORD reserved2;
UBYTE dm_attr_fnd; /* found file attribute */
dtime dm_time; /* file time */
ddate dm_date; /* file date */
time dm_time; /* file time */
date dm_date; /* file date */
ULONG dm_size; /* file size */
BYTE dm_name[FNAME_SIZE + FEXT_SIZE + 2]; /* file name */
} dmatch;

View File

@ -105,8 +105,8 @@ struct dirent {
UWORD dir_crdate; /* Creation date */
UWORD dir_accdate; /* Last access date */
UWORD dir_start_high; /* High word of the cluster */
dtime dir_time; /* Time file created/updated */
ddate dir_date; /* Date file created/updated */
time dir_time; /* Time file created/updated */
date dir_date; /* Date file created/updated */
UWORD dir_start; /* Starting cluster */
/* 1st available = 2 */
ULONG dir_size; /* File size in bytes */

View File

@ -86,8 +86,8 @@ typedef struct {
UWORD fcb_recsiz; /* Logical record size in bytes, */
/* default = 128 */
ULONG fcb_fsize; /* File size in bytes */
ddate fcb_date; /* Date file created */
dtime fcb_time; /* Time of last write */
date fcb_date; /* Date file created */
time fcb_time; /* Time of last write */
/* the following are reserved by system */
BYTE fcb_sftno; /* Device ID */
BYTE fcb_attrib_hi; /* share info, dev attrib word hi */

View File

@ -58,10 +58,8 @@ static BYTE *file_hRcsId =
/* bits 2, 3 reserved */
/* bits 4, 5, 6 sharing modes */
/* see PC Mag Nov 15, 1988 "Networked Database" p234 by Frank J Derfler Jr */
#define O_SHAREMASK 0x0070 /* mask to isolate shared bits */
#define O_COMPAT 0x0000 /* default, compatibility mode */
#define O_DENYALL 0x0010 /* sharing bits */
#define O_DENYWRITE 0x0020 /* " " */
#define O_DENYREAD 0x0030 /* " " */

View File

@ -22,28 +22,6 @@
wait ## seconds
if no key hit, boot from HD
Version_: only in kernel 2042 or higher, offline version identification
OemID: 0xFD for FreeDOS kernel, 0xDC for DosC kernel
Major: actual kernel version (not MS-DOS compatibility version), e.g. 2
Revision: revision sequence, e.g. 42 for kernel 2042
Release: 0 if released version, >0 for svn builds (e.g. svn revision #)
CheckDebugger: during initialization enable/disable check to stop in debugger if one is active
0 = do not check (assume absent),
1 = do check by running breakpoint,
2 = assume present
Verbose: amount of messages to display during initialization
-1 = quiet
0 = normal
1 = verbose
PartitionMode: how to handle GPT and MBR partitions
bits 0-1: 01=GPT if found, 00=MBR if found, 11=Hybrid, GPT first then MBR, 10=Hybrid, MBR first then GPT
in hybrid mode, EE partitions ignored, drives assigned by GPT or MBR first based on hybrid type
bits 2-4: 001=mount ESP (usually FAT32) partition, 010=mount MS Basic partitions, 100=mount unknown partitions
111=attempt to mount all paritions, 110=attempt to mount all but ESP partitions
bits 5-7: reserved, 0 else undefined behavior
*/
typedef struct _KernelConfig {
char CONFIG[6]; /* "CONFIG" */
@ -55,15 +33,4 @@ typedef struct _KernelConfig {
unsigned char ForceLBA;
unsigned char GlobalEnableLBAsupport; /* = 0 --> disable LBA support */
signed char BootHarddiskSeconds;
/* for version 2042 and higher only */
unsigned char Version_OemID;
unsigned char Version_Major;
unsigned short Version_Revision;
unsigned short Version_Release;
/* for version 2044 and higher only */
unsigned char CheckDebugger;
signed char Verbose;
unsigned char PartitionMode;
} KernelConfig;

View File

@ -59,9 +59,6 @@
#define REM_PRINTREDIR 0x1125
#define REM_EXTOC 0x112e
/* Redirector extensions */
#define REM_GETLARGESPACE 0x11a3
struct rgds {
UWORD r_spc;
UWORD r_navc;

View File

@ -28,7 +28,7 @@
/****************************************************************/
/* one byte alignment */
#include "algnbyte.h"
#include <algnbyte.h>
/*
* Description of the organization of NLS information -- 2000/02/13 ska
@ -175,7 +175,7 @@
*
* Performance tweaks:
* When the system -- This word applies to the combination of kernel and
* any loaded MUX-14 extension <EFBFBD> la NLSFUNC here. -- uppercases
* any loaded MUX-14 extension á la NLSFUNC here. -- uppercases
* _filenames_, it must perform a DOS-65-A2 internally. In the basic
* implementation this request would be channeled through MUX-14, even
* if there is no external NLSFUNC at all. Also, when a NLS pkg had
@ -403,7 +403,7 @@ struct nlsExtCntryInfo {
0: 12 hours (append AM/PM)
1: 24 houres
*/
intvec upCaseFct; /* far call to a function upcasing the
VOID(FAR * upCaseFct) (VOID); /* far call to a function upcasing the
character in register AL */
char dataSep[2]; /* ASCIZ of separator in data records */
};
@ -430,16 +430,12 @@ struct nlsPackage { /* the contents of one chain item of the
UWORD yeschar; /* yes / no character DOS-65-23 */
UWORD nochar;
unsigned numSubfct; /* number of supported sub-functions */
struct nlsPointer nlsPointers[5]; /* may grow dynamically */
struct nlsExtCntryInfo nlsExt;
struct nlsPointer nlsPointers[1]; /* grows dynamically */
};
struct nlsDBCS { /* The internal structure is unknown to me */
UWORD numEntries;
UWORD dbcsTbl[4]; /* I don't know max size but it should need
at least 3 words (6 bytes)
({0x81,0x9f,0xe0,0xfc,0,0} for CP932-Japan)
-- lpproj 2014/10/27 */
UWORD dbcsTbl[1];
};
struct nlsCharTbl {
@ -474,23 +470,20 @@ struct nlsInfoBlock { /* This block contains all information
maybe tweaked by NLSFUNC */
UWORD sysCodePage; /* system code page */
unsigned flags; /* implementation flags */
#ifdef __GNUC__
/* need to initialize using explicit segment/offset */
union {
struct { struct nlsPackage *off; char *seg; };
struct nlsPackage FAR *p;
} actPkg, chain;
#define actPkg actPkg.p
#define chain chain.p
#else
struct nlsPackage FAR *actPkg; /* current NLS package */
struct nlsPackage FAR *chain; /* first item of info chain --
hardcoded U.S.A./CP437 */
#endif
};
extern struct nlsInfoBlock ASM nlsInfo;
extern struct nlsPackage DOSFAR ASM nlsPackageHardcoded;
extern struct nlsPackage FAR ASM nlsPackageHardcoded;
/* These are the "must have" tables within the hard coded NLS pkg */
extern struct nlsFnamTerm FAR ASM nlsFnameTermHardcoded;
extern struct nlsDBCS FAR ASM nlsDBCSHardcoded;
extern struct nlsCharTbl FAR ASM nlsUpcaseHardcoded;
extern struct nlsCharTbl FAR ASM nlsFUpcaseHardcoded;
extern struct nlsCharTbl FAR ASM nlsCollHardcoded;
extern struct nlsExtCntryInfo FAR ASM nlsCntryInfoHardcoded;
extern BYTE FAR hcTablesStart[], hcTablesEnd[];
/***********************************************************************
@ -623,7 +616,7 @@ struct nlsCSys_loadPackage {
};
/* standard alignment */
#include "algndflt.h"
#include <algndflt.h>
#ifdef DEBUG
/* Enable debugging of NLS part */

View File

@ -57,7 +57,7 @@ static BYTE *pcb_hRcsId =
#endif
/* Force one-byte alignment for all the internal structures, see above */
#include "algnbyte.h"
#include <algnbyte.h>
/* */
/* interrupt handler structure definition */
/* */
@ -87,6 +87,14 @@ typedef struct {
UWORD si, di, ds, es;
} lregs;
/* Registers directly passed to syscall;
must be the same order as iregs!
Is used to define parameters. */
#define DIRECT_IREGS \
xreg a, xreg b, xreg c, xreg d, \
UWORD si, UWORD di, UWORD bp, UWORD ds, UWORD es, \
UWORD ip, UWORD cs, UWORD flags
/* Process control block for task switching */
typedef struct {
UWORD pc_ss;
@ -158,7 +166,7 @@ typedef struct {
#define FLG_CARRY 0x0001
/* Allow default alignment from now on */
#include "algndflt.h"
#include <algndflt.h>
#endif

View File

@ -102,14 +102,12 @@ static unsigned short __inline getSS(void)
#elif defined(__WATCOMC__) /* don't know a better way */
#if defined(_M_I86)
#define I86
#define __int__(intno) asm int intno;
void disable(void);
#pragma aux disable = "cli" __modify __exact [];
#pragma aux disable = "cli" modify exact [];
void enable(void);
#pragma aux enable = "sti" __modify __exact [];
#pragma aux enable = "sti" modify exact [];
#define asm __asm
#define far __far
#define CDECL __cdecl
@ -117,22 +115,19 @@ void enable(void);
#define PASCAL pascal
#define _CS getCS()
unsigned short getCS(void);
#pragma aux getCS = "mov dx,cs" __value [__dx] __modify __exact[__dx];
#pragma aux getCS = "mov dx,cs" value [dx] modify exact[dx];
#define _SS getSS()
unsigned short getSS(void);
#pragma aux getSS = "mov dx,ss" __value [__dx] __modify __exact[__dx];
#pragma aux getSS = "mov dx,ss" value [dx] modify exact[dx];
#if !defined(FORSYS) && !defined(EXEFLAT) && _M_IX86 >= 300
#pragma aux __default __parm [__ax __dx __cx] __modify [__ax __dx __es __fs] /* min.unpacked size */
#pragma aux default parm [ax dx cx] modify [ax dx es fs] /* min.unpacked size */
#endif
/* enable Possible loss of precision warning for compatibility with Borland */
#pragma enable_message(130)
#else
/* workaround for building some utils with OpenWatcom (flat model) */
#define MC68K
#if _M_IX86 >= 300 || defined(M_I386)
#define I386
#endif
#elif defined (_MYMC68K_COMILER_)
@ -140,44 +135,8 @@ unsigned short getSS(void);
#define MC68K
#elif defined(__GNUC__)
#ifdef __FAR
#define I86
#define STRINGIFY(x) #x
#define __int__(intno) asm volatile(STRINGIFY(int $##intno))
static inline void disable(void)
{
asm volatile("cli");
}
static inline void enable(void)
{
asm volatile("sti");
}
#define far __far
#define CDECL __attribute__((cdecl))
#define VA_CDECL
#define PASCAL
#define _CS getCS()
static inline unsigned short getCS(void)
{
unsigned short ret;
asm volatile("mov %%cs, %0" : "=r"(ret));
return ret;
}
#define _SS getSS()
static inline unsigned short getSS(void)
{
unsigned short ret;
asm volatile("mov %%ss, %0" : "=r"(ret));
return ret;
}
extern char DosDataSeg[];
#else
/* for warnings only ! */
#define MC68K
#endif
#else
#error Unknown compiler
@ -186,15 +145,11 @@ We might even deal with a pre-ANSI compiler. This will certainly not compile.
#ifdef I86
#if _M_IX86 >= 300 || defined(M_I386)
#ifndef I386
#define I386
#endif
#elif _M_IX86 >= 100 || defined(M_I286)
#ifndef I186
#define I186
#endif
#endif
#endif
#ifdef MC68K
#define far /* No far type */
@ -215,12 +170,10 @@ We might even deal with a pre-ANSI compiler. This will certainly not compile.
typedef __SIZE_TYPE__ size_t;
#else
#define CONST
#if !(defined(_SIZE_T) || defined(_SIZE_T_DEFINED) || defined(__SIZE_T_DEFINED))
typedef unsigned size_t;
#endif
#endif
#endif
#if defined(I86) && !defined(MC68K)
#ifdef I86
#define VOID void
#define FAR far /* segment architecture */
#define NEAR near /* " " */
@ -237,16 +190,7 @@ typedef unsigned size_t;
as 'ASMCFUNC', and is (and will be ?-) cdecl */
#define ASMCFUNC CDECL
#define ASMPASCAL PASCAL
#if defined(__GNUC__)
#define ASM
#else
#define ASM ASMCFUNC
#endif
/* variables that can be near or far: redefined in init-dat.h */
#define DOSFAR
#define DOSTEXTFAR
/* */
/* Boolean type & definitions of TRUE and FALSE boolean values */
/* */
@ -298,7 +242,7 @@ typedef unsigned short CLUSTER;
#endif
typedef unsigned short UNICODE;
#if defined(STATICS) || defined(__WATCOMC__) || defined(__GNUC__)
#if defined(STATICS) || defined(__WATCOMC__)
#define STATIC static /* local calls inside module */
#else
#define STATIC
@ -316,13 +260,6 @@ typedef signed long LONG;
#define LONG long
#endif
#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))
@ -353,11 +290,7 @@ typedef signed long LONG;
#define FP_SEG(fp) ((unsigned)((ULONG)(VOID FAR *)(fp)>>16))
#endif
#if defined(__GNUC__) && defined(__BUILTIN_IA16_FP_OFF)
#define FP_OFF(fp) __builtin_ia16_FP_OFF(fp)
#else
#define FP_OFF(fp) ((unsigned)(fp))
#endif
#endif
#endif
@ -368,11 +301,7 @@ typedef signed long LONG;
#define FP_OFF(fp) ((size_t)(fp))
#endif
#if defined(__GNUC__) && defined(__FAR)
typedef VOID FAR *intvec;
#else
typedef VOID (FAR ASMCFUNC * intvec) (void);
#endif
#define MK_PTR(type,seg,ofs) ((type FAR*) MK_FP (seg, ofs))
#if __TURBOC__ > 0x202

View File

@ -67,7 +67,7 @@ typedef struct {
for compatiblity with CP/M apps that do a near call to psp:5
and expect size (KB) of allocated segment in word at offset 6 */
UBYTE ps_farcall; /* 05 far call opcode */
intvec ps_reentry; /* 06 re-entry point */
VOID(FAR ASMCFUNC * ps_reentry) (void); /* 06 re-entry point */
intvec ps_isv22, /* 0a terminate address */
ps_isv23, /* 0e ctrl-break address */
@ -79,10 +79,10 @@ typedef struct {
UWORD ps_maxfiles; /* 32 maximum open files */
UBYTE FAR *ps_filetab; /* 34 open file table pointer */
VOID FAR *ps_prevpsp; /* 38 previous psp pointer */
UBYTE ps_dbcs_inputmode; /* 3c unused,see int21/6301h/6302h */
UBYTE ps_truename; /* 3d unused,append truename flag int2f/B711h */
UBYTE ps_fill2; /* 3c unused */
UBYTE ps_truename; /* 3d [unused] append truename flag int2f/B711h */
UBYTE ps_netx_taskid[2]; /* 3e [Novell only field] task id */
UWORD ps_retdosver; /* 40 version to return on int21/30h, defaults to true version */
UWORD ps_retdosver; /* 40 [unused] version to return on int21/30h */
UWORD pdb_next; /* 42 [Win only field] PSP chain */
UBYTE ps_fill2b[4]; /* 44 unused, 4 bytes */
UBYTE ps_olddos; /* 48 [Win only field] DOS/Win program */

View File

@ -61,8 +61,8 @@ typedef struct {
#else
CLUSTER sft_stclust; /* 0b - Starting cluster */
#endif
dtime sft_time; /* 0d - File time */
ddate sft_date; /* 0f - File date */
time sft_time; /* 0d - File time */
date sft_date; /* 0f - File date */
ULONG sft_size; /* 11 - File size */
ULONG sft_posit; /* 15 - Current file position */
UWORD sft_relclust; /* 19 - File relative cluster (low part) */
@ -115,7 +115,6 @@ typedef struct sfttbl {
/* the following bits are file (block) unique */
#define SFT_FDATE 0x4000 /* File date set */
#define SFT_FFIXEDMEDIA 0x0800 /* File on non-removable media - unused */
#define SFT_FCLEAN 0x0040 /* File has not been written to */
#define SFT_FDMASK 0x003f /* File mask for drive no */

View File

@ -196,57 +196,3 @@ irp_hi equ 26
%endif
%ENDIF
; macros to define stack arguments
; arg a, {b,4}, c
; defines a and c as "word" arguments and b as a "dword" argument
; for STDCALL defines .a as [bp+4], .b as [bp+6] and .c as [bp+10]
; for PASCAL defines .a as [bp+10], .b as [bp+6] and .c as [bp+4]
;
; popargs bx, {dx,ax}, cx pops these arguments of the stack (for PASCAL
; in reverse order). Here dx,ax is a dword argument dx:ax where dx is
; the high word. The caller is responsible for dealing with instruction
; pointer (ip) on the stack.
%ifdef gcc
%define STDCALL
%else
%define PASCAL
%endif
%macro definearg 1-2 2
%xdefine .%1 bp+.argloc
%assign .argloc .argloc+%2
%endmacro
%macro arg 1-*
%assign .argloc 4
%rep %0
%ifdef PASCAL
%rotate -1
%endif
definearg %1
%ifdef STDCALL
%rotate 1
%endif
%endrep
%endmacro
%macro multipop 1-*
%rep %0
%rotate -1
pop %1
%endrep
%endmacro
%macro popargs 1-*
%rep %0
%ifdef PASCAL
%rotate -1
%endif
multipop %1
%ifdef STDCALL
%rotate 1
%endif
%endrep
%endmacro

View File

@ -1,6 +1,6 @@
/****************************************************************/
/* */
/* dtime.h */
/* time.h */
/* */
/* DOS General Time Structure */
/* */
@ -39,7 +39,7 @@ static BYTE *time_hRcsId =
#endif
#endif
typedef UWORD dtime;
typedef UWORD time;
struct dostime
{

View File

@ -36,12 +36,12 @@
#endif
/* The actual kernel revision, 2000+REVISION_SEQ = 2.REVISION_SEQ */
#define REVISION_SEQ 43 /* returned in BL by int 21 function 30 */
#define REVISION_SEQ 42 /* returned in BL by int 21 function 30 */
#define OEM_ID 0xfd /* FreeDOS, returned in BH by int 21 30 */
/* Used for version information displayed to user at boot (& stored in os_release string) */
#ifndef KERNEL_VERSION
#define KERNEL_VERSION "- GIT "
#define KERNEL_VERSION "- SVN "
#endif
/* actual version string */

View File

@ -18,12 +18,6 @@ struct WinStartupInfo
ULONG optInstanceTable; /* used only if winver set to 0x400 (w95)*/
};
extern struct WinStartupInfo winStartupInfo;
#if defined __GNUC__
extern UWORD winseg1, winseg2, winseg3;
extern UBYTE markEndInstanceData;
extern struct lol FAR ASM DATASTART;
#endif
/* contains a list of offsets relative to DOS data segment of
various internal variables.

View File

@ -48,7 +48,6 @@
%ifndef WATCOM_INIT
%include "segs.inc"
%include "stacks.inc"
%ifdef _INIT
@ -135,10 +134,9 @@ pascal_setup:
cld
mov bl,6 ; majority (4) wants that
arg arg1, arg2, arg3
mov cx,[.arg3] ; majority (8) wants that (near and far)
mov si,[.arg2] ; majority (3) wants that (near)
mov di,[.arg1] ; majority (3) wants that (near)
mov cx,[4+bp] ; majority (8) wants that (near and far)
mov si,[6+bp] ; majority (3) wants that (near)
mov di,[8+bp] ; majority (3) wants that (near)
jmp ax
@ -194,17 +192,14 @@ FMEMCPYBACK:
FMEMCPY:
call pascal_setup
arg {d,4}, {s,4}, n
; Get the repetition count, n preset above
%ifdef STDCALL
mov cx,[.n]
%endif
; mov cx,[bp+4]
; Get the far source pointer, s
lds si,[.s]
lds si,[bp+6]
; Get the far destination pointer d
les di,[.d]
les di,[bp+10]
mov bl,10
jmp short domemcpy
@ -217,17 +212,14 @@ arg {d,4}, {s,4}, n
FMEMSET:
call pascal_setup
arg {d,4}, ch, n
; Get the repetition count, n - preset above
%ifdef STDCALL
mov cx,[.n]
%endif
; mov cx,[bp+4]
; Get the fill byte ch
mov ax,[.ch]
mov ax,[bp+6]
; Get the far source pointer, s
les di,[.d]
les di,[bp+8]
mov bl,8
domemset:
@ -248,12 +240,11 @@ domemset:
MEMSET:
call pascal_setup
arg d, ch, n
; Get the repitition count, n - preset above
; mov cx,[bp+4]
; Get the char ch
mov ax, [.ch]
mov ax, [bp+6]
; Get the far source pointer, d - preset above
; mov di,[bp+8]
@ -286,20 +277,21 @@ pascal_return:
; fstrcpy (void FAR*dest, void FAR *src);
%ifndef _INIT
global FSTRCPY
FSTRCPY:
call pascal_setup
arg {dest,4}, {src,4}
; Get the source pointer, ss
lds si,[.src]
lds si,[bp+4]
; and the destination pointer, d
les di,[.dest]
les di,[bp+8]
mov bl,8
jmp short dostrcpy
%endif
;******
global STRCPY
@ -307,13 +299,11 @@ STRCPY:
call pascal_setup
%ifdef PASCAL
; Get the source pointer, ss
mov si,[bp+4]
; and the destination pointer, d
mov di,[bp+6]
%endif
mov bl,4
dostrcpy:
@ -327,6 +317,7 @@ strcpy_loop:
jmp short pascal_return
;******************************************************************
%ifndef _INIT
global FSTRLEN
FSTRLEN:
call pascal_setup
@ -336,15 +327,14 @@ FSTRLEN:
mov bl,4
jmp short dostrlen
%endif
;**********************************************
global STRLEN
STRLEN:
call pascal_setup
; Get the source pointer, ss
%ifdef PASCAL
mov di,[bp+4]
%endif
mov bl,2
dostrlen:
@ -366,11 +356,8 @@ STRCHR:
call pascal_setup
; Get the source pointer, ss
arg src, ch
%ifdef STDCALL ; preset above for PASCAL
mov cx,[.ch]
mov si,[.src]
%endif
; mov cx,[bp+4] - preset above
; mov si,[bp+6] - preset above
mov bl,4
strchr_loop:
@ -401,12 +388,11 @@ strchr_found1:
FSTRCHR:
call pascal_setup
arg {src,4}, ch
; Get ch (preset above)
;mov cx, [bp+4]
;and the source pointer, src
lds si, [.src]
lds si, [bp+6]
;mov bl, 6 - preset above
@ -417,17 +403,14 @@ arg {src,4}, ch
FMEMCHR:
call pascal_setup
arg {src,4}, ch, n
; Get the length - preset above
%ifdef STDCALL
mov cx, [.n]
%endif
; mov cx, [bp+4]
; and the search value
mov ax, [.ch]
mov ax, [bp+6]
; and the source pointer, ss
les di, [.src]
les di, [bp+8]
mov bl, 8
@ -443,12 +426,11 @@ arg {src,4}, ch, n
FSTRCMP:
call pascal_setup
arg {dest,4}, {src,4}
; Get the source pointer, ss
lds si,[.src]
lds si,[bp+4]
; and the destination pointer, d
les di,[.dest]
les di,[bp+8]
mov bl,8
@ -525,17 +507,14 @@ strncmp_loop:
FMEMCMP:
call pascal_setup
arg {dest,4}, {src,4}, n
; the length - preset above
%ifdef STDCALL
mov cx, [.n]
%endif
; mov cx, [bp+4]
; Get the source pointer, ss
les di,[.src]
les di,[bp+6]
; and the destination pointer, d
lds si,[.dest]
lds si,[bp+10]
mov bl,10
@ -566,6 +545,10 @@ strncmp_retzero:
strncmp_done:
lahf
ror ah,1
%ifdef _INIT
strncmp_done2: jmp short pascal_return
%else
strncmp_done2: jmp pascal_return
%endif
%endif

View File

@ -96,8 +96,6 @@ STATIC void CharCmd(struct dhdr FAR **pdev, unsigned command)
STATIC int Busy(struct dhdr FAR **pdev)
{
CharCmd(pdev, C_NDREAD);
if (CharReqHdr.r_status & S_ERROR)
CharCmd(pdev, C_ISTAT);
return CharReqHdr.r_status & S_BUSY;
}
@ -142,7 +140,7 @@ int ndread(struct dhdr FAR **pdev)
#ifdef __WATCOMC__
void fast_put_char(char c);
#pragma aux fast_put_char = "int 29h" __parm[__al] __modify __exact [__bx]
#pragma aux fast_put_char = "int 29h" parm[al] modify exact [bx]
#else
/* writes a character in raw mode using int29 for speed */
@ -151,8 +149,6 @@ STATIC void fast_put_char(unsigned char chr)
#if defined(__TURBOC__)
_AL = chr;
__int__(0x29);
#elif defined(__GNUC__)
asm volatile("int $0x29":: "a"(chr):"bx");
#elif defined(I86)
asm
{
@ -296,11 +292,11 @@ long cooked_read(struct dhdr FAR **pdev, size_t n, char FAR *bp)
return xfer;
}
STATIC unsigned read_char_sft_dev(int sft_in, int sft_out,
STATIC unsigned char read_char_sft_dev(int sft_in, int sft_out,
struct dhdr FAR **pdev,
BOOL check_break)
{
unsigned c;
unsigned char c;
if (*pdev)
{
@ -497,8 +493,6 @@ void read_line(int sft_in, int sft_out, keyboard FAR * kp)
/* fall through */
default:
if (c >= 256)
break;
if (count < size - 1 || c == CR)
local_buffer[count++] = echo_char(c, sft_out);
else

View File

@ -62,8 +62,6 @@ STATIC struct MenuSelector MenuStruct[MENULINESMAX] BSS_INIT({0});
int nMenuLine BSS_INIT(0);
int MenuColor = -1;
extern char ASM kernel_command_line[256];
extern int kernel_command_line_length;
STATIC void WriteMenuLine(struct MenuSelector *menu)
{
@ -127,7 +125,8 @@ size_t ebda_size BSS_INIT(0);
static UBYTE ErrorAlreadyPrinted[128] BSS_INIT({0});
static char FAR *envp = master_env;
char master_env[128] BSS_INIT({0});
static char *envp = master_env;
struct config Config = {
0,
@ -156,14 +155,6 @@ COUNT UmbState BSS_INIT(0);
STATIC BYTE szLine[256] BSS_INIT({0});
STATIC BYTE szBuf[256] BSS_INIT({0});
#define MAX_CHAINS 5
struct CfgFile {
COUNT nFileDesc;
COUNT nCfgLine;
} cfgFile[MAX_CHAINS] BSS_INIT({0});
COUNT nCurChain BSS_INIT(0);
COUNT nFileDesc BSS_INIT(0);
BYTE singleStep BSS_INIT(FALSE); /* F8 processing */
BYTE SkipAllConfig BSS_INIT(FALSE); /* F5 processing */
BYTE askThisSingleCommand BSS_INIT(FALSE); /* ?device= device?= */
@ -197,7 +188,6 @@ STATIC VOID InitPgm(BYTE * pLine);
STATIC VOID InitPgmHigh(BYTE * pLine);
STATIC VOID CmdInstall(BYTE * pLine);
STATIC VOID CmdInstallHigh(BYTE * pLine);
STATIC VOID CmdChain(BYTE * pLine);
STATIC VOID CmdSet(BYTE * pLine);
@ -212,8 +202,7 @@ STATIC VOID CfgMenuEsc(BYTE * pLine);
STATIC VOID DoMenu(void);
STATIC VOID CfgMenuDefault(BYTE * pLine);
STATIC BYTE * skipwh(BYTE * s);
STATIC int iswh(unsigned char c);
STATIC BYTE * scan(BYTE * s, BYTE * d, int fMenuSelect);
STATIC BYTE * scan(BYTE * s, BYTE * d);
STATIC BOOL isnum(char ch);
#if 0
STATIC COUNT tolower(COUNT c);
@ -261,8 +250,8 @@ struct table {
};
STATIC struct table commands[] = {
/* first = switches! this one is special; some options will
always be ran, others depends on F5/F8 and ? processing */
/* first = switches! this one is special since it is asked for but
also checked before F5/F8 */
{"SWITCHES", 0, CfgSwitches},
/* rem is never executed by locking out pass */
@ -304,7 +293,6 @@ STATIC struct table commands[] = {
{"DEVICEHIGH", 2, DeviceHigh},
{"INSTALL", 2, CmdInstall},
{"INSTALLHIGH", 2, CmdInstallHigh},
{"CHAIN", 2, CmdChain},
{"SET", 2, CmdSet},
/* default action */
@ -352,6 +340,9 @@ void PreConfig(void)
/* printf("Preliminary %d buffers allocated at 0x%p\n", Config.cfgBuffers, buffers);*/
#endif
LoL->DPBp =
DynAlloc("DPBp", blk_dev.dh_name[0], sizeof(struct dpb));
LoL->sfthead = MK_FP(FP_SEG(LoL), 0xcc); /* &(LoL->firstsftt) */
/* LoL->FCBp = (sfttbl FAR *)&FcbSft; */
/* LoL->FCBp = (sfttbl FAR *)
@ -396,9 +387,9 @@ void PreConfig2(void)
if (Config.ebda2move)
{
ebda_size = ebdasize();
ram_top += ebda_size / 1024;
if (ebda_size > Config.ebda2move)
ebda_size = Config.ebda2move;
ram_top += ebda_size / 1024;
}
/* We expect ram_top as Kbytes, so convert to paragraphs */
@ -412,9 +403,8 @@ void PreConfig2(void)
if (ebda_size) /* move the Extended BIOS Data Area from top of RAM here */
movebda(ebda_size, FP_SEG(KernelAlloc(ebda_size, 'I', 0)));
/* if (UmbState == 2)
if (UmbState == 2)
umb_init();
*/
}
/* Do third pass initialization. */
@ -539,8 +529,6 @@ STATIC void umb_init(void)
UmbState = 1;
/* reset root */
/* Note: since device drivers can change what is considered top of memory (e.g. move XBDA) we must requery */
ram_top = init_oem();
LoL->uppermem_root = ram_top * 64 - 1;
/* create link mcb (below) */
@ -618,7 +606,7 @@ struct memdiskinfo {
UBYTE version; /* Memdisk major version */
UDWORD base; /* Pointer to disk data in high memory */
UDWORD size; /* Size of disk in 512 byte sectors */
char FAR * cmdline; /* Command line; currently <= 2047 chars */
char FAR * cmdline; /* Command line */
ADDRESS oldint13; /* Old INT 13h */
ADDRESS oldint15; /* Old INT 15h */
UWORD olddosmem; /* Amount of DOS memory before Memdisk loaded */
@ -629,213 +617,25 @@ struct memdiskinfo {
/* query_memdisk() based on similar subroutine in Eric Auer's public domain getargs.asm which is based on IFMEMDSK */
struct memdiskinfo FAR * ASMCFUNC query_memdisk(UBYTE drive);
struct memdiskopt {
BYTE * name;
UWORD size;
};
/* preprocesses memdisk command line to allow simpler handling
{ is replaced by unsigned offset to start of next config line
e.g. "{{HI{HI}{HI{HI" --> "13HI4HI}3HI3HI"
FreeDOS supports max 256 length config lines, memdisk 4 max command length 2047
*/
BYTE FAR * ProcessMemdiskLine(BYTE FAR *cLine)
{
BYTE FAR *ptr;
BYTE FAR *sLine = cLine;
/* skip everything until end of line or starting { */
for (; *cLine && (*cLine != '{'); ++cLine)
;
sLine = cLine;
for (ptr = cLine; *cLine; ptr = cLine)
{
/* skip everything until end of line or starting { */
for (++cLine; *cLine && (*cLine != '{'); ++cLine)
;
/* calc offset from previous { to next { or eol and replace previous { with offset */
*ptr = (BYTE)(cLine - ptr);
}
return sLine;
}
/* Given a pointer to a memdisk command line and buffer will copy the next
config.sys equivalent line to pLine and return updated cLine.
Call repeatedly until end of string (*cLine == '\0').
Each simulated line is indicated be enclosing the line in curly braces {}
with the end } optional - the next { will indicate end/beginning and
end of line. MEMDISK options may appear nearly anywhere on line and are
ignored - see memdisk_opts for list of recognized options.
*/
BYTE FAR * GetNextMemdiskLine(BYTE FAR *cLine, BYTE *pLine)
{
STATIC struct memdiskopt memdiskopts[] = {
{"initrd", 6}, {"BOOT_IMAGE", 10},
{"floppy", 6}, {"harddisk", 8}, {"iso", 3},
{"nopass", 6}, {"nopassany", 9},
{"edd", 3}, {"noedd", 5}
/*
{"c", 1}, {"h", 1}, {"s", 1},
{"raw", 3}, {"bigraw", 6}, {"int", 3}, {"safeint", 7}
*/
};
int ws = TRUE; /* treat start of line same as if whitespace seen */
BYTE FAR * mf = NULL; /* where last line split by memdisk option */
BYTE FAR *ptr = cLine; /* start of current cfg line, where { was */
BYTE FAR *sLine = cLine;
/* exit early if already at end of command line */
if (!*cLine) return cLine;
/* point to start of next line; terminates current line if no } found before here */
cLine += *cLine;
/* restore original character we overwrite with offset, for next iteration of cfg file */
*ptr = '{';
/* ASSERT ptr points to start of line { and cLine points to start of next line { (or eol)*/
/* copy chars to pLine buffer until } or start of next line */
for (++ptr; (*ptr != '}') && (ptr < cLine); ++ptr)
{
/* if not in last {} then simply copy chars up to } (or next {) */
if (*cLine) goto copy_char;
/* otherwise if last character was whitespace (or start of line) check for memdisk option to skip */
if (ws)
{
int i;
for (i = 0; i < 9; ++i)
{
/* compare with option */
if (fmemcmp(ptr, memdiskopts[i].name, memdiskopts[i].size) == 0)
{
BYTE c = *(ptr + memdiskopts[i].size);
/* ensure character after is end of line, =, or whitespace */
if (!c || (c == '=') || iswh(c))
{
/* flag this line split */
mf = ptr;
/* matched option so point past it */
ptr += memdiskopts[i].size;
/* allow extra whitespace between option and = by skipping it */
while (iswh(*ptr))
++ptr;
/* if option has = value then skip it as well */
if (*ptr == '=')
{
/* allow extra whitespace between = and value by skipping it */
while (iswh(*ptr))
++ptr;
/* skip past all characters after = */
for (; (*ptr != '}') && (ptr < cLine) && !iswh(*ptr); ++ptr)
;
}
break; /* memdisk option found, no need to keep check rest in list */
}
}
}
}
if (ptr < cLine)
{
ws = iswh(*ptr);
/* allow replacing X=Y prior to memdisk options with X=Z after */
/* on 1st pass if find a match we overwrite it with spaces */
if (mf && (*ptr == '='))
{
BYTE FAR *old=sLine, FAR *new;
/* check for = in command line */
for (; old < mf; ++old)
{
for (; (*old != '=') && (old < mf); ++old)
;
/* ASSERT ptr points to = after memdisk option and old points to = before memdisk option or mf */
/* compare backwards to see if same option */
for (new = ptr; (old >= sLine) && ((*old & 0xCD) == (*new & 0xCD)); --old, --new)
{
if (iswh(*old) || iswh(*new)) break;
}
/* if match found then overwrite, otherwise skip past the = */
if (((old <= sLine) || iswh(*old)) && iswh(*new))
{
/* match found so overwrite with spaces */
for(++old; !iswh(*old) && (old < mf); ++old)
*old = ' ';
}
else
{
for (; (*old != '=') && (old < mf); ++old)
;
}
}
}
copy_char:
*pLine = *ptr;
++pLine;
}
}
*pLine = 0;
/* return location to begin next scan from */
return cLine;
}
#endif
static unsigned check_config_commandline(char ** pointer, char * cc,
char const * commandbuffer, char const * command);
static unsigned check_config_commandline(char ** pointer, char * cc,
char const * commandbuffer, char const * command) {
unsigned length = strlen(command);
if (memcmp(commandbuffer, command, length) == 0
&& (commandbuffer[length] == '\t'
|| commandbuffer[length] == ' '
|| commandbuffer[length] == '='
|| commandbuffer[length] == 0)) {
for (cc += length; *cc == '\t' || *cc == ' '; ++cc);
if (*cc == '=') ++cc;
for (; *cc == '\t' || *cc == ' '; ++cc);
*pointer = cc;
return 1;
}
return 0;
}
VOID DoConfig(int nPass)
{
COUNT nFileDesc;
BYTE *pLine;
BOOL bEof = FALSE;
BOOL bEof;
#ifdef MEMDISK_ARGS
/* check if MEMDISK used for LoL->BootDrive, if so check for special appended arguments */
struct memdiskinfo FAR *mdsk = NULL;
BYTE FAR *cLine;
struct memdiskinfo FAR *mdsk;
BYTE FAR *mdsk_cfg = NULL;
/* memdisk check & usage requires 386+, DO NOT invoke if less than 386 */
if (LoL->cpu >= 3)
{
UBYTE drv = (LoL->BootDrive < 3)?0x0:0x80; /* 1=A,2=B,3=C */
mdsk = query_memdisk(drv);
if (mdsk != NULL)
{
cLine = ProcessMemdiskLine(mdsk->cmdline);
}
}
#endif
@ -847,81 +647,91 @@ VOID DoConfig(int nPass)
if (mdsk != NULL)
{
printf("MEMDISK version %u.%02u (%lu sectors)\n", mdsk->version, mdsk->version_minor, mdsk->size);
DebugPrintf(("MEMDISK args:{%S}\n", mdsk->cmdline));
}
else
{
DebugPrintf(("MEMDISK not detected!\n"));
DebugPrintf(("MEMDISK args:{%S} bootdrive=[%0Xh]\n", mdsk->cmdline, (unsigned int)drv));
}
#endif
}
#ifdef MEMDISK_ARGS
if (mdsk != NULL)
{
char * pp = kernel_command_line;
char * cc;
unsigned ii;
static char commandbuffer[256];
char * end = &kernel_command_line[kernel_command_line_length];
static char * configfile = "";
static char * altconfigfile = "fdconfig.sys";
static char * oldconfigfile = "config.sys";
static struct { char ** pointer; char const * command; }
configcommands[] = {
{ &configfile, "CONFIG" },
{ &altconfigfile, "ALTCONFIG" },
{ &oldconfigfile, "OLDCONFIG" },
{ NULL, NULL }
};
for (; pp < end; pp += strlen(pp) + 1) {
for (cc = pp; *cc == '\t' || *cc == ' '; ++cc);
strcpy(commandbuffer, cc);
strupr(commandbuffer);
for (ii = 0; configcommands[ii].pointer != NULL; ++ii)
if (check_config_commandline(configcommands[ii].pointer,
cc, commandbuffer, configcommands[ii].command))
/* scan for FD= */
/* when done mdsk->cmdline points to { character or assume no valid CONFIG options */
for (mdsk_cfg=mdsk->cmdline; *mdsk_cfg; ++mdsk_cfg)
{
if (*mdsk_cfg != ' ') continue;
++mdsk_cfg;
if (*mdsk_cfg != 'F') goto goback1;
++mdsk_cfg;
if (*mdsk_cfg != 'D') goto goback2;
++mdsk_cfg;
if (*mdsk_cfg != '=') goto goback3;
++mdsk_cfg;
break;
goback3:
--mdsk_cfg;
goback2:
--mdsk_cfg;
goback1:
--mdsk_cfg;
}
/* if FD= was not found then flag as no extra CONFIG lines */
if (!*mdsk_cfg) mdsk_cfg = NULL;
}
else
{
DebugPrintf(("MEMDISK not detected! bootdrive=[%0Xh]\n", (unsigned int)drv));
}
#endif
/* Check to see if we have a config.sys file. If not, just */
/* exit since we don't force the user to have one (but 1st */
/* also process MEMDISK passed config options if present). */
for (ii = 0; configcommands[ii].pointer != NULL; ++ii) {
if (**configcommands[ii].pointer != '\0') {
if ((nFileDesc = open(*configcommands[ii].pointer, 0)) >= 0) {
DebugPrintf(("Reading \"%s\"...\n", *configcommands[ii].pointer));
break;
} else {
DebugPrintf(("\"%s\" not found\n", *configcommands[ii].pointer));
if ((nFileDesc = open("fdconfig.sys", 0)) >= 0)
{
DebugPrintf(("Reading FDCONFIG.SYS...\n"));
}
}
}
if (configcommands[ii].pointer == NULL) {
/* at this point no config file was found, may return early */
else
{
DebugPrintf(("FDCONFIG.SYS not found\n"));
if ((nFileDesc = open("config.sys", 0)) < 0)
{
DebugPrintf(("CONFIG.SYS not found\n"));
#ifdef MEMDISK_ARGS
/* if memdisk in use then only assume end of file reached and proceed, else return early */
if (mdsk != NULL)
if (mdsk_cfg != NULL)
bEof = TRUE;
else
#endif
return;
}
else
{
DebugPrintf(("Reading CONFIG.SYS...\n"));
}
}
nCfgLine = 0; /* keep track of which line in file for errors */
/* Have one -- initialize. */
nCfgLine = 0;
bEof = 0;
pLine = szLine;
/* Read each line into the buffer and then parse the line, */
/* do the table lookup and execute the handler for that */
/* function. */
#ifdef MEMDISK_ARGS
for (; !bEof || (mdsk != NULL); nCfgLine++)
for (; !bEof || (mdsk_cfg != NULL); nCfgLine++)
#else
for (; !bEof; nCfgLine++)
#endif
{
struct table *pEntry;
pLineStart = szLine;
#ifdef MEMDISK_ARGS
if (!bEof)
{
@ -951,31 +761,49 @@ VOID DoConfig(int nPass)
pLine++;
}
*pLine = 0;
#ifdef MEMDISK_ARGS
}
else if (mdsk != NULL)
else if (mdsk_cfg != NULL)
{
cLine = GetNextMemdiskLine(cLine, szLine);
/* if end of memdisk command line reached, flag done */
if (!*cLine)
mdsk = NULL;
pLine = szLine;
/* copy data to near buffer skipping { and } */
if (*mdsk_cfg != '{') /* if not at start of line */
{
mdsk_cfg = NULL; /* no longer need data, so set to NULL to flag done */
}
else
{
for (pLine = szLine, mdsk_cfg++; *mdsk_cfg; mdsk_cfg++, pLine++)
{
/* copy character to near buffer */
*pLine = *mdsk_cfg;
/* ensure we don't copy too much, exceed our buffer size */
if (pLine >= szLine + sizeof(szLine) - 3)
{
CfgFailure(pLine);
printf("error - line overflow line %d \n", nCfgLine);
break;
}
/* if end of this simulated line is found, skip over EOL marker then proceed to process line */
if (*pLine == '}')
{
mdsk_cfg++;
break;
}
}
}
}
#endif
if (bEof && nCurChain) {
struct CfgFile *cfg = &cfgFile[--nCurChain];
close(nFileDesc);
bEof = FALSE;
nFileDesc = cfg->nFileDesc;
nCfgLine = cfg->nCfgLine;
continue;
}
*pLine = 0;
pLine = szLine;
DebugPrintf(("CONFIG=[%s]\n", szLine));
DebugPrintf(("CONFIG=[%s]\n", pLine));
/* Skip leading white space and get verb. */
pLine = scan(szLine, szBuf, 1);
pLine = scan(pLine, szBuf);
/* If the line was blank, skip it. Otherwise, look up */
/* the verb and execute the appropriate function. */
@ -984,19 +812,17 @@ VOID DoConfig(int nPass)
pEntry = LookUp(commands, szBuf);
/* should config command be executed on this pass? */
if (pEntry->pass >= 0 && pEntry->pass != nPass)
continue;
/* pass 0 always executed (rem Menu prompt switches) */
if (nPass == 0)
if (nPass == 0) /* pass 0 always executed (rem Menu prompt switches) */
{
pEntry->func(pLine);
continue;
}
else
{
if (SkipLine(pLineStart)) /* F5/F8/?/! processing */
if (SkipLine(pLineStart)) /* F5/F8 processing */
continue;
}
@ -1084,7 +910,6 @@ UWORD GetBiosKey(int timeout)
STATIC BOOL SkipLine(char *pLine)
{
short key;
COUNT i;
if (InitKernelConfig.SkipConfigSeconds >= 0)
{
@ -1127,8 +952,6 @@ STATIC BOOL SkipLine(char *pLine)
if (!askThisSingleCommand && !singleStep)
return FALSE;
for (i = 0; i < nCurChain; i++)
printf(" ");
printf("%s[Y,N]?", pLine);
for (;;)
@ -1206,8 +1029,11 @@ STATIC char *GetNumArg(char *p, int *num)
BYTE *GetStringArg(BYTE * pLine, BYTE * pszString)
{
/* look for STRING */
pLine = skipwh(pLine);
/* just return whatever string is there, including null */
return scan(pLine, pszString, 0);
return scan(pLine, pszString);
}
STATIC void Config_Buffers(BYTE * pLine)
@ -1222,7 +1048,7 @@ STATIC void Config_Buffers(BYTE * pLine)
STATIC void CfgBuffersHigh(BYTE * pLine)
{
Config_Buffers(pLine);
if (InitKernelConfig.Verbose >= 0) printf("Note: BUFFERS will be in HMA or low RAM, not in UMB\n");
printf("Note: BUFFERS will be in HMA or low RAM, not in UMB\n");
}
/**
@ -1273,11 +1099,10 @@ STATIC VOID sysVersion(BYTE * pLine)
if (GetNumArg(p, &minor) == (BYTE *) 0)
return;
if (InitKernelConfig.Verbose >= 0) printf("Changing reported version to %d.%d\n", major, minor);
printf("Changing reported version to %d.%d\n", major, minor);
LoL->os_setver_major = major; /* not the internal os_major */
LoL->os_setver_minor = minor; /* not the internal os_minor */
((psp far *)MK_FP(DOS_PSP, 0))->ps_retdosver = (minor << 8) + major;
}
STATIC VOID Files(BYTE * pLine)
@ -1334,17 +1159,14 @@ STATIC VOID Dosmem(BYTE * pLine)
BYTE *pTmp;
BYTE UMBwanted = FALSE;
GetStringArg(pLine, szBuf);
strcpy(szBuf, pLine);
pLine = GetStringArg(pLine, szBuf);
strupr(szBuf);
/* printf("DOS called with %s\n", szBuf); */
for (pTmp = szBuf;;)
{
while (*pTmp == ' ' || *pTmp == '\t')
pTmp++;
if (memcmp(pTmp, "UMB", 3) == 0)
{
UMBwanted = TRUE;
@ -1355,26 +1177,11 @@ STATIC VOID Dosmem(BYTE * pLine)
HMAState = HMA_REQ;
pTmp += 4;
}
if (memcmp(pTmp, "LOW", 3) == 0)
{
HMAState = HMA_LOW;
pTmp += 3;
}
if (memcmp(pTmp, "NOUMB", 5) == 0)
{
UMBwanted = FALSE;
pTmp += 5;
}
/* if (memcmp(pTmp, "CLAIMINIT",9) == 0) { INITDataSegmentClaimed = 0; pTmp += 9; }*/
pTmp = skipwh(pTmp);
if (*pTmp == '\0')
break;
if (*pTmp != ',')
{
CfgFailure(pLine + (pTmp - szBuf));
break;
}
pTmp++;
}
@ -1435,7 +1242,7 @@ STATIC VOID CfgSwitches(BYTE * pLine)
int n = 0;
if (*++pLine == ':')
pLine++; /* skip optional separator */
if (!(isnum(*pLine) || (*pLine == '-')))
if (!isnum(*pLine))
{
pLine--;
break;
@ -1567,24 +1374,22 @@ STATIC BOOL LoadCountryInfo(char *filenam, UWORD ctryCode, UWORD codePage)
} subf_data;
struct subf_tbl {
char sig[8]; /* signature for each subfunction data */
int idx; /* index of pointer in nls_hc.asm to be copied to */
void FAR *p; /* pointer to data in nls_hc.asm to be copied to */
};
static struct subf_tbl table[8] = {
{"\377 ", -1}, /* 0, unused */
{"\377CTYINFO", 5}, /* 1 */
{"\377UCASE ", 0}, /* 2 */
{"\377LCASE ", -1}, /* 3, not supported [yet] */
{"\377FUCASE ", 1}, /* 4 */
{"\377FCHAR ", 2}, /* 5 */
{"\377COLLATE", 3}, /* 6 */
{"\377DBCS ", 4} /* 7, not supported [yet] */
{"\377 ", NULL}, /* 0, unused */
{"\377CTYINFO", &nlsCntryInfoHardcoded},/* 1 */
{"\377UCASE ", &nlsUpcaseHardcoded}, /* 2 */
{"\377LCASE ", NULL}, /* 3, not supported [yet] */
{"\377FUCASE ", &nlsFUpcaseHardcoded}, /* 4 */
{"\377FCHAR ", &nlsFnameTermHardcoded},/* 5 */
{"\377COLLATE", &nlsCollHardcoded}, /* 6 */
{"\377DBCS ", &nlsDBCSHardcoded} /* 7, not supported [yet] */
};
static struct subf_hdr hdr[8];
static int entries, count;
int fd, i;
int fd, entries, count, i;
char *filename = filenam == NULL ? "\\COUNTRY.SYS" : filenam;
BOOL rc = FALSE;
BYTE FAR *ptable;
if ((fd = open(filename, 0)) < 0)
{
@ -1615,14 +1420,14 @@ err:printf("%s has invalid format\n", filename);
if (lseek(fd, entry.offset) == 0xffffffffL
|| read(fd, &count, sizeof(count)) != sizeof(count)
|| count > LENGTH(hdr)
|| read(fd, hdr, sizeof(struct subf_hdr) * count)
|| read(fd, &hdr, sizeof(struct subf_hdr) * count)
!= sizeof(struct subf_hdr) * count)
goto err;
for (i = 0; i < count; i++)
{
if (hdr[i].length != 6)
goto err;
if (hdr[i].id < 1 || hdr[i].id > 7 || hdr[i].id == 3)
if (hdr[i].id < 1 || hdr[i].id > 6 || hdr[i].id == 3)
continue;
if (lseek(fd, hdr[i].offset) == 0xffffffffL
|| read(fd, &subf_data, 10) != 10
@ -1643,29 +1448,7 @@ err:printf("%s has invalid format\n", filename);
subf_data.length = /* MS-DOS "CTYINFO" is up to 38 bytes */
min(subf_data.length, sizeof(struct CountrySpecificInfo));
}
if (hdr[i].id == 1)
ptable = (BYTE FAR *)&nlsPackageHardcoded.nlsExt.size;
else
ptable = nlsPackageHardcoded.nlsPointers[table[hdr[i].id].idx].pointer;
if (hdr[i].id == 7)
{
if (subf_data.length == 0)
{
/* if DBCS table (in country.sys) is empty, clear internal table */
*(DWORD *)(subf_data.buffer) = 0L;
fmemcpy(ptable, subf_data.buffer, 4);
}
else
{
fmemcpy(ptable + 2, subf_data.buffer, subf_data.length);
/* write length */
*(UWORD *)(subf_data.buffer) = subf_data.length;
fmemcpy(ptable, subf_data.buffer, 2);
}
continue;
}
fmemcpy(ptable + 2, subf_data.buffer,
fmemcpy((BYTE FAR *)(table[hdr[i].id].p) + 2, subf_data.buffer,
/* skip length ^*/ subf_data.length);
}
rc = TRUE;
@ -1924,7 +1707,6 @@ void FAR * KernelAllocPara(size_t nPara, char type, char *name, int mode)
seg base, start;
struct submcb FAR *p;
/* if no umb available force low allocation */
if (UmbState != 1)
mode = 0;
@ -2027,7 +1809,7 @@ STATIC BYTE * skipwh(BYTE * s)
return s;
}
STATIC BYTE * scan(BYTE * s, BYTE * d, int fMenuSelect)
STATIC BYTE * scan(BYTE * s, BYTE * d)
{
askThisSingleCommand = FALSE;
DontAskThisSingleCommand = FALSE;
@ -2036,12 +1818,9 @@ STATIC BYTE * scan(BYTE * s, BYTE * d, int fMenuSelect)
MenuLine = 0;
/* only check at beginning of line, ie when looking for
menu selection line applies to. Fixes issue where
value after = starts with number, eg shell=4dos */
/* does the line start with "123?" */
if (fMenuSelect && isnum(*s))
if (isnum(*s))
{
unsigned numbers = 0;
for ( ; isnum(*s); s++)
@ -2223,13 +2002,10 @@ STATIC void config_init_buffers(int wantedbuffers)
if (FP_SEG(pbuffer) == 0xffff)
{
buffers++;
if (InitKernelConfig.Verbose >= 0)
{
printf("Kernel: allocated %d Diskbuffers = %u Bytes in HMA\n",
buffers, buffers * sizeof(struct buffer));
}
}
}
/*
Undocumented feature: ANYDOS
@ -2418,17 +2194,8 @@ RestartInput:
printf("\n");
/* export the current selected config menu */
{
char buffer[10];
int len;
sprintf(buffer, "CONFIG=%c", MenuSelected+'0');
len = strlen(buffer);
fstrcpy(envp, buffer);
envp += len + 1;
*envp = 0;
envp[1] = 0;
envp[2] = 0;
}
sprintf(envp, "CONFIG=%c", MenuSelected+'0');
envp += 9;
if (MenuColor != -1)
ClearScreen(0x7);
}
@ -2538,9 +2305,63 @@ struct CountrySpecificInfoSmall {
};
struct CountrySpecificInfoSmall specificCountriesSupported[] = {
#include "../country/kernel.tb1"
/* table rewritten by Bernd Blaauw
Country ID : international numbering
Date format : M = Month, D = Day, Y = Year (4digit); 0=USA, 1=Europe, 2=Japan
Currency : $ = dollar, EUR = EURO, 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)
ID Date currency 1000 0.1 date time C digit time Locale/Country
-----------------------------------------------------------------------------*/
{ 1,_DATE_MDY,"$" ,',','.', '/',':', 0 , 2,_TIME_12},/* United States */
{ 2,_DATE_YMD,"$" ,',','.', '-',':', 0 , 2,_TIME_24},/* Canada French */
{ 3,_DATE_MDY,"$" ,',','.', '/',':', 0 , 2,_TIME_12},/* Latin America */
{ 7,_DATE_DMY,"RUB" ,' ',',', '.',':', 3 , 2,_TIME_24},/* Russia */
{ 31,_DATE_DMY,"EUR" ,'.',',', '-',':', 0 , 2,_TIME_24},/* Netherlands */
{ 32,_DATE_DMY,"EUR" ,'.',',', '-',':', 0 , 2,_TIME_24},/* Belgium */
{ 33,_DATE_DMY,"EUR" ,'.',',', '-',':', 0 , 2,_TIME_24},/* France */
{ 34,_DATE_DMY,"EUR" ,'.','\'','-',':', 0 , 2,_TIME_24},/* Spain */
{ 36,_DATE_DMY,"$HU" ,'.',',', '-',':', 0 , 2,_TIME_24},/* Hungary */
{ 38,_DATE_DMY,"$YU" ,'.',',', '-',':', 0 , 2,_TIME_24},/* Yugoslavia */
{ 39,_DATE_DMY,"EUR" ,'.',',', '-',':', 0 , 2,_TIME_24},/* Italy */
{ 41,_DATE_DMY,"SF" ,'.',',', '.',':', 0 , 2,_TIME_24},/* Switserland */
{ 42,_DATE_YMD,"$YU" ,'.',',', '.',':', 0 , 2,_TIME_24},/* Czech/Slovakia*/
{ 44,_DATE_DMY,"\x9c" ,'.',',', '/',':', 0 , 2,_TIME_24},/* United Kingdom*/
{ 45,_DATE_DMY,"DKK" ,'.',',', '-',':', 0 , 2,_TIME_24},/* Denmark */
{ 46,_DATE_YMD,"SEK" ,',','.', '-',':', 0 , 2,_TIME_24},/* Sweden */
{ 47,_DATE_DMY,"NOK" ,',','.', '.',':', 0 , 2,_TIME_24},/* Norway */
{ 48,_DATE_YMD,"PLN" ,',','.', '.',':', 0 , 2,_TIME_24},/* Poland */
{ 49,_DATE_DMY,"EUR" ,'.',',', '.',':', 1 , 2,_TIME_24},/* Germany */
{ 54,_DATE_DMY,"$ar" ,'.',',', '/',':', 1 , 2,_TIME_12},/* Argentina */
{ 55,_DATE_DMY,"$ar" ,'.',',', '/',':', 1 , 2,_TIME_24},/* Brazil */
{ 61,_DATE_MDY,"$" ,'.',',', '/',':', 0 , 2,_TIME_24},/* Int. English */
{ 81,_DATE_YMD,"\x81\x8f",',','.', '/',':', 0 , 2,_TIME_12},/* Japan */
{351,_DATE_DMY,"EUR" ,'.',',', '-',':', 0 , 2,_TIME_24},/* Portugal */
{358,_DATE_DMY,"EUR" ,' ',',', '.',':',0x3, 2,_TIME_24},/* Finland */
{359,_DATE_DMY,"BGL" ,' ',',', '.',':', 3 , 2,_TIME_24},/* Bulgaria */
{380,_DATE_DMY,"UAH" ,' ',',', '.',':', 3 , 2,_TIME_24},/* Ukraine */
};
/* 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 Santamaria Merino (SP)
*/
STATIC int LoadCountryInfoHardCoded(COUNT ctryCode)
{
struct CountrySpecificInfoSmall *country;
@ -2628,26 +2449,6 @@ STATIC VOID CmdInstallHigh(BYTE * pLine)
{
_CmdInstall(pLine,0x80); /* load high, if possible */
}
STATIC VOID CmdChain(BYTE * pLine)
{
struct CfgFile *cfg;
int fd;
InstallPrintf(("CHAIN: %s\n", pLine));
if (nCurChain >= MAX_CHAINS) {
CfgFailure(pLine);
return;
}
if ((fd = open(pLine, 0)) < 0) {
CfgFailure(pLine);
return;
}
cfg = &cfgFile[nCurChain++];
cfg->nFileDesc = nFileDesc;
cfg->nCfgLine = nCfgLine;
nFileDesc = fd;
nCfgLine = 0;
}
STATIC VOID InstallExec(struct instCmds *icmd)
{
@ -2742,64 +2543,22 @@ VOID DoInstall(void)
return;
}
STATIC BYTE far * searchvar(const BYTE * name, int length)
{
BYTE far * pp = master_env;
do {
if (!fmemcmp(name, pp, length + 1)) {
return pp;
}
pp += fstrlen(pp) + 1;
} while (*pp);
return NULL;
}
STATIC void deletevar(BYTE far * pp) {
int variablelength;
if (NULL == pp)
return;
variablelength = fstrlen(pp) + 1;
fmemcpy(pp, pp + variablelength, (unsigned)(envp + 3 - (pp + variablelength)));
/* our fmemcpy always copies forwards */
envp -= variablelength;
return;
}
STATIC VOID CmdSet(BYTE *pLine)
{
pLine = GetStringArg(pLine, szBuf);
pLine = skipwh(pLine); /* scan() stops at the equal sign or space */
if (*pLine == '=') /* equal sign is required */
{
int size, oldsize, namesize;
BYTE far * pp;
int size;
strupr(szBuf); /* all environment variables must be uppercase */
namesize = strlen(szBuf);
strcat(szBuf, "=");
pp = searchvar(szBuf, namesize);
pLine = skipwh(++pLine);
strcat(szBuf, pLine); /* append the variable value (may include spaces) */
size = strlen(szBuf);
if (size == namesize + 1) {
/* empty variable ? then just delete. (cannot fail) */
deletevar(pp);
return;
}
if (pp) {
oldsize = fstrlen(pp) + 1;
} else {
oldsize = 0;
}
if (size < master_env + sizeof(master_env) - (envp - oldsize) - 1 - 2)
if (size < master_env + sizeof(master_env) - envp - 1)
{ /* must end with two consequtive zeros */
deletevar(pp); /* now that there's enough space, actually delete */
fstrcpy(envp, szBuf);
strcpy(envp, szBuf);
envp += size + 1; /* add next variables starting at the second zero */
*envp = 0;
envp[1] = 0;
envp[2] = 0;
/* The word marker after last variable should not equal 1,
to indicate that there is no executable pathname following. */
}
else
printf("Master environment is full - can't add \"%s\"\n", szBuf);

View File

@ -57,11 +57,6 @@ uScanCode db 0 ; Scan code for con: device
global _kbdType
_kbdType db 0 ; 00 for 84key, 10h for 102key
%IFDEF DEBUG_PRINT_COMPORT
ASYNC_NEED_INIT db 1
%ENDIF
global ConInit
ConInit:
xor ax,ax
@ -161,8 +156,6 @@ CommonNdRdExit: ; *** tell if key waiting and return its ASCII if yes
add ah,[cs:_kbdType]
int 16h ; Get status, if zf=0 al=char
jz ConNdRd4 ; Jump if no char available
or ax,ax ; Also check for ax=0 as apparently some
jz ConNdRd4 ; int16h handlers set ax=0 to indicate unsupported function
call checke0 ; check for e0 scancode
or ax,ax ; Zero ?
jnz ConNdRd1 ; Jump if not zero
@ -250,63 +243,12 @@ _int29_handler:
push di
push bp
push bx
%IFDEF DEBUG_PRINT_COMPORT
cmp bx, 0xFD05 ; magic value for COM print routine
je .comprint
%ENDIF
mov ah,0Eh
mov bx,7
int 10h ; write char al, teletype mode
.int29hndlr_ret:
pop bx
pop bp
pop di
pop si
pop ax
iret
%IFDEF DEBUG_PRINT_COMPORT
%ifnum DEBUG_PRINT_COMPORT
%define DEBUG_USE_COMPORT DEBUG_PRINT_COMPORT
%else
%define DEBUG_USE_COMPORT 1 ; default to COM2 if not specified
%endif
.comprint:
push dx
mov dx, DEBUG_USE_COMPORT ; 0=COM1,1=COM2,2=COM3,3=COM4
mov ah, [cs:ASYNC_NEED_INIT]
or ah,ah
jz .skip_init
push ax ; preserve char (AL) to print
; initialize serial port using BIOS to DOS default
; of 2400 bps, 8 data bits, 1 stop bit, and no parity
mov ax, 0x00A3
int 14h ; BIOS initialize serial port
mov ax, 0x011B ; clear the remote screen (ESC[2J)
int 14h ; BIOS write character to serial port
mov ax, 0x015B ; '['
int 14h ; BIOS write character to serial port
mov ax, 0x0132 ; '2'
int 14h ; BIOS write character to serial port
mov ax, 0x014A ; 'J'
int 14h ; BIOS write character to serial port
; mark initialization complete
mov byte [cs:ASYNC_NEED_INIT], 0
pop ax ; restore char to print
.skip_init:
cmp al, 0x0A ; do we need to add a carriage return?
jne .print_it
mov ax, 0x010D ; print as \r\n
int 14h
mov al, 0x0A
.print_it:
mov ah, 0x01
int 14h ; BIOS write character to serial port
pop dx
jmp .int29hndlr_ret
%ENDIF ; DEBUG_PRINT_COMPORT

5108
kernel/country.asm Normal file

File diff suppressed because it is too large Load Diff

View File

@ -48,22 +48,6 @@ CPU 386
and ax, 0f000h
cmp ax, 0f000h
jnz is286 ; no the 4 msb stuck set to 1, so is a 808x or 8018x
; NEC V20/V30 support 186 instructions but
; do not mask the shift count like a 186.
; based on https://hg.pushbx.org/ecm/ldebug/file/7f3440d5824d/source/init.asm#l3071
; which is based on http://www.textfiles.com/hamradio/v20_bug.txt
mov ax, sp ; we use stack to do test
mov cx, 0 ; after pop still 0 if 8088/8086
push cx
inc cx ; after pop still 1 if NEC V20/V30
; next instructions may lock system if breakpoint or trace flag set
db 8Fh, 0C1h; pop r/m16 with operand cx on 808x, nop on NEC V20/V30
mov sp, ax ; reset stack to known good state (pre push, optional pop)
or cx, cx ; cx is 0 if 808x, 1 if NEC
jz is808x ; if not NEC then goto test for 808x vs 8018x
mov bx, cx ; treat NEC V20/V30 as 8018x, i.e. return 1
jmp short cleanup
is808x:
mov ax,1 ; determine if 8086 or 186
mov cl,64 ; try to shift further than size of ax
shr ax,cl

View File

@ -46,7 +46,7 @@ BYTE share_installed = 0;
code, so DOS simply negates this value and returns it in
AX. */
extern int ASMPASCAL
share_open_check(const char FAR * filename, /* pointer to fully qualified filename */
share_open_check(char * filename, /* pointer to fully qualified filename */
unsigned short pspseg, /* psp segment address of owner process */
int openmode, /* 0=read-only, 1=write-only, 2=read-write */
int sharemode); /* SHARE_COMPAT, etc... */
@ -86,13 +86,6 @@ extern int ASMPASCAL
unsigned long len, /* length (in bytes) of region to lock or unlock */
int unlock); /* one to unlock; zero to lock */
/* DOS calls this to see if share already has the file marked as open.
Returns:
1 if open
0 if not */
extern int ASMPASCAL
share_is_file_open(const char far * filename);
/* /// End of additions for SHARE. - Ron Cemer */
STATIC int remote_lock_unlock(sft FAR *sftp, /* SFT for file */
@ -100,13 +93,6 @@ STATIC int remote_lock_unlock(sft FAR *sftp, /* SFT for file */
unsigned long len, /* length (in bytes) of region to lock or unlock */
int unlock); /* one to unlock; zero to lock */
struct cds FAR *get_cds_unvalidated(unsigned drive)
{
if (drive >= lastdrive)
return NULL;
return &CDSp[drive];
}
/* get current directory structure for drive
return NULL if the CDS is not valid or the
drive is not within range */
@ -313,7 +299,7 @@ long DosRWSft(int sft_idx, size_t n, void FAR * bp, int mode)
return rwblock(sft_idx, bp, n, mode);
}
COUNT SftSeek2(int sft_idx, LONG new_pos, unsigned mode, UDWORD * p_result)
COUNT SftSeek(int sft_idx, LONG new_pos, unsigned mode)
{
sft FAR *s = idx_to_sft(sft_idx);
if (FP_OFF(s) == (size_t) -1)
@ -354,25 +340,17 @@ COUNT SftSeek2(int sft_idx, LONG new_pos, unsigned mode, UDWORD * p_result)
}
s->sft_posit = new_pos;
*p_result = new_pos;
return SUCCESS;
}
COUNT SftSeek(int sft_idx, LONG new_pos, unsigned mode)
{
UDWORD result;
return SftSeek2(sft_idx, new_pos, mode, &result);
}
ULONG DosSeek(unsigned hndl, LONG new_pos, COUNT mode, int *rc)
{
int sft_idx = get_sft_idx(hndl);
UDWORD result;
/* Get the SFT block that contains the SFT */
*rc = SftSeek2(sft_idx, new_pos, mode, &result);
*rc = SftSeek(sft_idx, new_pos, mode);
if (*rc == SUCCESS)
return result;
return idx_to_sft(sft_idx)->sft_posit;
return *rc;
}
@ -436,17 +414,6 @@ const char FAR *get_root(const char FAR * fname)
return fname;
}
STATIC void ConvertPathNameToFCBName(char *FCBName, const char *PathName)
{
ConvertNameSZToName83(FCBName, (char *)FP_OFF(get_root(PathName)));
FCBName[FNAME_SIZE + FEXT_SIZE] = '\0';
}
STATIC void set_fcbname(void)
{
ConvertPathNameToFCBName(DirEntBuffer.dir_name, PriPathName);
}
/* initialize SFT fields (for open/creat) for character devices */
STATIC int DeviceOpenSft(struct dhdr FAR *dhp, sft FAR *sftp)
{
@ -523,8 +490,6 @@ long DosOpenSft(char FAR * fname, unsigned flags, unsigned attrib)
if (result < SUCCESS)
return result;
set_fcbname();
/* now get a free system file table entry */
if ((sftp = get_free_sft(&sft_idx)) == (sft FAR *) - 1)
return DE_TOOMANY;
@ -538,18 +503,6 @@ long DosOpenSft(char FAR * fname, unsigned flags, unsigned attrib)
sftp->sft_shroff = -1; /* /// Added for SHARE - Ron Cemer */
sftp->sft_attrib = attrib = attrib | D_ARCHIVE;
/* check for a device */
if ((result & IS_DEVICE) && (dhp = IsDevice(fname)) != NULL)
{
int rc = DeviceOpenSft(dhp, sftp);
/* check the status code returned by the
* driver when we tried to open it
*/
if (rc < SUCCESS)
return rc;
return sft_idx;
}
if (result & IS_NETWORK)
{
int status;
@ -582,6 +535,18 @@ long DosOpenSft(char FAR * fname, unsigned flags, unsigned attrib)
return status;
}
/* check for a device */
if ((result & IS_DEVICE) && (dhp = IsDevice(fname)) != NULL)
{
int rc = DeviceOpenSft(dhp, sftp);
/* check the status code returned by the
* driver when we tried to open it
*/
if (rc < SUCCESS)
return rc;
return sft_idx;
}
/* First test the flags to see if the user has passed a valid */
/* file mode... */
if ((flags & O_ACCMODE) > 2)
@ -771,7 +736,7 @@ UWORD DosGetFree(UBYTE drive, UWORD * navc, UWORD * bps, UWORD * nc)
/* navc==NULL means: called from FatGetDrvData, fcbfns.c */
struct dpb FAR *dpbp;
struct cds FAR *cdsp;
COUNT rg[5]; /* add space for SI, although it's unused here */
COUNT rg[4];
UWORD spc;
/* first check for valid drive */
@ -781,7 +746,6 @@ UWORD DosGetFree(UBYTE drive, UWORD * navc, UWORD * bps, UWORD * nc)
if (cdsp == NULL)
return spc;
current_ldt = cdsp;
if (cdsp->cdsFlags & CDSNETWDRV)
{
if (remote_getfree(cdsp, rg) != SUCCESS)
@ -876,7 +840,7 @@ COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp)
{
struct dpb FAR *dpbp;
struct cds FAR *cdsp;
UCOUNT rg[5];
UCOUNT rg[4];
/* ensure all fields known value - clear reserved bytes & set xfs_version.actual to 0 */
fmemset(xfsp, 0, sizeof(struct xfreespace));
@ -899,10 +863,6 @@ COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp)
if (cdsp->cdsFlags & CDSNETWDRV)
{
/* Try redirector extension */
if (remote_getfree_11a3(cdsp, rg) != SUCCESS)
{
/* Fallback */
if (remote_getfree(cdsp, rg) != SUCCESS)
return DE_INVLDDRV;
@ -911,33 +871,6 @@ COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp)
xfsp->xfs_secsize = rg[2];
xfsp->xfs_freeclusters = rg[3];
}
else /* Supports extension */
{
UDWORD total, avail;
UDWORD bps, spc;
bps = rg[4];
spc = 1;
total = (((UDWORD)rg[0] << 16UL) | rg[1]);
avail = (((UDWORD)rg[2] << 16UL) | rg[3]);
while (total > 0x00ffffffUL && spc < 128) {
spc *= 2;
avail /= 2;
total /= 2;
}
while (total > 0x00ffffffUL && bps < 32768UL) {
bps *= 2;
avail /= 2;
total /= 2;
}
xfsp->xfs_secsize = bps;
xfsp->xfs_clussize = spc;
xfsp->xfs_totalclusters = total;
xfsp->xfs_freeclusters = avail;
}
}
else
{
dpbp = cdsp->cdsDpb;
@ -986,8 +919,6 @@ COUNT DosChangeDir(BYTE FAR * s)
if (result < SUCCESS)
return DE_PATHNOTFND;
set_fcbname();
if ((FP_OFF(current_ldt) != 0xFFFF) &&
(strlen(PriPathName) >= sizeof(current_ldt->cdsCurrentPath)))
return DE_PATHNOTFND;
@ -1011,6 +942,7 @@ COUNT DosChangeDir(BYTE FAR * s)
Some redirectors do not write back to the CDS.
SHSUCdX needs this. jt
*/
fstrcpy(current_ldt->cdsCurrentPath, PriPathName);
if (FP_OFF(current_ldt) != 0xFFFF)
{
fstrcpy(current_ldt->cdsCurrentPath, PriPathName);
@ -1045,8 +977,6 @@ COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name)
if (rc < SUCCESS)
return rc;
set_fcbname();
/* /// Added code here to do matching against device names.
DOS findfirst will match exact device names if the
filename portion (excluding the extension) contains
@ -1119,7 +1049,7 @@ COUNT DosFindNext(void)
/* findnext will always fail on a volume id search or device name */
if ((sda_tmp_dm.dm_attr_srch & ~(D_RDONLY | D_ARCHIVE | D_DEVICE)) == D_VOLID
|| (!(sda_tmp_dm.dm_drive & 0x80) && sda_tmp_dm.dm_entry == 0xffff))
|| sda_tmp_dm.dm_entry == 0xffff)
return DE_NFILES;
memset(&SearchDir, 0, sizeof(struct dirent));
@ -1130,7 +1060,7 @@ COUNT DosFindNext(void)
return pop_dmp(rc, dmp);
}
COUNT DosGetFtime(COUNT hndl, ddate * dp, dtime * tp)
COUNT DosGetFtime(COUNT hndl, date * dp, time * tp)
{
sft FAR *s;
/*sfttbl FAR *sp;*/
@ -1144,7 +1074,7 @@ COUNT DosGetFtime(COUNT hndl, ddate * dp, dtime * tp)
return SUCCESS;
}
COUNT DosSetFtimeSft(int sft_idx, ddate dp, dtime tp)
COUNT DosSetFtimeSft(int sft_idx, date dp, time tp)
{
/* Get the SFT block that contains the SFT */
sft FAR *s = idx_to_sft(sft_idx);
@ -1183,8 +1113,6 @@ COUNT DosGetFattr(BYTE FAR * name)
if (PriPathName[3] == '\0')
return 0x10;
set_fcbname();
if (result & IS_NETWORK)
return network_redirector(REM_GETATTRZ);
@ -1205,8 +1133,6 @@ COUNT DosSetFattr(BYTE FAR * name, UWORD attrp)
if (result < SUCCESS)
return result;
set_fcbname();
if (result & IS_NETWORK)
return remote_setfattr(attrp);
@ -1244,17 +1170,12 @@ COUNT DosDelete(BYTE FAR * path, int attrib)
if (result < SUCCESS)
return result;
set_fcbname();
if (result & IS_NETWORK)
return network_redirector(REM_DELETE);
if (result & IS_DEVICE)
return DE_FILENOTFND;
if (IsShareInstalled(TRUE) && share_is_file_open(PriPathName))
return DE_ACCESS;
return dos_delete(PriPathName, attrib);
}
@ -1267,9 +1188,6 @@ COUNT DosRenameTrue(BYTE * path1, BYTE * path2, int attrib)
if (FP_OFF(current_ldt) == 0xFFFF || (current_ldt->cdsFlags & CDSNETWDRV))
return network_redirector(REM_RENAME);
if (IsShareInstalled(TRUE) && share_is_file_open(path1))
return DE_ACCESS;
return dos_rename(path1, path2, attrib);
}
@ -1288,8 +1206,6 @@ COUNT DosRename(BYTE FAR * path1, BYTE FAR * path2)
if (result < SUCCESS)
return result;
set_fcbname();
if ((result & (IS_NETWORK | IS_DEVICE)) == IS_DEVICE)
return DE_FILENOTFND;
@ -1304,8 +1220,6 @@ COUNT DosMkRmdir(const char FAR * dir, int action)
if (result < SUCCESS)
return result;
set_fcbname();
if (result & IS_NETWORK)
return network_redirector(action == 0x39 ? REM_MKDIR : REM_RMDIR);
@ -1426,10 +1340,8 @@ BOOL IsShareInstalled(BOOL recheck)
extern unsigned char ASMPASCAL share_check(void);
if (recheck == FALSE)
return share_installed;
if (share_check() == 0xff)
if (!share_installed && share_check() == 0xff)
share_installed = TRUE;
else
share_installed = FALSE;
return share_installed;
}
@ -1443,10 +1355,7 @@ COUNT DosTruename(const char FAR *src, char FAR *dest)
*/
COUNT rc = truename(src, PriPathName, CDS_MODE_ALLOW_WILDCARDS);
if (rc >= SUCCESS)
{
fstrcpy(dest, PriPathName);
set_fcbname();
}
return rc;
}

View File

@ -36,15 +36,15 @@ segment HMA_TEXT
global _DosIdle_int
global _DosIdle_hlt
extern _InDOS
extern _cu_psp
extern _MachineId
extern critical_sp
extern _user_r
extern _InDOS:wrt DGROUP
extern _cu_psp:wrt DGROUP
extern _MachineId:wrt DGROUP
extern critical_sp:wrt DGROUP
extern _user_r:wrt DGROUP
; variables as the following are "part of" module inthndlr.c
; because of the define MAIN before include globals.h there!
extern _HaltCpuWhileIdle
extern _DGROUP_
extern _HaltCpuWhileIdle:wrt DGROUP
extern _DGROUP_:wrt HMA_TEXT
;
_DosIdle_hlt:
push ds

View File

@ -56,12 +56,12 @@ extern COUNT ASMPASCAL fl_lba_ReadWrite(BYTE drive, WORD mode,
* dap_p);
UWORD ASMPASCAL floppy_change(UWORD);
#ifdef __WATCOMC__
#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_lba_ReadWrite __modify __exact [__ax __dx]
#pragma aux (__pascal) floppy_change __modify __exact [__ax __cx __dx]
#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_lba_ReadWrite modify exact [ax dx]
#pragma aux (pascal) floppy_change modify exact [ax cx dx]
#endif
STATIC int LBA_Transfer(ddt * pddt, UWORD mode, VOID FAR * buffer,
@ -290,7 +290,7 @@ STATIC WORD RWzero(ddt * pddt, UWORD mode)
UWORD done;
return LBA_Transfer(pddt, mode,
(UBYTE FAR *) DiskTransferBuffer,
(UBYTE FAR *) & DiskTransferBuffer,
pddt->ddt_offset, 1, &done);
}
@ -392,7 +392,7 @@ STATIC WORD getbpb(ddt * pddt)
{
/* copy default bpb to be sure that there is no bogus data */
memcpy(pbpbarray, &pddt->ddt_defbpb, sizeof(bpb));
return 0;
return S_DONE;
}
pddt->ddt_descflags &= ~DF_NOACCESS; /* set drive to accessible */
@ -413,37 +413,16 @@ STATIC WORD getbpb(ddt * pddt)
*/
{
struct FS_info *fs = (struct FS_info *)&DiskTransferBuffer[0x27];
register BYTE extended_BPB_signature;
#ifdef WITHFAT32
if (pbpbarray->bpb_nfsect == 0)
{
/* FAT32 boot sector */
fs = (struct FS_info *)&DiskTransferBuffer[0x43];
/* Extended BPB signature, offset differs for FAT32 vs FAT12/16 */
extended_BPB_signature = DiskTransferBuffer[0x42];
}
else
#endif
extended_BPB_signature = DiskTransferBuffer[0x26];
/* 0x29 is usual signature value for serial#,vol label,& fstype;
0x28 older EBPB signature indicating only serial# is valid */
if ((extended_BPB_signature == 0x29) || (extended_BPB_signature == 0x28))
{
pddt->ddt_serialno = getlong(&fs->serialno);
} else {
/* short BPB, no serial # available */
pddt->ddt_serialno = 0;
}
if (extended_BPB_signature == 0x29)
{
fmemcpy(pddt->ddt_volume, fs->volume, sizeof fs->volume);
fmemcpy(pddt->ddt_fstype, fs->fstype, sizeof fs->fstype);
} else {
/* earlier extended BPB or short BPB, fields not available */
fmemcpy(pddt->ddt_volume, "NO NAME ", 11);
fmemcpy(pddt->ddt_fstype, "FAT?? ", 8);
}
memcpy(pddt->ddt_volume, fs->volume, sizeof fs->volume);
memcpy(pddt->ddt_fstype, fs->fstype, sizeof fs->fstype);
}
#ifdef DSK_DEBUG
@ -517,7 +496,6 @@ STATIC WORD IoctlQueblk(rqptr rp, ddt * pddt)
return failure(E_CMD);
}
/* read/write block with CHS based off start of drive's partition */
STATIC COUNT Genblockio(ddt * pddt, UWORD mode, WORD head, WORD track,
WORD sector, WORD count, VOID FAR * buffer)
{
@ -530,19 +508,6 @@ STATIC COUNT Genblockio(ddt * pddt, UWORD mode, WORD head, WORD track,
pddt->ddt_offset + sector, count, &transferred);
}
/* read/write block with CHS based off start of disk drive is on */
STATIC COUNT GenblockioAbs(ddt * pddt, UWORD mode, WORD head, WORD track,
WORD sector, WORD count, VOID FAR * buffer)
{
UWORD transferred;
/* apparently sector is ZERO, not ONE based !!! */
return LBA_Transfer(pddt, mode, buffer,
((ULONG) track * pddt->ddt_bpb.bpb_nheads + head) *
(ULONG) pddt->ddt_bpb.bpb_nsecs +
sector, count, &transferred);
}
STATIC WORD Genblkdev(rqptr rp, ddt * pddt)
{
int ret;
@ -581,10 +546,10 @@ STATIC WORD Genblkdev(rqptr rp, ddt * pddt)
/*pbpb->bpb_nsector = gblp->gbio_nsecs; */
break;
}
case 0x41: /* write track - CHS is absolute not relative to partition start */
case 0x41: /* write track */
{
struct gblkrw FAR *rw = rp->r_rw;
ret = GenblockioAbs(pddt, LBA_WRITE, rw->gbrw_head, rw->gbrw_cyl,
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);
@ -714,15 +679,6 @@ STATIC WORD Genblkdev(rqptr rp, ddt * pddt)
if (ret != 0)
return (ret);
/* return error if media lacks extended BPB with serial # */
{
register BYTE extended_BPB_signature =
DiskTransferBuffer[(pddt->ddt_bpb.bpb_nfsect != 0 ? 0x26 : 0x42)];
if ((extended_BPB_signature != 0x29) || (extended_BPB_signature != 0x28))
return failure(E_MEDIA);
}
/* otherwise, store serial # in extended BPB */
fs = (struct FS_info *)&DiskTransferBuffer
[(pddt->ddt_bpb.bpb_nfsect != 0 ? 0x27 : 0x43)];
fs->serialno = gioc->ioc_serialno;
@ -763,10 +719,10 @@ STATIC WORD Genblkdev(rqptr rp, ddt * pddt)
/*gblp->gbio_nsecs = pbpb->bpb_nsector; */
break;
}
case 0x61: /* read track - CHS is absolute on disk not relative to start of partition */
case 0x61: /* read track */
{
struct gblkrw FAR *rw = rp->r_rw;
ret = GenblockioAbs(pddt, LBA_READ, rw->gbrw_head, rw->gbrw_cyl,
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);
@ -780,7 +736,6 @@ STATIC WORD Genblkdev(rqptr rp, ddt * pddt)
if (ret != 0)
return (ret);
/* Note: getbpb() will initialize extended BPB fields with default values */
gioc->ioc_serialno = pddt->ddt_serialno;
fmemcpy(gioc->ioc_volume, pddt->ddt_volume, 11);
fmemcpy(gioc->ioc_fstype, pddt->ddt_fstype, 8);
@ -901,8 +856,7 @@ STATIC WORD dskerr(COUNT code)
translate LBA sectors into CHS addressing
*/
STATIC int LBA_to_CHS(ULONG LBA_address, struct CHS *chs, const ddt * pddt,
const bpb ** ppbpb)
STATIC int LBA_to_CHS(ULONG LBA_address, struct CHS *chs, const ddt * pddt)
{
/* we need the defbpb values since those are taken from the
BIOS, not from some random boot sector, except when
@ -927,7 +881,6 @@ STATIC int LBA_to_CHS(ULONG LBA_address, struct CHS *chs, const ddt * pddt,
chs->Cylinder = (UWORD)LBA_address;
chs->Head = hsrem / pbpb->bpb_nsecs;
chs->Sector = hsrem % pbpb->bpb_nsecs + 1;
*ppbpb = pbpb;
return 0;
}
@ -1021,13 +974,8 @@ STATIC int LBA_Transfer(ddt * pddt, UWORD mode, VOID FAR * buffer,
buffer = adjust_far(buffer);
for (; totaltodo != 0;)
{
count = totaltodo;
if ((pddt->ddt_descflags & DF_DMA_TRANSPARENT) == 0)
{
/* avoid overflowing 64K DMA boundary
for drives that don't handle this transparently */
/* avoid overflowing 64K DMA boundary */
count = DMA_max_transfer(buffer, totaltodo);
}
if (FP_SEG(buffer) >= 0xa000 || count == 0)
{
@ -1076,15 +1024,15 @@ STATIC int LBA_Transfer(ddt * pddt, UWORD mode, VOID FAR * buffer,
}
else
{ /* transfer data, using old bios functions */
const bpb *pbpb;
if (LBA_to_CHS(LBA_address, &chs, pddt, &pbpb))
if (LBA_to_CHS(LBA_address, &chs, pddt))
return 1;
/* avoid overflow at end of track */
if (chs.Sector + count > (unsigned)pbpb->bpb_nsecs + 1)
if (chs.Sector + count > (unsigned)pddt->ddt_bpb.bpb_nsecs + 1)
{
count = pbpb->bpb_nsecs + 1 - chs.Sector;
count = pddt->ddt_bpb.bpb_nsecs + 1 - chs.Sector;
}
error_code = (mode == LBA_READ ? fl_read :

View File

@ -48,6 +48,7 @@ additionally:
/*extern struct DynS FAR Dyn;*/
#ifndef __TURBOC__
#include "init-dat.h"
extern struct DynS DOSFAR ASM Dyn;
#else
extern struct DynS FAR ASM Dyn;

View File

@ -35,23 +35,20 @@ segment HMA_TEXT
extern _int21_syscall
extern _int21_service
extern _int2526_handler
extern _error_tos
extern _char_api_tos
extern _disk_api_tos
extern _user_r
extern _ErrorMode
extern _InDOS
%IFDEF WIN31SUPPORT
extern _winInstanced
%ENDIF ; WIN31SUPPORT
extern _cu_psp
extern _MachineId
extern critical_sp
extern _error_tos:wrt DGROUP
extern _char_api_tos:wrt DGROUP
extern _disk_api_tos:wrt DGROUP
extern _user_r:wrt DGROUP
extern _ErrorMode:wrt DGROUP
extern _InDOS:wrt DGROUP
extern _cu_psp:wrt DGROUP
extern _MachineId:wrt DGROUP
extern critical_sp:wrt DGROUP
extern int21regs_seg
extern int21regs_off
extern int21regs_seg:wrt DGROUP
extern int21regs_off:wrt DGROUP
extern _Int21AX
extern _Int21AX:wrt DGROUP
extern _DGROUP_
@ -239,10 +236,6 @@ reloc_call_int20_handler:
; int21_handler(iregs UserRegs)
;
reloc_call_int21_handler:
cmp ah,25h
je int21_func25
cmp ah,35h
je int21_func35
;
; Create the stack frame for C call. This is done to
; preserve machine state and provide a C structure for
@ -269,8 +262,12 @@ int21_reentry:
mov dx,[cs:_DGROUP_]
mov ds,dx
cmp ah,25h
je int21_user
cmp ah,33h
je int21_user
cmp ah,35h
je int21_user
cmp ah,50h
je int21_user
cmp ah,51h
@ -279,9 +276,7 @@ int21_reentry:
jne int21_1
int21_user:
%IFNDEF WIN31SUPPORT
call end_dos_crit_sect
%ENDIF ; NOT WIN31SUPPORT
call dos_crit_sect
push ss
push bp
@ -290,29 +285,6 @@ int21_user:
pop cx
jmp short int21_ret
int21_func25:
push es
push bx
xor bx,bx
mov es,bx
mov bl,al
shl bx,1
shl bx,1
mov [es:bx],dx
mov [es:bx+2],ds
pop bx
pop es
iret
int21_func35:
xor bx,bx
mov es,bx
mov bl,al
shl bx,1
shl bx,1
les bx,[es:bx]
iret
;
; normal entry, use one of our 4 stacks
;
@ -367,27 +339,15 @@ int21_onerrorstack:
jmp short int21_exit_nodec
int21_2:
%IFDEF WIN31SUPPORT ; begin critical section
; should be called as needed, but we just
; mark the whole int21 api as critical
call begin_dos_crit_sect
%ENDIF ; WIN31SUPPORT
inc byte [_InDOS]
int21_2: inc byte [_InDOS]
mov cx,_char_api_tos
or ah,ah
jz int21_3
%IFDEF WIN31SUPPORT ; testing, this function call crashes
cmp ah,06h
je int21_3
%ENDIF ; WIN31SUPPORT
cmp ah,0ch
jbe int21_normalentry
int21_3:
%IFNDEF WIN31SUPPORT
call end_dos_crit_sect
%ENDIF ; NOT WIN31SUPPORT
call dos_crit_sect
mov cx,_disk_api_tos
int21_normalentry:
@ -407,15 +367,6 @@ int21_normalentry:
call _int21_service
int21_exit: dec byte [_InDOS]
%IFDEF WIN31SUPPORT
call end_dos_crit_sect ; release all critical sections
%if 0
push ax
mov ax, 8101h ; Leave Critical Section
int 2ah
pop ax
%endif
%ENDIF ; WIN31SUPPORT
;
; Recover registers from system call. Registers and flags
@ -441,28 +392,11 @@ int21_ret:
; ... and return.
;
iret
%IFDEF WIN31SUPPORT
;
; begin DOS Critical Section 1
;
;
begin_dos_crit_sect:
; we only enable critical sections if Windows is active
; we currently use winInstanced, but may need to use separate patchable location
cmp word [_winInstanced], 0
jz skip_crit_sect
push ax
mov ax, 8001h ; Enter Critical Section
int 2ah
pop ax
skip_crit_sect:
ret
%ENDIF ; WIN31SUPPORT
;
; end Dos Critical Section 0 thur 7
;
;
end_dos_crit_sect:
dos_crit_sect:
mov [_Int21AX],ax ; needed!
push ax ; This must be here!!!
mov ah,82h ; re-enrty sake before disk stack

View File

@ -51,18 +51,17 @@ segment HMA_TEXT
push si
push ds ; sp=bp-8
arg {rhp,4}, {dhp,4}
lds si,[.dhp] ; ds:si = device header
les bx,[.rhp] ; es:bx = request header
lds si,[bp+4] ; ds:si = device header
les bx,[bp+8] ; es:bx = request header
mov ax, [si+6] ; construct strategy address
mov [.dhp], ax
mov [bp+4], ax
push si ; the bloody fucking RTSND.DOS
push di ; driver destroys SI,DI (tom 14.2.03)
call far[.dhp] ; call far the strategy
call far[bp+4] ; call far the strategy
pop di
pop si
@ -70,8 +69,8 @@ arg {rhp,4}, {dhp,4}
; Protect386Registers ; old free-EMM386 versions destroy regs in their INIT method
mov ax,[si+8] ; construct 'interrupt' address
mov [.dhp],ax ; construct interrupt address
call far[.dhp] ; call far the interrupt
mov [bp+4],ax ; construct interrupt address
call far[bp+4] ; call far the interrupt
; Restore386Registers ; less stack load and better performance...

View File

@ -52,7 +52,7 @@ COUNT map_cluster(f_node_ptr, COUNT);
STATIC int shrink_file(f_node_ptr fnp);
/* FAT time notation in the form of hhhh hmmm mmmd dddd (d = double second) */
STATIC dtime time_encode(struct dostime *t)
STATIC time time_encode(struct dostime *t)
{
return (t->hour << 11) | (t->minute << 5) | (t->second >> 1);
}
@ -103,9 +103,8 @@ STATIC void init_direntry(struct dirent *dentry, unsigned attrib,
#endif
dentry->dir_start = (UWORD)cluster;
dentry->dir_attrib = (UBYTE)attrib;
/* set create and last modified time & date */
dentry->dir_crtime = dentry->dir_time = dos_gettime();
dentry->dir_crdate = dentry->dir_date = dos_getdate();
dentry->dir_time = dos_gettime();
dentry->dir_date = dos_getdate();
}
/************************************************************************/
@ -463,9 +462,8 @@ COUNT dos_rmdir(BYTE * path)
return DE_PATHNOTFND;
/* Directories may have attributes, but if other than 'archive' */
/* or 'read only' then deny i.e. do not allow (SYSTEM|HIDDEN) */
/* directory to be deleted. */
if (fnp->f_dir.dir_attrib & ~(D_DIR | D_RDONLY | D_ARCHIVE))
/* then do not allow (RDONLY|SYSTEM|HIDDEN) directory to be deleted. */
if (fnp->f_dir.dir_attrib & ~(D_DIR |D_ARCHIVE))
return DE_ACCESS;
dir_read(fnp);
@ -666,7 +664,7 @@ STATIC int alloc_find_free(f_node_ptr fnp, char *path)
/* */
/* dos_getdate for the file date */
/* */
ddate dos_getdate(void)
date dos_getdate(void)
{
struct dosdate dd;
@ -679,7 +677,7 @@ ddate dos_getdate(void)
/* */
/* dos_gettime for the file time */
/* */
dtime dos_gettime(void)
time dos_gettime(void)
{
struct dostime dt;
@ -1584,17 +1582,13 @@ VOID bpb_to_dpb(bpb FAR * bpbp, REG struct dpb FAR * dpbp)
bpb sbpb;
fmemcpy(&sbpb, bpbp, sizeof(sbpb));
if (sbpb.bpb_nsector == 0) {
shftcnt = 8;
} else {
for (shftcnt = 0; (sbpb.bpb_nsector >> shftcnt) > 1; shftcnt++)
;
}
dpbp->dpb_shftcnt = shftcnt;
dpbp->dpb_mdb = sbpb.bpb_mdesc;
dpbp->dpb_secsize = sbpb.bpb_nbyte;
dpbp->dpb_clsmask = (sbpb.bpb_nsector - 1) & 0xFF;
dpbp->dpb_clsmask = sbpb.bpb_nsector - 1;
dpbp->dpb_fatstrt = sbpb.bpb_nreserved;
dpbp->dpb_fats = sbpb.bpb_nfat;
dpbp->dpb_dirents = sbpb.bpb_ndirent;

View File

@ -226,7 +226,7 @@ CLUSTER link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
if (ISFAT12(dpbp))
{
REG UBYTE FAR *fbp0; REG UBYTE FAR * fbp1;
REG UBYTE FAR *fbp0, FAR * fbp1;
struct buffer FAR * bp1;
unsigned cluster, cluster2;

View File

@ -47,8 +47,8 @@ STATIC void FcbNameInit(fcb FAR * lpFcb, BYTE * pszBuffer, COUNT * pCurDrive);
STATIC void FcbNextRecord(fcb FAR * lpFcb);
STATIC void FcbCalcRec(xfcb FAR * lpXfcb);
#define TestCmnSeps(lpFileName) (*lpFileName && strchr(":;,=+ \t", *lpFileName) != NULL)
#define TestFieldSeps(lpFileName) ((unsigned char)*lpFileName <= ' ' || strchr("/\\\"[]<>|.:;,=+\t", *lpFileName) != NULL)
#define TestCmnSeps(lpFileName) (*lpFileName && strchr(":<|>+=,", *lpFileName) != NULL)
#define TestFieldSeps(lpFileName) ((unsigned char)*lpFileName <= ' ' || strchr("/\"[]<>|.", *lpFileName) != NULL)
static dmatch Dmatch;
@ -78,7 +78,7 @@ BYTE FAR *FatGetDrvData(UBYTE drive, UBYTE * pspc, UWORD * bps, UWORD * nc)
return NULL;
}
#define PARSE_SKIP_LEAD_SEP 0x01
#define PARSE_SEP_STOP 0x01
#define PARSE_DFLT_DRIVE 0x02
#define PARSE_BLNK_FNAME 0x04
#define PARSE_BLNK_FEXT 0x08
@ -90,14 +90,13 @@ BYTE FAR *FatGetDrvData(UBYTE drive, UBYTE * pspc, UWORD * bps, UWORD * nc)
#ifndef IPL
UWORD FcbParseFname(UBYTE *wTestMode, const BYTE FAR * lpFileName, fcb FAR * lpFcb)
{
WORD wRetCodeDrive = FALSE, wRetCodeName = FALSE, wRetCodeExt = FALSE;
WORD wRetCodeName = FALSE, wRetCodeExt = FALSE;
/* pjv -- ExtFcbToFcb? */
/* skip leading separators if requested */
if (*wTestMode & PARSE_SKIP_LEAD_SEP)
if (!(*wTestMode & PARSE_SEP_STOP))
{
while (TestCmnSeps(lpFileName))
lpFileName = ParseSkipWh(lpFileName);
if (TestCmnSeps(lpFileName))
++lpFileName;
}
@ -105,20 +104,16 @@ UWORD FcbParseFname(UBYTE *wTestMode, const BYTE FAR * lpFileName, fcb FAR * lpF
lpFileName = ParseSkipWh(lpFileName);
/* Now check for drive specification */
/* If drive specified, set to it otherwise */
/* set to default drive unless leave as-is requested */
/* Undocumented behavior: should keep parsing even if drive */
/* specification is invalid -- tkchia 20220715 */
/* drive specification can refer to an invalid drive, but must */
/* not itself be a file name delimiter! -- tkchia 20220716 */
if (!TestFieldSeps(lpFileName) && *(lpFileName + 1) == ':')
if (*(lpFileName + 1) == ':')
{
/* non-portable construct to be changed */
REG UBYTE Drive = DosUpFChar(*lpFileName) - 'A';
if (get_cds(Drive) == NULL)
wRetCodeDrive = TRUE;
{
*wTestMode = PARSE_RET_BADDRIVE;
return FP_OFF(lpFileName);
}
lpFcb->fcb_drive = Drive + 1;
lpFileName += 2;
@ -127,8 +122,6 @@ UWORD FcbParseFname(UBYTE *wTestMode, const BYTE FAR * lpFileName, fcb FAR * lpF
}
/* Undocumented behavior, set record number & record size to 0 */
/* per MS-DOS Encyclopedia pp269 no other FCB fields modified */
/* except zeroing current block and record size fields */
lpFcb->fcb_cublock = lpFcb->fcb_recsiz = 0;
if (!(*wTestMode & PARSE_BLNK_FNAME))
@ -165,12 +158,7 @@ UWORD FcbParseFname(UBYTE *wTestMode, const BYTE FAR * lpFileName, fcb FAR * lpF
GetNameField(++lpFileName, (BYTE FAR *) lpFcb->fcb_fext,
FEXT_SIZE, (BOOL *) & wRetCodeExt);
if (wRetCodeDrive)
*wTestMode = PARSE_RET_BADDRIVE;
else if (wRetCodeName | wRetCodeExt)
*wTestMode = PARSE_RET_WILD;
else
*wTestMode = PARSE_RET_NOWILD;
*wTestMode = (wRetCodeName | wRetCodeExt) ? PARSE_RET_WILD : PARSE_RET_NOWILD;
return FP_OFF(lpFileName);
}
@ -181,6 +169,33 @@ const BYTE FAR * ParseSkipWh(const BYTE FAR * lpFileName)
return lpFileName;
}
#if 0 /* defined above */
BOOL TestCmnSeps(BYTE FAR * lpFileName)
{
BYTE *pszTest, *pszCmnSeps = ":<|>+=,";
for (pszTest = pszCmnSeps; *pszTest != '\0'; ++pszTest)
if (*lpFileName == *pszTest)
return TRUE;
return FALSE;
}
#endif
#if 0
BOOL TestFieldSeps(BYTE FAR * lpFileName)
{
BYTE *pszTest, *pszCmnSeps = "/\"[]<>|.";
/* Another non-portable construct */
if (*lpFileName <= ' ')
return TRUE;
for (pszTest = pszCmnSeps; *pszTest != '\0'; ++pszTest)
if (*lpFileName == *pszTest)
return TRUE;
return FALSE;
}
#endif
const BYTE FAR * GetNameField(const BYTE FAR * lpFileName, BYTE FAR * lpDestField,
COUNT nFieldSize, BOOL * pbWildCard)
@ -191,7 +206,8 @@ const BYTE FAR * GetNameField(const BYTE FAR * lpFileName, BYTE FAR * lpDestFiel
while (*lpFileName != '\0' && !TestFieldSeps(lpFileName)
&& nIndex < nFieldSize)
{
/* convert * into multiple ? for remaining length of field */
if (*lpFileName == ' ')
break;
if (*lpFileName == '*')
{
*pbWildCard = TRUE;
@ -199,11 +215,8 @@ const BYTE FAR * GetNameField(const BYTE FAR * lpFileName, BYTE FAR * lpDestFiel
++lpFileName;
break;
}
/* include ? as-is but flag for return purposes wildcard used */
if (*lpFileName == '?')
*pbWildCard = TRUE;
/* store uppercased character, and advance to next char */
*lpDestField++ = DosUpFChar(*lpFileName++);
++nIndex;
}
@ -517,8 +530,6 @@ UBYTE FcbDelete(xfcb FAR * lpXfcb)
UBYTE FcbRename(xfcb FAR * lpXfcb)
{
BYTE buf[FNAME_SIZE + FEXT_SIZE];
BOOL bWildCard;
rfcb FAR *lpRenameFcb;
COUNT FcbDrive;
UBYTE result = FCB_SUCCESS;
@ -526,9 +537,6 @@ UBYTE FcbRename(xfcb FAR * lpXfcb)
/* Build a traditional DOS file name */
lpRenameFcb = (rfcb FAR *) CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
/* expand wildcards in dest */
GetNameField(lpRenameFcb->renNewName, buf, FNAME_SIZE, &bWildCard);
GetNameField(lpRenameFcb->renNewExtent, buf + FNAME_SIZE, FEXT_SIZE, &bWildCard);
/* check for a device */
if (IsDevice(SecPathName))
@ -538,7 +546,7 @@ UBYTE FcbRename(xfcb FAR * lpXfcb)
else
{
dmatch Dmatch;
COUNT rc;
COUNT result;
wAttr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL);
dta = &Dmatch;
@ -553,7 +561,6 @@ UBYTE FcbRename(xfcb FAR * lpXfcb)
fcb LocalFcb;
BYTE *pToName;
const BYTE FAR *pFromPattern = Dmatch.dm_name;
const char *pToPattern = buf;
int i;
UBYTE mode = 0;
@ -562,20 +569,21 @@ UBYTE FcbRename(xfcb FAR * lpXfcb)
/* I'm cheating because this assumes that the */
/* struct alignments are on byte boundaries */
pToName = LocalFcb.fcb_fname;
pFromPattern = lpRenameFcb->renNewName;
for (i = 0; i < FNAME_SIZE + FEXT_SIZE; i++)
{
if (*pToPattern != '?')
*pToName = *pToPattern;
if (*pFromPattern != '?')
*pToName = *pFromPattern;
pToName++;
pToPattern++;
pFromPattern++;
}
SecPathName[0] = 'A' + FcbDrive - 1;
SecPathName[1] = ':';
strcpy(&SecPathName[2], Dmatch.dm_name);
rc = truename(SecPathName, PriPathName, 0);
result = truename(SecPathName, PriPathName, 0);
if (rc < SUCCESS || (rc & IS_DEVICE))
if (result < SUCCESS || (result & IS_DEVICE))
{
result = FCB_ERROR;
break;
@ -583,8 +591,8 @@ UBYTE FcbRename(xfcb FAR * lpXfcb)
/* now to build a dos name again */
LocalFcb.fcb_drive = FcbDrive;
FcbNameInit(&LocalFcb, loc_szBuffer, &FcbDrive);
rc = truename(loc_szBuffer, SecPathName, 0);
if (rc < SUCCESS || (rc & (IS_NETWORK|IS_DEVICE)) == IS_DEVICE
result = truename(loc_szBuffer, SecPathName, 0);
if (result < SUCCESS || (result & (IS_NETWORK|IS_DEVICE)) == IS_DEVICE
|| DosRenameTrue(PriPathName, SecPathName, wAttr) != SUCCESS)
{
result = FCB_ERROR;
@ -655,9 +663,7 @@ UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First)
/* Next initialze local variables by moving them from the fcb */
lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
if (First)
{
/* Reconstruct the dirmatch structure from the fcb */
/* Reconstrct the dirmatch structure from the fcb - doesn't hurt for first */
Dmatch.dm_drive = lpFcb->fcb_sftno;
fmemcpy(Dmatch.dm_name_pat, lpFcb->fcb_fname, FNAME_SIZE + FEXT_SIZE);
@ -668,7 +674,6 @@ UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First)
Dmatch.dm_dircluster = lpFcb->fcb_dirclst;
wAttr = D_ALL;
}
if ((xfcb FAR *) lpFcb != lpXfcb)
{

View File

@ -37,8 +37,8 @@ static BYTE *Globals_hRcsId =
#include "device.h"
#include "mcb.h"
#include "pcb.h"
#include "ddate.h"
#include "dtime.h"
#include "date.h"
#include "time.h"
#include "fat.h"
#include "fcb.h"
#include "tail.h"
@ -156,17 +156,18 @@ typedef BYTE *UPMAP;
/* */
/* External Assembly variables */
/* */
extern struct dhdr FAR ASM clk_dev; /* Clock device driver */
extern struct dhdr FAR ASM con_dev; /* Console device driver */
extern struct dhdr FAR ASM prn_dev; /* Generic printer device driver */
extern struct dhdr FAR ASM aux_dev; /* Generic aux device driver */
extern struct dhdr FAR ASM blk_dev; /* Block device (Disk) driver */
extern struct dhdr
FAR ASM clk_dev, /* Clock device driver */
FAR ASM con_dev, /* Console device driver */
FAR ASM prn_dev, /* Generic printer device driver */
FAR ASM aux_dev, /* Generic aux device driver */
FAR ASM blk_dev; /* Block device (Disk) driver */
extern COUNT *error_tos, /* error stack */
disk_api_tos, /* API handler stack - disk fns */
char_api_tos; /* API handler stack - char fns */
extern BYTE FAR _HMATextAvailable; /* first byte of available CODE area */
extern BYTE FAR _HMATextStart[]; /* first byte of HMAable CODE area */
extern BYTE FAR _HMATextEnd[]; /* and the last byte of it */
extern BYTE FAR _HMATextAvailable, /* first byte of available CODE area */
FAR _HMATextStart[], /* first byte of HMAable CODE area */
FAR _HMATextEnd[]; /* and the last byte of it */
extern
BYTE DosLoadedInHMA; /* if InitHMA has moved DOS up */
@ -235,8 +236,9 @@ extern UWORD ASM first_mcb, /* Start of user memory */
ASM uppermem_root; /* Start of umb chain (usually 9fff) */
extern char * ASM inputptr; /* pointer to unread CON input */
extern sfttbl FAR * ASM sfthead; /* System File Table head */
extern struct dhdr FAR * ASM clock; /* CLOCK$ device */
extern struct dhdr FAR * ASM syscon;/* console device */
extern struct dhdr
FAR * ASM clock, /* CLOCK$ device */
FAR * ASM syscon; /* console device */
extern WORD ASM maxsecsize; /* largest sector size in use (can use) */
extern struct buffer
FAR *ASM firstbuf; /* head of buffers linked list */
@ -268,8 +270,6 @@ extern BYTE ASM ErrorMode, /* Critical error flag */
ASM CritErrClass, ASM VgaSet,
ASM njoined; /* number of joined devices */
extern VOID FAR * ASM setverPtr; /* Pointer to SETVER list */
extern UWORD ASM Int21AX;
extern COUNT ASM CritErrCode;
extern BYTE FAR * ASM CritErrDev;
@ -372,9 +372,9 @@ VOID ASMPASCAL WriteATClock(BYTE *, BYTE, BYTE, BYTE);
VOID ASMPASCAL WritePCClock(ULONG);
intvec getvec(unsigned char);
#ifdef __WATCOMC__
#pragma aux (__pascal) ReadPCClock __modify __exact [__ax __cx __dx]
#pragma aux (__pascal) WriteATClock __modify __exact [__ax __bx __cx __dx]
#pragma aux (__pascal) WritePCClock __modify __exact [__ax __cx __dx]
#pragma aux (pascal) ReadPCClock modify exact [ax cx dx]
#pragma aux (pascal) WriteATClock modify exact [ax bx cx dx]
#pragma aux (pascal) WritePCClock modify exact [ax cx dx]
#endif
/* */
@ -410,12 +410,12 @@ void setvec(unsigned char intno, intvec vector);
/* ^Break handling */
#ifdef __WATCOMC__
#pragma aux (__cdecl) spawn_int23 __aborts;
#pragma aux (cdecl) spawn_int23 aborts;
#endif
void ASMCFUNC spawn_int23(void); /* procsupt.asm */
void ASMCFUNC DosIdle_hlt(void); /* dosidle.asm */
GLOBAL BYTE ASM ReturnAnyDosVersionExpected;
GLOBAL BYTE ReturnAnyDosVersionExpected;
GLOBAL BYTE ASM HaltCpuWhileIdle;
/* near fnodes:

View File

@ -1,6 +1,3 @@
#undef DOSFAR
#undef DOSTEXTFAR
/* Included by initialisation functions */
#if _MSC_VER != 0
@ -23,11 +20,6 @@ extern __segment DosTextSeg;
#define DOSFAR FAR
#define DOSTEXTFAR FAR
#elif defined(__GNUC__)
#define DOSFAR FAR
#define DOSTEXTFAR FAR
#elif !defined(I86)
#define DOSFAR

View File

@ -2,8 +2,8 @@
#define IN_INIT_MOD
#include "version.h"
#include "ddate.h"
#include "dtime.h"
#include "date.h"
#include "time.h"
#include "mcb.h"
#include "sft.h"
#include "fat.h"
@ -16,12 +16,12 @@
#include "tail.h"
#include "process.h"
#include "pcb.h"
#include "nls.h"
#include "buffer.h"
#include "dcb.h"
#include "lol.h"
#include "init-dat.h"
#include "nls.h"
#include "kconfig.h"
@ -38,7 +38,7 @@
#define BSS_INIT(x)
#endif
extern struct _KernelConfig ASM InitKernelConfig;
extern struct _KernelConfig InitKernelConfig;
/*
* Functions in `INIT_TEXT' may need to call functions in `_TEXT'. The entry
@ -57,7 +57,6 @@ extern struct _KernelConfig ASM InitKernelConfig;
#define memset init_memset
#define strchr init_strchr
#define strcpy init_strcpy
#define fstrcpy init_fstrcpy
#define strlen init_strlen
#define fstrlen init_fstrlen
#endif
@ -76,7 +75,6 @@ int ASMPASCAL fmemcmp(const void FAR *m1, const void FAR *m2, size_t n);
VOID ASMPASCAL memcpy( void *d, const void *s, size_t n);
VOID ASMPASCAL fmemcpy( void FAR *d, const void FAR *s, size_t n);
VOID ASMPASCAL strcpy(char *d, const char *s);
VOID ASMPASCAL fstrcpy(char FAR *d, const char FAR *s);
size_t ASMPASCAL strlen(const char *s);
size_t ASMPASCAL fstrlen(const char FAR *s);
char * ASMPASCAL strchr(const char *s, int ch);
@ -84,18 +82,17 @@ char * ASMPASCAL strchr(const char *s, int ch);
#ifdef __WATCOMC__
/* bx, cx, dx and es not used or clobbered for all asmsupt.asm functions except
(f)memchr/(f)strchr (which clobber dx) */
#pragma aux (__pascal) pascal_ax __modify __exact [__ax]
#pragma aux (pascal) pascal_ax modify exact [ax]
#pragma aux (pascal_ax) memset
#pragma aux (pascal_ax) fmemset
#pragma aux (pascal_ax) memcpy
#pragma aux (pascal_ax) fmemcpy
#pragma aux (pascal_ax) memcmp __modify __nomemory
#pragma aux (pascal_ax) fmemcmp __modify __nomemory
#pragma aux (pascal_ax) memcmp modify nomemory
#pragma aux (pascal_ax) fmemcmp modify nomemory
#pragma aux (pascal_ax) strcpy
#pragma aux (pascal_ax) fstrcpy
#pragma aux (pascal_ax) strlen __modify __nomemory
#pragma aux (pascal_ax) fstrlen __modify __nomemory
#pragma aux (__pascal) strchr __modify __exact [__ax __dx] __nomemory
#pragma aux (pascal_ax) strlen modify nomemory
#pragma aux (pascal_ax) fstrlen modify nomemory
#pragma aux (pascal) strchr modify exact [ax dx] nomemory
#endif
#undef LINESIZE
@ -147,7 +144,7 @@ COUNT ASMPASCAL Umb_Test(void);
COUNT ASMPASCAL UMB_get_largest(void FAR * driverAddress,
UCOUNT * seg, UCOUNT * size);
#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 */
@ -185,18 +182,18 @@ int ASMPASCAL init_switchar(int chr);
void ASMPASCAL keycheck(void);
void ASMPASCAL set_DTA(void far *dta);
#ifdef __WATCOMC__
#pragma aux (__pascal) init_call_intr __modify __exact [__ax]
#pragma aux (__pascal) read __modify __exact [__ax __bx __cx __dx]
#pragma aux (__pascal) init_DosOpen __modify __exact [__ax __bx __dx]
#pragma aux (__pascal) close __modify __exact [__ax __bx]
#pragma aux (__pascal) dup2 __modify __exact [__ax __bx __cx]
#pragma aux (__pascal) allocmem __modify __exact [__ax __bx]
#pragma aux (__pascal) init_PSPSet __modify __exact [__ax __bx]
#pragma aux (__pascal) init_DosExec __modify __exact [__ax __bx __dx __es]
#pragma aux (__pascal) init_setdrive __modify __exact [__ax __bx __dx]
#pragma aux (__pascal) init_switchar __modify __exact [__ax __bx __dx]
#pragma aux (__pascal) keycheck __modify __exact [__ax]
#pragma aux (__pascal) set_DTA __modify __exact [__ax __bx __dx]
#pragma aux (pascal) init_call_intr modify exact [ax]
#pragma aux (pascal) read modify exact [ax bx cx dx]
#pragma aux (pascal) init_DosOpen modify exact [ax bx dx]
#pragma aux (pascal) close modify exact [ax bx]
#pragma aux (pascal) dup2 modify exact [ax bx cx]
#pragma aux (pascal) allocmem modify exact [ax bx]
#pragma aux (pascal) init_PSPSet modify exact [ax bx]
#pragma aux (pascal) init_DosExec modify exact [ax bx dx es]
#pragma aux (pascal) init_setdrive modify exact [ax bx dx]
#pragma aux (pascal) init_switchar modify exact [ax bx dx]
#pragma aux (pascal) keycheck modify exact [ax]
#pragma aux (pascal) set_DTA modify exact [ax bx dx]
#endif
/* irqstack.asm */
@ -204,6 +201,8 @@ VOID ASMCFUNC init_stacks(VOID FAR * stack_base, COUNT nStacks,
WORD stackSize);
/* inthndlr.c */
VOID ASMCFUNC FAR int21_entry(iregs UserRegs);
VOID ASMCFUNC int21_service(iregs far * r);
VOID ASMCFUNC FAR int0_handler(void);
VOID ASMCFUNC FAR int6_handler(void);
VOID ASMCFUNC FAR int19_handler(void);
@ -222,11 +221,7 @@ VOID ASMCFUNC FAR int2f_handler(void);
VOID ASMCFUNC FAR cpm_entry(void);
/* kernel.asm */
#ifdef __GNUC__
VOID ASMCFUNC init_call_p_0(struct config FAR *Config) FAR __attribute__((noreturn));
#else
VOID ASMCFUNC FAR init_call_p_0(struct config FAR *Config); /* P_0, actually */
#endif
/* main.c */
VOID ASMCFUNC FreeDOSmain(void);
@ -254,26 +249,25 @@ 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 FAR ASM master_env[128];
extern char master_env[128];
extern struct lol FAR *LoL;
extern struct dhdr DOSTEXTFAR ASM blk_dev; /* Block device (Disk) driver */
extern struct buffer FAR *DOSFAR firstAvailableBuf; /* first 'available' buffer */
extern struct lol FAR ASM DATASTART;
extern struct lol ASM FAR DATASTART;
extern BYTE DOSFAR ASM _HMATextAvailable; /* first byte of available CODE area */
extern BYTE FAR ASM _HMATextStart[]; /* first byte of HMAable CODE area */
extern BYTE FAR ASM _HMATextEnd[];
extern BYTE DOSFAR ASM break_ena; /* break enabled flag */
extern BYTE DOSFAR ASM _InitTextStart[]; /* first available byte of ram */
extern BYTE DOSFAR ASM _InitTextEnd[];
extern BYTE DOSFAR ASM ReturnAnyDosVersionExpected;
extern BYTE DOSFAR ASM HaltCpuWhileIdle;
extern BYTE DOSFAR ASM _HMATextAvailable, /* first byte of available CODE area */
FAR ASM _HMATextStart[], /* first byte of HMAable CODE area */
FAR ASM _HMATextEnd[], DOSFAR ASM break_ena; /* break enabled flag */
extern BYTE DOSFAR ASM _InitTextStart[], /* first available byte of ram */
DOSFAR ASM _InitTextEnd[],
DOSFAR ReturnAnyDosVersionExpected,
DOSFAR ASM HaltCpuWhileIdle;
extern BYTE DOSFAR ASM internal_data[];
extern unsigned char DOSTEXTFAR ASM kbdType;
extern BYTE FAR ASM internal_data[];
extern unsigned char FAR ASM kbdType;
extern struct {
char ThisIsAConstantOne;
@ -281,7 +275,7 @@ extern struct {
struct CountrySpecificInfo C;
} DOSFAR ASM nlsCountryInfoHardcoded;
} FAR ASM nlsCountryInfoHardcoded;
/*
data shared between DSK.C and INITDISK.C
@ -316,26 +310,21 @@ struct RelocatedEntry {
UWORD jmpSegment;
};
extern struct RelocationTable DOSFAR ASM _HMARelocationTableStart[];
extern struct RelocationTable DOSFAR ASM _HMARelocationTableEnd[];
extern struct RelocationTable
DOSFAR ASM _HMARelocationTableStart[],
DOSFAR ASM _HMARelocationTableEnd[];
extern void FAR *DOSFAR ASM XMSDriverAddress;
extern UBYTE DOSFAR ASM XMS_Enable_Patch;
#ifdef __GNUC__
extern VOID ASMPASCAL _EnableA20(VOID) FAR;
extern VOID ASMPASCAL _DisableA20(VOID) FAR;
#else
extern VOID ASMPASCAL FAR _EnableA20(VOID);
extern VOID ASMPASCAL FAR _DisableA20(VOID);
#endif
extern void FAR * ASMPASCAL DetectXMSDriver(VOID);
extern int ASMPASCAL init_call_XMScall(void FAR * driverAddress, UWORD ax,
UWORD dx);
#ifdef __WATCOMC__
#pragma aux (__pascal) DetectXMSDriver __modify __exact [__ax __dx]
#pragma aux (__pascal) _EnableA20 __modify __exact [__ax]
#pragma aux (__pascal) _DisableA20 __modify __exact [__ax]
#pragma aux (pascal) DetectXMSDriver modify exact [ax dx]
#pragma aux (pascal) _EnableA20 modify exact [ax]
#pragma aux (pascal) _DisableA20 modify exact [ax]
#endif
#if defined(WATCOM) && 0

View File

@ -356,7 +356,7 @@ void init_LBA_to_CHS(struct CHS *chs, ULONG LBA_address,
void printCHS(char *title, struct CHS *chs)
{
/* has no fixed size for head/sect: is often 1/1 in our context */
if (InitKernelConfig.Verbose >= 0) printf("%s%4u-%u-%u", title, chs->Cylinder, chs->Head, chs->Sector);
printf("%s%4u-%u-%u", title, chs->Cylinder, chs->Head, chs->Sector);
}
/*
@ -417,7 +417,7 @@ VOID CalculateFATData(ddt * pddt, ULONG NumSectors, UBYTE FileSystem)
* (This is really done in fatfs.c, bpbtodpb) */
{
unsigned clust = (fatdat - 2 * defbpb->bpb_nfsect) / NSECTORFAT12;
unsigned maxclust = (defbpb->bpb_nfsect * 2 * FLOPPY_SEC_SIZE) / 3;
unsigned maxclust = (defbpb->bpb_nfsect * 2 * SEC_SIZE) / 3;
if (maxclust > FAT12MAX)
maxclust = FAT12MAX;
printf("FAT12: #clu=%u, fatlength=%u, maxclu=%u, limit=%u\n",
@ -434,7 +434,7 @@ VOID CalculateFATData(ddt * pddt, ULONG NumSectors, UBYTE FileSystem)
else
{ /* FAT16/FAT32 */
CLUSTER fatlength, maxcl;
unsigned long clust, maxclust, rest;
unsigned long clust, maxclust;
unsigned fatentpersec;
unsigned divisor;
@ -458,7 +458,7 @@ VOID CalculateFATData(ddt * pddt, ULONG NumSectors, UBYTE FileSystem)
defbpb->bpb_ndirent = 0;
defbpb->bpb_nreserved = 0x20;
fatdata = NumSectors - 0x20;
fatentpersec = FLOPPY_SEC_SIZE/4; /* how many 32bit FAT values fit in a default 512 byte sector */
fatentpersec = FLOPPY_SEC_SIZE/4;
maxcl = FAT32MAX;
}
else
@ -473,19 +473,17 @@ VOID CalculateFATData(ddt * pddt, ULONG NumSectors, UBYTE FileSystem)
max FAT16 size for FreeDOS = 4,293,984,256 bytes = 4GiB-983,040 */
if (fatdata > 8386688ul)
fatdata = 8386688ul;
fatentpersec = FLOPPY_SEC_SIZE/2; /* how many 16bit FAT values fit in a default 512 byte sector */
fatentpersec = FLOPPY_SEC_SIZE/2;
maxcl = FAT16MAX;
}
DebugPrintf(("%lu sectors for FAT+data, starting with %u sectors/cluster\n", fatdata, defbpb->bpb_nsector));
DebugPrintf(("%ld sectors for FAT+data, starting with %d sectors/cluster\n", fatdata, defbpb->bpb_nsector));
do
{
DebugPrintf(("Trying with %u sectors/cluster:\n", defbpb->bpb_nsector));
divisor = fatentpersec * defbpb->bpb_nsector + NFAT; /* # of fat entries per cluster + 2 */
rest = (unsigned)(fatdata % divisor);
fatlength = (CLUSTER)(fatdata / divisor);
fatlength += (CLUSTER)((2 * defbpb->bpb_nsector + divisor + rest - 1) / divisor);
DebugPrintf(("Trying with %d sectors/cluster:\n", defbpb->bpb_nsector));
divisor = fatentpersec * defbpb->bpb_nsector + NFAT;
fatlength = (CLUSTER)((fatdata + (2 * defbpb->bpb_nsector + divisor - 1))/
divisor);
/* Need to calculate number of clusters, since the unused parts of the
* FATS and data area together could make up space for an additional,
* not really present cluster. */
@ -494,7 +492,7 @@ VOID CalculateFATData(ddt * pddt, ULONG NumSectors, UBYTE FileSystem)
if (maxclust > maxcl)
maxclust = maxcl;
DebugPrintf(("FAT: #clu=%lu, fatlen=%lu, maxclu=%lu, limit=%lu\n",
clust, (ULONG)fatlength, maxclust, (ULONG)maxcl));
clust, fatlength, maxclust, maxcl));
if (clust > maxclust - 2)
{
clust = 0;
@ -564,10 +562,10 @@ void DosDefinePartition(struct DriveParamS *driveParam,
pddt->ddt_driveno = driveParam->driveno;
pddt->ddt_logdriveno = nUnits;
pddt->ddt_descflags = driveParam->descflags;
/* Turn off LBA if not forced and the partition is within 1023 cyls and of the right type */
/* Turn of LBA if not forced and the partition is within 1023 cyls and of the right type */
/* the FileSystem type was internally converted to LBA_xxxx if a non-LBA partition
above cylinder 1023 was found */
if (!(InitKernelConfig.ForceLBA || IsLBAPartition(pEntry->FileSystem) || ExtLBAForce))
if (!InitKernelConfig.ForceLBA && !ExtLBAForce && !IsLBAPartition(pEntry->FileSystem))
pddt->ddt_descflags &= ~DF_LBA;
pddt->ddt_ncyl = driveParam->chs.Cylinder;
@ -631,47 +629,49 @@ void DosDefinePartition(struct DriveParamS *driveParam,
}
/* Get the parameters of the hard disk */
STATIC int LBA_Get_Drive_Parameters(int drive, struct DriveParamS *driveParam, int firstPass)
STATIC int LBA_Get_Drive_Parameters(int drive, struct DriveParamS *driveParam)
{
iregs regs;
struct _bios_LBA_disk_parameterS lba_bios_parameters;
if (firstPass && (InitKernelConfig.Verbose >= 1))
printf("Checking for LBA support in BIOS for drive %02x\n", drive);
ExtLBAForce = FALSE;
memset(driveParam, 0, sizeof *driveParam);
drive |= 0x80;
/* use CHS if LBA support is not enabled by kernel configuration */
/* for tests - disable LBA support,
even if exists */
if (!InitKernelConfig.GlobalEnableLBAsupport)
{
if (firstPass && (InitKernelConfig.Verbose >= 1)) printf("LBA support disabled.\n");
goto StandardBios;
}
/* check for LBA support */
regs.b.x = 0x55aa;
regs.a.b.h = 0x41;
regs.d.b.l = drive;
regs.flags = FLG_CARRY; /* ensure carry is set to force error if unsupported */
init_call_intr(0x13, &regs);
if ((regs.flags & FLG_CARRY) || regs.b.x != 0xaa55 || !(regs.c.x & 0x01))
if (regs.b.x != 0xaa55 || (regs.flags & 0x01))
{
/* error conditions:
carry set or BX != 0xaa55 => no EDD spec compatible BIOS (LBA extensions not supported)
CX bit 1 is set if BIOS supports fixed disk subset (Disk Address Packet [DAP] subset),
or clear if fixed disk access subset not supported by LBA extensions
*/
goto StandardBios;
}
/* version 1.0, 2.0 have different verify */
if (regs.a.b.h < 0x21)
LBA_WRITE_VERIFY = 0x4301; /* may be problematic if INT13 is hooked by
different controllers / drivers */
/* by ralph :
if DAP cannot be used, don't use
LBA
*/
if ((regs.c.x & 1) == 0)
{
goto StandardBios;
}
/* drive supports LBA addressing */
/* version 1.0, 2.0 have different verify */
if (regs.a.x < 0x2100)
LBA_WRITE_VERIFY = 0x4301;
/* query disk size and DMA handling, geometry is queried later by INT13,08 */
memset(&lba_bios_parameters, 0, sizeof(lba_bios_parameters));
lba_bios_parameters.size = sizeof(lba_bios_parameters);
@ -681,56 +681,37 @@ STATIC int LBA_Get_Drive_Parameters(int drive, struct DriveParamS *driveParam, i
regs.d.b.l = drive;
init_call_intr(0x13, &regs);
if (regs.flags & FLG_CARRY)
/* error or DMA boundary errors not handled transparently */
if (regs.flags & 0x01)
{
/* carry flag set indicates failed LBA disk parameter query */
goto StandardBios;
}
/* verify maximum settings, we can't handle more */
if (lba_bios_parameters.heads > 0xffff ||
lba_bios_parameters.sectors > 0xffff ||
(lba_bios_parameters.totalSect == 0 &&
lba_bios_parameters.totalSectHigh == 0))
lba_bios_parameters.totalSectHigh != 0)
{
if (firstPass)
{
printf("Suspicious LBA disk parameters, reverting to CHS access:\n");
printf(" drive %02x, heads=%lu, sectors=%lu, total=0x%lx-%08lx\n",
printf("Drive is too large to handle, using only 1st 8 GB\n"
" drive %02x heads %lu sectors %lu , total=0x%lx-%08lx\n",
drive,
(ULONG) lba_bios_parameters.heads,
(ULONG) lba_bios_parameters.sectors,
(ULONG) lba_bios_parameters.totalSect,
(ULONG) lba_bios_parameters.totalSectHigh);
}
goto StandardBios;
}
/* restrict disk size to 2TB, because we can not handle more */
if (lba_bios_parameters.totalSectHigh == 0)
{
driveParam->total_sectors = lba_bios_parameters.totalSect;
}
else
{
if (firstPass) printf("Drive %02x is too large to handle, restricted to 2TB\n", drive);
driveParam->total_sectors = 0xffffffffUL;
}
/* if we arrive here, mark drive as LBA capable */
/* if we arrive here, success */
driveParam->descflags = DF_LBA;
if (lba_bios_parameters.information & 8)
driveParam->descflags |= DF_WRTVERIFY;
if (lba_bios_parameters.information & 1)
{
/* DMA boundary errors are handled transparently */
driveParam->descflags |= DF_DMA_TRANSPARENT;
}
StandardBios: /* get disk geometry, and if LBA is not enabled, also size */
if (firstPass && (InitKernelConfig.Verbose >= 1))
printf("Retrieving CHS values for drive\n");
StandardBios: /* old way to get parameters */
regs.a.b.h = 0x08;
regs.d.b.l = drive;
@ -738,9 +719,7 @@ StandardBios: /* get disk geometry, and if LBA is not enabled, also size */
init_call_intr(0x13, &regs);
if (regs.flags & 0x01)
{
goto ErrorReturn;
}
/* int13h call returns max value, store as count (#) i.e. +1 for 0 based heads & cylinders */
driveParam->chs.Head = (regs.d.x >> 8) + 1; /* DH = max head value = # of heads - 1 (0-255) */
@ -751,7 +730,6 @@ StandardBios: /* get disk geometry, and if LBA is not enabled, also size */
if (driveParam->chs.Sector == 0) {
/* happens e.g. with Bochs 1.x if no harddisk defined */
driveParam->chs.Sector = 63; /* avoid division by zero...! */
if (firstPass && (InitKernelConfig.Verbose >= 0))
printf("BIOS reported 0 sectors/track, assuming 63!\n");
}
@ -770,15 +748,9 @@ StandardBios: /* get disk geometry, and if LBA is not enabled, also size */
driveParam->chs.Head, driveParam->chs.Sector));
DebugPrintf((" total size %luMB\n\n", driveParam->total_sectors / 2048));
return driveParam->driveno;
ErrorReturn:
/* to avoid division by zero later, use some sane defaults */
driveParam->total_sectors = 0;
driveParam->chs.Head = 16;
driveParam->chs.Sector = 63;
return 0;
return driveParam->driveno;
}
/*
@ -841,15 +813,12 @@ void print_warning_suspect(char *partitionName, UBYTE fs, struct CHS *chs,
struct CHS *pEntry_chs)
{
if (!InitKernelConfig.ForceLBA)
{
if (InitKernelConfig.Verbose >= 0)
{
printf("WARNING: using suspect partition %s FS %02x:", partitionName, fs);
printCHS(" with calculated values ", chs);
printCHS(" instead of ", pEntry_chs);
printf("\n");
}
}
memcpy(pEntry_chs, chs, sizeof(struct CHS));
}
@ -919,7 +888,6 @@ BOOL ScanForPrimaryPartitions(struct DriveParamS * driveParam, int scan_type,
if (chs.Cylinder > 1023 || end.Cylinder > 1023)
{
/* if partition exceeds bounds of CHS addressing but LBA is not supported then skip partition */
if (!(driveParam->descflags & DF_LBA))
{
printf
@ -933,11 +901,8 @@ BOOL ScanForPrimaryPartitions(struct DriveParamS * driveParam, int scan_type,
continue;
}
/* if partition exceeds bounds of CHS addressing and we can use LBA
but partition type indicates to use CHS then print warning
and force internal filesystem indicator to enable LBA
*/
if (!(InitKernelConfig.ForceLBA || IsLBAPartition(pEntry->FileSystem) || ExtLBAForce))
if (!InitKernelConfig.ForceLBA && !ExtLBAForce
&& !IsLBAPartition(pEntry->FileSystem))
{
printf
("WARNING: Partition ID does not suggest LBA - part %s FS %02x.\n"
@ -1008,11 +973,6 @@ int Read1LBASector(struct DriveParamS *driveParam, unsigned drive,
for (num_retries = 0; num_retries < N_RETRY; num_retries++)
{
if (InitKernelConfig.Verbose >= 1)
{
printf("retry# %i sector %lu\n", num_retries, LBA_address);
}
regs.d.b.l = drive | 0x80;
LBA_to_CHS(&chs, LBA_address, driveParam);
/* Some old "security" software (PROT) traps int13 and assumes non
@ -1022,9 +982,8 @@ int Read1LBASector(struct DriveParamS *driveParam, unsigned drive,
the extended LBA partition type indicator.
*/
if ((driveParam->descflags & DF_LBA) &&
(InitKernelConfig.ForceLBA || ExtLBAForce || (chs.Cylinder > 1023)))
(InitKernelConfig.ForceLBA || ExtLBAForce || chs.Cylinder > 1023))
{
if (InitKernelConfig.Verbose >= 1) printf("LBA mode\n");
dap.number_of_blocks = 1;
dap.buffer_address = buffer;
dap.block_address_high = 0; /* clear high part */
@ -1037,7 +996,6 @@ int Read1LBASector(struct DriveParamS *driveParam, unsigned drive,
}
else
{ /* transfer data, using old bios functions */
if (InitKernelConfig.Verbose >= 1) printf("CHS mode\n");
/* avoid overflow at end of track */
if (chs.Cylinder > 1023)
@ -1066,7 +1024,6 @@ int Read1LBASector(struct DriveParamS *driveParam, unsigned drive,
/* Load the Partition Tables and get information on all drives */
int ProcessDisk(int scanType, unsigned drive, int PartitionsToIgnore)
{
/* note: error messages are only printed on first call, where (scanType==SCAN_PRIMARYBOOT) */
struct PartTableEntry PTable[4];
ULONG RelSectorOffset;
@ -1081,7 +1038,7 @@ int ProcessDisk(int scanType, unsigned drive, int PartitionsToIgnore)
/* Get the hard drive parameters and ensure that the drive exists. */
/* If there was an error accessing the drive, skip that drive. */
if (!LBA_Get_Drive_Parameters(drive, &driveParam,(scanType==SCAN_PRIMARYBOOT)))
if (!LBA_Get_Drive_Parameters(drive, &driveParam))
{
printf("can't get drive parameters for drive %02x\n", drive);
return PartitionsToIgnore;
@ -1089,9 +1046,6 @@ int ProcessDisk(int scanType, unsigned drive, int PartitionsToIgnore)
RelSectorOffset = 0; /* boot sector */
ExtendedPartitionOffset = 0; /* not found yet */
ExtLBAForce = 0; /* initially we are not dealing with partitions
within a type 0x0E LBA extended partition,
so we do not enforce LBA access by now */
/* Read the Primary Partition Table. */
@ -1118,7 +1072,7 @@ strange_restart:
if (++strangeHardwareLoop < 3)
goto strange_restart;
if (scanType==SCAN_PRIMARYBOOT) printf("illegal partition table - drive %02x sector %lu\n", drive,
printf("illegal partition table - drive %02x sector %lu\n", drive,
RelSectorOffset);
return PartitionsToIgnore;
}
@ -1148,7 +1102,7 @@ strange_restart:
{
RelSectorOffset = ExtendedPartitionOffset + PTable[iPart].RelSect;
if (ExtendedPartitionOffset == 0) /* first extended in chain? */
if (ExtendedPartitionOffset == 0)
{
ExtendedPartitionOffset = PTable[iPart].RelSect;
/* grand parent LBA -> all children and grandchildren LBA */
@ -1359,7 +1313,7 @@ void ReadAllPartitionTables(void)
if (InitKernelConfig.DLASortByDriveNo == 0)
{
if (InitKernelConfig.Verbose >= 1) printf("Drive Letter Assignment - DOS order\n");
/* printf("Drive Letter Assignment - DOS order\n"); */
/* Process primary partition table 1 partition only */
for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++)
@ -1388,13 +1342,13 @@ void ReadAllPartitionTables(void)
{
UBYTE bootdrv = peekb(0,0x5e0);
if (InitKernelConfig.Verbose >= 1) printf("Drive Letter Assignment - sorted by drive\n");
/* printf("Drive Letter Assignment - sorted by drive\n"); */
/* Process primary partition table 1 partition only */
for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++)
{
struct DriveParamS driveParam;
if (LBA_Get_Drive_Parameters(HardDrive, &driveParam, 0) &&
if (LBA_Get_Drive_Parameters(HardDrive, &driveParam) &&
driveParam.driveno == bootdrv)
{
foundPartitions[HardDrive] =
@ -1422,26 +1376,14 @@ void ReadAllPartitionTables(void)
ProcessDisk(SCAN_PRIMARY2, HardDrive, foundPartitions[HardDrive]);
}
}
if (InitKernelConfig.Verbose >= 0)
{
unsigned foundPartitionsCount = 0;
/* Tell user if no valid partitions found on any hard drive */
for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++)
{
foundPartitionsCount += foundPartitions[HardDrive];
}
/* printf("Found %i partitions\n", foundPartitionsCount); */
if (!foundPartitionsCount) printf("No supported partitions found.\n");
}
}
/* disk initialization: returns number of units */
COUNT dsk_init()
{
if (InitKernelConfig.Verbose >= 1) printf("\nInitDisk\n");
printf(" - InitDisk");
#if defined(DEBUG) && !defined(DOSEMU)
#ifdef DEBUG
{
iregs regs;
regs.a.x = 0x1112; /* select 43 line mode - more space for partinfo */

View File

@ -78,7 +78,7 @@ UWORD HMAFree BSS_INIT(0); /* first byte in HMA not yet used */
STATIC void InstallVDISK(void);
#ifdef DEBUG
#if defined(__TURBOC__) || defined(__GNUC__)
#ifdef __TURBOC__
#define int3() __int__(3);
#else
void int3()
@ -179,7 +179,6 @@ int MoveKernelToHMA()
return FALSE;
XMSDriverAddress = xms_addr;
XMS_Enable_Patch = 0x90; /* must be set after XMSDriverAddress */
#ifdef DEBUG
/* A) for debugging purpose, suppress this,
@ -305,7 +304,6 @@ VOID FAR * HMAalloc(COUNT bytesToAllocate)
unsigned CurrentKernelSegment = 0;
/* relocate segment with HMA_TEXT code group */
void MoveKernel(unsigned NewKernelSegment)
{
UBYTE FAR *HMADest;
@ -313,11 +311,9 @@ void MoveKernel(unsigned NewKernelSegment)
unsigned len;
unsigned jmpseg = CurrentKernelSegment;
/* if the first time called, initialize to end of HMA_TEXT code group segment */
if (CurrentKernelSegment == 0)
CurrentKernelSegment = FP_SEG(_HMATextEnd);
/* if already relocated into HMA, nothing to do */
if (CurrentKernelSegment == 0xffff)
return;
@ -327,8 +323,6 @@ void MoveKernel(unsigned NewKernelSegment)
len = (FP_OFF(_HMATextEnd) | 0x000f) - (FP_OFF(_HMATextStart) & 0xfff0);
/* HMA doesn't start until a paragraph into 0xffff segment */
/* HMA begins with VDISK header to mark area is used */
if (NewKernelSegment == 0xffff)
{
HMASource += HMAOFFSET;
@ -358,8 +352,7 @@ void MoveKernel(unsigned NewKernelSegment)
style table
*/
struct RelocationTable FAR *rp;
struct RelocationTable rtemp;
struct RelocationTable FAR *rp, rtemp;
/* verify, that all entries are valid */

View File

@ -31,56 +31,9 @@
%include "segs.inc"
%include "stacks.inc"
; macro to switch to an internal stack (if necessary), set DS == SS == DGROUP,
; and push the old SS:SP onto the internal stack
;
; destroys AX, SI, BP; turns on IRQs
;
; int2f does not really need to switch to a separate stack for MS-DOS
; compatibility; this is mainly to work around the C code's assumption
; that SS == DGROUP
;
; TODO: remove the need for this hackery -- tkchia
%macro SwitchToInt2fStack 0
mov ax,[cs:_DGROUP_]
mov ds,ax
mov si,ss
mov bp,sp
cmp ax,si
jz %%already
cli
mov ss,ax
extern int2f_stk_top
mov sp,int2f_stk_top
sti
%%already:
; well, GCC does not currently clobber function parameters passed on the
; stack; but just in case it decides to do that in the future, we push _two_
; copies of the old SS:SP:
; - the second copy can be passed as a pointer parameter to a C function
; - the first copy is used to actually restore the user stack later
push si
push bp
push si
push bp
%endmacro
; macro to switch back from an internal stack, i.e. undo SwitchToInt2fStack
;
; destroys BP; turns on IRQs -- tkchia
%macro DoneInt2fStack 0
pop bp
pop bp
pop bp
cli
pop ss
mov sp,bp
sti
%endmacro
segment HMA_TEXT
extern _cu_psp
extern _HaltCpuWhileIdle
extern _cu_psp:wrt DGROUP
extern _HaltCpuWhileIdle:wrt DGROUP
extern _syscall_MUX14
extern _DGROUP_
@ -122,14 +75,10 @@ WinIdle: ; only HLT if at haltlevel 2+
Int2f3: cmp ax,1680h ; Win "release time slice"
je WinIdle
cmp ah,16h
je FarTabRetn ; other Win Hook return fast
cmp ah,12h
je IntDosCal ; Dos Internal calls
cmp ah,13h
je IntDosCal ; Install Int13h Hook
cmp ah,16h
je IntDosCal ; Win (Multitasking) Hook
cmp ah,46h
je IntDosCal ; Win Hook to avoid MCB corruption
cmp ax,4a01h
je IntDosCal ; Dos Internal calls
@ -139,9 +88,6 @@ Int2f3: cmp ax,1680h ; Win "release time slice"
cmp ax,4a33h ; Check DOS version 7
jne Check4Share
xor ax,ax ; no undocumented shell strings
xor bx,bx ; RBIL undoc BX = ?? (0h)
; " DS:DX ASCIIZ shell exe name
; " DS:SI SHELL= line
iret
Check4Share:
%endif
@ -156,9 +102,8 @@ Int2f?14: ;; MUX-14 -- NLSFUNC API
push bp ; Preserve BP later on
Protect386Registers
PUSH$ALL
SwitchToInt2fStack
mov ds, [cs:_DGROUP_]
call _syscall_MUX14
DoneInt2fStack
pop bp ; Discard incoming AX
push ax ; Correct stack for POP$ALL
POP$ALL
@ -178,7 +123,7 @@ Int2f?iret:
; DRIVER.SYS calls - now only 0803.
DriverSysCal:
extern _Dyn
extern _Dyn:wrt DGROUP
cmp al, 3
jne Int2f?iret
mov ds, [cs:_DGROUP_]
@ -190,7 +135,7 @@ DriverSysCal:
; internal dos calls INT2F/12xx and INT2F/4A01,4A02 - handled through C
;**********************************************************************
IntDosCal:
; set up register structure
; set up register frame
;struct int2f12regs
;{
; [space for 386 regs]
@ -220,10 +165,9 @@ IntDosCal:
%endif
%endif
SwitchToInt2fStack
mov ds,[cs:_DGROUP_]
extern _int2F_12_handler
call _int2F_12_handler
DoneInt2fStack
%if XCPU >= 386
%ifdef WATCOM
@ -250,7 +194,6 @@ IntDosCal:
SHARE_CHECK:
mov ax, 0x1000
int 0x2f
test ax, "US" ; Uninstallable SHARE signature
ret
; DOS calls this to see if it's okay to open the file.
@ -259,7 +202,7 @@ SHARE_CHECK:
; error. If < 0 is returned, it is the negated error return
; code, so DOS simply negates this value and returns it in
; AX.
; STATIC int share_open_check(const char FAR * filename,
; STATIC int share_open_check(char * filename,
; /* pointer to fully qualified filename */
; unsigned short pspseg,
; /* psp segment address of owner process */
@ -268,17 +211,16 @@ SHARE_CHECK:
; int sharemode) /* SHARE_COMPAT, etc... */
global SHARE_OPEN_CHECK
SHARE_OPEN_CHECK:
push ds
pop es ; save ds
mov di, si ; save si
mov es, si ; save si
pop ax ; return address
popargs {ds,si},bx,cx,dx; filename,pspseg,openmode,sharemode;
pop dx ; sharemode;
pop cx ; openmode;
pop bx ; pspseg;
pop si ; filename
push ax ; return address
mov ax, 0x10a0
int 0x2f ; returns ax
mov si, di ; restore si
push es
pop ds ; restore ds
mov si, es ; restore si
ret
; DOS calls this to record the fact that it has successfully
@ -319,13 +261,12 @@ share_common:
mov bp, sp
push si
push di
arg pspseg, fileno, {ofs,4}, {len,4}, allowcriter
mov bx, [.pspseg] ; pspseg
mov cx, [.fileno] ; fileno
mov si, [.ofs+2] ; high word of ofs
mov di, [.ofs] ; low word of ofs
les dx, [.len] ; len
or ax, [.allowcriter] ; allowcriter/unlock
mov bx, [bp + 16] ; pspseg
mov cx, [bp + 14] ; fileno
mov si, [bp + 12] ; high word of ofs
mov di, [bp + 10] ; low word of ofs
les dx, [bp + 6] ; len
or ax, [bp + 4] ; allowcriter/unlock
int 0x2f
pop di
pop si
@ -347,25 +288,6 @@ SHARE_LOCK_UNLOCK:
mov ax,0x10a4
jmp short share_common
; DOS calls this to see if share already has the file marked as open.
; Returns:
; 1 if open
; 0 if not
; STATIC WORD share_is_file_open(const char far *filename) /* pointer to fully qualified filename */
global SHARE_IS_FILE_OPEN
SHARE_IS_FILE_OPEN:
mov si, ds
mov es, si ; save ds
pop ax ; save return address
pop si ; filename
pop ds ; SEG filename
push ax ; restore return address
mov ax, 0x10a6
int 0x2f ; returns ax
mov si, es ; restore ds
mov ds, si
ret
; Int 2F Multipurpose Remote System Calls
;
; added by James Tabor jimtabor@infohwy.com
@ -401,8 +323,10 @@ remote_lock_unlock:
global NETWORK_REDIRECTOR_MX
NETWORK_REDIRECTOR_MX:
pop bx ; ret address
popargs ax,{es,dx},cx ; cmd (ax), seg:off s
; stack value (arg); cx in remote_rw
pop cx ; stack value (arg); cx in remote_rw
pop dx ; off s
pop es ; seg s
pop ax ; cmd (ax)
push bx ; ret address
call_int2f:
push bp
@ -428,8 +352,6 @@ call_int2f:
push cx ; arg
cmp al, 0ch
je remote_getfree
cmp al, 0xa3
je remote_getfree
cmp al, 1eh
je remote_print_doredir
cmp al, 1fh
@ -480,7 +402,6 @@ remote_getfree:
mov [di+2],bx
mov [di+4],cx
mov [di+6],dx
mov [di+8],si ; for REM_GETLARGEFREE, unused on REM_GETFREE
jmp short ret_set_ax_to_carry
remote_rw:
@ -510,7 +431,7 @@ int2f_restore_ds:
; extern UWORD ASMPASCAL call_nls(UWORD bp, UWORD FAR *buf,
; UWORD subfct, UWORD cp, UWORD cntry, UWORD bufsize);
extern _nlsInfo
extern _nlsInfo:wrt DGROUP
global CALL_NLS
CALL_NLS:
pop es ; ret addr
@ -576,7 +497,6 @@ FLOPPY_CHANGE:
segment INIT_TEXT
; int ASMPASCAL UMB_get_largest(void FAR * driverAddress,
; UCOUNT * seg, UCOUNT * size);
arg {driverAddress,4}, argseg, size
global UMB_GET_LARGEST
UMB_GET_LARGEST:
@ -585,7 +505,7 @@ UMB_GET_LARGEST:
mov dx,0xffff ; go for broke!
mov ax,1000h ; get the UMBs
call far [.driverAddress] ; Call the driver
call far [bp+8] ; Call the driver
;
; bl = 0xB0 and ax = 0 so do it again.
@ -597,7 +517,7 @@ UMB_GET_LARGEST:
je umbt_error
mov ax,1000h ; dx set with largest size
call far [.driverAddress] ; Call the driver
call far [bp+8] ; Call the driver
cmp ax,1
jne umbt_error
@ -605,10 +525,10 @@ UMB_GET_LARGEST:
; and the size
mov cx,bx ; *seg = segment
mov bx, [.argseg]
mov bx, [bp+6]
mov [bx],cx
mov bx, [.size] ; *size = size
mov bx, [bp+4] ; *size = size
mov [bx],dx
umbt_ret:

View File

@ -31,8 +31,6 @@
#include "portab.h"
#include "globals.h"
#include "nls.h"
#include "win.h"
#include "debug.h"
#ifdef VERSION_STRINGS
BYTE *RcsId =
@ -65,38 +63,16 @@ struct HugeSectorBlock {
/* variables needed for the rest of the handler. */
/* this here works on the users stack !! and only very few functions
are allowed */
/* TODO: really, really make sure that this function works properly */
/* even when SS != DGROUP (some changes to the compiler (!) may be */
/* necessary). Currently, between Turbo C++, gcc-ia16, & Open Watcom, */
/* it seems only Watcom has explicit support for calling near-data */
/* functions with SS != DGROUP. The code for this function happens to */
/* to compile under gcc-ia16 to correctly-behaving code _for now_. But */
/* it will be better to be able to guarantee this. -- tkchia 20191207 */
/* Update: I added experimental SS != DGROUP support, and a __seg_ss */
/* address space qualifier, to gcc-ia16 around January 2020. This */
/* function now uses these if available. In particular, the iregs *irp */
/* structure will always be on the stack, so (as far as the calling */
/* convention permits) the function can treat the irp pointer as a */
/* 16-bit pointer relative to SS. -- tkchia 20200417 */
#if defined __GNUC__ && defined __IA16_FEATURE_ATTRIBUTE_NO_ASSUME_SS_DATA
__attribute__((no_assume_ss_data))
VOID ASMCFUNC int21_syscall(iregs __seg_ss * irp, ...)
#else
VOID ASMCFUNC int21_syscall(iregs FAR * irp)
#endif
{
Int21AX = irp->AX;
switch (irp->AH)
{
/* Set Interrupt Vector - now implemented in entry.asm */
#if 0
/* Set Interrupt Vector */
case 0x25:
setvec(irp->AL, (intvec)MK_FP(irp->DS, irp->DX));
break;
#endif
/* DosVars - get/set dos variables */
case 0x33:
@ -142,22 +118,11 @@ VOID ASMCFUNC int21_syscall(iregs FAR * irp)
/* the remaining are FreeDOS extensions */
/* return CPU family */
case 0xfa:
irp->AL = CPULevel;
break;
#if 0 /* unknown if used / usage */
case 0xfb:
#endif
#if 1 /* duplicates DOS 4 int 2F/122Fh, but used by CALLVER */
/* set FreeDOS returned version for int 21.30 from BX */
case 0xfc:
os_setver_major = irp->BL;
os_setver_minor = irp->BH;
break;
#endif
/* Toggle DOS-C rdwrblock trace dump */
#ifdef DEBUG
@ -175,17 +140,12 @@ VOID ASMCFUNC int21_syscall(iregs FAR * irp)
/* Get DOS-C release string pointer */
case 0xff:
#if !defined __GNUC__ || defined __IA16_FEATURE_ATTRIBUTE_NO_ASSUME_SS_DATA
irp->DX = FP_SEG(os_release);
#else /* TODO: remove this hacky SS != DGROUP workaround --tkchia 20191207 */
asm volatile("movw %%ds, %0" : "=g" (irp->DX));
#endif
irp->AX = FP_OFF(os_release);
}
break;
/* Get Interrupt Vector - now implemented in entry.asm */
#if 0
/* Get Interrupt Vector */
case 0x35:
{
intvec p = getvec(irp->AL);
@ -193,7 +153,6 @@ VOID ASMCFUNC int21_syscall(iregs FAR * irp)
irp->BX = FP_OFF(p);
break;
}
#endif
/* Set PSP */
case 0x50:
@ -422,7 +381,6 @@ VOID ASMCFUNC int21_service(iregs FAR * r)
COUNT rc;
long lrc;
lregs lr; /* 8 local registers (ax, bx, cx, dx, si, di, ds, es) */
psp FAR *psp = MK_FP(cu_psp, 0);
#define FP_DS_DX (MK_FP(lr.DS, lr.DX))
#define FP_ES_DI (MK_FP(lr.ES, lr.DI))
@ -430,7 +388,7 @@ VOID ASMCFUNC int21_service(iregs FAR * r)
#define CLEAR_CARRY_FLAG() r->FLAGS &= ~FLG_CARRY
#define SET_CARRY_FLAG() r->FLAGS |= FLG_CARRY
psp->ps_stack = (BYTE FAR *) r;
((psp FAR *) MK_FP(cu_psp, 0))->ps_stack = (BYTE FAR *) r;
fmemcpy(&lr, r, sizeof(lregs) - 4);
lr.DS = r->DS;
@ -768,12 +726,12 @@ dispatch:
/* Get (editable) DOS Version */
case 0x30:
{
if (lr.AL == 1) /* from RBIL, if AL=1 then return version_flags */
lr.BH = version_flags;
else
lr.BH = OEM_ID;
lr.AX = psp->ps_retdosver;
lr.AL = os_setver_major;
lr.AH = os_setver_minor;
lr.BL = REVISION_SEQ;
lr.CX = 0; /* do not set this to a serial number!
32RTM won't like non-zero values */
@ -803,7 +761,6 @@ dispatch:
}
}
}
break;
@ -911,8 +868,10 @@ dispatch:
rc = DosGetCountryInformation(cntry, FP_DS_DX);
if (rc >= SUCCESS)
{
/* HACK FIXME */
if (cntry == (UWORD) - 1)
cntry = nlsInfo.actPkg->cntry;
cntry = 1;
/* END OF HACK */
lr.AX = lr.BX = cntry;
}
}
@ -965,7 +924,8 @@ dispatch:
case 0x42:
if (lr.AL > 2)
goto error_invalid;
lrc = DosSeek(lr.BX, (LONG)MK_ULONG(lr.CX, lr.DX), lr.AL, &rc);
lrc = DosSeek(lr.BX, (LONG)((((ULONG) (lr.CX)) << 16) | lr.DX), lr.AL,
&rc);
if (rc == SUCCESS)
{
lr.DX = (UWORD)(lrc >> 16);
@ -1003,7 +963,7 @@ dispatch:
case 0x39:
/* Dos Remove Directory */
case 0x3a:
rc = DosMkRmdir(FP_DS_DX, lr.CL);
rc = DosMkRmdir(FP_DS_DX, lr.AH);
goto short_check;
/* Dos rename file */
@ -1081,7 +1041,8 @@ dispatch:
#if 0
if (cu_psp == lr.ES)
{
psp->ps_size = lr.BX + cu_psp;
psp FAR *p = MK_FP(cu_psp, 0);
p->ps_size = lr.BX + cu_psp;
}
#endif
if (DosMemCheck() != SUCCESS)
@ -1178,8 +1139,6 @@ dispatch:
/* Dos Create New Psp & set p_size */
case 0x55:
child_psp(lr.DX, cu_psp, lr.SI);
/* copy command line from the parent (required for some device loaders) */
fmemcpy(MK_FP(lr.DX, 0x80), MK_FP(cu_psp, 0x80), 128);
cu_psp = lr.DX;
break;
@ -1200,8 +1159,8 @@ dispatch:
case 0x01:
rc = DosSetFtime((COUNT) lr.BX, /* Handle */
(ddate) lr.DX, /* FileDate */
(dtime) lr.CX); /* FileTime */
(date) lr.DX, /* FileDate */
(time) lr.CX); /* FileTime */
break;
default:
@ -1418,7 +1377,7 @@ dispatch:
case 0:
p = DosGetDBCS();
lr.DS = FP_SEG(p);
lr.SI = FP_OFF(p) + 2;
lr.SI = FP_OFF(p);
break;
case 1: /* set Korean Hangul input method to DL 0/1 */
lr.AL = 0xff; /* flag error (AL would be 0 if okay) */
@ -1548,143 +1507,10 @@ dispatch:
/* case 0x6d and above not implemented : see default; return AL=0 */
#ifdef WITHFAT32
/* LFN API */
/* LFN functions - fail with "function not supported" error code */
case 0x71:
switch (lr.AL)
{
#ifdef WITHLFNAPI
/* Win95 LFN - reset drive */
case 0x0d:
/* Win95 LFN - make directory */
case 0x39:
/* Win95 LFN - remove directory */
case 0x3a:
/* Win95 LFN - change directory */
case 0x3b:
/* Win95 LFN - delete file */
case 0x41:
/* Win95 LFN - extended get/set file attributes */
case 0x43:
/* Win95 LFN - get current directory */
case 0x47:
/* Win95 LFN - find first file */
case 0x4e:
/* Win95 LFN - find next file */
case 0xa2: /* internal - same as 0x4f */
case 0x4f: {
goto unsupp;
}
/* Win95 LFN - rename file */
case 0x56:
/* Win95 LFN - canonicalize file name/path */
case 0x60: {
switch (lr.CL)
{
/* truename - canonicalize path, accepts short/long/or combination as input and may return combined short/long name */
case 0x00: {
}
/* get canonical short (8.3) name or path, truename that accepts long name and returns short name */
case 0x01: {
}
/* get canonical long name or path, truename that accepts short name and returns long name */
case 0x02: {
}
default:
goto unsupp;
}
}
/* Win95 LFN - create or open file */
case 0xa9: /* for real-mode servers only, AX is _global_ file handle on return */
case 0x6c: {
goto unsupp;
}
/* Win95 LFN - get volume information */
case 0xa0:
/* Win95 LFN - find file close */
case 0xa1: {
lfn_findclose:
goto unsupp;
}
#if 0
/* Win95 LFN - internal use ??? */
case 0xa3:
case 0xa4:
case 0xa5:
goto unsupp;
#endif
#endif
/* EDR-DOS LFN - Long LSEEK - SET CURRENT 64-bit FILE POSITION */
case 0x42:
/* Win95 LFN - get file info by handle */
case 0xa6: {
/* only passed to redirector supported for now */
iregs saved_r;
sft FAR *s;
unsigned char idx;
if (lr.BX >= psp->ps_maxfiles)
{
rc = DE_INVLDHNDL;
goto error_exit;
}
idx = psp->ps_filetab[lr.BX];
s = idx_to_sft(idx);
if (s == (sft FAR *)-1)
{
rc = DE_INVLDHNDL;
goto error_exit;
}
if (!(s->sft_flags & SFT_FSHARED)) {
if (lr.AL != 0x42) {
goto unsupp; /* unsupported on local fs yet */
}
}
/* call to redirector */
fmemcpy(&saved_r, r, sizeof(saved_r));
r->ES = FP_SEG(s);
r->DI = FP_OFF(s);
r->flags |= FLG_CARRY;
r->AH = 0x11;
call_intr(0x2f, r);
if (!(r->flags & FLG_CARRY)) {
r->ES = saved_r.ES;
r->DI = saved_r.DI;
goto real_exit;
}
/* carry still set - unhandled */
fmemcpy(r, &saved_r, sizeof(saved_r));
goto unsupp;
}
#ifdef WITHLFNAPI
/* Win95 LFN - Win95 64 UTC file time to/from DOS date and time (local timezone) */
case 0xa7: {
/* Note: valid input range limited to Jan 1, 1980 to Dec 31, 2107 */
switch (lr.BL)
{
/* from Win95 UTC to DOS date/time */
case 0x00: {
}
/* from DOS date/time to Win95 UTC */
case 0x01: {
}
default:
goto unsupp;
}
}
/* Win95 LFN - generate short filename */
case 0xa8:
/* Win95 LFN - subst */
case 0xaa: {
goto unsupp;
}
#endif
default:
goto unsupp;
}
#ifdef WITHLFNAPI
/* Win95 beta LFN - find close */
case 0x72: goto lfn_findclose;
#endif
lr.AL = 00;
goto error_carry;
/* DOS 7.0+ FAT32 extended functions */
case 0x73:
@ -1710,7 +1536,7 @@ lfn_findclose:
break;
/* Setup LFN inode */
case 0x03:
rc = lfn_setup_inode(lr.BX, MK_ULONG(lr.CX, lr.DX), MK_ULONG(lr.SI,lr.DI));
rc = lfn_setup_inode(lr.BX, ((ULONG)lr.CX << 16) | lr.DX, ((ULONG)lr.SI << 16) | lr.DI);
break;
/* Create LFN entries */
case 0x04:
@ -1734,13 +1560,6 @@ lfn_findclose:
#endif
}
goto exit_dispatch;
#ifdef WITHFAT32
unsupp:
{
lr.AL = 00;
goto error_carry;
}
#endif
long_check:
if (lrc >= SUCCESS)
{
@ -1818,9 +1637,7 @@ VOID ASMCFUNC int2526_handler(WORD mode, struct int25regs FAR * r)
else
mode = DSKREADINT25;
drv = r->ax & 0x7f; /* according to RBIL, some programs may try with */
/* high bit of AL set, so mask it together with AH */
/* otherwise we might access a non-existing unit */
drv = r->ax;
if (drv >= lastdrive)
{
@ -1914,22 +1731,13 @@ struct int2f12regs {
UWORD callerARG1; /* used if called from INT2F/12 */
};
extern intvec FAR ASM BIOSInt13;
extern intvec FAR ASM UserInt13;
extern intvec FAR ASM BIOSInt19;
/* WARNING: modifications in `r' are used outside of int2F_12_handler()
* On input r.AX==0x12xx, 0x4A01 or 0x4A02
* also handle Windows' DOS notification hooks, r.AH==0x16 and r.AH==0x13
*/
VOID ASMCFUNC int2F_12_handler(struct int2f12regs FAR *pr)
VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
{
COUNT rc;
long lrc;
UDWORD tsize;
#define r (*pr)
if (r.AH == 0x4a)
{
@ -1942,9 +1750,8 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs FAR *pr)
size = ~offs; /* BX for query HMA */
if (r.AL == 0x02) /* allocate HMA space */
{
tsize = (r.BX + 0xf) & 0xfffffff0UL; /* align to paragraph */
if (tsize < size)
size = (UWORD)tsize;
if (r.BX < size)
size = r.BX;
AllocateHMASpace(offs, offs+size);
firstAvailableBuf += size;
}
@ -1953,257 +1760,6 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs FAR *pr)
r.BX = size;
return;
}
else if (r.AH == 0x13) /* set disk interrupt (13h) handler */
{
/* set new values for int13h calls, and must return old values */
register intvec tmp = UserInt13;
UserInt13 = MK_FP(r.ds, r.DX); /* int13h handler to use */
r.ds = FP_SEG(tmp); r.DX = FP_OFF(tmp);
tmp = BIOSInt13;
BIOSInt13 = MK_FP(r.es, r.BX); /* int13h handler to restore on reboot */
r.es = FP_SEG(tmp); r.BX = FP_OFF(tmp);
return;
}
else if (r.AH == 0x16) /* Window/Multitasking hooks */
{
#ifdef WIN31SUPPORT /* See "DOS Internals" or RBIL under DOSMGR for details */
switch (r.AL)
{
/* default: unhandled requests pass through unchanged */
case 0x0: /* is Windows active */
case 0x0A: /* identify Windows version */
{
/* return AX unchanged if Windows not active */
break;
} /* 0x0, 0x0A */
case 0x03: /* Windows Get Instance Data */
{
/* This should only be called if AX=1607h/BX=15h is not supported. */
/* The data returned here corresponds directly with text entries that
can also be in INSTANCE.386 [which in theory means Windows could
be updated to support FD kernel without responding to these?].
*/
DebugPrintf(("get instance data\n"));
break;
} /* 0x03 */
case 0x05: /* Windows Startup Broadcast */
{
/* After receiving this call we activate compatibility changes
as DOS 5 does, though can wait until 0x07 subfunc 0x01
*/
/* on entry:
DX flags, bit 0 is set(=1) for standard mode
DI Windows version#, major# in high byte
CX 0, set on exit to nonzero to fail load request
DS:SI is 0000:0000, for enhanced mode, at most 1 program can
set to memory manager calling point to disable V86
ES:BX is 0000:0000, set to startup structure
*/
/* r.CX = 0x0; ** redundant and could be set nonzero by another hooked program */
r.es = FP_SEG(&winStartupInfo);
r.BX = FP_OFF(&winStartupInfo);
winStartupInfo.winver = r.di; /* match what caller says it is */
#if defined __GNUC__
winseg1 = FP_SEG(&winStartupInfo);
winseg2 = FP_SEG(&DATASTART);
winseg3 = FP_OFF(&markEndInstanceData);
#endif
winInstanced = 1; /* internal flag marking Windows is active */
DebugPrintf(("Win startup\n"));
break;
} /* 0x05 */
case 0x06: /* Windows Exit Broadcast */
{
/* can do nothing or can remove any changes made
specifically for Windows, must preserve DS.
Note: If Windows fatally exits then may not be called.
*/
winInstanced = 0; /* internal flag marking Windows is NOT active */
DebugPrintf(("Win exit\n"));
break;
} /* 0x06 */
case 0x07: /* DOSMGR Virtual Device API */
{
DebugPrintf(("Vxd:DOSMGR:%x:%x:%x:%x\n",r.AX,r.BX,r.CX,r.DX));
if (r.BX == 0x15) /* VxD id of "DOSMGR" */
{
switch (r.CX)
{
/* default: unhandled requests pass through unchanged */
case 0x00: /* query if supported */
{
r.CX = winInstanced; /* should always be nonzero if Win is active */
r.DX = FP_SEG(&nul_dev); /* data segment / segment of DOS drivers */
r.es = FP_SEG(&winPatchTable); /* es:bx points to table of offsets */
r.BX = FP_OFF(&winPatchTable);
break;
}
case 0x01: /* enable Win support, ie patch DOS */
{
/* DOS 5+ return with bitflags unchanged, Windows critical section
needs are handled without need to patch. If this
function does not return successfully windows will
attempt to do the patching itself (very bad idea).
On entry BX is bitflags describing support requested,
and on return DX is set to which we can support.
Note: any we report as unhandled Windows will attempt
to patch kernel to handle, probably not a good idea.
0001h: enable critical section signals (int 2Ah functions
80h/81h) to allow re-entering DOS while InDOS.
0002h: allow nonzero local machine ID, ie different VMs
report different values.
FIXME: does this mean we need to set this or does Windows?
0004h: split up binary reads to increase int 2Ah function 84h scheduling
/ turn Int 21h function 3Fh on STDIN into polling loop
0008h: notify Windows of halting due to internal stack errors
0010h: notify Windows of logical drive map change ("Insert disk X:")
*/
r.BX = r.DX; /* sure we support everything asked for, ;-) */
r.DX = 0xA2AB; /* on succes DX:AX set to A2AB:B97Ch */
r.AX = 0xB97C;
/* FIXME: do we need to do anything special for FD kernel? */
break;
}
case 0x02: /* disable Win support, ie remove patches */
{
/* Note: if we do anything special in 'patch DOS', undo it here.
This is only called when Windows exits, can be ignored.
*/
r.CX = 0; /* for compatibility with MS-DOS 5/6 */
break;
}
case 0x03: /* get internal structure sizes */
{
if (r.CX & 0x01) /* size of Current Directory Structure in bytes */
{
r.DX = 0xA2AB; /* on succes DS:AX set to A2AB:B97Ch */
r.AX = 0xB97C;
r.CX = sizeof(struct cds);
}
else
r.CX = 0; /* unknown or unsupported structure requested */
break;
}
case 0x04: /* Get Instancing Exemptions */
{
/* On exit BX is bit flags denoting data that is instanced
so Windows need not instance it. DOS 5&6 fail with DX=CX=0.
0001h: Current Directory Structure
0002h: System File Table and device status of STDOUT
0004h: device driver chain
0008h: Swappable Data Area
*/
r.DX = 0xA2AB; /* on succes DX:AX set to A2AB:B97Ch */
r.AX = 0xB97C;
r.BX = 0; /* a zero here tells Windows to instance everything */
break;
}
case 0x05: /* get device driver size */
{
/* On entry ES:DI points to possible device driver
if is not one return with AX=BX=CX=DX=0
else return BX:CX size in bytes allocated to driver
and DX:AX set to A2AB:B97Ch */
mcb FAR *smcb = MK_PTR(mcb, (r.ES-1), 0); /* para before is possibly submcb segment */
/* drivers always start a seg:0 (DI==0), so if not then either
not device driver or duplicate (ie device driver file loaded
is of multi-driver variety; multiple device drivers in same file,
whose memory was allocated as a single chunk)
Drivers don't really have a MCB, instead the DOS MCB is broken
up into submcbs, which will have a type of 'D' (or 'E')
So we check that this is primary segment, a device driver, and owner.
*/
if (!r.DI && (smcb->m_type == 'D') && (smcb->m_psp == r.ES))
{
ULONG size = smcb->m_size * 16ul;
r.BX = hiword(size);
r.CX = loword(size);
r.DX = 0xA2AB; /* on succes DX:AX set to A2AB:B97Ch */
r.AX = 0xB97C;
break;
}
r.DX = 0; /* we aren't one so return unsupported */
r.AX = 0;
r.BX = 0;
r.CX = 0;
break;
}
}
}
DebugPrintf(("Vxd:DOSMGR:%x:%x:%x:%x\n",r.AX,r.BX,r.CX,r.DX));
break;
} /* 0x07 */
case 0x08: /* Windows Init Complete Broadcast */
{
DebugPrintf(("Init complete\n"));
break;
} /* 0x08 */
case 0x09: /* Windows Begin Exit Broadcast */
{
DebugPrintf(("Exit initiated\n"));
break;
} /* 0x09 */
case 0x0B: /* Win TSR Identify */
{
DebugPrintf(("TSR identify request.\n"));
break;
} /* 0x0B */
case 0x80: /* Win Release Time-slice */
{
/* This function is generally only called in idle loops */
DosIdle_hlt();
r.AX = 0;
/* DebugPrintf(("Release Time Slice\n")); */
break;
} /* 0x80 */
case 0x81: /* Win3 Begin Critical Section */
{
DebugPrintf(("Begin CritSect\n"));
break;
} /* 0x81 */
case 0x82: /* Win3 End Critical Section */
{
DebugPrintf(("End CritSect\n"));
break;
} /* 0x82 */
case 0x8F: /* Win4 Close Awareness */
{
if (r.DH != 0x01) /* query close */
r.AX = 0x0;
/* else r.AX = 0x168F; don't close -- continue execution */
break;
} /* 0x8F */
default:
DebugPrintf(("Win call (int 2Fh/16h): %04x %04x %04x %04x\n", r.AX, r.BX, r.CX, r.DX));
break;
}
#endif
return;
}
else if (r.AH == 0x46) /* MS Windows WinOLDAP switching */
{
#ifdef WIN31SUPPORT /* See "DOS Internals" under DOSMGR or RBIL for details */
if (r.AL == 0x01) /* save MCB */
{
/* To prevent corruption when dos=umb where Windows 3.0 standard
writes a sentinel at 9FFEh, DOS 5 will save the MCB marking
end of conventional memory (ie MCB following caller's PSP memory
block [which I assume occupies all of conventional memory] into
the DOS data segment.
Note: presumably Win3.1 uses the WinPatchTable.OffLastMCBSeg
when DOS ver > 5 to do this itself.
*/
/* FIXME: Implement this! */
}
else if (r.AL == 0x02) /* restore MCB */
{
/* Copy the MCB we previously saved back. */
/* FIXME: Implement this! */
}
#endif
return;
}
/* else (r.AH == 0x12) */
switch (r.AL)
{
@ -2234,37 +1790,6 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs FAR *pr)
}
break;
case 0x0a: /* perform critical error */
/* differs from 0x06 as uses current drive & error on stack */
/* code, drive number, error, device header */
r.AL = CriticalError(0x38, /* ignore/retry/fail - based on RBIL possible return values */
default_drive,
r.callerARG1, /* error, from RBIL passed on stack */
CDSp[(WORD)default_drive].cdsDpb->dpb_device);
r.FLAGS |= FLG_CARRY;
if (r.AL == 1) r.FLAGS &= ~FLG_CARRY; /* carry clear if should retry */
break;
case 0x0b: /* sharing violation occurred */
{
/* ES:DI = SFT for previous open of file */
sft FAR *sftp = MK_FP(r.ES, r.DI);
/* default to don't retry, ie fail/abort/etc other than retry */
r.FLAGS |= FLG_CARRY;
/* from RBIL if SFT for FCB or compatibility mode without NOINHERIT call int24h */
if ((sftp->sft_mode & O_FCB) || !(sftp->sft_mode & (O_SHAREMASK | O_NOINHERIT)))
{
r.AL = CriticalError(0x38, /* ignore/retry/fail - ??? */
default_drive,
r.callerARG1, /* error, from RBIL passed on stack */
CDSp[(WORD)default_drive].cdsDpb->dpb_device);
/* clear carry if should retry */
if (r.AL == 1) r.FLAGS &= ~FLG_CARRY;
}
r.AX = 0x20; /* error sharing violation */
}
break;
case 0x0c: /* perform "device open" for device, set owner for FCB */
if (lpCurSft->sft_flags & SFT_FDEVICE)
@ -2358,7 +1883,7 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs FAR *pr)
; probable use: get sizeof(CDSentry)
*/
{
struct cds FAR *cdsp = get_cds_unvalidated(r.callerARG1 & 0xff);
struct cds FAR *cdsp = get_cds(r.callerARG1 & 0xff);
if (cdsp == NULL)
{
@ -2382,46 +1907,6 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs FAR *pr)
r.AL = (r.CL & 3) ? 28 : 29;
break;
case 0x1f: /* build current directory structure */
{
/* this is similar to ARG1-'A', but case-insensitive.
* Note: the letter is passed here, not number! */
int drv = (r.callerARG1 & 0x1f) - 1;
struct cds FAR *cdsp;
if (drv < 0 || r.callerARG1 < 'A' || r.callerARG1 > 'z')
{
r.FLAGS |= FLG_CARRY;
break;
}
cdsp = get_cds_unvalidated(drv);
if (cdsp == NULL)
{
r.FLAGS |= FLG_CARRY;
break;
}
strcpy(TempCDS.cdsCurrentPath, "?:\\");
*TempCDS.cdsCurrentPath = (BYTE)(r.callerARG1 & 0xff);
TempCDS.cdsBackslashOffset = 2;
if (cdsp->cdsFlags)
{
TempCDS.cdsDpb = cdsp->cdsDpb;
TempCDS.cdsFlags = CDSPHYSDRV; /* don't inherit CDS flags */
}
else
{
TempCDS.cdsDpb = NULL;
TempCDS.cdsFlags = 0;
}
TempCDS.cdsStrtClst = 0xffff;
TempCDS.cdsParam = 0xffff;
TempCDS.cdsStoreUData = 0xffff;
r.CX = sizeof(TempCDS);
r.ES = FP_SEG(&TempCDS);
r.DI = FP_OFF(&TempCDS);
r.FLAGS &= ~FLG_CARRY;
break;
}
case 0x20: /* get job file table entry */
{
psp FAR *p = MK_FP(cu_psp, 0);
@ -2479,21 +1964,6 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs FAR *pr)
rc = DosClose(r.BX);
goto short_check;
#ifdef WITHFAT32
#ifdef WITHLFNAPI
case 0x42: /* 64-bit move file pointer */
{
/* r.(DS:DX) points to 64-bit file position instead of r.(CX:DX) being 32-bit file position */
UDWORD FAR *filepos = MK_FP(r.DS, r.DX);
if (*(filepos+1) != 0) /* we currently only handle lower 32 bits, upper 32 bits must be 0 */
goto error_invalid;
r.BP = (UWORD)r.CL;
r.CX = hiword(*filepos);
r.DX = loword(*filepos);
/* fall through to 32-bit move file pointer (0x28) */
}
#endif
#endif
case 0x28: /* move file pointer */
/*
* RBIL says: "sets user stack frame pointer to dummy buffer,
@ -2565,13 +2035,13 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs FAR *pr)
doesn't work!! */
break;
case 0x2f: /* updates version returned by int 21/30h for all processes */
if (r.DX) /* set returned version from DX */
case 0x2f:
if (r.DX)
{
os_setver_major = r.DL;
os_setver_minor = r.DH;
}
else /* set returned version from emulated true DOS version */
else
{
os_setver_major = os_major;
os_setver_minor = os_minor;
@ -2607,8 +2077,6 @@ error_exit:
CritErrCode = r.AX; /* Maybe set */
error_carry:
r.FLAGS |= FLG_CARRY;
#undef r
}
/*

View File

@ -26,9 +26,8 @@
;
%include "segs.inc"
%include "stacks.inc"
%macro INTR 1
%macro INTR 0
push bp ; Standard C entry
mov bp,sp
@ -41,18 +40,12 @@
push es
%endif
push ds
pushf
arg nr, {rp,%1}
mov ax, [.nr] ; interrupt number
mov ax, [bp+6] ; interrupt number
mov [cs:%%intr_1-1], al
jmp short %%intr_2 ; flush the instruction cache
%%intr_2:
%if %1 == 4
lds bx, [.rp] ; regpack structure FAR
%else
mov bx, [.rp] ; regpack structure
%endif
%%intr_2 mov bx, [bp+4] ; regpack structure
mov ax, [bx]
mov cx, [bx+4]
mov dx, [bx+6]
mov si, [bx+8]
@ -60,9 +53,6 @@ arg nr, {rp,%1}
mov bp, [bx+12]
push word [bx+14] ; ds
mov es, [bx+16]
mov ah, byte [bx+22] ; flags
sahf
mov ax, [bx]
mov bx, [bx+2]
pop ds
int 0
@ -72,33 +62,23 @@ arg nr, {rp,%1}
push ds
push bx
mov bx, sp
%if %1 == 4
mov ds, [ss:bx+6]
%ifdef WATCOM
lds bx, [ss:bx+(14+8)+4] ; FAR address of REGPACK, pascal convention
mov bx, [ss:bx+24] ; address of REGPACK
%else
lds bx, [ss:bx+14+.rp-bp] ; FAR address of REGPACK, SP=BX + skip saved registers (14) +
%endif
%else
mov ds, [ss:bx+8]
%ifdef WATCOM
mov bx, [ss:bx+26] ; NEAR address of REGPACK, pascal convention
%else
mov bx, [ss:bx+14+.rp-bp] ; NEAR address of REGPACK
%endif
mov bx, [ss:bx+16] ; address of REGPACK
%endif
mov [bx], ax
pop word [bx+2] ; bx
pop word [bx+2]
mov [bx+4], cx
mov [bx+6], dx
mov [bx+8], si
mov [bx+10], di
mov [bx+12], bp
pop word [bx+14] ; ds
pop word [bx+14]
mov [bx+16], es
pop word [bx+22] ; flags
pop word [bx+22]
; restore all registers to values from INTR entry
popf
pop ds
%ifdef WATCOM
pop es
@ -109,23 +89,18 @@ arg nr, {rp,%1}
pop di
pop si
pop bp
ret 4
%endmacro
segment HMA_TEXT
;
; void ASMPASCAL call_intr(WORD nr, struct REGPACK FAR *rp)
;
global CALL_INTR
CALL_INTR:
INTR 4 ; rp is far, DWORD argument
ret 6
;; COUNT ASMPASCAL res_DosExec(COUNT mode, exec_blk * ep, BYTE * lp)
global RES_DOSEXEC
RES_DOSEXEC:
pop es ; ret address
popargs ax,bx,dx ; mode, exec block, filename
pop dx ; filename
pop bx ; exec block
pop ax ; mode
push es ; ret address
mov ah, 4bh
push ds
@ -140,7 +115,9 @@ no_exec_error:
global RES_READ
RES_READ:
pop ax ; ret address
popargs bx,dx,cx ; fd, buf, count
pop cx ; count
pop dx ; buf
pop bx ; fd
push ax ; ret address
mov ah, 3fh
int 21h
@ -157,8 +134,7 @@ segment INIT_TEXT
;
global INIT_CALL_INTR
INIT_CALL_INTR:
INTR 2 ; rp is near, WORD argument
ret 4
INTR
;
; int init_call_XMScall( (WORD FAR * driverAddress)(), WORD AX, WORD DX)
@ -168,7 +144,10 @@ INIT_CALL_INTR:
global INIT_CALL_XMSCALL
INIT_CALL_XMSCALL:
pop bx ; ret address
popargs {es,cx},ax,dx
pop dx
pop ax
pop cx ; driver address
pop es
push cs ; ret address
push bx
@ -211,7 +190,8 @@ KEYCHECK:
INIT_DOSOPEN:
;; init calling DOS through ints:
pop bx ; ret address
popargs dx,ax ; pathname, flags
pop ax ; flags
pop dx ; pathname
push bx ; ret address
mov ah, 3dh
;; AX will have the file handle
@ -236,7 +216,9 @@ CLOSE:
global READ
READ:
pop ax ; ret address
popargs bx,dx,cx ; fd,buf,count
pop cx ; count
pop dx ; buf
pop bx ; fd
push ax ; ret address
mov ah, 3fh
jmp short common_int21
@ -245,7 +227,8 @@ READ:
global DUP2
DUP2:
pop ax ; ret address
popargs bx,cx ; oldfd,newfd
pop cx ; newfd
pop bx ; oldfd
push ax ; ret address
mov ah, 46h
jmp short common_int21
@ -256,7 +239,9 @@ DUP2:
global LSEEK
LSEEK:
pop ax ; ret address
popargs bx,{cx,dx} ; fd, position high:low
pop dx ; position low
pop cx ; position high
pop bx ; fd
push ax ; ret address
mov ax,4200h ; origin: start of file
int 21h
@ -280,7 +265,9 @@ INIT_PSPSET:
global INIT_DOSEXEC
INIT_DOSEXEC:
pop es ; ret address
popargs ax,bx,dx ; mode, exec block, filename
pop dx ; filename
pop bx ; exec block
pop ax ; mode
push es ; ret address
mov ah, 4bh
push ds
@ -326,7 +313,8 @@ ALLOCMEM:
global SET_DTA
SET_DTA:
pop ax ; ret address
popargs {bx,dx} ; seg:off(dta)
pop bx ; seg(dta)
pop dx ; off(dta)
push ax ; ret address
mov ah, 1ah
push ds

View File

@ -31,18 +31,18 @@
%include "segs.inc"
%include "stacks.inc"
extern ConTable
extern LptTable
extern ComTable
extern uPrtNo
extern CommonNdRdExit
;!! extern _NumFloppies
extern blk_stk_top
extern clk_stk_top
extern ConTable:wrt LGROUP
extern LptTable:wrt LGROUP
extern ComTable:wrt LGROUP
extern uPrtNo:wrt LGROUP
extern CommonNdRdExit:wrt LGROUP
;!! extern _NumFloppies:wrt DGROUP
extern blk_stk_top:wrt DGROUP
extern clk_stk_top:wrt DGROUP
extern _reloc_call_blk_driver
extern _reloc_call_clk_driver
extern _TEXT_DGROUP
extern _TEXT_DGROUP:wrt LGROUP
;---------------------------------------------------
;
@ -212,7 +212,6 @@ uUnitNumber dw 0
; at any time. The request is stored into memory in the one and only
; location available for that purpose.
;
global GenStrategy
GenStrategy:
mov word [cs:_ReqPktPtr],bx
mov word [cs:_ReqPktPtr+2],es
@ -501,12 +500,12 @@ GetUnitNum:
blk_driver_params:
dw blk_stk_top
dw _reloc_call_blk_driver
dw DGROUP
dw seg _reloc_call_blk_driver
clk_driver_params:
dw clk_stk_top
dw _reloc_call_clk_driver
dw DGROUP
dw seg _reloc_call_clk_driver
; clock device interrupt
clk_entry:

View File

@ -49,12 +49,12 @@
%define E_FAILURE 12 ; General Failure
extern _IOExit
extern _IOSuccess
extern _IOErrorExit
extern _IOErrCnt
extern _IODone
extern _IOCommandError
extern GetUnitNum
extern _ReqPktPtr
extern _IOExit:wrt LGROUP
extern _IOSuccess:wrt LGROUP
extern _IOErrorExit:wrt LGROUP
extern _IOErrCnt:wrt LGROUP
extern _IODone:wrt LGROUP
extern _IOCommandError:wrt LGROUP
extern GetUnitNum:wrt LGROUP
extern _ReqPktPtr:wrt LGROUP

View File

@ -114,10 +114,10 @@ int DosDevIOctl(lregs * r)
{
case 0x00:
/* Get the flags from the SFT */
r->AX = flags & 0xff;
if (flags & SFT_FDEVICE)
r->AX |= (s->sft_dev->dh_attr & 0xff00);
/* else: files/networks return 0 in AH/DH */
r->AX = (flags & 0xff) | (s->sft_dev->dh_attr & 0xff00);
else
r->AX = flags;
/* Undocumented result, Ax = Dx seen using Pcwatch */
r->DX = r->AX;
return SUCCESS;

View File

@ -29,13 +29,12 @@
;
%include "segs.inc"
%include "stacks.inc"
%include "ludivmul.inc"
segment PSP
extern _ReqPktPtr
extern _ReqPktPtr:wrt LGROUP
STACK_SIZE equ 384/2 ; stack allocated in words
@ -43,10 +42,7 @@ STACK_SIZE equ 384/2 ; stack allocated in words
; KERNEL BEGINS HERE, i.e. this is byte 0 of KERNEL.SYS
;************************************************************
%ifidn __OUTPUT_FORMAT__, obj
..start:
%endif
bootloadunit: ; (byte of short jump re-used)
entry:
jmp short realentry
@ -57,7 +53,6 @@ entry:
;************************************************************
global _LowKernelConfig
_LowKernelConfig:
config_signature:
db 'CONFIG' ; constant
dw configend-configstart; size of config area
; to be checked !!!
@ -71,29 +66,7 @@ ForceLBA db 0 ;
GlobalEnableLBAsupport db 1 ;
BootHarddiskSeconds db 0 ;
; The following VERSION resource must be keep in sync with VERSION.H
Version_OemID db 0xFD ; OEM_ID
Version_Major db 2
Version_Revision dw 43 ; REVISION_SEQ
Version_Release dw 1 ; 0=release build, >0=svn#
CheckDebugger: db 0 ; 0 = no check, 1 = check, 2 = assume present
Verbose db 0 ; -1 = quiet, 0 = normal, 1 = verbose
PartitionMode db 0x1f ; bits 0-1: 01=GPT if found, 00=MBR if found, 11=Hybrid, GPT first then MBR, 10=Hybrid, MBR first then GPT
; in hybrid mode, EE partitions ignored, drives assigned by GPT or MBR first based on hybrid type
; bits 2-4: 001=mount ESP (usually FAT32) partition, 010=mount MS Basic partitions, 100=mount unknown partitions
; 111=attempt to mount all paritions, 110=attempt to mount all but ESP partitions
; bits 5-7: reserved, 0 else undefined behavior
configend:
kernel_config_size: equ configend - config_signature
; must be below-or-equal the size of struct _KernelConfig
; in the file kconfig.h !
times (32 - 4) - ($ - $$) db 0
bootloadstack: dd 0
;************************************************************
; KERNEL CONFIGURATION AREA END
@ -110,23 +83,9 @@ bootloadstack: dd 0
; init sequence
;************************************************************
cpu 8086 ; (keep initial entry compatible)
global realentry
realentry: ; execution continues here
push cs
pop ds
xor di, di
mov byte [di + bootloadunit - $$], bl
push bp
mov word [di + bootloadstack - $$], sp
mov word [di + bootloadstack + 2 - $$], ss
jmp entry_common
times 0C0h - ($ - $$) nop ; magic offset (used by exeflat)
entry_common:
%ifndef QUIET
push ax
push bx
pushf
@ -136,36 +95,13 @@ entry_common:
popf
pop bx
pop ax
%endif
push cs
pop ds
jmp IGROUP:kernel_start
beyond_entry: times 256-(beyond_entry-entry) db 0
jmp far kernel_start
beyond_entry: resb 256-(beyond_entry-entry)
; scratch area for data (DOS_PSP)
_master_env equ $ - 128
global _master_env
segment INIT_TEXT
%ifdef TEST_FILL_INIT_TEXT
%macro step 0
%if _LFSR & 1
%assign _LFSR (_LFSR >> 1) ^ 0x80200003
%else
%assign _LFSR (_LFSR >> 1)
%endif
%endmacro
align 16
%assign _LFSR 1
%rep 1024 * 8
dd _LFSR
step
%endrep
%endif
extern _FreeDOSmain
extern _query_cpu
@ -173,9 +109,7 @@ segment INIT_TEXT
; kernel start-up
;
kernel_start:
cld
%ifndef QUIET
push bx
pushf
mov ax, 0e32h ; '2' Tracecode - kernel entered
@ -183,78 +117,32 @@ kernel_start:
int 010h
popf
pop bx
%endif
extern _kernel_command_line
; INP: ds => entry section, with CONFIG block
; and compressed entry help data
; (actually always used now)
initialise_command_line_buffer:
mov dx, I_GROUP
mov es, dx
mov bl, [bootloadunit]
lds si, [bootloadstack] ; -> original ss:sp - 2
lea ax, [si + 2] ; ax = original sp
mov si, word [si] ; si = original bp
; Note that the kernel command line buffer in
; the init data segment is pre-initialised to
; hold 0x00 0xFF in the first two bytes. This
; is used to indicate no command line present,
; as opposed to an empty command line which
; will hold 0x00 0x00.
; If any of the branches to .none are taken then
; the buffer is not modified so it retains the
; 0x00 0xFF contents.
cmp si, 114h ; buffer fits below ss:bp ?
jb .none ; no -->
cmp word [si - 14h], "CL" ; signature passed to us ?
jne .none ; no -->
lea si, [si - 114h] ; -> command line buffer
cmp ax, si ; stack top starts below-or-equal buffer ?
ja .none ; no -->
mov di, _kernel_command_line ; our buffer
mov cx, 255
xor ax, ax
push di
rep movsb ; copy up to 255 bytes
stosb ; truncate
pop di
mov ch, 1 ; cx = 256
repne scasb ; scan for terminator
rep stosb ; clear remainder of buffer
; (make sure we do not have 0x00 0xFF
; even if the command line given is
; actually the empty string)
.none:
mov ax,seg init_tos
cli
mov ss, dx
mov ss,ax
mov sp,init_tos
int 12h ; move init text+data to higher memory
mov cl,6
shl ax,cl ; convert kb to para
mov dx,15 + INITSIZE
mov dx,15 + init_end wrt INIT_TEXT
mov cl,4
shr dx,cl
sub ax,dx
mov es,ax
mov dx,INITTEXTSIZE ; para aligned
mov dx,__INIT_DATA_START wrt INIT_TEXT ; para aligned
shr dx,cl
add ax,dx
mov ss,ax ; set SS to init data segment
sti ; now enable them
mov ax,cs
mov dx,__HMATextEnd ; para aligned
mov dx,__InitTextStart wrt HMA_TEXT ; para aligned
shr dx,cl
%ifdef WATCOM
add ax,dx
%endif
mov ds,ax
mov si,-2 + INITSIZE; word aligned
mov si,-2 + init_end wrt INIT_TEXT ; word aligned
lea cx,[si+2]
mov di,si
shr cx,1
@ -268,7 +156,7 @@ initialise_command_line_buffer:
sub ax,dx
mov es,ax ; es = new HMA_TEXT
mov si,-2 + __HMATextEnd
mov si,-2 + __InitTextStart wrt HMA_TEXT
lea cx,[si+2]
mov di,si
shr cx,1
@ -287,7 +175,6 @@ cont: ; Now set up call frame
mov ds,[cs:_INIT_DGROUP]
mov bp,sp ; and set up stack frame for c
%ifndef QUIET
push bx
pushf
mov ax, 0e33h ; '3' Tracecode - kernel entered
@ -295,7 +182,6 @@ cont: ; Now set up call frame
int 010h
popf
pop bx
%endif
mov byte [_BootDrive],bl ; tell where we came from
@ -306,111 +192,14 @@ cont: ; Now set up call frame
;!! mov byte [_NumFloppies],al ; and how many
call _query_cpu
%if XCPU != 86
%if XCPU < 186 || (XCPU % 100) != 86 || (XCPU / 100) > 9
%fatal Unknown CPU level defined
%endif
cmp al, (XCPU / 100)
jb cpu_abort ; if CPU not supported -->
cpu XCPU
%endif
mov [_CPULevel], al
initialise_kernel_config:
extern _InitKernelConfig
mov ax, ss ; => init data segment
mov si, 60h
mov ds, si ; => entry section
mov si, _LowKernelConfig ; -> our CONFIG block
mov es, ax ; => init data segment
mov di, _InitKernelConfig ; -> init's CONFIG block buffer
mov cx, kernel_config_size / 2 ; size that we support
rep movsw ; copy it over
%if kernel_config_size & 1
movsb ; allow odd size
%endif
mov ds, ax ; => init data segment
check_debugger_present:
extern _debugger_present
mov al, 1 ; assume debugger present
cmp byte [di - kernel_config_size + (CheckDebugger - config_signature)], 1
ja .skip_ints_00_06 ; 2 means assume present
jb .absent ; 0 means assume absent
clc ; 1 means check
int3 ; break to debugger
jc .skip_ints_00_06
; The debugger should set CY here to indicate its
; presence. The flag set is checked later to skip
; overwriting the interrupt vectors 00h, 01h, 03h,
; and 06h. This logic is taken from lDOS init.
.absent:
xor ax, ax ; no debugger present
.skip_ints_00_06:
mov byte [_debugger_present], al
mov byte [_CPULevel],al
; TODO display error if built for 386 running on 8086 etc
mov ax,ss
mov ds,ax
mov es,ax
jmp _FreeDOSmain
%if XCPU != 86
cpu 8086
cpu_abort:
mov ah, 0Fh
int 10h ; get video mode, bh = active page
call .first ; print string that follows (address pushed by call)
%define LOADNAME "FreeDOS"
db 13,10 ; (to emit a blank line after the tracecodes)
db 13,10
db LOADNAME, " load error: An 80", '0'+(XCPU / 100)
db "86 processor or higher is required by this build.",13,10
db "To use ", LOADNAME, " on this processor please"
db " obtain a compatible build.",13,10
db 13,10
db "Press any key to reboot.",13,10
db 0
.display:
mov ah, 0Eh
mov bl, 07h ; page in bh, bl = colour for some modes
int 10h ; write character (may change bp!)
db 0A8h ; [test al,imm8] skip "pop si" [=imm8] after the first iteration
.first:
pop si ; (first iteration only) get message address from stack
cs lodsb ; get character
test al, al ; zero ?
jnz .display ; no, display and get next character -->
xor ax, ax
xor dx, dx
int 13h ; reset floppy disks
xor ax, ax
mov dl, 80h
int 13h ; reset hard disks
; this "test ax, imm16" opcode is used to
db 0A9h ; skip "sti" \ "hlt" [=imm16] during first iteration
.wait:
sti
hlt ; idle while waiting for keystroke
mov ah, 01h
int 16h ; get keystroke
jz .wait ; none available, loop -->
mov ah, 00h
int 16h ; remove keystroke from buffer
int 19h ; reboot
jmp short $ ; (in case it returns, which it shouldn't)
cpu XCPU
%endif ; XCPU != 86
segment INIT_TEXT_END
@ -426,9 +215,10 @@ segment CONST
; NUL device strategy
;
global _nul_strtgy
extern GenStrategy
_nul_strtgy:
jmp LGROUP:GenStrategy
mov word [cs:_ReqPktPtr],bx ;save rq headr
mov word [cs:_ReqPktPtr+2],es
retf
;
; NUL device interrupt
@ -437,9 +227,7 @@ _nul_strtgy:
_nul_intr:
push es
push bx
mov bx,LGROUP
mov es,bx
les bx,[es:_ReqPktPtr] ;es:bx--> rqheadr
les bx,[cs:_ReqPktPtr] ;es:bx--> rqheadr
cmp byte [es:bx+2],4 ;if read, set 0 read
jne no_nul_read
mov word [es:bx+12h],0
@ -456,22 +244,14 @@ segment _LOWTEXT
global _intvec_table
_intvec_table: db 10h
dd 0
; used by int13 handler and get/set via int 2f/13h
global _BIOSInt13 ; BIOS provided disk handler
global _UserInt13 ; actual disk handler used by kernel
db 13h
_BIOSInt13: dd 0
dd 0
db 15h
dd 0
; used for cleanup on reboot
global _BIOSInt19
db 19h
_BIOSInt19: dd 0
dd 0
db 1Bh
dd 0
; default to using BIOS provided disk handler
db 13h
_UserInt13: dd 0
; floppy parameter table
global _int1e_table
@ -519,13 +299,13 @@ _first_mcb dw 0 ;-0002 Start of user memory
global MARK0026H
; A reference seems to indicate that this should start at offset 26h.
MARK0026H equ $
_DPBp dd -1 ; 0000 First drive Parameter Block
_DPBp dd 0 ; 0000 First drive Parameter Block
global _sfthead
_sfthead dd 0 ; 0004 System File Table head
global _clock
_clock dd 0 ; 0008 CLOCK$ device
global _syscon
_syscon dw _con_dev,LGROUP ; 000c console device
_syscon dw _con_dev,seg _con_dev ; 000c console device
global _maxsecsize
_maxsecsize dw 512 ; 0010 maximum bytes/sector of any block device
dd 0 ; 0012 pointer to buffers info structure
@ -541,8 +321,8 @@ _nblkdev db 0 ; 0020 number of block devices
_lastdrive db 0 ; 0021 value of last drive
global _nul_dev
_nul_dev: ; 0022 device chain root
extern _con_dev
dw _con_dev, LGROUP
extern _con_dev:wrt LGROUP
dw _con_dev, seg _con_dev
; next is con_dev at init time.
dw 8004h ; attributes = char device, NUL bit set
dw _nul_strtgy
@ -550,9 +330,8 @@ _nul_dev: ; 0022 device chain root
db 'NUL '
global _njoined
_njoined db 0 ; 0034 number of joined devices
dw 0 ; 0035 DOS 4 near pointer to special names (always zero in DOS 5) [setver precursor]
global _setverPtr
_setverPtr dw 0,0 ; 0037 setver list (far pointer, set by setver driver)
dw 0 ; 0035 DOS 4 pointer to special names (always zero in DOS 5)
setverPtr dw 0,0 ; 0037 setver list
dw 0 ; 003B cs offset for fix a20
dw 0 ; 003D psp of last umb exec
global _LoL_nbuffers
@ -621,26 +400,13 @@ _winStartupInfo:
dd 0 ; next startup info structure, 0:0h marks end
dd 0 ; far pointer to name virtual device file or 0:0h
dd 0 ; far pointer, reference data for virtual device driver
%ifnidni __OUTPUT_FORMAT__, elf
dw instance_table,seg instance_table ; array of instance data
%else
dw instance_table ; array of instance data
global _winseg1
_winseg1: dw 0
%endif
instance_table: ; should include stacks, Win may auto determine SDA region
; we simply include whole DOS data segment
%ifnidni __OUTPUT_FORMAT__, elf
dw seg _DATASTART, 0 ; [SEG:OFF] address of region's base
dw _markEndInstanceData wrt seg _DATASTART ; size in bytes
%else
global _winseg2
_winseg2: dw 0
dw 0 ; [SEG:OFF] address of region's base
global _winseg3
_winseg3: dw 0 ; size in bytes
%endif
dw 0, seg _DATASTART ; [SEG:OFF] address of region's base
dw markEndInstanceData wrt seg _DATASTART ; size in bytes
dd 0 ; 0 marks end of table
patch_bytes: ; mark end of array of offsets of critical section bytes to patch
dw 0 ; and 0 length for end of instance_table entry
global _winPatchTable
_winPatchTable: ; returns offsets to various internal variables
@ -649,11 +415,11 @@ _winPatchTable: ; returns offsets to various internal variables
dw save_BX ; where BX stored during int21h dispatch
dw _InDOS ; offset of InDOS flag
dw _MachineId ; offset to variable containing MachineID
dw _CritPatch ; offset of to array of offsets to patch
dw patch_bytes ; offset of to array of offsets to patch
; NOTE: this points to a null terminated
; array of offsets of critical section bytes
; to patch, for now we can just point this
; to an empty table
; to patch, for now we just point this to
; an empty table, purposely not _CritPatch
; ie we just point to a 0 word to mark end
dw _uppermem_root ; seg of last arena header in conv memory
; this matches MS DOS's location, but
@ -666,8 +432,6 @@ _winPatchTable: ; returns offsets to various internal variables
_firstsftt:
dd -1 ; link to next
dw 5 ; count
times 5*59 db 0 ; reserve space for the 5 sft entries
db 0 ; pad byte so next value on even boundary
; Some references seem to indicate that this data should start at 01fbh in
; order to maintain 100% MS-DOS compatibility.
@ -735,15 +499,13 @@ _net_name db ' ' ;-27 - 15 Character Network Name
global _return_code
global _internal_data
; ensure offset of critical patch table remains fixed, some programs hard code offset
times (0315h - ($ - DATASTART)) db 0
global _CritPatch
_CritPatch dw 0 ;-11 zero list of patched critical
dw 0 ; section variables
dw 0 ; DOS puts 0d0ch here but some
dw 0 ; progs really write to that addr.
dw 0 ;-03 - critical patch list terminator
db 90h ;-01 - unused, NOP pad byte
_CritPatch dw 0d0ch ;-11 zero list of patched critical
dw 0d0ch ; section variables
dw 0d0ch
dw 0d0ch
dw 0d0ch
db 0 ;-01 - unknown
_internal_data: ; <-- Address returned by INT21/5D06
_ErrorMode db 0 ; 00 - Critical Error Flag
_InDOS db 0 ; 01 - Indos Flag
@ -974,11 +736,6 @@ blk_stk_top:
times 128 dw 0
clk_stk_top:
; int2fh private stack
global int2f_stk_top
times 128 dw 0
int2f_stk_top:
; Dynamic data:
; member of the DOS DATA GROUP
; and marks definitive end of all used data in kernel data segment
@ -1003,8 +760,7 @@ segment DYN_DATA
_Dyn:
DynAllocated dw 0
global _markEndInstanceData
_markEndInstanceData: ; mark end of DOS data seg we say needs instancing
markEndInstanceData: ; mark end of DOS data seg we say needs instancing
segment ID_B
@ -1056,32 +812,9 @@ __U4D:
LDIVMODU
%endif
%ifdef gcc
%macro ULONG_HELPERS 1
global %1udivsi3
%1udivsi3: call %1ldivmodu
ret 8
global %1umodsi3
%1umodsi3: call %1ldivmodu
mov dx, cx
mov ax, bx
ret 8
%1ldivmodu: LDIVMODU
global %1ashlsi3
%1ashlsi3: LSHLU
global %1lshrsi3
%1lshrsi3: LSHRU
%endmacro
ULONG_HELPERS ___
%endif
times 0xd0 - ($-begin_hma) db 0
resb 0xd0 - ($-begin_hma)
; reserve space for far jump to cp/m routine
times 5 db 0
resb 5
;End of HMA segment
segment HMA_TEXT_END
@ -1093,7 +826,7 @@ __HMATextEnd: ; and c version
; The default stack (_TEXT:0) will overwrite the data area, so I create a dummy
; stack here to ease debugging. -- ror4
segment _STACK class(STACK) nobits stack
segment _STACK class=STACK stack
@ -1208,20 +941,17 @@ __HMARelocationTableEnd:
; will be only ever called, if HMA (DOS=HIGH) is enabled.
; for obvious reasons it should be located at the relocation table
;
global _XMSDriverAddress
_XMSDriverAddress:
dw 0 ; XMS driver, if detected
dw 0
global _ENABLEA20
_ENABLEA20:
mov ah,5
UsingXMSdriver:
global _XMS_Enable_Patch
_XMS_Enable_Patch: ; SMC: patch to nop (90h) to enable use of XMS
retf
push bx
call 0:0 ; (immediate far address patched)
global _XMSDriverAddress
_XMSDriverAddress: equ $ - 4 ; XMS driver, if detected
call far [cs:_XMSDriverAddress]
pop bx
retf
@ -1230,6 +960,8 @@ _DISABLEA20:
mov ah,6
jmp short UsingXMSdriver
dslowmem dw 0
eshighmem dw 0ffffh
global forceEnableA20
forceEnableA20:
@ -1237,40 +969,44 @@ forceEnableA20:
push ds
push es
push ax
push si
push di
push cx
pushf
cld
.retry:
xor si, si ; = 0000h
mov ds, si ; => low memory (IVT)
dec si ; = FFFFh
mov es, si ; => HMA at offset 10h
inc si ; back to 0, -> IVT entry 0 and 1
mov di, 10h ; -> HMA, or wrapping around to 0:0
mov cx, 4
repe cmpsw ; compare up to 4 words
je .enable
forceEnableA20retry:
mov ds, [cs:dslowmem]
mov es, [cs:eshighmem]
.success:
popf
pop cx
pop di
pop si
mov ax, [ds:00000h]
cmp ax, [es:00010h]
jne forceEnableA20success
mov ax, [ds:00002h]
cmp ax, [es:00012h]
jne forceEnableA20success
mov ax, [ds:00004h]
cmp ax, [es:00014h]
jne forceEnableA20success
mov ax, [ds:00006h]
cmp ax, [es:00016h]
jne forceEnableA20success
;
; ok, we have to enable A20 )at least seems so
;
call far _ENABLEA20
jmp short forceEnableA20retry
forceEnableA20success:
pop ax
pop es
pop ds
retn
.enable:
; ok, we have to enable A20 (at least seems so)
push cs ; make far call stack frame
call _ENABLEA20
jmp short .retry
ret
;
; global f*cking compatibility issues:
;
; very old brain dead software (PKLITE, copyright 1990)
@ -1278,14 +1014,22 @@ forceEnableA20:
;
global _ExecUserDisableA20
_ExecUserDisableA20:
cmp word [cs:_XMSDriverAddress], byte 0
jne NeedToDisable
cmp word [cs:_XMSDriverAddress+2], byte 0
je noNeedToDisable
NeedToDisable:
push ax
push cs ; make far call stack frame
call _DISABLEA20 ; (no-op if not in HMA, patched otherwise)
call far _DISABLEA20
pop ax
noNeedToDisable:
iret
;
; Default Int 24h handler -- always returns fail
; so we have not to relocate it (now)
;
@ -1306,7 +1050,3 @@ _TEXT_DGROUP dw DGROUP
segment INIT_TEXT
global _INIT_DGROUP
_INIT_DGROUP dw DGROUP
%ifdef gcc
ULONG_HELPERS _init_
%endif

View File

@ -1,196 +0,0 @@
/* Linker script for DOS executables with separate data and text segments.
Partly derived from dos-exe-small.ld in newlib-ia16 and elks-separate.ld. */
OUTPUT_FORMAT(binary)
DOS_PSP = 0x60;
MEMOFS = DOS_PSP * 16 - SIZEOF(.msdos_mz_hdr);
/* these GROUPs play the same role as GROUPS (segments) in OMF */
PGROUP = (MEMOFS + LOADADDR(.ptext)) / 16;
LGROUP = (MEMOFS + LOADADDR(.ltext)) / 16;
DGROUP = (MEMOFS + LOADADDR(.data)) / 16;
_DosDataSeg = DGROUP;
TGROUP = (MEMOFS + LOADADDR(.text)) / 16;
IGROUP = (MEMOFS + LOADADDR(.itext)) / 16;
I_GROUP = (MEMOFS + LOADADDR(.idata)) / 16;
INITSIZE = SIZEOF(.itext) + SIZEOF(.idata) + SIZEOF(.ibss);
SECTIONS
{
/* Fabricate a .exe header here. Although libbfd does have an
"i386msdos" back-end which produces an "MZ" exe header, it cannot do
certain things (yet). */
.msdos_mz_hdr : {
/* Signature. */
SHORT (0x5a4d)
/* Bytes in last 512-byte page. */
SHORT (LOADADDR (.ibss) % 512)
/* Total number of 512-byte pages. */
SHORT (ALIGN(LOADADDR (.ibss), 512) / 512)
/* Relocation entries. */
SHORT ((__msdos_mz_rel_end - __msdos_mz_rel_start) / 4)
/* Header size in paragraphs. */
SHORT (SIZEOF(.msdos_mz_hdr) / 16)
/* Minimum extra paragraphs. */
SHORT (ALIGN(SIZEOF (.ibss) + SIZEOF(.istack), 16) / 16)
/* Maximum extra paragraphs. */
SHORT (0xffff)
/* Initial %ss. */
SHORT (LOADADDR (.istack) / 16 )
/* Initial %sp. */
SHORT (LOADADDR (.istack) % 16 + SIZEOF(.istack))
/* Padding for Checksum (unused) and initial cs:ip (0:0) */
. = 0x18;
/* Relocation table offset. */
SHORT (. + 4)
/* Overlay number */
SHORT (0)
/* Relocations */
HIDDEN (__msdos_mz_rel_start = .);
*(.msdos_mz_reloc .msdos_mz_reloc.*)
HIDDEN (__msdos_mz_rel_end = .);
/* Padding */
. = ALIGN (16);
}
/* Target PSP section. */
.ptext 0 : AT (SIZEOF(.msdos_mz_hdr)) {
*(PSP)
}
/* Target low data+text sections. */
.ltext 0 : AT (LOADADDR(.ptext) + SIZEOF(.ptext)) {
*(_IRQTEXT)
*(_LOWTEXT)
*(_IO_TEXT)
*(_IO_FIXED_DATA)
}
/* Target data sections. */
.data 0 : AT (ALIGN(LOADADDR(.ltext) + SIZEOF(.ltext), 16)) {
*(_FIXED_DATA)
*(_BSS)
*(EXCLUDE_FILE (config.obj iasmsupt.obj *init*.obj iprf.obj main.obj) .bss)
*(_DATA)
*(EXCLUDE_FILE (config.obj iasmsupt.obj *init*.obj iprf.obj main.obj) .data)
*(_DATAEND)
*(CONST)
*(CONST2)
*(EXCLUDE_FILE (config.obj iasmsupt.obj *init*.obj iprf.obj main.obj) .rodata)
*(EXCLUDE_FILE (config.obj iasmsupt.obj *init*.obj iprf.obj main.obj) .rodata.*)
*(DYN_DATA)
ASSERT(. <= 0xfff8,
"Error: too large for a small-model .exe file.");
}
/* Target text sections. */
.text 0 : AT (ALIGN(LOADADDR(.data) + SIZEOF(.data), 16)) {
*(HMA_TEXT_START)
*(HMA_TEXT)
_call_intr = CALL_INTR;
_res_DosExec = RES_DOSEXEC;
_res_read = RES_READ;
_strlen = STRLEN;
_fstrlen = FSTRLEN;
_strlen = STRLEN;
_fstrcmp = FSTRCMP;
_strchr = STRCHR;
_fstrchr = FSTRCHR;
_fmemchr = FMEMCHR;
_strcpy = STRCPY;
_fmemcpy = FMEMCPY;
_fstrcpy = FSTRCPY;
_memcpy = MEMCPY;
_fmemset = FMEMSET;
_memset = MEMSET;
_memcmp = MEMCMP;
_fmemcmp = FMEMCMP;
_network_redirector_mx = NETWORK_REDIRECTOR_MX;
_execrh = EXECRH;
_share_check = SHARE_CHECK;
_share_open_check = SHARE_OPEN_CHECK;
_share_close_file = SHARE_CLOSE_FILE;
_share_access_check = SHARE_ACCESS_CHECK;
_share_lock_unlock = SHARE_LOCK_UNLOCK;
_share_is_file_open = SHARE_IS_FILE_OPEN;
_call_nls = CALL_NLS;
_fl_reset = FL_RESET;
_fl_diskchanged = FL_DISKCHANGED;
_fl_format = FL_FORMAT;
_fl_read = FL_READ;
_fl_write = FL_WRITE;
_fl_verify = FL_VERIFY;
_fl_setdisktype = FL_SETDISKTYPE;
_fl_setmediatype = FL_SETMEDIATYPE;
_fl_readkey = FL_READKEY;
_fl_lba_ReadWrite = FL_LBA_READWRITE;
_floppy_change = FLOPPY_CHANGE;
_ReadPCClock = READPCCLOCK;
_WritePCClock = WRITEPCCLOCK;
_WriteATClock = WRITEATCLOCK;
*(EXCLUDE_FILE (config.obj iasmsupt.obj *init*.obj iprf.obj main.obj) .text)
*(HMA_TEXT_END)
ASSERT(. <= 0x10000,
"Error: too large for a small-model .exe file.");
}
/* Target init text sections. */
.itext 0 : AT (LOADADDR(.text) + SIZEOF(.text)) {
*(INIT_TEXT_START)
*(INIT_TEXT)
_init_execrh = INIT_EXECRH;
_init_memset = INIT_MEMSET;
_init_fmemset = INIT_FMEMSET;
_init_memcmp = INIT_MEMCMP;
_init_fmemcmp = INIT_FMEMCMP;
_init_memcpy = INIT_MEMCPY;
_init_fmemcpy = INIT_FMEMCPY;
_init_strcpy = INIT_STRCPY;
_init_fstrcpy = INIT_FSTRCPY;
_init_strlen = INIT_STRLEN;
_init_fstrlen = INIT_FSTRLEN;
_init_strchr = INIT_STRCHR;
_UMB_get_largest = UMB_GET_LARGEST;
_init_call_intr = INIT_CALL_INTR;
_read = READ;
_init_DosOpen = INIT_DOSOPEN;
_close = CLOSE;
_dup2 = DUP2;
_lseek = LSEEK;
_allocmem = ALLOCMEM;
_init_PSPSet = INIT_PSPSET;
_init_DosExec = INIT_DOSEXEC;
_init_setdrive = INIT_SETDRIVE;
_init_switchar = INIT_SWITCHAR;
_keycheck = KEYCHECK;
_set_DTA = SET_DTA;
_DetectXMSDriver = DETECTXMSDRIVER;
_init_call_XMScall = INIT_CALL_XMSCALL;
__EnableA20 = _ENABLEA20;
__DisableA20 = _DISABLEA20;
*(.text)
*(INIT_TEXT_END)
ASSERT(. <= 0x10000,
"Error: too large for a small-model .exe file.");
}
/* Target init data sections. */
.idata 0 : AT (LOADADDR(.itext) + SIZEOF(.itext)) {
*(ID_B)
*(.data)
*(.rodata) *(.rodata.*)
*(ID_E)
}
.ibss (NOLOAD) : AT (LOADADDR(.idata) + SIZEOF(.idata)) {
*(IB_B)
*(.bss)
*(IB_E)
}
.istack 0 (NOLOAD) : AT (LOADADDR(.ibss) + SIZEOF(.ibss)) {
*(_STACK)
. = 0x1000;
}
/DISCARD/ : { *(.*) }
}

View File

@ -105,7 +105,7 @@ COUNT lfn_free_inode(COUNT handle)
* Return value.
* SUCCESS, LHE_INVLDHNDL
*/
COUNT lfn_setup_inode(COUNT handle, ULONG dirstart, ULONG diroff)
COUNT lfn_setup_inode(COUNT handle, ULONG dirstart, UWORD diroff)
{
f_node_ptr fnp = xlt_fd(handle);
if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL;

View File

@ -51,25 +51,16 @@
; destroys:
; flags
;
%ifdef STDCALL
push bp
mov bp, sp
mov ax, [bp+6]
mov dx, [bp+8]
mov bx, [bp+10]
mov cx, [bp+12]
pop bp
%endif
test cx, cx ; divisor > 2^16-1 ?
jnz %%big_divisor ; yes, divisor > 2^16-1
cmp dx, bx ; only one division needed ? (cx = 0)
test cx, cx ; divisor > 2^32-1 ?
jnz %%big_divisor ; yes, divisor > 32^32-1
cmp dx, bx ; only one division needed ? (ecx = 0)
jb %%one_div ; yes, one division sufficient
xchg cx, ax ; save dividend-lo in cx, ax=0
xchg ax, dx ; get dividend-hi in ax, dx=0
div bx ; quotient-hi in ax
div bx ; quotient-hi in eax
xchg ax, cx ; cx = quotient-hi, ax =dividend-lo
%%one_div:
@ -85,57 +76,37 @@
push dx ; save
push ax ; dividend
mov si, bx ; divisor now in
mov di, cx ; di:si and cx:bx
mov di, cx ; di:bx and cx:si
%%shift_loop:
shr dx, 1 ; shift both
rcr ax, 1 ; dividend
shr cx, 1 ; and divisor
rcr ax, 1 ; divisor and
shr di, 1 ; and dividend
rcr bx, 1 ; right by 1 bit
jnz %%shift_loop ; loop if di non-zero (rcr does not touch ZF)
div bx ; compute quotient dx:ax>>x / cx:bx>>x (stored in ax; remainder in dx not used)
mov di, cx ; restore original divisor (di:si)
div bx ; compute quotient
pop bx ; get dividend lo-word
mov cx, ax ; save quotient
mul di ; quotient * divisor hi-word (low only)
pop dx ; dividend high
sub dx,ax ; dividend high - divisor high * quotient, no overflow (carry/borrow) possible here
push dx ; save dividend high
push di ; save divisor hi-word
xchg ax, di ; save in di
mov ax, cx ; ax=quotient
mul si ; quotient * divisor lo-word
sub bx, ax ; dividend-lo - (quot.*divisor-lo)-lo
add dx, di ; dx:ax = quotient * divisor
pop di ; restore divisor hi-word
sub bx, ax ; dividend-lo - (quot.*divisor)-lo
mov ax, cx ; get quotient
pop cx ; restore dividend hi-word
sbb cx, dx ; subtract (divisor-lo * quot.)-hi from dividend-hi
sbb cx, dx ; subtract divisor * quot. from dividend
sbb dx, dx ; 0 if remainder > 0, else FFFFFFFFh
and si, dx ; nothing to add
and di, dx ; back if remainder positive di:si := di:si(cx:bx) & dx:dx
add bx, si ; correct remainder cx:bx += di:si
adc cx, di ; and
add ax, dx ; quotient if necessary ax += dx
xor dx, dx ; clear hi-word of quot (ax<=FFFFh) dx := 0
and di, dx ; back if remainder positive
add bx, si ; correct remaider
adc cx, di ; and quotient if
add ax, dx ; necessary
xor dx, dx ; clear hi-word of quot (ax<=FFFFFFFFh)
pop di ; restore temp
pop si ; variables
ret
%endmacro
%macro LSHLU 0
pop bx
popargs {dx,ax},cx
push bx
jcxz %%ret
%%loop: shl ax, 1
rcl dx, 1
loop %%loop
%%ret: ret
%endmacro
%macro LSHRU 0
pop bx
popargs {dx,ax},cx
push bx
jcxz %%ret
%%loop: shr dx, 1
rcr ax, 1
loop %%loop
%%ret: ret
%endmacro

View File

@ -38,12 +38,14 @@ static BYTE *mainRcsId =
#endif
static char copyright[] =
"(C) Copyright 1995-2023 Pasquale J. Villani and The FreeDOS Project.\n"
"(C) Copyright 1995-2012 Pasquale J. Villani and The FreeDOS Project.\n"
"All Rights Reserved. This is free software and comes with ABSOLUTELY NO\n"
"WARRANTY; you can redistribute it and/or modify it under the terms of the\n"
"GNU General Public License as published by the Free Software Foundation;\n"
"either version 2, or (at your option) any later version.\n";
struct _KernelConfig InitKernelConfig BSS_INIT({0});
STATIC VOID InitIO(void);
STATIC VOID update_dcb(struct dhdr FAR *);
@ -68,18 +70,10 @@ __segment DosTextSeg = 0;
struct lol FAR *LoL = &DATASTART;
struct _KernelConfig ASM InitKernelConfig = { -1 };
char ASM kernel_command_line[256] = { 0, -1 }; /* special none value */
int kernel_command_line_length BSS_INIT(0);
UBYTE ASM debugger_present = 0xFF; /* initialised in kernel.asm
do NOT set 0 here or compiler may
move it into bss that we zero out */
VOID ASMCFUNC FreeDOSmain(void)
{
unsigned char drv;
unsigned char FAR *p;
char * pp;
#ifdef _MSC_VER
extern FAR prn_dev;
@ -98,8 +92,17 @@ VOID ASMCFUNC FreeDOSmain(void)
drv = LoL->BootDrive + 1;
p = MK_FP(0, 0x5e0);
if (fmemcmp(p+2,"CONFIG",6) == 0) /* UPX */
{
*p = drv - 1; /* compatibility with older kernels */
fmemcpy(&InitKernelConfig, p+2, sizeof(InitKernelConfig));
drv = *p + 1;
*(DWORD FAR *)(p+2) = 0;
}
else
{
*p = drv - 1;
fmemcpy(&InitKernelConfig, &LowKernelConfig, sizeof(InitKernelConfig));
}
if (drv >= 0x80)
@ -109,23 +112,6 @@ VOID ASMCFUNC FreeDOSmain(void)
/* install DOS API and other interrupt service routines, basic kernel functionality works */
setup_int_vectors();
#ifdef DEBUG
/* printf must go after setup_int_vectors call */
if (kernel_command_line[0] == 0 && kernel_command_line[1] == (char)-1) {
printf("\nKERNEL: Command line is not specified.\n");
} else {
printf("\nKERNEL: Command line is \"%s\"\n", kernel_command_line);
}
#endif
kernel_command_line_length = strlen(kernel_command_line);
for (pp = kernel_command_line; *pp; ++pp) {
if (*pp == ';') {
*pp = 0;
}
}
/* check if booting from floppy/CD */
CheckContinueBootFromHarddisk();
/* display copyright info and kernel emulation status */
@ -172,7 +158,6 @@ STATIC void PSPInit(void)
/* Clear out new psp first */
fmemset(p, 0, sizeof(psp));
/* high half is used as environment */
/* initialize all entries and exits */
/* CP/M-like exit point */
@ -215,9 +200,6 @@ STATIC void PSPInit(void)
/* open file table pointer */
p->ps_filetab = p->ps_files;
/* default system version for int21/ah=30 */
p->ps_retdosver = (LoL->os_setver_minor << 8) + LoL->os_setver_major;
/* first command line argument */
/* p->ps_fcb1.fcb_drive = 0; already set */
fmemset(p->ps_fcb1.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE);
@ -225,7 +207,9 @@ STATIC void PSPInit(void)
/* p->ps_fcb2.fcb_drive = 0; already set */
fmemset(p->ps_fcb2.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE);
/* do not modify command line tail, used as environment */
/* local command line */
/* p->ps_cmd.ctCount = 0; command tail, already set */
p->ps_cmd.ctBuffer[0] = 0xd; /* command tail */
}
#ifndef __WATCOMC__
@ -256,41 +240,37 @@ STATIC void setup_int_vectors(void)
} vectors[] =
{
/* all of these are in the DOS DS */
{ 0x80 | 0x0, FP_OFF(int0_handler) }, /* zero divide */
{ 0x80 | 0x1, FP_OFF(empty_handler) }, /* single step */
{ 0x80 | 0x3, FP_OFF(empty_handler) }, /* debug breakpoint */
{ 0x80 | 0x6, FP_OFF(int6_handler) }, /* invalid opcode */
{ 0x19, FP_OFF(int19_handler) }, /* BIOS bootstrap loader, vdisk */
{ 0x0, FP_OFF(int0_handler) }, /* zero divide */
{ 0x1, FP_OFF(empty_handler) }, /* single step */
{ 0x3, FP_OFF(empty_handler) }, /* debug breakpoint */
{ 0x6, FP_OFF(int6_handler) }, /* invalid opcode */
{ 0x19, FP_OFF(int19_handler) },
{ 0x20, FP_OFF(int20_handler) },
{ 0x21, FP_OFF(int21_handler) }, /* primary DOS API */
{ 0x21, FP_OFF(int21_handler) },
{ 0x22, FP_OFF(int22_handler) },
{ 0x24, FP_OFF(int24_handler) },
{ 0x25, FP_OFF(low_int25_handler) }, /* DOS abs read/write calls */
{ 0x25, FP_OFF(low_int25_handler) },
{ 0x26, FP_OFF(low_int26_handler) },
{ 0x27, FP_OFF(int27_handler) },
{ 0x28, FP_OFF(int28_handler) },
{ 0x2a, FP_OFF(int2a_handler) },
{ 0x2f, FP_OFF(int2f_handler) } /* multiplex int */
{ 0x2f, FP_OFF(int2f_handler) }
};
struct vec *pvec;
struct lowvec FAR *plvec;
int i;
/* save current int vectors so can restore on reboot and call original directly */
for (plvec = intvec_table; plvec < intvec_table + 6; plvec++)
for (plvec = intvec_table; plvec < intvec_table + 5; plvec++)
plvec->isv = getvec(plvec->intno);
/* install default handlers */
for (i = 0x23; i <= 0x3f; i++)
setvec(i, empty_handler); /* note: int 31h segment should be DOS DS */
setvec(i, empty_handler);
HaltCpuWhileIdle = 0;
for (pvec = vectors; pvec < vectors + (sizeof vectors/sizeof *pvec); pvec++)
if ((pvec->intno & 0x80) == 0 || debugger_present == 0)
setvec(pvec->intno & 0x7F, (intvec)MK_FP(FP_SEG(empty_handler), pvec->handleroff));
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);
/* handlers for int 0x1b and 0x29 are in the device driver area LOWTEXT (0x70) */
/* these two are in the device driver area LOWTEXT (0x70) */
setvec(0x1b, got_cbreak);
setvec(0x29, int29_handler); /* required for printf! */
}
@ -305,14 +285,7 @@ STATIC void init_kernel(void)
/* Init oem hook - returns memory size in KB */
ram_top = init_oem();
/* Note: HMA_TEXT and init code already moved higher in
conventional memory by startup code, however, we still
need to adjust any references to new location. So use
current CS as that is where we were moved to and perform
any fixups needed. Note this will also re-copy the
HMA_TEXT segment, so be sure not to overwrite it prior
to the MoveKernel() call. Kernel moved to around 8F??:0000
*/
/* move kernel to high conventional RAM, just below the init code */
#ifdef __WATCOMC__
lpTop = MK_FP(_CS, 0);
#else
@ -437,17 +410,6 @@ STATIC VOID FsConfig(VOID)
STATIC VOID signon()
{
if (InitKernelConfig.Verbose < 0)
{
#ifdef CUSTOM_BRANDING
printf("\n\r" CUSTOM_BRANDING "\n\n");
#else
printf("\n\r%S\n\n", MK_FP(FP_SEG(LoL), FP_OFF(LoL->os_release)));
#endif
} else {
#ifdef CUSTOM_BRANDING
printf("\n\r" CUSTOM_BRANDING "\n\n%s", copyright);
#else
printf("\r%S"
"Kernel compatibility %d.%d - "
#if defined(__BORLANDC__)
@ -468,8 +430,6 @@ STATIC VOID signon()
" - 80386 CPU required"
#elif defined (I186)
" - 80186 CPU required"
#else
" - 808x compatible"
#endif
#ifdef WITHFAT32
@ -478,8 +438,6 @@ STATIC VOID signon()
"\n\n%s",
MK_FP(FP_SEG(LoL), FP_OFF(LoL->os_release)),
MAJOR_RELEASE, MINOR_RELEASE, copyright);
#endif
}
}
STATIC void kernel()
@ -487,7 +445,8 @@ STATIC void kernel()
CommandTail Cmd;
if (master_env[0] == '\0') /* some shells panic on empty master env. */
fmemcpy(master_env, "PATH=.\0\0\0\0", sizeof("PATH=.\0\0\0\0"));
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 */
@ -541,40 +500,20 @@ STATIC VOID update_dcb(struct dhdr FAR * dhp)
COUNT nunits = dhp->dh_name[0];
struct dpb FAR *dpb;
/* printf("nblkdev = %i\n", LoL->nblkdev); */
/* if no units, nothing to do, ensure at least 1 unit for rest of logic */
if (nunits == 0) return;
/* allocate memory for new device control blocks, insert into chain [at end], and update our pointer to new end */
if ( LoL->first_mcb ) {
dpb = (struct dpb FAR *)KernelAlloc(nunits * sizeof(struct dpb), 'E', Config.cfgDosDataUmb);
}
else {
dpb = DynAlloc("DPBp", blk_dev.dh_name[0], sizeof(struct dpb));
}
/* find end of dpb chain or initialize root if needed */
if (LoL->nblkdev == 0)
{
/* update root pointer to new end (our just allocated block) */
LoL->DPBp = dpb;
}
dpb = LoL->DPBp;
else
{
struct dpb FAR *tmp_dpb;
/* find current end of dpb chain by following next pointers to end */
for (tmp_dpb = LoL->DPBp; (ULONG) tmp_dpb->dpb_next != 0xffffffffl; tmp_dpb = dpb->dpb_next)
for (dpb = LoL->DPBp; (ULONG) dpb->dpb_next != 0xffffffffl;
dpb = dpb->dpb_next)
;
/* insert into chain [at end] */
tmp_dpb->dpb_next = dpb;
dpb = dpb->dpb_next =
KernelAlloc(nunits * sizeof(struct dpb), 'E', Config.cfgDosDataUmb);
}
/* dpb points to last block, one just allocated */
for (Index = 0; Index < nunits; Index++)
{
/* printf("processing unit %i of %i nunits\n", Index, nunits); */
dpb->dpb_next = dpb + 1; /* memory allocated as array, so next is just next element */
dpb->dpb_next = dpb + 1;
dpb->dpb_unit = LoL->nblkdev;
dpb->dpb_subunit = Index;
dpb->dpb_device = dhp;
@ -584,14 +523,10 @@ STATIC VOID update_dcb(struct dhdr FAR * dhp)
LoL->CDSp[LoL->nblkdev].cdsDpb = dpb;
LoL->CDSp[LoL->nblkdev].cdsFlags = CDSPHYSDRV;
}
++dpb; /* dbp = dbp->dpb_next; */
++dpb;
++LoL->nblkdev;
}
/* note that always at least 1 valid dpb due to above early exit if nunits==0 */
(dpb - 1)->dpb_next = (void FAR *)0xFFFFFFFFl;
/* printf("processed %i nunits\n", nunits); */
}
/* If cmdLine is NULL, this is an internal driver */
@ -840,12 +775,8 @@ STATIC void CheckContinueBootFromHarddisk(void)
init_call_intr(0x13, &r);
{
#if __GNUC__
asm volatile("jmp $0,$0x7c00");
#else
void (far *reboot)(void) = (void (far*)(void)) MK_FP(0x0,0x7c00);
(*reboot)();
#endif
}
}

View File

@ -21,46 +21,39 @@ OBJS4=break.obj dosfns.obj fatdir.obj fatfs.obj fattab.obj fcbfns.obj \
inthndlr.obj
OBJS5=ioctl.obj memmgr.obj task.obj newstuff.obj nls.obj network.obj
OBJS6=prf.obj misc.obj strings.obj syspack.obj lfnapi.obj iasmsupt.obj memdisk.obj
OBJS7=main.obj config.obj initoem.obj inithma.obj dyninit.obj iprf.obj
OBJS8=initdisk.obj initclk.obj cpu.obj
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS6) $(OBJS7) $(OBJS8)
OBJS7=main.obj config.obj initoem.obj inithma.obj dyninit.obj iprf.obj \
initdisk.obj initclk.obj cpu.obj
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS6) $(OBJS7)
# *Explicit Rules*
production: ../bin/$(TARGET).sys
production: ../bin/$(TARGET).sys ../bin/country.sys
../bin/$(TARGET).sys: kernel.sys
$(CP) kernel.sys ..$(DIRSEP)bin
$(CP) kernel.sys ..$(DIRSEP)bin$(DIRSEP)$(TARGET).sys
$(CP) kernel.map ..$(DIRSEP)bin$(DIRSEP)$(TARGET).map
kernel.sys: kernel.exe ../utils/exeflat.exe ../utils/upxentry.bin ../utils/upxdevic.bin exeflat.rsp
..$(DIRSEP)utils$(DIRSEP)exeflat.exe kernel.exe kernel.sys $(LOADSEG) @exeflat.rsp
# -S to avoid showing expected relocations
# 0x10 & 0x78 or 0x79 depending on compilation options
kernel.sys: kernel.exe ../utils/exeflat.exe
..$(DIRSEP)utils$(DIRSEP)exeflat.exe kernel.exe kernel.sys $(LOADSEG) -S0x10 -S0x78 -S0x79 $(UPXOPT) $(XUPX)
kernel.exe: $(TARGET).lnk $(OBJS) $(LIBS)
$(LINK) @$(TARGET).lnk;
../bin/country.sys: country.asm
$(NASM) -o $*.sys country.asm
clobber: clean
-$(RM) kernel.exe kernel.sys status.me
clean:
-$(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.cod *.err *.lnk *.rsp
-$(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.cod *.err *.lnk
# 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
# -S to avoid showing expected relocations
# 0x10 & 0x78 or 0x79 depending on compilation options
exeflat.rsp: makefile
-$(RM) exeflat.rsp
$(ECHOTO) exeflat.rsp -S0x10
$(ECHOTO) exeflat.rsp -S0x78
$(ECHOTO) exeflat.rsp -S0x79
$(ECHOTO) exeflat.rsp -E..$(DIRSEP)utils$(DIRSEP)upxentry.bin
$(ECHOTO) exeflat.rsp -D..$(DIRSEP)utils$(DIRSEP)upxdevic.bin
$(ECHOTO) exeflat.rsp $(UPXOPT)
$(ECHOTO) exeflat.rsp $(XUPX)
$(TARGET).lnk: turboc.cfg makefile ../mkfiles/generic.mak ../mkfiles/$(COMPILER).mak
-$(RM) *.lnk
$(ECHOTO) $(TARGET).lnk $(OBJS1)+
@ -69,8 +62,7 @@ $(TARGET).lnk: turboc.cfg makefile ../mkfiles/generic.mak ../mkfiles/$(COMPILER)
$(ECHOTO) $(TARGET).lnk $(OBJS4)+
$(ECHOTO) $(TARGET).lnk $(OBJS5)+
$(ECHOTO) $(TARGET).lnk $(OBJS6)+
$(ECHOTO) $(TARGET).lnk $(OBJS7)+
$(ECHOTO) $(TARGET).lnk $(OBJS8)
$(ECHOTO) $(TARGET).lnk $(OBJS7)
$(ECHOTO) $(TARGET).lnk kernel.exe
$(ECHOTO) $(TARGET).lnk kernel.map
$(ECHOTO) $(TARGET).lnk $(LIBS)
@ -97,7 +89,7 @@ serial.obj: serial.asm io.inc $(TARGET).lnk
HDRS=\
$(HDR)portab.h $(HDR)device.h $(HDR)mcb.h $(HDR)pcb.h \
$(HDR)fat.h $(HDR)fcb.h $(HDR)tail.h $(HDR)dtime.h $(HDR)process.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)version.h dyndata.h
@ -165,7 +157,7 @@ initclk.obj: initclk.c $(INITHEADERS) $(TARGET).lnk
#the string functions for INIT_TEXT
iasmsupt.obj: asmsupt.asm $(TARGET).lnk
$(NASM) -D$(COMPILER) -D_INIT -f obj $(NASMFLAGS) -o iasmsupt.obj asmsupt.asm
$(NASM) -D$(COMPILER) -D_INIT $(NASMFLAGS) -f obj -o iasmsupt.obj asmsupt.asm
#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

View File

@ -316,7 +316,7 @@ COUNT DosMemFree(UWORD para)
*/
COUNT DosMemChange(UWORD para, UWORD size, UWORD * maxSize)
{
REG mcb FAR *p; mcb FAR * q;
REG mcb FAR *p, FAR * q;
/* Initialize */
p = para2far(para - 1); /* pointer to MCB */

View File

@ -185,10 +185,7 @@ long DosMkTmp(BYTE FAR * pathname, UWORD attr)
*/
#define PATH_ERROR() \
fstrchr(src, '/') == 0 && fstrchr(src, '\\') == 0 \
? DE_FILENOTFND \
: DE_PATHNOTFND
#define PATH_ERROR goto errRet
#define PATHLEN 128
@ -252,7 +249,7 @@ STATIC const char _DirChars[] = "\"[]:|<>+=;,";
#define addChar(c) \
{ \
if (p >= dest + SFTMAX) return PATH_ERROR(); /* path too long */ \
if (p >= dest + SFTMAX) PATH_ERROR; /* path too long */ \
*p++ = c; \
}
@ -302,69 +299,9 @@ COUNT truename(const char FAR * src, char * dest, COUNT mode)
else
result = default_drive;
dhp = IsDevice(src);
cdsEntry = get_cds(result);
if (cdsEntry == NULL)
{
/* If opening a character device, DOS allows device name
to be prefixed by [invalid] drive letter and/or optionally
\DEV\ directory prefix, however, any other directory
including root (\) is an invalid path if drive is not
valid and returns such.
Whereas truename always fails for invalid drive.
*/
if (dhp && (mode & CDS_MODE_CHECK_DEV_PATH) && (result >= lastdrive))
{
/* Note: check for (result >= lastdrive) means invalid drive
was provided as otherwise we would have used default_drive
so we know src in the form of X:?
fail if anything other than no path or path is \DEV\
*/
const char FAR *s = src+2;
char c = *s;
if( c != '\\' && c != '/' ) c = '\0';
/* could be 1 letter devicename, don't go scanning random memory */
if (*(src+3) != '\0')
{
s = fstrchr(src+3, '\\'); /* ?is there \ or / other than immediately after drive: */
if (s == NULL) s = fstrchr(src+3, '/');
}
else
{
s = NULL;
}
if (c == '\0')
{
/* either X:devicename or X:path\devicename */
if (s != NULL) goto invalid_path;
}
else
{
/* either X:\devicename or X:\path\devicename
only X:\DEV\devicename is valid path
*/
if (s == NULL) goto invalid_path;
if (s != src+6) goto invalid_path;
if (fmemcmp(src+3, "DEV", 3) != 0) goto invalid_path;
s = fstrchr(src+7, '\\');
if (s == NULL) s = fstrchr(src+7, '/');
if (s != NULL) goto invalid_path;
}
/* use CDS of current drive (MS-DOS may return drive P: for invalid drive.) */
result = default_drive;
cdsEntry = get_cds(result);
if (cdsEntry == NULL) goto invalid_path;
}
else
{
invalid_path:
return DE_PATHNOTFND;
}
}
fmemcpy(&TempCDS, cdsEntry, sizeof(TempCDS));
tn_printf(("CDS entry: #%u @%p (%u) '%s'\n", result, cdsEntry,
@ -375,6 +312,7 @@ invalid_path:
if (TempCDS.cdsFlags & CDSNETWDRV)
result |= IS_NETWORK;
dhp = IsDevice(src); /* returns header if -char- device */
if (dhp)
result |= IS_DEVICE;
@ -529,18 +467,14 @@ invalid_path:
if(*src == '.')
{
int dots = 1;
/* special directory component */
++src;
if (*src == '.') /* skip the second dot */
{
++src;
dots++;
}
if (*src == '/' || *src == '\\' || *src == '\0')
{
--p; /* backup the backslash */
if (dots == 2)
if (src[-2] == '.')
{
/* ".." entry */
/* remove last path component */
@ -552,9 +486,12 @@ invalid_path:
}
/* ill-formed .* or ..* entries => return error */
errRet:
/* The error is either PATHNOTFND or FILENOTFND
depending on if it is not the last component */
return PATH_ERROR();
return fstrchr(src, '/') == 0 && fstrchr(src, '\\') == 0
? DE_FILENOTFND
: DE_PATHNOTFND;
}
/* normal component */
@ -587,7 +524,7 @@ invalid_path:
if (c == '.')
{
if (state & PNE_DOT) /* multiple dots are ill-formed */
return PATH_ERROR();
PATH_ERROR;
/* strip trailing dot */
if (*src == '/' || *src == '\\' || *src == '\0')
break;
@ -599,7 +536,7 @@ invalid_path:
state |= PNE_WILDCARD;
if (i) { /* name length in limits */
--i;
if (!DirChar(c)) return PATH_ERROR();
if (!DirChar(c)) PATH_ERROR;
addChar(c);
}
}
@ -712,7 +649,7 @@ if exist report.out del report.out
cmdspy stop
cmdspy flush
cmdspy restart
int ax=0x6000 -buf ds:si="abcöflkgsxkf\0" -buf es:di="%256s" -int 0x21 -d es:di:128 >spy_int.out
int ax=0x6000 -buf ds:si="abcöflkgsxkf\0" -buf es:di="%256s" -int 0x21 -d es:di:128 >spy_int.out
cmdspy stop
cmdspy report report.out
more report.out
@ -732,11 +669,11 @@ more report.out
1123: IN: C:\TOOL\INT.COM [FAIL 0001]
1123: OUT: C:\INTRSPY\SPY_INT.OUT
1123: orig buffer: C:\TOOL\INT.COM
1123: IN: abcöflkgsxkf [FAIL 0001]
1123: IN: abcöflkgsxkf [FAIL 0001]
1123: OUT: C:\TOOL\INT.COM
1123: orig buffer: abcöflkgsxkf
1123: orig buffer: abcöflkgsxkf
1123: IN: C:\INTRSPY\SPY_INT.BAT [FAIL 0001]
1123: OUT: C:\INTRSPY\ABCÖFLKG
1123: OUT: C:\INTRSPY\ABCÖFLKG
1123: orig buffer: C:\INTRSPY\SPY_INT.BAT
1123: IN: cmdspy.??? [FAIL 0001]
1123: OUT: C:\INTRSPY
@ -758,7 +695,7 @@ DOSERR: 0000 (0)
*<es:di:128> {
43(C) 3A(:) 5C(\) 49(I) 4E(N) 54(T) 52(R) 53(S) 50(P) 59(Y) 5C(\) 41(A)
42(B) 43(C) 99(Ö) 46(F) 4C(L) 4B(K) 47(G) 00(.) 3D(=) 30(0) 30(0) 30(0)
42(B) 43(C) 99(Ö) 46(F) 4C(L) 4B(K) 47(G) 00(.) 3D(=) 30(0) 30(0) 30(0)
30(0) 20( ) 20( ) 20( ) 43(C) 58(X) 3D(=) 30(0) 30(0) 30(0) 30(0) 28(()
30(0) 29()) 20( ) 32(2) 38(8) 28(() 28(() 29()) 20( ) 33(3) 30(0) 28(()
30(0) 29()) 20( ) 32(2) 39(9) 28(() 29()) 29()) 20( ) 32(2) 30(0) 28(()

View File

@ -36,7 +36,7 @@
#include "portab.h"
#include "globals.h"
#include "pcb.h"
#include "nls.h"
#include <nls.h>
#ifdef VERSION_STRINGS
static BYTE *RcsId =
@ -66,13 +66,8 @@ struct nlsInfoBlock ASM nlsInfo = {
#ifdef NLS_REORDER_POINTERS
| NLS_CODE_REORDER_POINTERS
#endif
#ifdef __GNUC__
, {.seg=DosDataSeg, .off=&nlsPackageHardcoded} /* hardcoded first package */
, {.seg=DosDataSeg, .off=&nlsPackageHardcoded} /* first item in chain */
#else
, &nlsPackageHardcoded /* hardcoded first package */
, &nlsPackageHardcoded /* first item in chain */
#endif
};
/* getTableX return the pointer to the X'th table; X==subfct */
@ -98,9 +93,6 @@ struct nlsInfoBlock ASM nlsInfo = {
***** MUX calling functions ****************************************
********************************************************************/
#ifdef __GNUC__
#define call_nls(a,b,c,d,e,f) call_nls(f,e,d,c,b,a)
#endif
extern long ASMPASCAL call_nls(UWORD, VOID FAR *, UWORD, UWORD, UWORD, UWORD);
/*== DS:SI _always_ points to global NLS info structure <-> no
* subfct can use these registers for anything different. ==ska*/
@ -667,54 +659,60 @@ VOID FAR *DosGetDBCS(void)
Return value: AL register to be returned
if AL == 0, Carry must be cleared, otherwise set
*/
UWORD ASMCFUNC syscall_MUX14(iregs FAR *pr)
UWORD ASMCFUNC syscall_MUX14(DIRECT_IREGS)
{
struct nlsPackage FAR *nls; /* addressed NLS package */
log(("NLS: MUX14(): subfct=%x, cp=%u, cntry=%u\n", pr->AL, pr->BX, pr->DX));
UNREFERENCED_PARAMETER(flags);
UNREFERENCED_PARAMETER(cs);
UNREFERENCED_PARAMETER(ip);
UNREFERENCED_PARAMETER(ds);
UNREFERENCED_PARAMETER(es);
UNREFERENCED_PARAMETER(si);
if ((nls = searchPackage(pr->BX, pr->DX)) == NULL)
log(("NLS: MUX14(): subfct=%x, cp=%u, cntry=%u\n", AL, BX, DX));
if ((nls = searchPackage(BX, DX)) == NULL)
return DE_INVLDFUNC; /* no such package */
log(("NLS: MUX14(): NLS pkg found\n"));
switch (pr->AL)
switch (AL)
{
case NLSFUNC_INSTALL_CHECK:
pr->BX = NLS_FREEDOS_NLSFUNC_ID;
BX = NLS_FREEDOS_NLSFUNC_ID;
return SUCCESS; /* kernel just simulates default functions */
case NLSFUNC_DOS38:
return nlsGetData(nls, NLS_DOS_38, MK_FP(pr->ES, pr->DI), 34);
return nlsGetData(nls, NLS_DOS_38, MK_FP(ES, DI), 34);
case NLSFUNC_GETDATA:
return nlsGetData(nls, pr->BP, MK_FP(pr->ES, pr->DI), pr->CX);
return nlsGetData(nls, BP, MK_FP(ES, DI), CX);
case NLSFUNC_DRDOS_GETDATA:
/* Does not pass buffer length */
return nlsGetData(nls, pr->CL, MK_FP(pr->ES, pr->DI), 512);
return nlsGetData(nls, CL, MK_FP(ES, DI), 512);
case NLSFUNC_LOAD_PKG:
return nlsLoadPackage(nls);
case NLSFUNC_LOAD_PKG2:
return nlsSetPackage(nls);
case NLSFUNC_YESNO:
return nlsYesNo(nls, pr->CX);
return nlsYesNo(nls, CX);
case NLSFUNC_UPMEM:
nlsUpMem(nls, MK_FP(pr->ES, pr->DI), pr->CX);
nlsUpMem(nls, MK_FP(ES, DI), CX);
return SUCCESS;
case NLSFUNC_FILE_UPMEM:
#ifdef NLS_DEBUG
{
unsigned j;
BYTE FAR *p;
log(("NLS: MUX14(FILE_UPMEM): len=%u, %04x:%04x=\"", pr->CX,
pr->ES, pr->DI));
for (j = 0, p = MK_FP(pr->ES, pr->DI); j < pr->CX; ++j)
log(("NLS: MUX14(FILE_UPMEM): len=%u, %04x:%04x=\"", CX, ES, DI));
for (j = 0, p = MK_FP(ES, DI); j < CX; ++j)
printf("%c", p[j] > 32 ? p[j] : '.');
printf("\"\n");
}
#endif
nlsFUpMem(nls, MK_FP(pr->ES, pr->DI), pr->CX);
nlsFUpMem(nls, MK_FP(ES, DI), CX);
return SUCCESS;
}
log(("NLS: MUX14(): Invalid function %x\n", pr->AL));
log(("NLS: MUX14(): Invalid function %x\n", AL));
return DE_INVLDFUNC; /* no such function */
}

View File

@ -14,15 +14,15 @@ _nlsPackageHardcoded:
DB 000h, 000h, 000h, 000h, 001h, 000h, 0b5h, 001h
DB 00fh, 000h, 059h, 000h, 04eh, 000h, 006h, 000h
DB 002h
DW ?table2, DGROUP
DW ?table2, SEG ?table2
DB 004h
DW ?table4, DGROUP
DW ?table4, SEG ?table4
DB 005h
DW ?table5, DGROUP
DW ?table5, SEG ?table5
DB 006h
DW ?table6, DGROUP
DW ?table6, SEG ?table6
DB 007h
DW ?table7, DGROUP
DW ?table7, SEG ?table7
GLOBAL _nlsCountryInfoHardcoded
_nlsCountryInfoHardcoded:
DB 001h
@ -32,8 +32,8 @@ _nlsCntryInfoHardcoded:
DB 01ch, 000h, 001h, 000h, 0b5h, 001h, 000h, 000h
DB 024h, 000h, 000h, 000h, 000h, 02ch, 000h, 02eh
DB 000h, 02dh, 000h, 03ah, 000h, 000h, 002h, 000h
extern _CharMapSrvc
DW _CharMapSrvc, DGROUP
extern _CharMapSrvc:wrt DGROUP
DW _CharMapSrvc, SEG _CharMapSrvc
DB 02ch, 000h
GLOBAL _hcTablesStart
_hcTablesStart:
@ -122,7 +122,6 @@ _nlsCollHardcoded:
GLOBAL _nlsDBCSHardcoded
_nlsDBCSHardcoded:
?table7:
DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
DB 000h, 000h
DB 000h, 000h, 000h, 000h
GLOBAL _hcTablesEnd
_hcTablesEnd:

View File

@ -29,11 +29,7 @@
#include "portab.h"
#ifdef FORSYS
#ifdef __GNUC__
#include <unistd.h>
#else
#include <io.h>
#endif
#include <stdarg.h>
#endif
@ -73,12 +69,6 @@ void put_console(int c)
_DX = FP_OFF(buff);
_AX = 0x13;
__int__(0xe6);
#elif defined(__GNUC__)
asm volatile(
"int $0xe6\n"
: /* outputs */
: /* inputs */ "a"(0x13), "e"(FP_SEG(buff)), "d"(FP_OFF(buff))
);
#elif defined(I86)
asm
{
@ -99,14 +89,7 @@ void put_console(int c)
#else
#ifdef __WATCOMC__
void int29(char c);
#pragma aux int29 = "int 0x29" __parm [__al] __modify __exact [__bx];
#ifdef DEBUG_PRINT_COMPORT
void fastComPrint(char c);
#pragma aux fastComPrint = \
"mov bx, 0xFD05" \
"int 0x29" __parm [__al] __modify __exact [__bx];
#endif
#pragma aux int29 = "int 0x29" parm [al] modify exact [bx];
#endif
void put_console(int c)
@ -122,11 +105,6 @@ void put_console(int c)
__int__(0x29);
#elif defined(__WATCOMC__)
int29(c);
#if defined DEBUG_PRINT_COMPORT
fastComPrint(c);
#endif
#elif defined(__GNUC__)
asm volatile("int $0x29" : : "a"(c) : "bx");
#elif defined(I86)
__asm
{
@ -167,11 +145,6 @@ STATIC VOID handle_char(COUNT c)
if (charp == 0)
put_console(c);
else
#ifdef DEBUG_PRINT_COMPORT
if (charp == (BYTE SSFAR *)-1)
fastComPrint(c);
else
#endif
*charp++ = c;
}
@ -179,8 +152,7 @@ STATIC VOID handle_char(COUNT c)
STATIC void ltob(LONG n, BYTE SSFAR * s, COUNT base)
{
ULONG u;
BYTE SSFAR *p;
BYTE SSFAR *q;
BYTE SSFAR *p, SSFAR *q;
int c;
u = n;
@ -252,25 +224,12 @@ int VA_CDECL sprintf(char * buff, CONST char * fmt, ...)
return 0;
}
#ifdef DEBUG_PRINT_COMPORT
int dbgc_printf(CONST char * fmt, ...)
{
va_list arg;
va_start(arg, fmt);
charp = (BYTE SSFAR *)-1;
do_printf(fmt, arg);
handle_char('\0');
return 0;
}
#endif
STATIC void do_printf(CONST BYTE * fmt, va_list arg)
{
int base, size;
BYTE s[13]; /* long enough for a 32-bit octal number string with sign */
BYTE flags;
BYTE FAR *p;
int base;
BYTE s[11], FAR * p;
int size;
unsigned char flags;
for (;*fmt != '\0'; fmt++)
{

View File

@ -31,10 +31,10 @@
%include "segs.inc"
extern _user_r
extern _user_r:wrt DGROUP
extern _break_flg ; break detected flag
extern _int21_handler ; far call system services
extern _break_flg:wrt DGROUP ; break detected flag
extern _int21_handler:wrt DGROUP ; far call system services
%include "stacks.inc"
@ -71,7 +71,7 @@ _exec_user:
;
POP$ALL
extern _ExecUserDisableA20
jmp DGROUP:_ExecUserDisableA20
jmp far _ExecUserDisableA20
do_iret:
extern _int21_iret
jmp _int21_iret
@ -263,7 +263,7 @@ _spawn_int23:
??int23_respawn:
pop bp ;; Restore the original register
jmp DGROUP:_int21_handler
jmp far _int21_handler
;
; interrupt enable and disable routines

View File

@ -54,7 +54,7 @@ unsigned char ctrl_break_pressed(void);
unsigned char check_handle_break(struct dhdr FAR **pdev);
void handle_break(struct dhdr FAR **pdev, int sft_out);
#ifdef __WATCOMC__
#pragma aux handle_break __aborts;
#pragma aux handle_break aborts;
#endif
/* chario.c */
@ -102,8 +102,8 @@ COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s);
COUNT DosChangeDir(BYTE FAR * s);
COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name);
COUNT DosFindNext(void);
COUNT DosGetFtime(COUNT hndl, ddate * dp, dtime * tp);
COUNT DosSetFtimeSft(int sft_idx, ddate dp, dtime tp);
COUNT DosGetFtime(COUNT hndl, date * dp, time * tp);
COUNT DosSetFtimeSft(int sft_idx, date dp, time tp);
#define DosSetFtime(hndl, dp, tp) DosSetFtimeSft(get_sft_idx(hndl), (dp), (tp))
COUNT DosGetFattr(BYTE FAR * name);
COUNT DosSetFattr(BYTE FAR * name, UWORD attrp);
@ -118,7 +118,6 @@ COUNT DosLockUnlock(COUNT hndl, LONG pos, LONG len, COUNT unlock);
int idx_to_sft_(int SftIndex);
sft FAR *idx_to_sft(int SftIndex);
int get_sft_idx(UCOUNT hndl);
struct cds FAR *get_cds_unvalidated(unsigned dsk);
struct cds FAR *get_cds(unsigned dsk);
struct cds FAR *get_cds1(unsigned dsk);
COUNT DosTruename(const char FAR * src, char FAR * dest);
@ -127,8 +126,8 @@ COUNT DosTruename(const char FAR * src, char FAR * dest);
VOID ASMCFUNC DosIdle_int(void);
VOID ASMCFUNC DosIdle_hlt(void);
#ifdef __WATCOMC__
#pragma aux (__cdecl) DosIdle_int __modify __exact []
#pragma aux (__cdecl) DosIdle_hlt __modify __exact []
#pragma aux (cdecl) DosIdle_int modify exact []
#pragma aux (cdecl) DosIdle_hlt modify exact []
#endif
/* error.c */
@ -158,8 +157,8 @@ COUNT dos_close(COUNT fd);
COUNT dos_delete(BYTE * path, int attrib);
COUNT dos_rmdir(BYTE * path);
COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib);
ddate dos_getdate(void);
dtime dos_gettime(void);
date dos_getdate(void);
time dos_gettime(void);
COUNT dos_mkdir(BYTE * dir);
BOOL last_link(f_node_ptr fnp);
COUNT map_cluster(REG f_node_ptr fnp, COUNT mode);
@ -218,13 +217,11 @@ void FcbCloseAll(void);
UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First);
/* intr.asm */
UWORD ASMPASCAL call_intr(WORD nr, iregs FAR * rp);
COUNT ASMPASCAL res_DosExec(COUNT mode, exec_blk * ep, BYTE * lp);
UCOUNT ASMPASCAL res_read(int fd, void *buf, UCOUNT count);
#ifdef __WATCOMC__
#pragma aux (__pascal) call_intr __modify __exact [__ax]
#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 */
@ -250,7 +247,7 @@ VOID mcb_print(mcb FAR * mcbp);
COUNT lfn_allocate_inode(VOID);
COUNT lfn_free_inode(COUNT handle);
COUNT lfn_setup_inode(COUNT handle, ULONG dirstart, ULONG diroff);
COUNT lfn_setup_inode(COUNT handle, ULONG dirstart, UWORD diroff);
COUNT lfn_create_entries(COUNT handle, lfn_inode_ptr lip);
COUNT lfn_remove_entries(COUNT handle);
@ -279,7 +276,7 @@ COUNT DosSetCountry(UWORD cntry);
COUNT DosGetCodepage(UWORD * actCP, UWORD * sysCP);
COUNT DosSetCodepage(UWORD actCP, UWORD sysCP);
VOID FAR *DosGetDBCS(void);
UWORD ASMCFUNC syscall_MUX14(iregs FAR *);
UWORD ASMCFUNC syscall_MUX14(DIRECT_IREGS);
/* prf.c */
#ifdef DEBUG
@ -318,21 +315,21 @@ int /*ASMCFUNC*/ ASMPASCAL fmemcmp(const void FAR *m1, const void FAR *m2, size_
#ifdef __WATCOMC__
/* bx, cx, dx and es not used or clobbered for all asmsupt.asm functions except
(f)memchr/(f)strchr (which clobber dx) */
#pragma aux (__pascal) pascal_ax __modify __exact [__ax]
#pragma aux (pascal) pascal_ax modify exact [ax]
#pragma aux (pascal_ax) fmemcpy
#pragma aux (pascal_ax) memcpy
#pragma aux (pascal_ax) fmemset
#pragma aux (pascal_ax) memset
#pragma aux (pascal_ax) fmemcmp __modify __nomemory
#pragma aux (pascal_ax) memcmp __modify __nomemory
#pragma aux (pascal_ax) fmemcmp modify nomemory
#pragma aux (pascal_ax) memcmp modify nomemory
#pragma aux (pascal_ax) fstrcpy
#pragma aux (pascal_ax) strcpy
#pragma aux (pascal_ax) fstrlen __modify __nomemory
#pragma aux (pascal_ax) strlen __modify __nomemory
#pragma aux (__pascal) memchr __modify __exact [__ax __dx] __nomemory
#pragma aux (__pascal) fmemchr __modify __exact [__ax __dx] __nomemory
#pragma aux (__pascal) strchr __modify __exact [__ax __dx] __nomemory
#pragma aux (__pascal) fstrchr __modify __exact [__ax __dx] __nomemory
#pragma aux (pascal_ax) fstrlen modify nomemory
#pragma aux (pascal_ax) strlen modify nomemory
#pragma aux (pascal) memchr modify exact [ax dx] nomemory
#pragma aux (pascal) fmemchr modify exact [ax dx] nomemory
#pragma aux (pascal) strchr modify exact [ax dx] nomemory
#pragma aux (pascal) fstrchr modify exact [ax dx] nomemory
#endif
/* sysclk.c */
@ -377,7 +374,6 @@ int network_redirector_fp(unsigned cmd, void far *s);
long ASMPASCAL network_redirector_mx(unsigned cmd, void far *s, void *arg);
#define remote_rw(cmd,s,arg) network_redirector_mx(cmd, s, (void *)arg)
#define remote_getfree(s,d) (int)network_redirector_mx(REM_GETSPACE, s, d)
#define remote_getfree_11a3(s,d) (int)network_redirector_mx(REM_GETLARGESPACE, s, d)
#define remote_lseek(s,new_pos) network_redirector_mx(REM_LSEEK, s, &new_pos)
#define remote_setfattr(attr) (int)network_redirector_mx(REM_SETATTR, NULL, (void *)attr)
#define remote_printredir(dx,ax) (int)network_redirector_mx(REM_PRINTREDIR, MK_FP(0,dx),(void *)ax)

View File

@ -43,81 +43,57 @@ CPU XCPU
%define WATCOM
%endif
%ifidn __OUTPUT_FORMAT__, obj
group PGROUP PSP
group LGROUP _IRQTEXT _LOWTEXT _IO_TEXT _IO_FIXED_DATA _TEXT
group DGROUP _FIXED_DATA _BSS _DATA _DATAEND CONST CONST2 DCONST DYN_DATA
%ifdef WATCOM
group TGROUP HMA_TEXT_START HMA_TEXT HMA_TEXT_END INIT_TEXT_START INIT_TEXT INIT_TEXT_END
%define IGROUP TGROUP
group I_GROUP ID_B I_DATA ICONST ICONST2 ID_E IB_B I_BSS IB_E
%else
group TGROUP HMA_TEXT_START HMA_TEXT HMA_TEXT_END
group IGROUP INIT_TEXT_START INIT_TEXT INIT_TEXT_END
group I_GROUP ID_B ID ID_E IC IDATA IB_B IB IB_E
%endif
%define class(x) class=x
%define nobits
%define exec
%define INITSIZE init_end wrt INIT_TEXT
%define INITTEXTSIZE __INIT_DATA_START wrt INIT_TEXT
%else ; using ELF
BITS 16
; groups are defined in the linker script kernel.ld
extern PGROUP
extern DGROUP
extern LGROUP
extern TGROUP
extern IGROUP
extern I_GROUP
%define class(x)
%define stack
extern INITSIZE
%define INITTEXTSIZE __InitTextEnd
%endif
segment PSP class(PSP)
segment _IRQTEXT class(LCODE) exec
segment _LOWTEXT class(LCODE) exec
segment _IO_TEXT class(LCODE) exec
segment _IO_FIXED_DATA class(LCODE) align=2
segment _TEXT class(LCODE) exec
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
segment PSP class=PSP
segment _IRQTEXT class=LCODE
segment _LOWTEXT class=LCODE
segment _IO_TEXT class=LCODE
segment _IO_FIXED_DATA class=LCODE align=2
segment _TEXT class=LCODE
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
segment CONST class(DATA) align=2
segment CONST2 class(DATA) align=2
segment CONST class=DATA align=2
segment CONST2 class=DATA align=2
;for MSC
segment DCONST class(DCONST) align=2
segment DYN_DATA class(DYN_DATA)
segment HMA_TEXT_START class(CODE) align=16
segment HMA_TEXT class(CODE) exec
segment HMA_TEXT_END class(CODE) align=16
segment INIT_TEXT_START class(CODE) align=16
segment INIT_TEXT class(CODE) exec
segment INIT_TEXT_END class(CODE) align=16
segment DCONST class=DCONST align=2
segment DYN_DATA class=DYN_DATA
segment HMA_TEXT_START class=CODE align=16
segment HMA_TEXT class=CODE
segment HMA_TEXT_END class=CODE
segment INIT_TEXT_START class=CODE align=16
segment INIT_TEXT class=CODE
segment INIT_TEXT_END class=CODE
%ifdef WATCOM
segment ID_B class(FAR_DATA) align=16
segment I_DATA class(FAR_DATA) align=2
segment ICONST class(FAR_DATA) align=2
segment ICONST2 class(FAR_DATA) align=2
segment ID_E class(FAR_DATA) align=2
segment IB_B class(FAR_DATA) align=2
segment I_BSS class(FAR_DATA) align=2
segment IB_E class(FAR_DATA) align=2
segment ID_B class=FAR_DATA align=16
segment I_DATA class=FAR_DATA align=2
segment ICONST class=FAR_DATA align=2
segment ICONST2 class=FAR_DATA align=2
segment ID_E class=FAR_DATA align=2
segment IB_B class=FAR_DATA align=2
segment I_BSS class=FAR_DATA align=2
segment IB_E class=FAR_DATA align=2
%else
segment ID_B class(ID) align=16
segment ID class(ID) align=2
segment IDATA class(ID) align=2
segment ID_E class(ID) align=2
segment IC class(IC) align=2
segment IB_B class(IB) align=2 nobits
segment IB class(IB) align=2 nobits
segment IB_E class(IB) align=2 nobits
segment ID_B class=ID align=16
segment ID class=ID align=2
segment IDATA class=ID align=2
segment ID_E class=ID align=2
segment IC class=IC align=2
segment IB_B class=IB align=2
segment IB class=IB align=2
segment IB_E class=IB align=2
%endif

View File

@ -50,7 +50,7 @@ ComTable db 0Ah
segment _IO_TEXT
extern CommonNdRdExit
extern CommonNdRdExit:wrt LGROUP
ComRead:
jcxz ComRd3

View File

@ -27,8 +27,8 @@
/****************************************************************/
#include "portab.h"
#include "dtime.h"
#include "ddate.h"
#include "time.h"
#include "date.h"
#include "globals.h"
#ifdef VERSION_STRINGS

Some files were not shown because too many files have changed in this diff Show More