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 # Object Files
*.OBJ *.OBJ
*.obj
# List Files # List Files
*.LST *.LST
*.lst
# Map files # Map files
*.MAP *.MAP
*.map
*.SYM
*.sym
# Executable files # Executable files
*.EXE *.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 @@
fd kernel fdkernel
========= ========
FreeDOS kernel - current 0xFD version is 2.43 (2043) FreeDOS kernel
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)

View File

@ -1,30 +1,92 @@
@ECHO OFF @ECHO OFF
IF "%1"=="" GOTO USAGE 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 - ECHO tag SVN with release version - svn copy trunk/ tags/ke%1
git tag -a -m "Tag kernel release %1" ke%1 HEAD 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"
ECHO get a clean tree PAUSE
if EXIST ..\SOURCE RMDIR /S /Q ..\SOURCE > NUL ECHO svn export to get clean tree
::git clone -v --local --branch ke%1 . ..\SOURCE\ke%1\ if EXIST SOURCE RMDIR /S /Q SOURCE > NUL
git clone -v --local . ..\SOURCE\ke%1\ 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 SET VERSION=%1
RD /S /Q ..\SOURCE\ke%1\.git > NUL SET LSMRET=SRC
RD /S /Q ..\SOURCE\ke%1\.github > NUL SET LSMFILE=SOURCE\ke%1\docs\fdkernel.lsm
DEL /Q ..\SOURCE\ke%1\.git* > NUL GOTO LSM
DEL /Q ..\SOURCE\ke%1\*.yml > NUL :SRC
DEL /Q ..\SOURCE\ke%1\ci*.sh > NUL ECHO zipping source
DEL /Q ..\SOURCE\ke%1\docs\*.yml > NUL 7z.exe a -tzip -mx9 -mpass15 -r ke%1s.zip SOURCE\*
DEL /Q ..\SOURCE\ke%1\docs\CNAME > NUL ECHO creating APPINFO and expected packaging dir structure
pause ECHO using working configuration file
COPY trunk\CONFIG.BAT SOURCE\ke%1 > NUL
CD SOURCE\ke%1
ECHO %CD% ECHO build and packaging
CALL MAKEPKGS.BAT %1 RELEASE 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 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 :USAGE
ECHO Tag and build release kernels - usage: RELEASE {VERSION} e.g. RELEASE 2039 ECHO Tag and build release kernels - usage: RELEASE {VERSION} e.g. RELEASE 2039
:DONE :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, ; License along with DOS-C; see the file COPYING. If not,
; write to the Free Software Foundation, 675 Mass Ave, ; write to the Free Software Foundation, 675 Mass Ave,
; Cambridge, MA 02139, USA. ; Cambridge, MA 02139, USA.
; Memory layout for the FreeDOS FAT12/FAT16 boot process:
; ;
; ... ;
; |-------| 1FE0h:7E00h = 27C00h (159 KiB) ; +--------+ 1FE0:7E00
; |BOOTSEC| loader relocates itself here first thing, ; |BOOT SEC|
; |RELOC. | before loading root directory/FAT/kernel file ; |RELOCATE|
; |-------| 1FE0h:7C00h = 27A00h (158 KiB) ; |--------| 1FE0:7C00
; | gap | PARAMS live here ; |LBA PKT |
; |LBA PKT| LBA disk packet ; |--------| 1FE0:7BC0
; |-------| 1FE0h:7BC0h = 279C0h (158 KiB) ; |--------| 1FE0:7BA0
; | gap | READADDR_* live here ; |BS STACK|
; |-------| 1FE0h:7BA0h = 279A0h (158 KiB) ; |--------|
; | STACK | below relocated loader, above sector buffer (size 5.9 KiB) ; |4KBRDBUF| used to avoid crossing 64KB DMA boundary
; ... ; |--------| 1FE0:63A0
; |-------| 1FE0h:6400h = 26200h (152 KiB) ; | |
; |SEC.BUF| sector buffer, to avoid crossing 64 KiB DMA boundary (size 8 KiB) ; |--------| 1FE0:3000
; |-------| 1FE0h:4400h = 24200h (144 KiB) ; | CLUSTER|
; ... ; | LIST |
; |-------| 1FE0h:4380h = 24182h (144 KiB) ; |--------| 1FE0:2000
; |CLUSTER| built from FAT, listing every cluster of the kernel file. ; | |
; | LIST | file <= 134 KiB, cluster >= 32 Byte, hence <= 8578 B list. ; |--------| 0000:7E00
; |-------| 1FE0h:2200h = 22000h (136 KiB) ; |BOOT SEC| overwritten by max 128k FAT buffer
; ... ; |ORIGIN | and later by max 134k loaded kernel
; |-------| 0000h:7E00h = 07E00h (31.5 KiB) ; |--------| 0000:7C00
; |BOOTSEC| possibly overwritten by the FAT (<= 128 KiB) and the kernel, ; | |
; |ORIGIN | so the bootsector relocates itself up... ; |--------|
; |-------| 0000h:7C00h = 07C00h (31 KiB) ; |KERNEL | also used as max 128k FAT buffer
; ... ; |LOADED | before kernel loading starts
; |-------| ; |--------| 0060:0000
; |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.
;%define ISFAT12 1 ;%define ISFAT12 1
;%define ISFAT16 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 segment .text
@ -124,8 +91,8 @@ Entry: jmp short real_start
%define LOADSEG 0x0060 %define LOADSEG 0x0060
%define CLUSTLIST 0x2200 ; offset of temporary buffer for FAT %define FATBUF 0x2000 ; offset of temporary buffer for FAT
; chain cluster list ; chain
; Some extra variables ; Some extra variables
@ -133,16 +100,7 @@ Entry: jmp short real_start
;----------------------------------------------------------------------- ;-----------------------------------------------------------------------
times 36h - ($ - $$) db 0 times 0x3E-$+$$ 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
; using bp-Entry+loadseg_xxx generates smaller code than using just ; using bp-Entry+loadseg_xxx generates smaller code than using just
; loadseg_xxx, where bp is initialized to Entry, so bp-Entry equals 0 ; 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_32 word [LBA_PACKET+12]
%define LBA_SECTOR_48 word [LBA_PACKET+14] %define LBA_SECTOR_48 word [LBA_PACKET+14]
%define READBUF 0x4400 ; max 8 KiB buffer %define READBUF 0x63A0 ; max 4KB buffer (min 2KB stack), == stacktop-0x1800
%define READADDR_OFF word BP-0x60 ; pointer within user buffer %define READADDR_OFF BP-0x60-0x1804 ; pointer within user buffer
%define READADDR_SEG word BP-0x60+2 %define READADDR_SEG BP-0x60-0x1802
%define PARAMS LBA_PACKET+0x10 %define PARAMS LBA_PACKET+0x10
;%define RootDirSecs PARAMS+0x0 ; # of sectors root dir uses ;%define RootDirSecs PARAMS+0x0 ; # of sectors root dir uses
@ -203,7 +161,6 @@ real_start:
jmp word 0x1FE0:cont jmp word 0x1FE0:cont
loadseg_off dw 0 loadseg_off dw 0
magicoffset "loadseg", 5Ch, 5Ch
loadseg_seg dw LOADSEG loadseg_seg dw LOADSEG
cont: cont:
@ -216,7 +173,6 @@ cont:
; in DL, however we work around this in SYS.COM by NOP'ing out the use of DL ; 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) ; (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 [drive], dl ; rely on BIOS drive number in DL
mov LBA_SIZE, 10h 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, 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 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: ffDone:
push ax ; store first cluster number push ax ; store first cluster number
@ -321,7 +277,7 @@ ffDone:
push ds push ds
pop es pop es
mov ds, [loadseg_60] mov ds, [loadseg_60]
mov di, CLUSTLIST mov di, FATBUF
next_clust: stosw ; store cluster number next_clust: stosw ; store cluster number
mov si, ax ; SI = 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 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 cluster_next: lodsw ; AX = next cluster to read
or ax, ax ; EOF? or ax, ax ; EOF?
@ -390,9 +346,7 @@ load_next: dec ax ; cluster numbers start with 2
dec ax dec ax
mov di, word [bsSecPerClust] mov di, word [bsSecPerClust]
dec di ; minus one if 256 spc and di, 0xff ; DI = sectors per cluster
and di, 0xff ; DI = sectors per cluster - 1
inc di ; = spc
mul di mul di
add ax, [data_start] add ax, [data_start]
adc dx, [data_start+2] ; DX:AX = first sector to read 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. ; shows text after the call to this function.
show.do_show:
mov ah, 0Eh ; show character
int 10h ; via "TTY" mode
show: pop si show: pop si
lodsb ; get character lodsb ; get character
push si ; stack up potential return address push si ; stack up potential return address
cmp al, 0 ; end of string? mov ah,0x0E ; show character
jne .do_show ; until done int 0x10 ; via "TTY" mode
cmp al,'.' ; end of string?
jne show ; until done
ret ret
boot_error: call show boot_error: call show
; db "Error! Hit a key to reboot.",0 ; db "Error! Hit a key to reboot."
db "Error!",0 db "Error!."
xor ah,ah xor ah,ah
int 0x13 ; reset floppy int 0x13 ; reset floppy
@ -437,12 +390,8 @@ readDisk: push si
mov word [READADDR_SEG], es mov word [READADDR_SEG], es
mov word [READADDR_OFF], bx mov word [READADDR_OFF], bx
%ifndef QUIET
call show call show
db ".",0 db "."
%else ; ensure code after this still at same location
times 5 nop
%endif
read_next: read_next:
;******************** LBA_READ ******************************* ;******************** LBA_READ *******************************
@ -453,7 +402,7 @@ read_next:
mov bx,055aah ; mov bx,055aah ;
mov dl, [drive] 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: test dl,dl ; don't use LBA addressing on A:
jz read_normal_BIOS ; might be a (buggy) jz read_normal_BIOS ; might be a (buggy)
; CDROM-BOOT floppy emulation ; CDROM-BOOT floppy emulation
@ -557,7 +506,6 @@ do_int13_read:
times 0x01f1-$+$$ db 0 times 0x01f1-$+$$ db 0
magicoffset "kernel name", 1F1h, 1F1h
filename db "KERNEL SYS",0,0 filename db "KERNEL SYS",0,0
sign dw 0xAA55 sign dw 0xAA55

View File

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

View File

@ -27,36 +27,27 @@
; Memory layout for the FreeDOS FAT32 single stage boot process: ; Memory layout for the FreeDOS FAT32 single stage boot process:
;
; ... ; ...
; |-------| 1FE0h:7E00h = 27C00h (159 KiB) ; |-------| 1FE0:7E00
; |BOOTSEC| loader relocates itself here first thing, ; |BOOTSEC|
; |RELOC. | before loading root directory/FAT/kernel file ; |RELOC. |
; |-------| 1FE0h:7C00h = 27A00h (158 KiB) ; |-------| 1FE0:7C00
; | STACK | below relocated loader, above FAT sector (size 22 KiB)
; ... ; ...
; |-------| 2200h:2000h = 24000h (144 KiB) ; |-------| 2000:0200
; | FAT | (only 1 sector buffered, maximum sector size 8 KiB) ; | FAT | (only 1 sector buffered)
; |-------| 2200h:0000h = 22000h (136 KiB) ; |-------| 2000:0000
; ... ; ...
; |-------| 0000h:7E00h = 07E00h (31.5 KiB) ; |-------| 0000:7E00
; |BOOTSEC| overwritten by the kernel, so the ; |BOOTSEC| overwritten by the kernel, so the
; |ORIGIN | bootsector relocates itself up... ; |ORIGIN | bootsector relocates itself up...
; |-------| 0000h:7C00h = 07C00h (31 KiB) ; |-------| 0000:7C00
; ... ; ...
; |-------| ; |-------|
; |KERNEL | maximum size 128 KiB (overwrites bootsec origin) ; |KERNEL | maximum size 134k (overwrites bootsec origin)
; |LOADED | (holds 1 sector directory buffer before kernel file load) ; |LOADED | (holds 1 sector directory buffer before kernel load)
; |-------| 0060h:0000h = 00600h (1.5 KiB) ; |-------| 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 segment .text
@ -94,7 +85,7 @@ Entry: jmp short real_start
%define LOADSEG 0x0060 %define LOADSEG 0x0060
%define FATSEG 0x2200 %define FATSEG 0x2000
%define fat_secshift fat_afterss-1 ; each fat sector describes 2^?? %define fat_secshift fat_afterss-1 ; each fat sector describes 2^??
; clusters (db) (selfmodifying) ; clusters (db) (selfmodifying)
@ -105,11 +96,7 @@ Entry: jmp short real_start
%define data_start bp+0x4c ; first data sector (dd) %define data_start bp+0x4c ; first data sector (dd)
; (overwriting unused bytes) ; (overwriting unused bytes)
times 52h - ($ - $$) db 0 times 0x5a-$+$$ 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
; not used: [0x42] = byte 0x29 (ext boot param flag) ; not used: [0x42] = byte 0x29 (ext boot param flag)
; [0x43] = dword serial ; [0x43] = dword serial
; [0x47] = label (padded with 00, 11 bytes) ; [0x47] = label (padded with 00, 11 bytes)
@ -134,9 +121,7 @@ real_start: cld
rep movsw ; move boot code to the 0x1FE0:0x0000 rep movsw ; move boot code to the 0x1FE0:0x0000
jmp word 0x1FE0:cont jmp word 0x1FE0:cont
loadseg_off dw 0 loadseg_off dw 0, LOADSEG
magicoffset "loadseg", 78h
dw LOADSEG
; ------------- ; -------------
@ -144,15 +129,10 @@ cont: mov ds, ax
mov ss, ax ; stack and BP-relative moves up, too mov ss, ax ; stack and BP-relative moves up, too
lea sp, [bp-0x20] lea sp, [bp-0x20]
sti sti
magicoffset "set unit", 82h
mov [drive], dl ; BIOS passes drive number in DL mov [drive], dl ; BIOS passes drive number in DL
%ifndef QUIET
mov si, msg_LoadFreeDOS mov si, msg_LoadFreeDOS
call print ; modifies AX BX SI 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: boot_success: mov bl, [drive]
mov dl, [drive] ; for Enhanced DR-DOS load
mov bl, dl ; for FreeDOS load
jmp far [loadsegoff_60] jmp far [loadsegoff_60]
;----------------------------------------------------------------------- ;-----------------------------------------------------------------------
@ -331,8 +309,6 @@ convert_cluster:
dec eax dec eax
movzx edx, byte [bsSecPerClust] movzx edx, byte [bsSecPerClust]
dec dl ; spc - 1
inc dx ; spc
push edx push edx
mul edx mul edx
pop edx pop edx
@ -421,7 +397,6 @@ msg_BootError db "No "
; currently, only "kernel.sys not found" gives a message, ; currently, only "kernel.sys not found" gives a message,
; but read errors in data or root or fat sectors do not. ; but read errors in data or root or fat sectors do not.
magicoffset "kernel name", 1F1h
filename db "KERNEL SYS" filename db "KERNEL SYS"
sign dw 0, 0xAA55 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 production: fat12com.bin fat16com.bin fat32chs.bin fat32lba.bin oemfat12.bin oemfat16.bin
fat12com.bin: boot.asm magic.mac fat12com.bin: boot.asm
$(NASM) -dISFAT12 $(NASMBOOTFLAGS) boot.asm -lfat12com.lst -ofat12com.bin $(NASM) -dISFAT12 boot.asm -l$*.lst -ofat12com.bin
fat16com.bin: boot.asm magic.mac fat16com.bin: boot.asm
$(NASM) -dISFAT16 $(NASMBOOTFLAGS) boot.asm -lfat16com.lst -ofat16com.bin $(NASM) -dISFAT16 boot.asm -l$*.lst -ofat16com.bin
fat32chs.bin: boot32.asm magic.mac fat32chs.bin: boot32.asm
$(NASM) $(NASMBOOTFLAGS) boot32.asm -lfat32chs.lst -ofat32chs.bin $(NASM) boot32.asm -l$*.lst -ofat32chs.bin
fat32lba.bin: boot32lb.asm magic.mac fat32lba.bin: boot32lb.asm
$(NASM) $(NASMBOOTFLAGS) boot32lb.asm -lfat32lba.lst -ofat32lba.bin $(NASM) boot32lb.asm -l$*.lst -ofat32lba.bin
oemfat12.bin: oemboot.asm magic.mac oemfat12.bin: oemboot.asm
$(NASM) -dISFAT12 $(NASMBOOTFLAGS) oemboot.asm -loemfat12.lst -ooemfat12.bin $(NASM) -dISFAT12 oemboot.asm -l$*.lst -ooemfat12.bin
oemfat16.bin: oemboot.asm magic.mac oemfat16.bin: oemboot.asm
$(NASM) -dISFAT16 $(NASMBOOTFLAGS) oemboot.asm -loemfat16.lst -ooemfat16.bin $(NASM) -dISFAT16 oemboot.asm -l$*.lst -ooemfat16.bin
clobber: clean clobber: clean
-$(RM) *.bin status.me -$(RM) *.bin status.me

View File

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

View File

@ -25,6 +25,7 @@ if not exist config.bat goto abort
call config.bat call config.bat
:-if "%LAST%" == "" goto noenv :-if "%LAST%" == "" goto noenv
set dos4g=quiet
:----------------------------------------------------------------------- :-----------------------------------------------------------------------
:- following is command line handling :- following is command line handling
@ -50,7 +51,6 @@ if "%1" == "x86" goto setCPU
if "%1" == "upx" set XUPX=upx --8086 --best if "%1" == "upx" set XUPX=upx --8086 --best
if "%1" == "debug" set ALLCFLAGS=%ALLCFLAGS% -DDEBUG if "%1" == "debug" set ALLCFLAGS=%ALLCFLAGS% -DDEBUG
if "%1" == "lfn" set ALLCFLAGS=%ALLCFLAGS% -DWITHLFNAPI
if "%1" == "lfnapi" set ALLCFLAGS=%ALLCFLAGS% -DWITHLFNAPI if "%1" == "lfnapi" set ALLCFLAGS=%ALLCFLAGS% -DWITHLFNAPI
if "%1" == "win" set ALLCFLAGS=%ALLCFLAGS% -DWIN31SUPPORT if "%1" == "win" set ALLCFLAGS=%ALLCFLAGS% -DWIN31SUPPORT
@ -117,20 +117,6 @@ cd ..\kernel
%MAKE% production %MAKE% production
if errorlevel 1 goto abort-cd 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 .. cd ..
set XERROR= set XERROR=
@ -169,8 +155,6 @@ if "%1" == "" goto abort
if "%2" == "/V" goto :setDefineWithValue if "%2" == "/V" goto :setDefineWithValue
set ALLCFLAGS=%ALLCFLAGS% -D%1 set ALLCFLAGS=%ALLCFLAGS% -D%1
set NASMFLAGS=%NASMFLAGS% -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 goto nextOption
:setDefineWithValue :setDefineWithValue

View File

@ -15,6 +15,7 @@ set onerror=if not "%XERROR%" == "" goto daswarwohlnix
:***** MSCL kernels :***** MSCL kernels
call config.bat call config.bat
set dos4g=quiet
if "%MS_BASE%" == "" goto no_ms if "%MS_BASE%" == "" goto no_ms
call build -r msc 386 fat16 call build -r msc 386 fat16
@ -46,7 +47,7 @@ call build -r tc 86 fat32
:***** (Open) Watcom kernels :***** (Open) Watcom kernels
if not "%COMPILER%" == "WATCOM" goto no_wc if "%WATCOM%" == "" goto no_wc
call build -r wc 386 fat32 call build -r wc 386 fat32
%ONERROR% %ONERROR%
call build -r wc 386 fat16 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 cd ..\kernel
%MAKE% clean %MAKE% clean
cd ..\setver
%MAKE% clean
cd ..\hdr cd ..\hdr
if exist *.bak del *.bak if exist *.bak del *.bak

View File

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

View File

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

View File

@ -15,8 +15,8 @@ XNASM=nasm
#********************************************************************** #**********************************************************************
#- where is the BASE dir of your compiler(s) ?? #- where is the BASE dir of your compiler(s) ??
#********************************************************************** #**********************************************************************
# if WATCOM maybe you need to set your WATCOM environment variables # if WATCOM maybe you need to set your WATCOM environment variables
# and path # and path
ifndef WATCOM ifndef WATCOM
WATCOM=$(HOME)/watcom WATCOM=$(HOME)/watcom
@ -28,7 +28,7 @@ endif
#********************************************************************** #**********************************************************************
XUPX=upx --8086 --best XUPX=upx --8086 --best
# or use # or use
#unexport XUPX #unexport XUPX
# without the # if you don't want to use it # without the # if you don't want to use it
@ -52,12 +52,12 @@ XUPX=upx --8086 --best
# select your default target: required CPU and what FAT system to support # select your default target: required CPU and what FAT system to support
#********************************************************************* #*********************************************************************
# XCPU=86 XCPU=86
# XCPU=186 # XCPU=186
XCPU=386 # XCPU=386
# XFAT=16 XFAT=16
XFAT=32 # XFAT=32
# Give extra compiler DEFINE flags here # Give extra compiler DEFINE flags here
# such as -DDEBUG : extra DEBUG output # 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%" == "TC2" set MAKE=%TC2_BASE%\make
if "%COMPILER%" == "TURBOCPP" set MAKE=%TP1_BASE%\bin\make if "%COMPILER%" == "TURBOCPP" set MAKE=%TP1_BASE%\bin\make
if "%COMPILER%" == "TC3" set MAKE=%TC3_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%" == "BC5" set MAKE=%BC5_BASE%\bin\make
if "%COMPILER%" == "WATCOM" set MAKE=wmake /ms /h 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 if "%COMPILER%" == "MSCL8" set MAKE=%MS_BASE%\bin\nmake /nologo
echo Make is %MAKE%. 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%" == "TC2" set XLINK=%TC2_BASE%\tlink /m/c
if "%COMPILER%" == "TURBOCPP" set XLINK=%TP1_BASE%\bin\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%" == "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%" == "BC5" set XLINK=%BC5_BASE%\bin\tlink /m/c
if "%COMPILER%" == "WATCOM" set XLINK=..\utils\wlinker /ma/nologo 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 if "%COMPILER%" == "MSCL8" set XLINK=%MS_BASE%\bin\link /ONERROR:NOEXE /ma /nologo
echo Linker is %XLINK%. echo Linker is %XLINK%.
@ -75,12 +71,10 @@ set XLINK=
set TC2_BASE= set TC2_BASE=
set TP1_BASE= set TP1_BASE=
set TC3_BASE= set TC3_BASE=
set BC3_BASE=
set BC5_BASE= set BC5_BASE=
set MS_BASE= set MS_BASE=
set XNASM= set XNASM=
set NASMFLAGS= set NASMFLAGS=
set NASMBOOTFLAGS=
set XUPX= set XUPX=
set UPXOPT= set UPXOPT=
set LOADSEG= 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 not have to worry about resetting up your configuration because your
CONFIG.BAT file will not get replaced! 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: Building on Linux:
================== ==================
@ -38,16 +33,6 @@ make clean
- to clobber (delete everything that was generated): - to clobber (delete everything that was generated):
make clobber 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: Notes:
====== ======
The recommended compiler and assembler at the time of writing (2009/05/19) The recommended compiler and assembler at the time of writing (2009/05/19)

View File

@ -305,12 +305,8 @@ Example: switchar=-
SWITCHES SWITCHES
Usage: switches=/E[:xxx] /F /K /N /W Usage: switches=/E[:xxx] /F /K /N /W
Adjusts boot time processing behaviour. Adjusts boot time processing behaviour.
/E specifies how to handle moving of EBDA (Extended BIOS Data Area), /E enables moving of EBDA (Extended BIOS Data Area), optionally a
if a size in bytes is specified [xxx, in range of 48-1024] size in kilobytes may be 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
/F skips the delay checking for F5/F8 keystroke before processing /F skips the delay checking for F5/F8 keystroke before processing
config.sys [equivalent to SYS CONFIG skipconfigseconds=0] config.sys [equivalent to SYS CONFIG skipconfigseconds=0]
F5 and F8 are only processed if pressed before DOS boots but 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. handling for 102/105 key keyboards.
/N disables F5/F8 support [equivalent to kernel config (SYS CONFIG, /N disables F5/F8 support [equivalent to kernel config (SYS CONFIG,
run SYS CONFIG /? for explanations) skipconfigseconds=-1] run SYS CONFIG /? for explanations) skipconfigseconds=-1]
F5 (skip config) and F8 (single step config.sys) key presses F5 (skip config) and F8 (single step config.sys) are ignored.
are ignored (note: with /F a well timed F5/F8 still works, whereas
/N completely disables).
/W is NOT supported in FreeDOS. This option in MS DOS would set a flag /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, 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
VERSION VERSION
Usage: version=x.y Usage: version=x.y

View File

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

View File

@ -1,15 +1,13 @@
Begin3 Begin3
Title: The FreeDOS Kernel Title: The FreeDOS Kernel
Version: git Version: SVN
Entered-date: N/A Entered-date: N/A
Description: The FreeDOS Kernel Description: The FreeDOS Kernel
Keywords: kernel, FreeDOS, DOS, MSDOS Keywords: kernel, FreeDOS, DOS, MSDOS
Author: (developers: can be reached on the freedos-kernel mailing list) Author: (developers: can be reached on the freedos-kernel mailing list)
Maintained-by: freedos-kernel@lists.sourceforge.net Maintained-by: freedos-kernel@lists.sourceforge.net
Primary-site: http://github.com/fdos/kernel Primary-site: http://freedos.sourceforge.net/kernel/
Alternate-site: http://www.fdos.org/kernel/
Alternate-site: http://freedos.sourceforge.net/kernel/
Original-site: http://www.gcfl.net/pub/FreeDOS/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 Copying-policy: GPL2
End 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. 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 2012 Feb 07 - Build 2041
-------- Jeremy Davis -------- 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 See the DOCS directory for more documentation and information about
the FreeDOS Kernel. the FreeDOS Kernel.
Contents of release zip files: Contents of zip files:
ke20xx_16.zip : binaries for 8086, FAT16 ke20xx_16.zip : binaries for 8086, FAT16
ke20xx_32.zip : binaries for 8086, FAT16, FAT32 ke20xx_32.zip : binaries for 8086, FAT16, FAT32
ke20xxsrc.zip : sources for the kernel 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 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 like to make a suggestion, go to the bug tracking web page at
the kernel's GitHub site: http://sourceforge.net/tracker/?group_id=5109&atid=105109
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.
An archive of old (Bugzilla) items is at www.freedos.org/bugzilla/ 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 Copyright
--------- ---------
DOS-C is (c) Copyright 1995, 1996 by Pasquale J. Villani DOS-C is (c) Copyright 1995, 1996 by Pasquale J. Villani
All Rights Reserved. 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: documentation by:
Jeremy Davis Jeremy Davis
Bart Oldeman Bart Oldeman
@ -23,18 +23,12 @@ Usage: SYS [source] drive: [bootsect] [{option}]
/BOOTONLY: do *not* copy kernel / shell, only update boot sector or image /BOOTONLY: do *not* copy kernel / shell, only update boot sector or image
/UPDATE : copy kernel and update boot sector (do *not* copy shell) /UPDATE : copy kernel and update boot sector (do *not* copy shell)
/OEM : indicates boot sector, filenames, and load segment to use /OEM : indicates boot sector, filenames, and load segment to use
/OEM:FD FreeDOS settings /OEM:FD use FreeDOS compatible settings
/OEM:EDR Enhanced DR-DOS (DRBIO.SYS and DRDOS.SYS) /OEM:DR use DR DOS 7+ compatible settings (same as /OEM)
/OEM:LEDRPACK Enhanced DR-DOS (EDRPACK.SYS, lDOS drload) /OEM:PC use PC-DOS compatible settings
/OEM:LEDR Enhanced DR-DOS (EDRDOS.COM, lDOS iniload) /OEM:MS use MS-DOS compatible settings
/OEM:LMSPACK OSS MS-DOS (LMSPACK.SYS, lDOS drload) /OEM:W9x use MS Win9x DOS compatible settings
/OEM:LMS OSS MS-DOS (LMSDOS.COM, lDOS iniload) default is /OEM:AUTO, select DOS based on existing files
/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
/K name : name of kernel to use in boot sector instead of KERNEL.SYS /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 /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,... /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) (note that CHS may still be used if LBA check fails)
and /FORCE:CHS will always bypass use of LBA extensions. 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: Kernel Configuration Options:

View File

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

View File

@ -24,7 +24,7 @@
OBJS = floppy.obj rdpcclk.obj wrpcclk.obj wratclk.obj 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) device.lib : $(OBJS)
-$(RM) device.lib -$(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 "../kernel/segs.inc"
%include "../hdr/stacks.inc"
segment HMA_TEXT segment HMA_TEXT
@ -48,14 +47,13 @@ WRITEATCLOCK:
; bcdMinutes = 6 ; bcdMinutes = 6
; bcdHours = 8 ; bcdHours = 8
; bcdDays = 10 ; bcdDays = 10
arg bcdDays, bcdHours, bcdMinutes, bcdSeconds mov ch,byte [bp+8] ;bcdHours
mov ch,byte [.bcdHours] mov cl,byte [bp+6] ;bcdMinutes
mov cl,byte [.bcdMinutes] mov dh,byte [bp+4] ;bcdSeconds
mov dh,byte [.bcdSeconds]
mov dl,0 mov dl,0
mov ah,3 mov ah,3
int 1ah int 1ah
mov bx,word [.bcdDays] mov bx,word [bp+10] ;bcdDays
mov dx,word [bx] mov dx,word [bx]
mov cx,word [bx+2] mov cx,word [bx+2]
mov ah,5 mov ah,5

View File

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

View File

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

View File

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

View File

@ -152,13 +152,13 @@ typedef struct {
UWORD bpb_nreserved; /* # Reserved Sectors */ UWORD bpb_nreserved; /* # Reserved Sectors */
UBYTE bpb_nfat; /* # FATs */ UBYTE bpb_nfat; /* # FATs */
UWORD bpb_ndirent; /* # Root Directory entries */ 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 */ UBYTE bpb_mdesc; /* MEDIA Descriptor Byte */
UWORD bpb_nfsect; /* FAT size in sectors */ UWORD bpb_nfsect; /* FAT size in sectors */
UWORD bpb_nsecs; /* Sectors per track */ UWORD bpb_nsecs; /* Sectors per track */
UWORD bpb_nheads; /* Number of heads */ UWORD bpb_nheads; /* Number of heads */
ULONG bpb_hidden; /* Hidden sectors */ ULONG bpb_hidden; /* Hidden sectors */
ULONG bpb_huge; /* Total volume Size in sectors if*/ ULONG bpb_huge; /* Size in sectors if */
/* bpb_nsize == 0 */ /* bpb_nsize == 0 */
#ifdef WITHFAT32 #ifdef WITHFAT32
ULONG bpb_xnfsect; /* FAT size in sectors if */ ULONG bpb_xnfsect; /* FAT size in sectors if */
@ -253,7 +253,6 @@ typedef struct ddtstruct {
/* freedos specific flag bits */ /* freedos specific flag bits */
#define DF_LBA 0x400 #define DF_LBA 0x400
#define DF_WRTVERIFY 0x800 #define DF_WRTVERIFY 0x800
#define DF_DMA_TRANSPARENT 0x1000 /* DMA boundary errors are handled transparently */
/* typedef struct ddtstruct ddt;*/ /* typedef struct ddtstruct ddt;*/
@ -496,7 +495,7 @@ WORD ASMCFUNC FAR clk_driver(rqptr rp);
/* execrh.asm */ /* execrh.asm */
#if defined(__WATCOMC__) && _M_IX86 >= 300 #if defined(__WATCOMC__) && _M_IX86 >= 300
WORD execrh(request FAR *, struct dhdr FAR *); 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 #else
WORD ASMPASCAL execrh(request FAR *, struct dhdr FAR *); WORD ASMPASCAL execrh(request FAR *, struct dhdr FAR *);
#endif #endif

View File

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

View File

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

View File

@ -86,8 +86,8 @@ typedef struct {
UWORD fcb_recsiz; /* Logical record size in bytes, */ UWORD fcb_recsiz; /* Logical record size in bytes, */
/* default = 128 */ /* default = 128 */
ULONG fcb_fsize; /* File size in bytes */ ULONG fcb_fsize; /* File size in bytes */
ddate fcb_date; /* Date file created */ date fcb_date; /* Date file created */
dtime fcb_time; /* Time of last write */ time fcb_time; /* Time of last write */
/* the following are reserved by system */ /* the following are reserved by system */
BYTE fcb_sftno; /* Device ID */ BYTE fcb_sftno; /* Device ID */
BYTE fcb_attrib_hi; /* share info, dev attrib word hi */ 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 2, 3 reserved */
/* bits 4, 5, 6 sharing modes */ /* 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_SHAREMASK 0x0070 /* mask to isolate shared bits */
#define O_COMPAT 0x0000 /* default, compatibility mode */
#define O_DENYALL 0x0010 /* sharing bits */ #define O_DENYALL 0x0010 /* sharing bits */
#define O_DENYWRITE 0x0020 /* " " */ #define O_DENYWRITE 0x0020 /* " " */
#define O_DENYREAD 0x0030 /* " " */ #define O_DENYREAD 0x0030 /* " " */

View File

@ -21,29 +21,7 @@
' hit any key to continue to boot from 'diskette or CD' ' hit any key to continue to boot from 'diskette or CD'
wait ## seconds wait ## seconds
if no key hit, boot from HD 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 { typedef struct _KernelConfig {
char CONFIG[6]; /* "CONFIG" */ char CONFIG[6]; /* "CONFIG" */
@ -55,15 +33,4 @@ typedef struct _KernelConfig {
unsigned char ForceLBA; unsigned char ForceLBA;
unsigned char GlobalEnableLBAsupport; /* = 0 --> disable LBA support */ unsigned char GlobalEnableLBAsupport; /* = 0 --> disable LBA support */
signed char BootHarddiskSeconds; 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; } KernelConfig;

View File

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

View File

@ -28,7 +28,7 @@
/****************************************************************/ /****************************************************************/
/* one byte alignment */ /* one byte alignment */
#include "algnbyte.h" #include <algnbyte.h>
/* /*
* Description of the organization of NLS information -- 2000/02/13 ska * Description of the organization of NLS information -- 2000/02/13 ska
@ -175,7 +175,7 @@
* *
* Performance tweaks: * Performance tweaks:
* When the system -- This word applies to the combination of kernel and * 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 * _filenames_, it must perform a DOS-65-A2 internally. In the basic
* implementation this request would be channeled through MUX-14, even * implementation this request would be channeled through MUX-14, even
* if there is no external NLSFUNC at all. Also, when a NLS pkg had * 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) 0: 12 hours (append AM/PM)
1: 24 houres 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 */ character in register AL */
char dataSep[2]; /* ASCIZ of separator in data records */ 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 yeschar; /* yes / no character DOS-65-23 */
UWORD nochar; UWORD nochar;
unsigned numSubfct; /* number of supported sub-functions */ unsigned numSubfct; /* number of supported sub-functions */
struct nlsPointer nlsPointers[5]; /* may grow dynamically */ struct nlsPointer nlsPointers[1]; /* grows dynamically */
struct nlsExtCntryInfo nlsExt;
}; };
struct nlsDBCS { /* The internal structure is unknown to me */ struct nlsDBCS { /* The internal structure is unknown to me */
UWORD numEntries; UWORD numEntries;
UWORD dbcsTbl[4]; /* I don't know max size but it should need UWORD dbcsTbl[1];
at least 3 words (6 bytes)
({0x81,0x9f,0xe0,0xfc,0,0} for CP932-Japan)
-- lpproj 2014/10/27 */
}; };
struct nlsCharTbl { struct nlsCharTbl {
@ -474,23 +470,20 @@ struct nlsInfoBlock { /* This block contains all information
maybe tweaked by NLSFUNC */ maybe tweaked by NLSFUNC */
UWORD sysCodePage; /* system code page */ UWORD sysCodePage; /* system code page */
unsigned flags; /* implementation flags */ 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 *actPkg; /* current NLS package */
struct nlsPackage FAR *chain; /* first item of info chain -- struct nlsPackage FAR *chain; /* first item of info chain --
hardcoded U.S.A./CP437 */ hardcoded U.S.A./CP437 */
#endif
}; };
extern struct nlsInfoBlock ASM nlsInfo; 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[]; extern BYTE FAR hcTablesStart[], hcTablesEnd[];
/*********************************************************************** /***********************************************************************
@ -623,7 +616,7 @@ struct nlsCSys_loadPackage {
}; };
/* standard alignment */ /* standard alignment */
#include "algndflt.h" #include <algndflt.h>
#ifdef DEBUG #ifdef DEBUG
/* Enable debugging of NLS part */ /* Enable debugging of NLS part */

View File

@ -57,7 +57,7 @@ static BYTE *pcb_hRcsId =
#endif #endif
/* Force one-byte alignment for all the internal structures, see above */ /* Force one-byte alignment for all the internal structures, see above */
#include "algnbyte.h" #include <algnbyte.h>
/* */ /* */
/* interrupt handler structure definition */ /* interrupt handler structure definition */
/* */ /* */
@ -87,6 +87,14 @@ typedef struct {
UWORD si, di, ds, es; UWORD si, di, ds, es;
} lregs; } 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 */ /* Process control block for task switching */
typedef struct { typedef struct {
UWORD pc_ss; UWORD pc_ss;
@ -158,7 +166,7 @@ typedef struct {
#define FLG_CARRY 0x0001 #define FLG_CARRY 0x0001
/* Allow default alignment from now on */ /* Allow default alignment from now on */
#include "algndflt.h" #include <algndflt.h>
#endif #endif

View File

@ -77,7 +77,7 @@ void __emit__(char, ...);
#define enable() __emit__(0xfb) #define enable() __emit__(0xfb)
#endif #endif
#elif defined(_MSC_VER) #elif defined (_MSC_VER)
#define I86 #define I86
#define asm __asm #define asm __asm
@ -102,14 +102,12 @@ static unsigned short __inline getSS(void)
#elif defined(__WATCOMC__) /* don't know a better way */ #elif defined(__WATCOMC__) /* don't know a better way */
#if defined(_M_I86)
#define I86 #define I86
#define __int__(intno) asm int intno; #define __int__(intno) asm int intno;
void disable(void); void disable(void);
#pragma aux disable = "cli" __modify __exact []; #pragma aux disable = "cli" modify exact [];
void enable(void); void enable(void);
#pragma aux enable = "sti" __modify __exact []; #pragma aux enable = "sti" modify exact [];
#define asm __asm #define asm __asm
#define far __far #define far __far
#define CDECL __cdecl #define CDECL __cdecl
@ -117,22 +115,19 @@ void enable(void);
#define PASCAL pascal #define PASCAL pascal
#define _CS getCS() #define _CS getCS()
unsigned short getCS(void); 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() #define _SS getSS()
unsigned short getSS(void); 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 #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 #endif
/* enable Possible loss of precision warning for compatibility with Borland */ /* enable Possible loss of precision warning for compatibility with Borland */
#pragma enable_message(130) #pragma enable_message(130)
#else #if _M_IX86 >= 300 || defined(M_I386)
#define I386
/* workaround for building some utils with OpenWatcom (flat model) */
#define MC68K
#endif #endif
#elif defined (_MYMC68K_COMILER_) #elif defined (_MYMC68K_COMILER_)
@ -140,44 +135,8 @@ unsigned short getSS(void);
#define MC68K #define MC68K
#elif defined(__GNUC__) #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 ! */ /* for warnings only ! */
#define MC68K #define MC68K
#endif
#else #else
#error Unknown compiler #error Unknown compiler
@ -186,15 +145,11 @@ We might even deal with a pre-ANSI compiler. This will certainly not compile.
#ifdef I86 #ifdef I86
#if _M_IX86 >= 300 || defined(M_I386) #if _M_IX86 >= 300 || defined(M_I386)
#ifndef I386
#define I386 #define I386
#endif
#elif _M_IX86 >= 100 || defined(M_I286) #elif _M_IX86 >= 100 || defined(M_I286)
#ifndef I186
#define I186 #define I186
#endif #endif
#endif #endif
#endif
#ifdef MC68K #ifdef MC68K
#define far /* No far type */ #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; typedef __SIZE_TYPE__ size_t;
#else #else
#define CONST #define CONST
#if !(defined(_SIZE_T) || defined(_SIZE_T_DEFINED) || defined(__SIZE_T_DEFINED))
typedef unsigned size_t; typedef unsigned size_t;
#endif #endif
#endif #endif
#endif #ifdef I86
#if defined(I86) && !defined(MC68K)
#define VOID void #define VOID void
#define FAR far /* segment architecture */ #define FAR far /* segment architecture */
#define NEAR near /* " " */ #define NEAR near /* " " */
@ -237,16 +190,7 @@ typedef unsigned size_t;
as 'ASMCFUNC', and is (and will be ?-) cdecl */ as 'ASMCFUNC', and is (and will be ?-) cdecl */
#define ASMCFUNC CDECL #define ASMCFUNC CDECL
#define ASMPASCAL PASCAL #define ASMPASCAL PASCAL
#if defined(__GNUC__)
#define ASM
#else
#define ASM ASMCFUNC #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 */ /* Boolean type & definitions of TRUE and FALSE boolean values */
/* */ /* */
@ -298,7 +242,7 @@ typedef unsigned short CLUSTER;
#endif #endif
typedef unsigned short UNICODE; typedef unsigned short UNICODE;
#if defined(STATICS) || defined(__WATCOMC__) || defined(__GNUC__) #if defined(STATICS) || defined(__WATCOMC__)
#define STATIC static /* local calls inside module */ #define STATIC static /* local calls inside module */
#else #else
#define STATIC #define STATIC
@ -316,13 +260,6 @@ typedef signed long LONG;
#define LONG long #define LONG long
#endif #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_UWORD(hib,lob) (((UWORD)(hib) << 8u) | (UBYTE)(lob))
#define MK_ULONG(hiw,low) (((ULONG)(hiw) << 16u) | (UWORD)(low)) #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)) #define FP_SEG(fp) ((unsigned)((ULONG)(VOID FAR *)(fp)>>16))
#endif #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)) #define FP_OFF(fp) ((unsigned)(fp))
#endif
#endif #endif
#endif #endif
@ -368,11 +301,7 @@ typedef signed long LONG;
#define FP_OFF(fp) ((size_t)(fp)) #define FP_OFF(fp) ((size_t)(fp))
#endif #endif
#if defined(__GNUC__) && defined(__FAR)
typedef VOID FAR *intvec;
#else
typedef VOID (FAR ASMCFUNC * intvec) (void); typedef VOID (FAR ASMCFUNC * intvec) (void);
#endif
#define MK_PTR(type,seg,ofs) ((type FAR*) MK_FP (seg, ofs)) #define MK_PTR(type,seg,ofs) ((type FAR*) MK_FP (seg, ofs))
#if __TURBOC__ > 0x202 #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 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 */ and expect size (KB) of allocated segment in word at offset 6 */
UBYTE ps_farcall; /* 05 far call opcode */ 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 */ intvec ps_isv22, /* 0a terminate address */
ps_isv23, /* 0e ctrl-break address */ ps_isv23, /* 0e ctrl-break address */
@ -79,10 +79,10 @@ typedef struct {
UWORD ps_maxfiles; /* 32 maximum open files */ UWORD ps_maxfiles; /* 32 maximum open files */
UBYTE FAR *ps_filetab; /* 34 open file table pointer */ UBYTE FAR *ps_filetab; /* 34 open file table pointer */
VOID FAR *ps_prevpsp; /* 38 previous psp pointer */ VOID FAR *ps_prevpsp; /* 38 previous psp pointer */
UBYTE ps_dbcs_inputmode; /* 3c unused,see int21/6301h/6302h */ UBYTE ps_fill2; /* 3c unused */
UBYTE ps_truename; /* 3d unused,append truename flag int2f/B711h */ UBYTE ps_truename; /* 3d [unused] append truename flag int2f/B711h */
UBYTE ps_netx_taskid[2]; /* 3e [Novell only field] task id */ 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 */ UWORD pdb_next; /* 42 [Win only field] PSP chain */
UBYTE ps_fill2b[4]; /* 44 unused, 4 bytes */ UBYTE ps_fill2b[4]; /* 44 unused, 4 bytes */
UBYTE ps_olddos; /* 48 [Win only field] DOS/Win program */ UBYTE ps_olddos; /* 48 [Win only field] DOS/Win program */

View File

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

View File

@ -196,57 +196,3 @@ irp_hi equ 26
%endif %endif
%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 */ /* DOS General Time Structure */
/* */ /* */
@ -39,7 +39,7 @@ static BYTE *time_hRcsId =
#endif #endif
#endif #endif
typedef UWORD dtime; typedef UWORD time;
struct dostime struct dostime
{ {

View File

@ -36,12 +36,12 @@
#endif #endif
/* The actual kernel revision, 2000+REVISION_SEQ = 2.REVISION_SEQ */ /* 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 */ #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) */ /* Used for version information displayed to user at boot (& stored in os_release string) */
#ifndef KERNEL_VERSION #ifndef KERNEL_VERSION
#define KERNEL_VERSION "- GIT " #define KERNEL_VERSION "- SVN "
#endif #endif
/* actual version string */ /* actual version string */

View File

@ -18,12 +18,6 @@ struct WinStartupInfo
ULONG optInstanceTable; /* used only if winver set to 0x400 (w95)*/ ULONG optInstanceTable; /* used only if winver set to 0x400 (w95)*/
}; };
extern struct WinStartupInfo winStartupInfo; 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 /* contains a list of offsets relative to DOS data segment of
various internal variables. various internal variables.

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -57,11 +57,6 @@ uScanCode db 0 ; Scan code for con: device
global _kbdType global _kbdType
_kbdType db 0 ; 00 for 84key, 10h for 102key _kbdType db 0 ; 00 for 84key, 10h for 102key
%IFDEF DEBUG_PRINT_COMPORT
ASYNC_NEED_INIT db 1
%ENDIF
global ConInit global ConInit
ConInit: ConInit:
xor ax,ax xor ax,ax
@ -161,8 +156,6 @@ CommonNdRdExit: ; *** tell if key waiting and return its ASCII if yes
add ah,[cs:_kbdType] add ah,[cs:_kbdType]
int 16h ; Get status, if zf=0 al=char int 16h ; Get status, if zf=0 al=char
jz ConNdRd4 ; Jump if no char available 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 call checke0 ; check for e0 scancode
or ax,ax ; Zero ? or ax,ax ; Zero ?
jnz ConNdRd1 ; Jump if not zero jnz ConNdRd1 ; Jump if not zero
@ -250,63 +243,12 @@ _int29_handler:
push di push di
push bp push bp
push bx push bx
%IFDEF DEBUG_PRINT_COMPORT
cmp bx, 0xFD05 ; magic value for COM print routine
je .comprint
%ENDIF
mov ah,0Eh mov ah,0Eh
mov bx,7 mov bx,7
int 10h ; write char al, teletype mode int 10h ; write char al, teletype mode
.int29hndlr_ret:
pop bx pop bx
pop bp pop bp
pop di pop di
pop si pop si
pop ax pop ax
iret 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 and ax, 0f000h
cmp ax, 0f000h cmp ax, 0f000h
jnz is286 ; no the 4 msb stuck set to 1, so is a 808x or 8018x 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 ax,1 ; determine if 8086 or 186
mov cl,64 ; try to shift further than size of ax mov cl,64 ; try to shift further than size of ax
shr ax,cl shr ax,cl

View File

@ -46,7 +46,7 @@ BYTE share_installed = 0;
code, so DOS simply negates this value and returns it in code, so DOS simply negates this value and returns it in
AX. */ AX. */
extern int ASMPASCAL 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 */ unsigned short pspseg, /* psp segment address of owner process */
int openmode, /* 0=read-only, 1=write-only, 2=read-write */ int openmode, /* 0=read-only, 1=write-only, 2=read-write */
int sharemode); /* SHARE_COMPAT, etc... */ int sharemode); /* SHARE_COMPAT, etc... */
@ -86,13 +86,6 @@ extern int ASMPASCAL
unsigned long len, /* length (in bytes) of region to lock or unlock */ unsigned long len, /* length (in bytes) of region to lock or unlock */
int unlock); /* one to unlock; zero to lock */ 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 */ /* /// End of additions for SHARE. - Ron Cemer */
STATIC int remote_lock_unlock(sft FAR *sftp, /* SFT for file */ 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 */ unsigned long len, /* length (in bytes) of region to lock or unlock */
int unlock); /* one to unlock; zero to lock */ 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 /* get current directory structure for drive
return NULL if the CDS is not valid or the return NULL if the CDS is not valid or the
drive is not within range */ 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); 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); sft FAR *s = idx_to_sft(sft_idx);
if (FP_OFF(s) == (size_t) -1) 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; s->sft_posit = new_pos;
*p_result = new_pos;
return SUCCESS; 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) ULONG DosSeek(unsigned hndl, LONG new_pos, COUNT mode, int *rc)
{ {
int sft_idx = get_sft_idx(hndl); int sft_idx = get_sft_idx(hndl);
UDWORD result;
/* Get the SFT block that contains the SFT */ /* 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) if (*rc == SUCCESS)
return result; return idx_to_sft(sft_idx)->sft_posit;
return *rc; return *rc;
} }
@ -436,17 +414,6 @@ const char FAR *get_root(const char FAR * fname)
return 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 */ /* initialize SFT fields (for open/creat) for character devices */
STATIC int DeviceOpenSft(struct dhdr FAR *dhp, sft FAR *sftp) 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) if (result < SUCCESS)
return result; return result;
set_fcbname();
/* now get a free system file table entry */ /* now get a free system file table entry */
if ((sftp = get_free_sft(&sft_idx)) == (sft FAR *) - 1) if ((sftp = get_free_sft(&sft_idx)) == (sft FAR *) - 1)
return DE_TOOMANY; 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_shroff = -1; /* /// Added for SHARE - Ron Cemer */
sftp->sft_attrib = attrib = attrib | D_ARCHIVE; 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) if (result & IS_NETWORK)
{ {
int status; int status;
@ -582,6 +535,18 @@ long DosOpenSft(char FAR * fname, unsigned flags, unsigned attrib)
return status; 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 */ /* First test the flags to see if the user has passed a valid */
/* file mode... */ /* file mode... */
if ((flags & O_ACCMODE) > 2) 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 */ /* navc==NULL means: called from FatGetDrvData, fcbfns.c */
struct dpb FAR *dpbp; struct dpb FAR *dpbp;
struct cds FAR *cdsp; struct cds FAR *cdsp;
COUNT rg[5]; /* add space for SI, although it's unused here */ COUNT rg[4];
UWORD spc; UWORD spc;
/* first check for valid drive */ /* first check for valid drive */
@ -781,7 +746,6 @@ UWORD DosGetFree(UBYTE drive, UWORD * navc, UWORD * bps, UWORD * nc)
if (cdsp == NULL) if (cdsp == NULL)
return spc; return spc;
current_ldt = cdsp;
if (cdsp->cdsFlags & CDSNETWDRV) if (cdsp->cdsFlags & CDSNETWDRV)
{ {
if (remote_getfree(cdsp, rg) != SUCCESS) if (remote_getfree(cdsp, rg) != SUCCESS)
@ -876,7 +840,7 @@ COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp)
{ {
struct dpb FAR *dpbp; struct dpb FAR *dpbp;
struct cds FAR *cdsp; struct cds FAR *cdsp;
UCOUNT rg[5]; UCOUNT rg[4];
/* ensure all fields known value - clear reserved bytes & set xfs_version.actual to 0 */ /* ensure all fields known value - clear reserved bytes & set xfs_version.actual to 0 */
fmemset(xfsp, 0, sizeof(struct xfreespace)); fmemset(xfsp, 0, sizeof(struct xfreespace));
@ -899,44 +863,13 @@ COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp)
if (cdsp->cdsFlags & CDSNETWDRV) if (cdsp->cdsFlags & CDSNETWDRV)
{ {
/* Try redirector extension */ if (remote_getfree(cdsp, rg) != SUCCESS)
if (remote_getfree_11a3(cdsp, rg) != SUCCESS) return DE_INVLDDRV;
{
/* Fallback */
if (remote_getfree(cdsp, rg) != SUCCESS)
return DE_INVLDDRV;
xfsp->xfs_clussize = rg[0]; xfsp->xfs_clussize = rg[0];
xfsp->xfs_totalclusters = rg[1]; xfsp->xfs_totalclusters = rg[1];
xfsp->xfs_secsize = rg[2]; xfsp->xfs_secsize = rg[2];
xfsp->xfs_freeclusters = rg[3]; 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 else
{ {
@ -986,8 +919,6 @@ COUNT DosChangeDir(BYTE FAR * s)
if (result < SUCCESS) if (result < SUCCESS)
return DE_PATHNOTFND; return DE_PATHNOTFND;
set_fcbname();
if ((FP_OFF(current_ldt) != 0xFFFF) && if ((FP_OFF(current_ldt) != 0xFFFF) &&
(strlen(PriPathName) >= sizeof(current_ldt->cdsCurrentPath))) (strlen(PriPathName) >= sizeof(current_ldt->cdsCurrentPath)))
return DE_PATHNOTFND; return DE_PATHNOTFND;
@ -1011,6 +942,7 @@ COUNT DosChangeDir(BYTE FAR * s)
Some redirectors do not write back to the CDS. Some redirectors do not write back to the CDS.
SHSUCdX needs this. jt SHSUCdX needs this. jt
*/ */
fstrcpy(current_ldt->cdsCurrentPath, PriPathName);
if (FP_OFF(current_ldt) != 0xFFFF) if (FP_OFF(current_ldt) != 0xFFFF)
{ {
fstrcpy(current_ldt->cdsCurrentPath, PriPathName); fstrcpy(current_ldt->cdsCurrentPath, PriPathName);
@ -1045,8 +977,6 @@ COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name)
if (rc < SUCCESS) if (rc < SUCCESS)
return rc; return rc;
set_fcbname();
/* /// Added code here to do matching against device names. /* /// Added code here to do matching against device names.
DOS findfirst will match exact device names if the DOS findfirst will match exact device names if the
filename portion (excluding the extension) contains 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 */ /* 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 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; return DE_NFILES;
memset(&SearchDir, 0, sizeof(struct dirent)); memset(&SearchDir, 0, sizeof(struct dirent));
@ -1130,7 +1060,7 @@ COUNT DosFindNext(void)
return pop_dmp(rc, dmp); return pop_dmp(rc, dmp);
} }
COUNT DosGetFtime(COUNT hndl, ddate * dp, dtime * tp) COUNT DosGetFtime(COUNT hndl, date * dp, time * tp)
{ {
sft FAR *s; sft FAR *s;
/*sfttbl FAR *sp;*/ /*sfttbl FAR *sp;*/
@ -1144,7 +1074,7 @@ COUNT DosGetFtime(COUNT hndl, ddate * dp, dtime * tp)
return SUCCESS; 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 */ /* Get the SFT block that contains the SFT */
sft FAR *s = idx_to_sft(sft_idx); sft FAR *s = idx_to_sft(sft_idx);
@ -1183,8 +1113,6 @@ COUNT DosGetFattr(BYTE FAR * name)
if (PriPathName[3] == '\0') if (PriPathName[3] == '\0')
return 0x10; return 0x10;
set_fcbname();
if (result & IS_NETWORK) if (result & IS_NETWORK)
return network_redirector(REM_GETATTRZ); return network_redirector(REM_GETATTRZ);
@ -1205,8 +1133,6 @@ COUNT DosSetFattr(BYTE FAR * name, UWORD attrp)
if (result < SUCCESS) if (result < SUCCESS)
return result; return result;
set_fcbname();
if (result & IS_NETWORK) if (result & IS_NETWORK)
return remote_setfattr(attrp); return remote_setfattr(attrp);
@ -1244,17 +1170,12 @@ COUNT DosDelete(BYTE FAR * path, int attrib)
if (result < SUCCESS) if (result < SUCCESS)
return result; return result;
set_fcbname();
if (result & IS_NETWORK) if (result & IS_NETWORK)
return network_redirector(REM_DELETE); return network_redirector(REM_DELETE);
if (result & IS_DEVICE) if (result & IS_DEVICE)
return DE_FILENOTFND; return DE_FILENOTFND;
if (IsShareInstalled(TRUE) && share_is_file_open(PriPathName))
return DE_ACCESS;
return dos_delete(PriPathName, attrib); 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)) if (FP_OFF(current_ldt) == 0xFFFF || (current_ldt->cdsFlags & CDSNETWDRV))
return network_redirector(REM_RENAME); return network_redirector(REM_RENAME);
if (IsShareInstalled(TRUE) && share_is_file_open(path1))
return DE_ACCESS;
return dos_rename(path1, path2, attrib); return dos_rename(path1, path2, attrib);
} }
@ -1288,8 +1206,6 @@ COUNT DosRename(BYTE FAR * path1, BYTE FAR * path2)
if (result < SUCCESS) if (result < SUCCESS)
return result; return result;
set_fcbname();
if ((result & (IS_NETWORK | IS_DEVICE)) == IS_DEVICE) if ((result & (IS_NETWORK | IS_DEVICE)) == IS_DEVICE)
return DE_FILENOTFND; return DE_FILENOTFND;
@ -1304,8 +1220,6 @@ COUNT DosMkRmdir(const char FAR * dir, int action)
if (result < SUCCESS) if (result < SUCCESS)
return result; return result;
set_fcbname();
if (result & IS_NETWORK) if (result & IS_NETWORK)
return network_redirector(action == 0x39 ? REM_MKDIR : REM_RMDIR); return network_redirector(action == 0x39 ? REM_MKDIR : REM_RMDIR);
@ -1426,10 +1340,8 @@ BOOL IsShareInstalled(BOOL recheck)
extern unsigned char ASMPASCAL share_check(void); extern unsigned char ASMPASCAL share_check(void);
if (recheck == FALSE) if (recheck == FALSE)
return share_installed; return share_installed;
if (share_check() == 0xff) if (!share_installed && share_check() == 0xff)
share_installed = TRUE; share_installed = TRUE;
else
share_installed = FALSE;
return share_installed; 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); COUNT rc = truename(src, PriPathName, CDS_MODE_ALLOW_WILDCARDS);
if (rc >= SUCCESS) if (rc >= SUCCESS)
{
fstrcpy(dest, PriPathName); fstrcpy(dest, PriPathName);
set_fcbname();
}
return rc; return rc;
} }

View File

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

View File

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

View File

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

View File

@ -35,23 +35,20 @@ segment HMA_TEXT
extern _int21_syscall extern _int21_syscall
extern _int21_service extern _int21_service
extern _int2526_handler extern _int2526_handler
extern _error_tos extern _error_tos:wrt DGROUP
extern _char_api_tos extern _char_api_tos:wrt DGROUP
extern _disk_api_tos extern _disk_api_tos:wrt DGROUP
extern _user_r extern _user_r:wrt DGROUP
extern _ErrorMode extern _ErrorMode:wrt DGROUP
extern _InDOS extern _InDOS:wrt DGROUP
%IFDEF WIN31SUPPORT extern _cu_psp:wrt DGROUP
extern _winInstanced extern _MachineId:wrt DGROUP
%ENDIF ; WIN31SUPPORT extern critical_sp:wrt DGROUP
extern _cu_psp
extern _MachineId
extern critical_sp
extern int21regs_seg extern int21regs_seg:wrt DGROUP
extern int21regs_off extern int21regs_off:wrt DGROUP
extern _Int21AX extern _Int21AX:wrt DGROUP
extern _DGROUP_ extern _DGROUP_
@ -239,10 +236,6 @@ reloc_call_int20_handler:
; int21_handler(iregs UserRegs) ; int21_handler(iregs UserRegs)
; ;
reloc_call_int21_handler: 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 ; Create the stack frame for C call. This is done to
; preserve machine state and provide a C structure for ; preserve machine state and provide a C structure for
@ -269,8 +262,12 @@ int21_reentry:
mov dx,[cs:_DGROUP_] mov dx,[cs:_DGROUP_]
mov ds,dx mov ds,dx
cmp ah,25h
je int21_user
cmp ah,33h cmp ah,33h
je int21_user je int21_user
cmp ah,35h
je int21_user
cmp ah,50h cmp ah,50h
je int21_user je int21_user
cmp ah,51h cmp ah,51h
@ -279,9 +276,7 @@ int21_reentry:
jne int21_1 jne int21_1
int21_user: int21_user:
%IFNDEF WIN31SUPPORT call dos_crit_sect
call end_dos_crit_sect
%ENDIF ; NOT WIN31SUPPORT
push ss push ss
push bp push bp
@ -290,29 +285,6 @@ int21_user:
pop cx pop cx
jmp short int21_ret 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 ; normal entry, use one of our 4 stacks
; ;
@ -367,27 +339,15 @@ int21_onerrorstack:
jmp short int21_exit_nodec jmp short int21_exit_nodec
int21_2: int21_2: inc byte [_InDOS]
%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]
mov cx,_char_api_tos mov cx,_char_api_tos
or ah,ah or ah,ah
jz int21_3 jz int21_3
%IFDEF WIN31SUPPORT ; testing, this function call crashes
cmp ah,06h
je int21_3
%ENDIF ; WIN31SUPPORT
cmp ah,0ch cmp ah,0ch
jbe int21_normalentry jbe int21_normalentry
int21_3: int21_3:
%IFNDEF WIN31SUPPORT call dos_crit_sect
call end_dos_crit_sect
%ENDIF ; NOT WIN31SUPPORT
mov cx,_disk_api_tos mov cx,_disk_api_tos
int21_normalentry: int21_normalentry:
@ -407,15 +367,6 @@ int21_normalentry:
call _int21_service call _int21_service
int21_exit: dec byte [_InDOS] 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 ; Recover registers from system call. Registers and flags
@ -441,28 +392,11 @@ int21_ret:
; ... and return. ; ... and return.
; ;
iret 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 Critical Section 0 thur 7
; ;
; ;
end_dos_crit_sect: dos_crit_sect:
mov [_Int21AX],ax ; needed! mov [_Int21AX],ax ; needed!
push ax ; This must be here!!! push ax ; This must be here!!!
mov ah,82h ; re-enrty sake before disk stack mov ah,82h ; re-enrty sake before disk stack

View File

@ -51,18 +51,17 @@ segment HMA_TEXT
push si push si
push ds ; sp=bp-8 push ds ; sp=bp-8
arg {rhp,4}, {dhp,4} lds si,[bp+4] ; ds:si = device header
lds si,[.dhp] ; ds:si = device header les bx,[bp+8] ; es:bx = request header
les bx,[.rhp] ; es:bx = request header
mov ax, [si+6] ; construct strategy address mov ax, [si+6] ; construct strategy address
mov [.dhp], ax mov [bp+4], ax
push si ; the bloody fucking RTSND.DOS push si ; the bloody fucking RTSND.DOS
push di ; driver destroys SI,DI (tom 14.2.03) 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 di
pop si pop si
@ -70,8 +69,8 @@ arg {rhp,4}, {dhp,4}
; Protect386Registers ; old free-EMM386 versions destroy regs in their INIT method ; Protect386Registers ; old free-EMM386 versions destroy regs in their INIT method
mov ax,[si+8] ; construct 'interrupt' address mov ax,[si+8] ; construct 'interrupt' address
mov [.dhp],ax ; construct interrupt address mov [bp+4],ax ; construct interrupt address
call far[.dhp] ; call far the interrupt call far[bp+4] ; call far the interrupt
; Restore386Registers ; less stack load and better performance... ; 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); STATIC int shrink_file(f_node_ptr fnp);
/* FAT time notation in the form of hhhh hmmm mmmd dddd (d = double second) */ /* 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); return (t->hour << 11) | (t->minute << 5) | (t->second >> 1);
} }
@ -103,9 +103,8 @@ STATIC void init_direntry(struct dirent *dentry, unsigned attrib,
#endif #endif
dentry->dir_start = (UWORD)cluster; dentry->dir_start = (UWORD)cluster;
dentry->dir_attrib = (UBYTE)attrib; dentry->dir_attrib = (UBYTE)attrib;
/* set create and last modified time & date */ dentry->dir_time = dos_gettime();
dentry->dir_crtime = dentry->dir_time = dos_gettime(); dentry->dir_date = dos_getdate();
dentry->dir_crdate = dentry->dir_date = dos_getdate();
} }
/************************************************************************/ /************************************************************************/
@ -463,9 +462,8 @@ COUNT dos_rmdir(BYTE * path)
return DE_PATHNOTFND; return DE_PATHNOTFND;
/* Directories may have attributes, but if other than 'archive' */ /* Directories may have attributes, but if other than 'archive' */
/* or 'read only' then deny i.e. do not allow (SYSTEM|HIDDEN) */ /* then do not allow (RDONLY|SYSTEM|HIDDEN) directory to be deleted. */
/* directory to be deleted. */ if (fnp->f_dir.dir_attrib & ~(D_DIR |D_ARCHIVE))
if (fnp->f_dir.dir_attrib & ~(D_DIR | D_RDONLY | D_ARCHIVE))
return DE_ACCESS; return DE_ACCESS;
dir_read(fnp); dir_read(fnp);
@ -666,7 +664,7 @@ STATIC int alloc_find_free(f_node_ptr fnp, char *path)
/* */ /* */
/* dos_getdate for the file date */ /* dos_getdate for the file date */
/* */ /* */
ddate dos_getdate(void) date dos_getdate(void)
{ {
struct dosdate dd; struct dosdate dd;
@ -679,7 +677,7 @@ ddate dos_getdate(void)
/* */ /* */
/* dos_gettime for the file time */ /* dos_gettime for the file time */
/* */ /* */
dtime dos_gettime(void) time dos_gettime(void)
{ {
struct dostime dt; struct dostime dt;
@ -1584,17 +1582,13 @@ VOID bpb_to_dpb(bpb FAR * bpbp, REG struct dpb FAR * dpbp)
bpb sbpb; bpb sbpb;
fmemcpy(&sbpb, bpbp, sizeof(sbpb)); fmemcpy(&sbpb, bpbp, sizeof(sbpb));
if (sbpb.bpb_nsector == 0) { for (shftcnt = 0; (sbpb.bpb_nsector >> shftcnt) > 1; shftcnt++)
shftcnt = 8; ;
} else {
for (shftcnt = 0; (sbpb.bpb_nsector >> shftcnt) > 1; shftcnt++)
;
}
dpbp->dpb_shftcnt = shftcnt; dpbp->dpb_shftcnt = shftcnt;
dpbp->dpb_mdb = sbpb.bpb_mdesc; dpbp->dpb_mdb = sbpb.bpb_mdesc;
dpbp->dpb_secsize = sbpb.bpb_nbyte; 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_fatstrt = sbpb.bpb_nreserved;
dpbp->dpb_fats = sbpb.bpb_nfat; dpbp->dpb_fats = sbpb.bpb_nfat;
dpbp->dpb_dirents = sbpb.bpb_ndirent; dpbp->dpb_dirents = sbpb.bpb_ndirent;

View File

@ -226,7 +226,7 @@ CLUSTER link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
if (ISFAT12(dpbp)) if (ISFAT12(dpbp))
{ {
REG UBYTE FAR *fbp0; REG UBYTE FAR * fbp1; REG UBYTE FAR *fbp0, FAR * fbp1;
struct buffer FAR * bp1; struct buffer FAR * bp1;
unsigned cluster, cluster2; 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 FcbNextRecord(fcb FAR * lpFcb);
STATIC void FcbCalcRec(xfcb FAR * lpXfcb); STATIC void FcbCalcRec(xfcb FAR * lpXfcb);
#define TestCmnSeps(lpFileName) (*lpFileName && strchr(":;,=+ \t", *lpFileName) != NULL) #define TestCmnSeps(lpFileName) (*lpFileName && strchr(":<|>+=,", *lpFileName) != NULL)
#define TestFieldSeps(lpFileName) ((unsigned char)*lpFileName <= ' ' || strchr("/\\\"[]<>|.:;,=+\t", *lpFileName) != NULL) #define TestFieldSeps(lpFileName) ((unsigned char)*lpFileName <= ' ' || strchr("/\"[]<>|.", *lpFileName) != NULL)
static dmatch Dmatch; static dmatch Dmatch;
@ -78,7 +78,7 @@ BYTE FAR *FatGetDrvData(UBYTE drive, UBYTE * pspc, UWORD * bps, UWORD * nc)
return NULL; return NULL;
} }
#define PARSE_SKIP_LEAD_SEP 0x01 #define PARSE_SEP_STOP 0x01
#define PARSE_DFLT_DRIVE 0x02 #define PARSE_DFLT_DRIVE 0x02
#define PARSE_BLNK_FNAME 0x04 #define PARSE_BLNK_FNAME 0x04
#define PARSE_BLNK_FEXT 0x08 #define PARSE_BLNK_FEXT 0x08
@ -90,14 +90,13 @@ BYTE FAR *FatGetDrvData(UBYTE drive, UBYTE * pspc, UWORD * bps, UWORD * nc)
#ifndef IPL #ifndef IPL
UWORD FcbParseFname(UBYTE *wTestMode, const BYTE FAR * lpFileName, fcb FAR * lpFcb) 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? */ /* pjv -- ExtFcbToFcb? */
if (!(*wTestMode & PARSE_SEP_STOP))
/* skip leading separators if requested */
if (*wTestMode & PARSE_SKIP_LEAD_SEP)
{ {
while (TestCmnSeps(lpFileName)) lpFileName = ParseSkipWh(lpFileName);
if (TestCmnSeps(lpFileName))
++lpFileName; ++lpFileName;
} }
@ -105,20 +104,16 @@ UWORD FcbParseFname(UBYTE *wTestMode, const BYTE FAR * lpFileName, fcb FAR * lpF
lpFileName = ParseSkipWh(lpFileName); lpFileName = ParseSkipWh(lpFileName);
/* Now check for drive specification */ /* Now check for drive specification */
/* If drive specified, set to it otherwise */ if (*(lpFileName + 1) == ':')
/* 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) == ':')
{ {
/* non-portable construct to be changed */ /* non-portable construct to be changed */
REG UBYTE Drive = DosUpFChar(*lpFileName) - 'A'; REG UBYTE Drive = DosUpFChar(*lpFileName) - 'A';
if (get_cds(Drive) == NULL) if (get_cds(Drive) == NULL)
wRetCodeDrive = TRUE; {
*wTestMode = PARSE_RET_BADDRIVE;
return FP_OFF(lpFileName);
}
lpFcb->fcb_drive = Drive + 1; lpFcb->fcb_drive = Drive + 1;
lpFileName += 2; 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 */ /* 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; lpFcb->fcb_cublock = lpFcb->fcb_recsiz = 0;
if (!(*wTestMode & PARSE_BLNK_FNAME)) 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, GetNameField(++lpFileName, (BYTE FAR *) lpFcb->fcb_fext,
FEXT_SIZE, (BOOL *) & wRetCodeExt); FEXT_SIZE, (BOOL *) & wRetCodeExt);
if (wRetCodeDrive) *wTestMode = (wRetCodeName | wRetCodeExt) ? PARSE_RET_WILD : PARSE_RET_NOWILD;
*wTestMode = PARSE_RET_BADDRIVE;
else if (wRetCodeName | wRetCodeExt)
*wTestMode = PARSE_RET_WILD;
else
*wTestMode = PARSE_RET_NOWILD;
return FP_OFF(lpFileName); return FP_OFF(lpFileName);
} }
@ -181,6 +169,33 @@ const BYTE FAR * ParseSkipWh(const BYTE FAR * lpFileName)
return 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, const BYTE FAR * GetNameField(const BYTE FAR * lpFileName, BYTE FAR * lpDestField,
COUNT nFieldSize, BOOL * pbWildCard) COUNT nFieldSize, BOOL * pbWildCard)
@ -191,7 +206,8 @@ const BYTE FAR * GetNameField(const BYTE FAR * lpFileName, BYTE FAR * lpDestFiel
while (*lpFileName != '\0' && !TestFieldSeps(lpFileName) while (*lpFileName != '\0' && !TestFieldSeps(lpFileName)
&& nIndex < nFieldSize) && nIndex < nFieldSize)
{ {
/* convert * into multiple ? for remaining length of field */ if (*lpFileName == ' ')
break;
if (*lpFileName == '*') if (*lpFileName == '*')
{ {
*pbWildCard = TRUE; *pbWildCard = TRUE;
@ -199,11 +215,8 @@ const BYTE FAR * GetNameField(const BYTE FAR * lpFileName, BYTE FAR * lpDestFiel
++lpFileName; ++lpFileName;
break; break;
} }
/* include ? as-is but flag for return purposes wildcard used */
if (*lpFileName == '?') if (*lpFileName == '?')
*pbWildCard = TRUE; *pbWildCard = TRUE;
/* store uppercased character, and advance to next char */
*lpDestField++ = DosUpFChar(*lpFileName++); *lpDestField++ = DosUpFChar(*lpFileName++);
++nIndex; ++nIndex;
} }
@ -517,8 +530,6 @@ UBYTE FcbDelete(xfcb FAR * lpXfcb)
UBYTE FcbRename(xfcb FAR * lpXfcb) UBYTE FcbRename(xfcb FAR * lpXfcb)
{ {
BYTE buf[FNAME_SIZE + FEXT_SIZE];
BOOL bWildCard;
rfcb FAR *lpRenameFcb; rfcb FAR *lpRenameFcb;
COUNT FcbDrive; COUNT FcbDrive;
UBYTE result = FCB_SUCCESS; UBYTE result = FCB_SUCCESS;
@ -526,10 +537,7 @@ UBYTE FcbRename(xfcb FAR * lpXfcb)
/* Build a traditional DOS file name */ /* Build a traditional DOS file name */
lpRenameFcb = (rfcb FAR *) CommonFcbInit(lpXfcb, SecPathName, &FcbDrive); 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 */ /* check for a device */
if (IsDevice(SecPathName)) if (IsDevice(SecPathName))
{ {
@ -538,7 +546,7 @@ UBYTE FcbRename(xfcb FAR * lpXfcb)
else else
{ {
dmatch Dmatch; dmatch Dmatch;
COUNT rc; COUNT result;
wAttr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL); wAttr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL);
dta = &Dmatch; dta = &Dmatch;
@ -553,7 +561,6 @@ UBYTE FcbRename(xfcb FAR * lpXfcb)
fcb LocalFcb; fcb LocalFcb;
BYTE *pToName; BYTE *pToName;
const BYTE FAR *pFromPattern = Dmatch.dm_name; const BYTE FAR *pFromPattern = Dmatch.dm_name;
const char *pToPattern = buf;
int i; int i;
UBYTE mode = 0; UBYTE mode = 0;
@ -562,20 +569,21 @@ UBYTE FcbRename(xfcb FAR * lpXfcb)
/* I'm cheating because this assumes that the */ /* I'm cheating because this assumes that the */
/* struct alignments are on byte boundaries */ /* struct alignments are on byte boundaries */
pToName = LocalFcb.fcb_fname; pToName = LocalFcb.fcb_fname;
pFromPattern = lpRenameFcb->renNewName;
for (i = 0; i < FNAME_SIZE + FEXT_SIZE; i++) for (i = 0; i < FNAME_SIZE + FEXT_SIZE; i++)
{ {
if (*pToPattern != '?') if (*pFromPattern != '?')
*pToName = *pToPattern; *pToName = *pFromPattern;
pToName++; pToName++;
pToPattern++; pFromPattern++;
} }
SecPathName[0] = 'A' + FcbDrive - 1; SecPathName[0] = 'A' + FcbDrive - 1;
SecPathName[1] = ':'; SecPathName[1] = ':';
strcpy(&SecPathName[2], Dmatch.dm_name); 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; result = FCB_ERROR;
break; break;
@ -583,8 +591,8 @@ UBYTE FcbRename(xfcb FAR * lpXfcb)
/* now to build a dos name again */ /* now to build a dos name again */
LocalFcb.fcb_drive = FcbDrive; LocalFcb.fcb_drive = FcbDrive;
FcbNameInit(&LocalFcb, loc_szBuffer, &FcbDrive); FcbNameInit(&LocalFcb, loc_szBuffer, &FcbDrive);
rc = truename(loc_szBuffer, SecPathName, 0); result = truename(loc_szBuffer, SecPathName, 0);
if (rc < SUCCESS || (rc & (IS_NETWORK|IS_DEVICE)) == IS_DEVICE if (result < SUCCESS || (result & (IS_NETWORK|IS_DEVICE)) == IS_DEVICE
|| DosRenameTrue(PriPathName, SecPathName, wAttr) != SUCCESS) || DosRenameTrue(PriPathName, SecPathName, wAttr) != SUCCESS)
{ {
result = FCB_ERROR; result = FCB_ERROR;
@ -655,20 +663,17 @@ UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First)
/* Next initialze local variables by moving them from the fcb */ /* Next initialze local variables by moving them from the fcb */
lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive); lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
if (First) /* Reconstrct the dirmatch structure from the fcb - doesn't hurt for first */
{ Dmatch.dm_drive = lpFcb->fcb_sftno;
/* Reconstruct the dirmatch structure from the fcb */
Dmatch.dm_drive = lpFcb->fcb_sftno;
fmemcpy(Dmatch.dm_name_pat, lpFcb->fcb_fname, FNAME_SIZE + FEXT_SIZE); fmemcpy(Dmatch.dm_name_pat, lpFcb->fcb_fname, FNAME_SIZE + FEXT_SIZE);
DosUpFMem((BYTE FAR *) Dmatch.dm_name_pat, FNAME_SIZE + FEXT_SIZE); DosUpFMem((BYTE FAR *) Dmatch.dm_name_pat, FNAME_SIZE + FEXT_SIZE);
Dmatch.dm_attr_srch = wAttr; Dmatch.dm_attr_srch = wAttr;
Dmatch.dm_entry = lpFcb->fcb_strtclst; Dmatch.dm_entry = lpFcb->fcb_strtclst;
Dmatch.dm_dircluster = lpFcb->fcb_dirclst; Dmatch.dm_dircluster = lpFcb->fcb_dirclst;
wAttr = D_ALL; wAttr = D_ALL;
}
if ((xfcb FAR *) lpFcb != lpXfcb) if ((xfcb FAR *) lpFcb != lpXfcb)
{ {

View File

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

View File

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

View File

@ -2,8 +2,8 @@
#define IN_INIT_MOD #define IN_INIT_MOD
#include "version.h" #include "version.h"
#include "ddate.h" #include "date.h"
#include "dtime.h" #include "time.h"
#include "mcb.h" #include "mcb.h"
#include "sft.h" #include "sft.h"
#include "fat.h" #include "fat.h"
@ -16,12 +16,12 @@
#include "tail.h" #include "tail.h"
#include "process.h" #include "process.h"
#include "pcb.h" #include "pcb.h"
#include "nls.h"
#include "buffer.h" #include "buffer.h"
#include "dcb.h" #include "dcb.h"
#include "lol.h" #include "lol.h"
#include "init-dat.h" #include "init-dat.h"
#include "nls.h"
#include "kconfig.h" #include "kconfig.h"
@ -38,7 +38,7 @@
#define BSS_INIT(x) #define BSS_INIT(x)
#endif #endif
extern struct _KernelConfig ASM InitKernelConfig; extern struct _KernelConfig InitKernelConfig;
/* /*
* Functions in `INIT_TEXT' may need to call functions in `_TEXT'. The entry * 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 memset init_memset
#define strchr init_strchr #define strchr init_strchr
#define strcpy init_strcpy #define strcpy init_strcpy
#define fstrcpy init_fstrcpy
#define strlen init_strlen #define strlen init_strlen
#define fstrlen init_fstrlen #define fstrlen init_fstrlen
#endif #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 memcpy( void *d, const void *s, size_t n);
VOID ASMPASCAL fmemcpy( void FAR *d, const void FAR *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 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 strlen(const char *s);
size_t ASMPASCAL fstrlen(const char FAR *s); size_t ASMPASCAL fstrlen(const char FAR *s);
char * ASMPASCAL strchr(const char *s, int ch); char * ASMPASCAL strchr(const char *s, int ch);
@ -84,18 +82,17 @@ char * ASMPASCAL strchr(const char *s, int ch);
#ifdef __WATCOMC__ #ifdef __WATCOMC__
/* bx, cx, dx and es not used or clobbered for all asmsupt.asm functions except /* bx, cx, dx and es not used or clobbered for all asmsupt.asm functions except
(f)memchr/(f)strchr (which clobber dx) */ (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) memset
#pragma aux (pascal_ax) fmemset #pragma aux (pascal_ax) fmemset
#pragma aux (pascal_ax) memcpy #pragma aux (pascal_ax) memcpy
#pragma aux (pascal_ax) fmemcpy #pragma aux (pascal_ax) fmemcpy
#pragma aux (pascal_ax) memcmp __modify __nomemory #pragma aux (pascal_ax) memcmp modify nomemory
#pragma aux (pascal_ax) fmemcmp __modify __nomemory #pragma aux (pascal_ax) fmemcmp modify nomemory
#pragma aux (pascal_ax) strcpy #pragma aux (pascal_ax) strcpy
#pragma aux (pascal_ax) fstrcpy #pragma aux (pascal_ax) strlen modify nomemory
#pragma aux (pascal_ax) strlen __modify __nomemory #pragma aux (pascal_ax) fstrlen modify nomemory
#pragma aux (pascal_ax) fstrlen __modify __nomemory #pragma aux (pascal) strchr modify exact [ax dx] nomemory
#pragma aux (__pascal) strchr __modify __exact [__ax __dx] __nomemory
#endif #endif
#undef LINESIZE #undef LINESIZE
@ -147,7 +144,7 @@ COUNT ASMPASCAL Umb_Test(void);
COUNT ASMPASCAL UMB_get_largest(void FAR * driverAddress, COUNT ASMPASCAL UMB_get_largest(void FAR * driverAddress,
UCOUNT * seg, UCOUNT * size); UCOUNT * seg, UCOUNT * size);
#ifdef __WATCOMC__ #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 #endif
/* inithma.c */ /* inithma.c */
@ -185,18 +182,18 @@ int ASMPASCAL init_switchar(int chr);
void ASMPASCAL keycheck(void); void ASMPASCAL keycheck(void);
void ASMPASCAL set_DTA(void far *dta); void ASMPASCAL set_DTA(void far *dta);
#ifdef __WATCOMC__ #ifdef __WATCOMC__
#pragma aux (__pascal) init_call_intr __modify __exact [__ax] #pragma aux (pascal) init_call_intr modify exact [ax]
#pragma aux (__pascal) read __modify __exact [__ax __bx __cx __dx] #pragma aux (pascal) read modify exact [ax bx cx dx]
#pragma aux (__pascal) init_DosOpen __modify __exact [__ax __bx __dx] #pragma aux (pascal) init_DosOpen modify exact [ax bx dx]
#pragma aux (__pascal) close __modify __exact [__ax __bx] #pragma aux (pascal) close modify exact [ax bx]
#pragma aux (__pascal) dup2 __modify __exact [__ax __bx __cx] #pragma aux (pascal) dup2 modify exact [ax bx cx]
#pragma aux (__pascal) allocmem __modify __exact [__ax __bx] #pragma aux (pascal) allocmem modify exact [ax bx]
#pragma aux (__pascal) init_PSPSet __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_DosExec modify exact [ax bx dx es]
#pragma aux (__pascal) init_setdrive __modify __exact [__ax __bx __dx] #pragma aux (pascal) init_setdrive modify exact [ax bx dx]
#pragma aux (__pascal) init_switchar __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) keycheck modify exact [ax]
#pragma aux (__pascal) set_DTA __modify __exact [__ax __bx __dx] #pragma aux (pascal) set_DTA modify exact [ax bx dx]
#endif #endif
/* irqstack.asm */ /* irqstack.asm */
@ -204,6 +201,8 @@ VOID ASMCFUNC init_stacks(VOID FAR * stack_base, COUNT nStacks,
WORD stackSize); WORD stackSize);
/* inthndlr.c */ /* 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 int0_handler(void);
VOID ASMCFUNC FAR int6_handler(void); VOID ASMCFUNC FAR int6_handler(void);
VOID ASMCFUNC FAR int19_handler(void); VOID ASMCFUNC FAR int19_handler(void);
@ -222,11 +221,7 @@ VOID ASMCFUNC FAR int2f_handler(void);
VOID ASMCFUNC FAR cpm_entry(void); VOID ASMCFUNC FAR cpm_entry(void);
/* kernel.asm */ /* 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 */ VOID ASMCFUNC FAR init_call_p_0(struct config FAR *Config); /* P_0, actually */
#endif
/* main.c */ /* main.c */
VOID ASMCFUNC FreeDOSmain(void); 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 UWORD ram_top; /* How much ram in Kbytes */
extern char singleStep; extern char singleStep;
extern char SkipAllConfig; extern char SkipAllConfig;
extern char FAR ASM master_env[128]; extern char master_env[128];
extern struct lol FAR *LoL; extern struct lol FAR *LoL;
extern struct dhdr DOSTEXTFAR ASM blk_dev; /* Block device (Disk) driver */ extern struct dhdr DOSTEXTFAR ASM blk_dev; /* Block device (Disk) driver */
extern struct buffer FAR *DOSFAR firstAvailableBuf; /* first 'available' buffer */ 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 DOSFAR ASM _HMATextAvailable, /* first byte of available CODE area */
extern BYTE FAR ASM _HMATextStart[]; /* first byte of HMAable CODE area */ FAR ASM _HMATextStart[], /* first byte of HMAable CODE area */
extern BYTE FAR ASM _HMATextEnd[]; FAR ASM _HMATextEnd[], DOSFAR ASM break_ena; /* break enabled flag */
extern BYTE DOSFAR ASM break_ena; /* break enabled flag */ extern BYTE DOSFAR ASM _InitTextStart[], /* first available byte of ram */
extern BYTE DOSFAR ASM _InitTextStart[]; /* first available byte of ram */ DOSFAR ASM _InitTextEnd[],
extern BYTE DOSFAR ASM _InitTextEnd[]; DOSFAR ReturnAnyDosVersionExpected,
extern BYTE DOSFAR ASM ReturnAnyDosVersionExpected; DOSFAR ASM HaltCpuWhileIdle;
extern BYTE DOSFAR ASM HaltCpuWhileIdle;
extern BYTE DOSFAR ASM internal_data[]; extern BYTE FAR ASM internal_data[];
extern unsigned char DOSTEXTFAR ASM kbdType; extern unsigned char FAR ASM kbdType;
extern struct { extern struct {
char ThisIsAConstantOne; char ThisIsAConstantOne;
@ -281,7 +275,7 @@ extern struct {
struct CountrySpecificInfo C; struct CountrySpecificInfo C;
} DOSFAR ASM nlsCountryInfoHardcoded; } FAR ASM nlsCountryInfoHardcoded;
/* /*
data shared between DSK.C and INITDISK.C data shared between DSK.C and INITDISK.C
@ -316,26 +310,21 @@ struct RelocatedEntry {
UWORD jmpSegment; UWORD jmpSegment;
}; };
extern struct RelocationTable DOSFAR ASM _HMARelocationTableStart[]; extern struct RelocationTable
extern struct RelocationTable DOSFAR ASM _HMARelocationTableEnd[]; DOSFAR ASM _HMARelocationTableStart[],
DOSFAR ASM _HMARelocationTableEnd[];
extern void FAR *DOSFAR ASM XMSDriverAddress; 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 _EnableA20(VOID);
extern VOID ASMPASCAL FAR _DisableA20(VOID); extern VOID ASMPASCAL FAR _DisableA20(VOID);
#endif
extern void FAR * ASMPASCAL DetectXMSDriver(VOID); extern void FAR * ASMPASCAL DetectXMSDriver(VOID);
extern int ASMPASCAL init_call_XMScall(void FAR * driverAddress, UWORD ax, extern int ASMPASCAL init_call_XMScall(void FAR * driverAddress, UWORD ax,
UWORD dx); UWORD dx);
#ifdef __WATCOMC__ #ifdef __WATCOMC__
#pragma aux (__pascal) DetectXMSDriver __modify __exact [__ax __dx] #pragma aux (pascal) DetectXMSDriver modify exact [ax dx]
#pragma aux (__pascal) _EnableA20 __modify __exact [__ax] #pragma aux (pascal) _EnableA20 modify exact [ax]
#pragma aux (__pascal) _DisableA20 __modify __exact [__ax] #pragma aux (pascal) _DisableA20 modify exact [ax]
#endif #endif
#if defined(WATCOM) && 0 #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) void printCHS(char *title, struct CHS *chs)
{ {
/* has no fixed size for head/sect: is often 1/1 in our context */ /* 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) */ * (This is really done in fatfs.c, bpbtodpb) */
{ {
unsigned clust = (fatdat - 2 * defbpb->bpb_nfsect) / NSECTORFAT12; 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) if (maxclust > FAT12MAX)
maxclust = FAT12MAX; maxclust = FAT12MAX;
printf("FAT12: #clu=%u, fatlength=%u, maxclu=%u, limit=%u\n", printf("FAT12: #clu=%u, fatlength=%u, maxclu=%u, limit=%u\n",
@ -434,7 +434,7 @@ VOID CalculateFATData(ddt * pddt, ULONG NumSectors, UBYTE FileSystem)
else else
{ /* FAT16/FAT32 */ { /* FAT16/FAT32 */
CLUSTER fatlength, maxcl; CLUSTER fatlength, maxcl;
unsigned long clust, maxclust, rest; unsigned long clust, maxclust;
unsigned fatentpersec; unsigned fatentpersec;
unsigned divisor; unsigned divisor;
@ -458,7 +458,7 @@ VOID CalculateFATData(ddt * pddt, ULONG NumSectors, UBYTE FileSystem)
defbpb->bpb_ndirent = 0; defbpb->bpb_ndirent = 0;
defbpb->bpb_nreserved = 0x20; defbpb->bpb_nreserved = 0x20;
fatdata = NumSectors - 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; maxcl = FAT32MAX;
} }
else 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 */ max FAT16 size for FreeDOS = 4,293,984,256 bytes = 4GiB-983,040 */
if (fatdata > 8386688ul) if (fatdata > 8386688ul)
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; 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 do
{ {
DebugPrintf(("Trying with %u sectors/cluster:\n", defbpb->bpb_nsector)); DebugPrintf(("Trying with %d sectors/cluster:\n", defbpb->bpb_nsector));
divisor = fatentpersec * defbpb->bpb_nsector + NFAT; /* # of fat entries per cluster + 2 */ divisor = fatentpersec * defbpb->bpb_nsector + NFAT;
rest = (unsigned)(fatdata % divisor); fatlength = (CLUSTER)((fatdata + (2 * defbpb->bpb_nsector + divisor - 1))/
fatlength = (CLUSTER)(fatdata / divisor); divisor);
fatlength += (CLUSTER)((2 * defbpb->bpb_nsector + divisor + rest - 1) / divisor);
/* Need to calculate number of clusters, since the unused parts of the /* Need to calculate number of clusters, since the unused parts of the
* FATS and data area together could make up space for an additional, * FATS and data area together could make up space for an additional,
* not really present cluster. */ * not really present cluster. */
@ -494,7 +492,7 @@ VOID CalculateFATData(ddt * pddt, ULONG NumSectors, UBYTE FileSystem)
if (maxclust > maxcl) if (maxclust > maxcl)
maxclust = maxcl; maxclust = maxcl;
DebugPrintf(("FAT: #clu=%lu, fatlen=%lu, maxclu=%lu, limit=%lu\n", 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) if (clust > maxclust - 2)
{ {
clust = 0; clust = 0;
@ -564,10 +562,10 @@ void DosDefinePartition(struct DriveParamS *driveParam,
pddt->ddt_driveno = driveParam->driveno; pddt->ddt_driveno = driveParam->driveno;
pddt->ddt_logdriveno = nUnits; pddt->ddt_logdriveno = nUnits;
pddt->ddt_descflags = driveParam->descflags; 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 /* the FileSystem type was internally converted to LBA_xxxx if a non-LBA partition
above cylinder 1023 was found */ 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_descflags &= ~DF_LBA;
pddt->ddt_ncyl = driveParam->chs.Cylinder; pddt->ddt_ncyl = driveParam->chs.Cylinder;
@ -631,47 +629,49 @@ void DosDefinePartition(struct DriveParamS *driveParam,
} }
/* Get the parameters of the hard disk */ /* 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; iregs regs;
struct _bios_LBA_disk_parameterS lba_bios_parameters; struct _bios_LBA_disk_parameterS lba_bios_parameters;
if (firstPass && (InitKernelConfig.Verbose >= 1)) ExtLBAForce = FALSE;
printf("Checking for LBA support in BIOS for drive %02x\n", drive);
memset(driveParam, 0, sizeof *driveParam); memset(driveParam, 0, sizeof *driveParam);
drive |= 0x80; 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 (!InitKernelConfig.GlobalEnableLBAsupport)
{ {
if (firstPass && (InitKernelConfig.Verbose >= 1)) printf("LBA support disabled.\n");
goto StandardBios; goto StandardBios;
} }
/* check for LBA support */ /* check for LBA support */
regs.b.x = 0x55aa; regs.b.x = 0x55aa;
regs.a.b.h = 0x41; regs.a.b.h = 0x41;
regs.d.b.l = drive; regs.d.b.l = drive;
regs.flags = FLG_CARRY; /* ensure carry is set to force error if unsupported */
init_call_intr(0x13, &regs); 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; goto StandardBios;
} }
/* version 1.0, 2.0 have different verify */ /* by ralph :
if (regs.a.b.h < 0x21) if DAP cannot be used, don't use
LBA_WRITE_VERIFY = 0x4301; /* may be problematic if INT13 is hooked by LBA
different controllers / drivers */ */
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)); memset(&lba_bios_parameters, 0, sizeof(lba_bios_parameters));
lba_bios_parameters.size = sizeof(lba_bios_parameters); lba_bios_parameters.size = sizeof(lba_bios_parameters);
@ -681,66 +681,45 @@ STATIC int LBA_Get_Drive_Parameters(int drive, struct DriveParamS *driveParam, i
regs.d.b.l = drive; regs.d.b.l = drive;
init_call_intr(0x13, &regs); 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; goto StandardBios;
} }
/* verify maximum settings, we can't handle more */
if (lba_bios_parameters.heads > 0xffff || if (lba_bios_parameters.heads > 0xffff ||
lba_bios_parameters.sectors > 0xffff || lba_bios_parameters.sectors > 0xffff ||
(lba_bios_parameters.totalSect == 0 && lba_bios_parameters.totalSectHigh != 0)
lba_bios_parameters.totalSectHigh == 0))
{ {
if (firstPass) printf("Drive is too large to handle, using only 1st 8 GB\n"
{ " drive %02x heads %lu sectors %lu , total=0x%lx-%08lx\n",
printf("Suspicious LBA disk parameters, reverting to CHS access:\n");
printf(" drive %02x, heads=%lu, sectors=%lu, total=0x%lx-%08lx\n",
drive, drive,
(ULONG) lba_bios_parameters.heads, (ULONG) lba_bios_parameters.heads,
(ULONG) lba_bios_parameters.sectors, (ULONG) lba_bios_parameters.sectors,
(ULONG) lba_bios_parameters.totalSect, (ULONG) lba_bios_parameters.totalSect,
(ULONG) lba_bios_parameters.totalSectHigh); (ULONG) lba_bios_parameters.totalSectHigh);
}
goto StandardBios; goto StandardBios;
} }
/* restrict disk size to 2TB, because we can not handle more */ driveParam->total_sectors = lba_bios_parameters.totalSect;
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; driveParam->descflags = DF_LBA;
if (lba_bios_parameters.information & 8) if (lba_bios_parameters.information & 8)
driveParam->descflags |= DF_WRTVERIFY; 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 */ StandardBios: /* old way to get parameters */
if (firstPass && (InitKernelConfig.Verbose >= 1))
printf("Retrieving CHS values for drive\n");
regs.a.b.h = 0x08; regs.a.b.h = 0x08;
regs.d.b.l = drive; regs.d.b.l = drive;
init_call_intr(0x13, &regs); init_call_intr(0x13, &regs);
if (regs.flags & 0x01) if (regs.flags & 0x01)
{
goto ErrorReturn; goto ErrorReturn;
}
/* int13h call returns max value, store as count (#) i.e. +1 for 0 based heads & cylinders */ /* 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) */ driveParam->chs.Head = (regs.d.x >> 8) + 1; /* DH = max head value = # of heads - 1 (0-255) */
@ -751,8 +730,7 @@ StandardBios: /* get disk geometry, and if LBA is not enabled, also size */
if (driveParam->chs.Sector == 0) { if (driveParam->chs.Sector == 0) {
/* happens e.g. with Bochs 1.x if no harddisk defined */ /* happens e.g. with Bochs 1.x if no harddisk defined */
driveParam->chs.Sector = 63; /* avoid division by zero...! */ driveParam->chs.Sector = 63; /* avoid division by zero...! */
if (firstPass && (InitKernelConfig.Verbose >= 0)) printf("BIOS reported 0 sectors/track, assuming 63!\n");
printf("BIOS reported 0 sectors/track, assuming 63!\n");
} }
if (!(driveParam->descflags & DF_LBA)) if (!(driveParam->descflags & DF_LBA))
@ -770,15 +748,9 @@ StandardBios: /* get disk geometry, and if LBA is not enabled, also size */
driveParam->chs.Head, driveParam->chs.Sector)); driveParam->chs.Head, driveParam->chs.Sector));
DebugPrintf((" total size %luMB\n\n", driveParam->total_sectors / 2048)); DebugPrintf((" total size %luMB\n\n", driveParam->total_sectors / 2048));
return driveParam->driveno;
ErrorReturn: ErrorReturn:
/* to avoid division by zero later, use some sane defaults */
driveParam->total_sectors = 0; return driveParam->driveno;
driveParam->chs.Head = 16;
driveParam->chs.Sector = 63;
return 0;
} }
/* /*
@ -842,13 +814,10 @@ void print_warning_suspect(char *partitionName, UBYTE fs, struct CHS *chs,
{ {
if (!InitKernelConfig.ForceLBA) if (!InitKernelConfig.ForceLBA)
{ {
if (InitKernelConfig.Verbose >= 0) printf("WARNING: using suspect partition %s FS %02x:", partitionName, fs);
{ printCHS(" with calculated values ", chs);
printf("WARNING: using suspect partition %s FS %02x:", partitionName, fs); printCHS(" instead of ", pEntry_chs);
printCHS(" with calculated values ", chs); printf("\n");
printCHS(" instead of ", pEntry_chs);
printf("\n");
}
} }
memcpy(pEntry_chs, chs, sizeof(struct CHS)); 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 (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)) if (!(driveParam->descflags & DF_LBA))
{ {
printf printf
@ -933,11 +901,8 @@ BOOL ScanForPrimaryPartitions(struct DriveParamS * driveParam, int scan_type,
continue; continue;
} }
/* if partition exceeds bounds of CHS addressing and we can use LBA if (!InitKernelConfig.ForceLBA && !ExtLBAForce
but partition type indicates to use CHS then print warning && !IsLBAPartition(pEntry->FileSystem))
and force internal filesystem indicator to enable LBA
*/
if (!(InitKernelConfig.ForceLBA || IsLBAPartition(pEntry->FileSystem) || ExtLBAForce))
{ {
printf printf
("WARNING: Partition ID does not suggest LBA - part %s FS %02x.\n" ("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++) 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; regs.d.b.l = drive | 0x80;
LBA_to_CHS(&chs, LBA_address, driveParam); LBA_to_CHS(&chs, LBA_address, driveParam);
/* Some old "security" software (PROT) traps int13 and assumes non /* 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. the extended LBA partition type indicator.
*/ */
if ((driveParam->descflags & DF_LBA) && 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.number_of_blocks = 1;
dap.buffer_address = buffer; dap.buffer_address = buffer;
dap.block_address_high = 0; /* clear high part */ dap.block_address_high = 0; /* clear high part */
@ -1037,7 +996,6 @@ int Read1LBASector(struct DriveParamS *driveParam, unsigned drive,
} }
else else
{ /* transfer data, using old bios functions */ { /* transfer data, using old bios functions */
if (InitKernelConfig.Verbose >= 1) printf("CHS mode\n");
/* avoid overflow at end of track */ /* avoid overflow at end of track */
if (chs.Cylinder > 1023) 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 */ /* Load the Partition Tables and get information on all drives */
int ProcessDisk(int scanType, unsigned drive, int PartitionsToIgnore) 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]; struct PartTableEntry PTable[4];
ULONG RelSectorOffset; 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. */ /* Get the hard drive parameters and ensure that the drive exists. */
/* If there was an error accessing the drive, skip that drive. */ /* 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); printf("can't get drive parameters for drive %02x\n", drive);
return PartitionsToIgnore; return PartitionsToIgnore;
@ -1089,9 +1046,6 @@ int ProcessDisk(int scanType, unsigned drive, int PartitionsToIgnore)
RelSectorOffset = 0; /* boot sector */ RelSectorOffset = 0; /* boot sector */
ExtendedPartitionOffset = 0; /* not found yet */ 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. */ /* Read the Primary Partition Table. */
@ -1118,7 +1072,7 @@ strange_restart:
if (++strangeHardwareLoop < 3) if (++strangeHardwareLoop < 3)
goto strange_restart; 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); RelSectorOffset);
return PartitionsToIgnore; return PartitionsToIgnore;
} }
@ -1148,7 +1102,7 @@ strange_restart:
{ {
RelSectorOffset = ExtendedPartitionOffset + PTable[iPart].RelSect; RelSectorOffset = ExtendedPartitionOffset + PTable[iPart].RelSect;
if (ExtendedPartitionOffset == 0) /* first extended in chain? */ if (ExtendedPartitionOffset == 0)
{ {
ExtendedPartitionOffset = PTable[iPart].RelSect; ExtendedPartitionOffset = PTable[iPart].RelSect;
/* grand parent LBA -> all children and grandchildren LBA */ /* grand parent LBA -> all children and grandchildren LBA */
@ -1359,7 +1313,7 @@ void ReadAllPartitionTables(void)
if (InitKernelConfig.DLASortByDriveNo == 0) 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 */ /* Process primary partition table 1 partition only */
for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++) for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++)
@ -1388,13 +1342,13 @@ void ReadAllPartitionTables(void)
{ {
UBYTE bootdrv = peekb(0,0x5e0); 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 */ /* Process primary partition table 1 partition only */
for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++) for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++)
{ {
struct DriveParamS driveParam; struct DriveParamS driveParam;
if (LBA_Get_Drive_Parameters(HardDrive, &driveParam, 0) && if (LBA_Get_Drive_Parameters(HardDrive, &driveParam) &&
driveParam.driveno == bootdrv) driveParam.driveno == bootdrv)
{ {
foundPartitions[HardDrive] = foundPartitions[HardDrive] =
@ -1422,26 +1376,14 @@ void ReadAllPartitionTables(void)
ProcessDisk(SCAN_PRIMARY2, HardDrive, foundPartitions[HardDrive]); 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 */ /* disk initialization: returns number of units */
COUNT dsk_init() COUNT dsk_init()
{ {
if (InitKernelConfig.Verbose >= 1) printf("\nInitDisk\n"); printf(" - InitDisk");
#if defined(DEBUG) && !defined(DOSEMU) #ifdef DEBUG
{ {
iregs regs; iregs regs;
regs.a.x = 0x1112; /* select 43 line mode - more space for partinfo */ 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); STATIC void InstallVDISK(void);
#ifdef DEBUG #ifdef DEBUG
#if defined(__TURBOC__) || defined(__GNUC__) #ifdef __TURBOC__
#define int3() __int__(3); #define int3() __int__(3);
#else #else
void int3() void int3()
@ -179,7 +179,6 @@ int MoveKernelToHMA()
return FALSE; return FALSE;
XMSDriverAddress = xms_addr; XMSDriverAddress = xms_addr;
XMS_Enable_Patch = 0x90; /* must be set after XMSDriverAddress */
#ifdef DEBUG #ifdef DEBUG
/* A) for debugging purpose, suppress this, /* A) for debugging purpose, suppress this,
@ -305,7 +304,6 @@ VOID FAR * HMAalloc(COUNT bytesToAllocate)
unsigned CurrentKernelSegment = 0; unsigned CurrentKernelSegment = 0;
/* relocate segment with HMA_TEXT code group */
void MoveKernel(unsigned NewKernelSegment) void MoveKernel(unsigned NewKernelSegment)
{ {
UBYTE FAR *HMADest; UBYTE FAR *HMADest;
@ -313,11 +311,9 @@ void MoveKernel(unsigned NewKernelSegment)
unsigned len; unsigned len;
unsigned jmpseg = CurrentKernelSegment; unsigned jmpseg = CurrentKernelSegment;
/* if the first time called, initialize to end of HMA_TEXT code group segment */
if (CurrentKernelSegment == 0) if (CurrentKernelSegment == 0)
CurrentKernelSegment = FP_SEG(_HMATextEnd); CurrentKernelSegment = FP_SEG(_HMATextEnd);
/* if already relocated into HMA, nothing to do */
if (CurrentKernelSegment == 0xffff) if (CurrentKernelSegment == 0xffff)
return; return;
@ -327,8 +323,6 @@ void MoveKernel(unsigned NewKernelSegment)
len = (FP_OFF(_HMATextEnd) | 0x000f) - (FP_OFF(_HMATextStart) & 0xfff0); 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) if (NewKernelSegment == 0xffff)
{ {
HMASource += HMAOFFSET; HMASource += HMAOFFSET;
@ -358,8 +352,7 @@ void MoveKernel(unsigned NewKernelSegment)
style table style table
*/ */
struct RelocationTable FAR *rp; struct RelocationTable FAR *rp, rtemp;
struct RelocationTable rtemp;
/* verify, that all entries are valid */ /* verify, that all entries are valid */

View File

@ -31,56 +31,9 @@
%include "segs.inc" %include "segs.inc"
%include "stacks.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 segment HMA_TEXT
extern _cu_psp extern _cu_psp:wrt DGROUP
extern _HaltCpuWhileIdle extern _HaltCpuWhileIdle:wrt DGROUP
extern _syscall_MUX14 extern _syscall_MUX14
extern _DGROUP_ extern _DGROUP_
@ -122,14 +75,10 @@ WinIdle: ; only HLT if at haltlevel 2+
Int2f3: cmp ax,1680h ; Win "release time slice" Int2f3: cmp ax,1680h ; Win "release time slice"
je WinIdle je WinIdle
cmp ah,16h
je FarTabRetn ; other Win Hook return fast
cmp ah,12h cmp ah,12h
je IntDosCal ; Dos Internal calls 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 cmp ax,4a01h
je IntDosCal ; Dos Internal calls je IntDosCal ; Dos Internal calls
@ -139,9 +88,6 @@ Int2f3: cmp ax,1680h ; Win "release time slice"
cmp ax,4a33h ; Check DOS version 7 cmp ax,4a33h ; Check DOS version 7
jne Check4Share jne Check4Share
xor ax,ax ; no undocumented shell strings 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 iret
Check4Share: Check4Share:
%endif %endif
@ -156,9 +102,8 @@ Int2f?14: ;; MUX-14 -- NLSFUNC API
push bp ; Preserve BP later on push bp ; Preserve BP later on
Protect386Registers Protect386Registers
PUSH$ALL PUSH$ALL
SwitchToInt2fStack mov ds, [cs:_DGROUP_]
call _syscall_MUX14 call _syscall_MUX14
DoneInt2fStack
pop bp ; Discard incoming AX pop bp ; Discard incoming AX
push ax ; Correct stack for POP$ALL push ax ; Correct stack for POP$ALL
POP$ALL POP$ALL
@ -178,7 +123,7 @@ Int2f?iret:
; DRIVER.SYS calls - now only 0803. ; DRIVER.SYS calls - now only 0803.
DriverSysCal: DriverSysCal:
extern _Dyn extern _Dyn:wrt DGROUP
cmp al, 3 cmp al, 3
jne Int2f?iret jne Int2f?iret
mov ds, [cs:_DGROUP_] mov ds, [cs:_DGROUP_]
@ -190,7 +135,7 @@ DriverSysCal:
; internal dos calls INT2F/12xx and INT2F/4A01,4A02 - handled through C ; internal dos calls INT2F/12xx and INT2F/4A01,4A02 - handled through C
;********************************************************************** ;**********************************************************************
IntDosCal: IntDosCal:
; set up register structure ; set up register frame
;struct int2f12regs ;struct int2f12regs
;{ ;{
; [space for 386 regs] ; [space for 386 regs]
@ -220,10 +165,9 @@ IntDosCal:
%endif %endif
%endif %endif
SwitchToInt2fStack mov ds,[cs:_DGROUP_]
extern _int2F_12_handler extern _int2F_12_handler
call _int2F_12_handler call _int2F_12_handler
DoneInt2fStack
%if XCPU >= 386 %if XCPU >= 386
%ifdef WATCOM %ifdef WATCOM
@ -250,7 +194,6 @@ IntDosCal:
SHARE_CHECK: SHARE_CHECK:
mov ax, 0x1000 mov ax, 0x1000
int 0x2f int 0x2f
test ax, "US" ; Uninstallable SHARE signature
ret ret
; DOS calls this to see if it's okay to open the file. ; 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 ; error. If < 0 is returned, it is the negated error return
; code, so DOS simply negates this value and returns it in ; code, so DOS simply negates this value and returns it in
; AX. ; AX.
; STATIC int share_open_check(const char FAR * filename, ; STATIC int share_open_check(char * filename,
; /* pointer to fully qualified filename */ ; /* pointer to fully qualified filename */
; unsigned short pspseg, ; unsigned short pspseg,
; /* psp segment address of owner process */ ; /* psp segment address of owner process */
@ -268,17 +211,16 @@ SHARE_CHECK:
; int sharemode) /* SHARE_COMPAT, etc... */ ; int sharemode) /* SHARE_COMPAT, etc... */
global SHARE_OPEN_CHECK global SHARE_OPEN_CHECK
SHARE_OPEN_CHECK: SHARE_OPEN_CHECK:
push ds mov es, si ; save si
pop es ; save ds
mov di, si ; save si
pop ax ; return address 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 push ax ; return address
mov ax, 0x10a0 mov ax, 0x10a0
int 0x2f ; returns ax int 0x2f ; returns ax
mov si, di ; restore si mov si, es ; restore si
push es
pop ds ; restore ds
ret ret
; DOS calls this to record the fact that it has successfully ; DOS calls this to record the fact that it has successfully
@ -319,13 +261,12 @@ share_common:
mov bp, sp mov bp, sp
push si push si
push di push di
arg pspseg, fileno, {ofs,4}, {len,4}, allowcriter mov bx, [bp + 16] ; pspseg
mov bx, [.pspseg] ; pspseg mov cx, [bp + 14] ; fileno
mov cx, [.fileno] ; fileno mov si, [bp + 12] ; high word of ofs
mov si, [.ofs+2] ; high word of ofs mov di, [bp + 10] ; low word of ofs
mov di, [.ofs] ; low word of ofs les dx, [bp + 6] ; len
les dx, [.len] ; len or ax, [bp + 4] ; allowcriter/unlock
or ax, [.allowcriter] ; allowcriter/unlock
int 0x2f int 0x2f
pop di pop di
pop si pop si
@ -347,25 +288,6 @@ SHARE_LOCK_UNLOCK:
mov ax,0x10a4 mov ax,0x10a4
jmp short share_common 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 ; Int 2F Multipurpose Remote System Calls
; ;
; added by James Tabor jimtabor@infohwy.com ; added by James Tabor jimtabor@infohwy.com
@ -401,8 +323,10 @@ remote_lock_unlock:
global NETWORK_REDIRECTOR_MX global NETWORK_REDIRECTOR_MX
NETWORK_REDIRECTOR_MX: NETWORK_REDIRECTOR_MX:
pop bx ; ret address pop bx ; ret address
popargs ax,{es,dx},cx ; cmd (ax), seg:off s pop cx ; stack value (arg); cx in remote_rw
; stack value (arg); cx in remote_rw pop dx ; off s
pop es ; seg s
pop ax ; cmd (ax)
push bx ; ret address push bx ; ret address
call_int2f: call_int2f:
push bp push bp
@ -428,8 +352,6 @@ call_int2f:
push cx ; arg push cx ; arg
cmp al, 0ch cmp al, 0ch
je remote_getfree je remote_getfree
cmp al, 0xa3
je remote_getfree
cmp al, 1eh cmp al, 1eh
je remote_print_doredir je remote_print_doredir
cmp al, 1fh cmp al, 1fh
@ -480,7 +402,6 @@ remote_getfree:
mov [di+2],bx mov [di+2],bx
mov [di+4],cx mov [di+4],cx
mov [di+6],dx mov [di+6],dx
mov [di+8],si ; for REM_GETLARGEFREE, unused on REM_GETFREE
jmp short ret_set_ax_to_carry jmp short ret_set_ax_to_carry
remote_rw: remote_rw:
@ -510,7 +431,7 @@ int2f_restore_ds:
; extern UWORD ASMPASCAL call_nls(UWORD bp, UWORD FAR *buf, ; extern UWORD ASMPASCAL call_nls(UWORD bp, UWORD FAR *buf,
; UWORD subfct, UWORD cp, UWORD cntry, UWORD bufsize); ; UWORD subfct, UWORD cp, UWORD cntry, UWORD bufsize);
extern _nlsInfo extern _nlsInfo:wrt DGROUP
global CALL_NLS global CALL_NLS
CALL_NLS: CALL_NLS:
pop es ; ret addr pop es ; ret addr
@ -576,8 +497,7 @@ FLOPPY_CHANGE:
segment INIT_TEXT segment INIT_TEXT
; int ASMPASCAL UMB_get_largest(void FAR * driverAddress, ; int ASMPASCAL UMB_get_largest(void FAR * driverAddress,
; UCOUNT * seg, UCOUNT * size); ; UCOUNT * seg, UCOUNT * size);
arg {driverAddress,4}, argseg, size global UMB_GET_LARGEST
global UMB_GET_LARGEST
UMB_GET_LARGEST: UMB_GET_LARGEST:
push bp push bp
@ -585,7 +505,7 @@ UMB_GET_LARGEST:
mov dx,0xffff ; go for broke! mov dx,0xffff ; go for broke!
mov ax,1000h ; get the UMBs 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. ; bl = 0xB0 and ax = 0 so do it again.
@ -597,7 +517,7 @@ UMB_GET_LARGEST:
je umbt_error je umbt_error
mov ax,1000h ; dx set with largest size mov ax,1000h ; dx set with largest size
call far [.driverAddress] ; Call the driver call far [bp+8] ; Call the driver
cmp ax,1 cmp ax,1
jne umbt_error jne umbt_error
@ -605,10 +525,10 @@ UMB_GET_LARGEST:
; and the size ; and the size
mov cx,bx ; *seg = segment mov cx,bx ; *seg = segment
mov bx, [.argseg] mov bx, [bp+6]
mov [bx],cx mov [bx],cx
mov bx, [.size] ; *size = size mov bx, [bp+4] ; *size = size
mov [bx],dx mov [bx],dx
umbt_ret: umbt_ret:

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@ -29,13 +29,12 @@
; ;
%include "segs.inc" %include "segs.inc"
%include "stacks.inc"
%include "ludivmul.inc" %include "ludivmul.inc"
segment PSP segment PSP
extern _ReqPktPtr extern _ReqPktPtr:wrt LGROUP
STACK_SIZE equ 384/2 ; stack allocated in words STACK_SIZE equ 384/2 ; stack allocated in words
@ -43,11 +42,8 @@ STACK_SIZE equ 384/2 ; stack allocated in words
; KERNEL BEGINS HERE, i.e. this is byte 0 of KERNEL.SYS ; KERNEL BEGINS HERE, i.e. this is byte 0 of KERNEL.SYS
;************************************************************ ;************************************************************
%ifidn __OUTPUT_FORMAT__, obj
..start: ..start:
%endif entry:
bootloadunit: ; (byte of short jump re-used)
entry:
jmp short realentry jmp short realentry
;************************************************************ ;************************************************************
@ -57,7 +53,6 @@ entry:
;************************************************************ ;************************************************************
global _LowKernelConfig global _LowKernelConfig
_LowKernelConfig: _LowKernelConfig:
config_signature:
db 'CONFIG' ; constant db 'CONFIG' ; constant
dw configend-configstart; size of config area dw configend-configstart; size of config area
; to be checked !!! ; to be checked !!!
@ -71,29 +66,7 @@ ForceLBA db 0 ;
GlobalEnableLBAsupport db 1 ; GlobalEnableLBAsupport db 1 ;
BootHarddiskSeconds db 0 ; 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: 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 ; KERNEL CONFIGURATION AREA END
@ -110,23 +83,9 @@ bootloadstack: dd 0
; init sequence ; init sequence
;************************************************************ ;************************************************************
cpu 8086 ; (keep initial entry compatible)
global realentry
realentry: ; execution continues here 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 ax
push bx push bx
pushf pushf
@ -136,36 +95,13 @@ entry_common:
popf popf
pop bx pop bx
pop ax pop ax
%endif
push cs jmp far kernel_start
pop ds beyond_entry: resb 256-(beyond_entry-entry)
jmp IGROUP:kernel_start
beyond_entry: times 256-(beyond_entry-entry) db 0
; scratch area for data (DOS_PSP) ; scratch area for data (DOS_PSP)
_master_env equ $ - 128
global _master_env
segment INIT_TEXT 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 _FreeDOSmain
extern _query_cpu extern _query_cpu
@ -173,9 +109,7 @@ segment INIT_TEXT
; kernel start-up ; kernel start-up
; ;
kernel_start: kernel_start:
cld
%ifndef QUIET
push bx push bx
pushf pushf
mov ax, 0e32h ; '2' Tracecode - kernel entered mov ax, 0e32h ; '2' Tracecode - kernel entered
@ -183,78 +117,32 @@ kernel_start:
int 010h int 010h
popf popf
pop bx 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 cli
mov ss, dx mov ss,ax
mov sp, init_tos mov sp,init_tos
int 12h ; move init text+data to higher memory int 12h ; move init text+data to higher memory
mov cl,6 mov cl,6
shl ax,cl ; convert kb to para shl ax,cl ; convert kb to para
mov dx,15 + INITSIZE mov dx,15 + init_end wrt INIT_TEXT
mov cl,4 mov cl,4
shr dx,cl shr dx,cl
sub ax,dx sub ax,dx
mov es,ax mov es,ax
mov dx,INITTEXTSIZE ; para aligned mov dx,__INIT_DATA_START wrt INIT_TEXT ; para aligned
shr dx,cl shr dx,cl
add ax,dx add ax,dx
mov ss,ax ; set SS to init data segment mov ss,ax ; set SS to init data segment
sti ; now enable them sti ; now enable them
mov ax,cs mov ax,cs
mov dx,__HMATextEnd ; para aligned mov dx,__InitTextStart wrt HMA_TEXT ; para aligned
shr dx,cl shr dx,cl
%ifdef WATCOM %ifdef WATCOM
add ax,dx add ax,dx
%endif %endif
mov ds,ax mov ds,ax
mov si,-2 + INITSIZE; word aligned mov si,-2 + init_end wrt INIT_TEXT ; word aligned
lea cx,[si+2] lea cx,[si+2]
mov di,si mov di,si
shr cx,1 shr cx,1
@ -268,7 +156,7 @@ initialise_command_line_buffer:
sub ax,dx sub ax,dx
mov es,ax ; es = new HMA_TEXT mov es,ax ; es = new HMA_TEXT
mov si,-2 + __HMATextEnd mov si,-2 + __InitTextStart wrt HMA_TEXT
lea cx,[si+2] lea cx,[si+2]
mov di,si mov di,si
shr cx,1 shr cx,1
@ -287,7 +175,6 @@ cont: ; Now set up call frame
mov ds,[cs:_INIT_DGROUP] mov ds,[cs:_INIT_DGROUP]
mov bp,sp ; and set up stack frame for c mov bp,sp ; and set up stack frame for c
%ifndef QUIET
push bx push bx
pushf pushf
mov ax, 0e33h ; '3' Tracecode - kernel entered mov ax, 0e33h ; '3' Tracecode - kernel entered
@ -295,7 +182,6 @@ cont: ; Now set up call frame
int 010h int 010h
popf popf
pop bx pop bx
%endif
mov byte [_BootDrive],bl ; tell where we came from mov byte [_BootDrive],bl ; tell where we came from
@ -306,110 +192,13 @@ cont: ; Now set up call frame
;!! mov byte [_NumFloppies],al ; and how many ;!! mov byte [_NumFloppies],al ; and how many
call _query_cpu call _query_cpu
%if XCPU != 86 mov byte [_CPULevel],al
%if XCPU < 186 || (XCPU % 100) != 86 || (XCPU / 100) > 9 ; TODO display error if built for 386 running on 8086 etc
%fatal Unknown CPU level defined
%endif mov ax,ss
cmp al, (XCPU / 100) mov ds,ax
jb cpu_abort ; if CPU not supported --> mov es,ax
jmp _FreeDOSmain
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
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 segment INIT_TEXT_END
@ -426,9 +215,10 @@ segment CONST
; NUL device strategy ; NUL device strategy
; ;
global _nul_strtgy global _nul_strtgy
extern GenStrategy
_nul_strtgy: _nul_strtgy:
jmp LGROUP:GenStrategy mov word [cs:_ReqPktPtr],bx ;save rq headr
mov word [cs:_ReqPktPtr+2],es
retf
; ;
; NUL device interrupt ; NUL device interrupt
@ -437,9 +227,7 @@ _nul_strtgy:
_nul_intr: _nul_intr:
push es push es
push bx push bx
mov bx,LGROUP les bx,[cs:_ReqPktPtr] ;es:bx--> rqheadr
mov es,bx
les bx,[es:_ReqPktPtr] ;es:bx--> rqheadr
cmp byte [es:bx+2],4 ;if read, set 0 read cmp byte [es:bx+2],4 ;if read, set 0 read
jne no_nul_read jne no_nul_read
mov word [es:bx+12h],0 mov word [es:bx+12h],0
@ -456,22 +244,14 @@ segment _LOWTEXT
global _intvec_table global _intvec_table
_intvec_table: db 10h _intvec_table: db 10h
dd 0 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 db 13h
_BIOSInt13: dd 0 dd 0
db 15h db 15h
dd 0 dd 0
; used for cleanup on reboot
global _BIOSInt19
db 19h db 19h
_BIOSInt19: dd 0 dd 0
db 1Bh db 1Bh
dd 0 dd 0
; default to using BIOS provided disk handler
db 13h
_UserInt13: dd 0
; floppy parameter table ; floppy parameter table
global _int1e_table global _int1e_table
@ -519,13 +299,13 @@ _first_mcb dw 0 ;-0002 Start of user memory
global MARK0026H global MARK0026H
; A reference seems to indicate that this should start at offset 26h. ; A reference seems to indicate that this should start at offset 26h.
MARK0026H equ $ MARK0026H equ $
_DPBp dd -1 ; 0000 First drive Parameter Block _DPBp dd 0 ; 0000 First drive Parameter Block
global _sfthead global _sfthead
_sfthead dd 0 ; 0004 System File Table head _sfthead dd 0 ; 0004 System File Table head
global _clock global _clock
_clock dd 0 ; 0008 CLOCK$ device _clock dd 0 ; 0008 CLOCK$ device
global _syscon global _syscon
_syscon dw _con_dev,LGROUP ; 000c console device _syscon dw _con_dev,seg _con_dev ; 000c console device
global _maxsecsize global _maxsecsize
_maxsecsize dw 512 ; 0010 maximum bytes/sector of any block device _maxsecsize dw 512 ; 0010 maximum bytes/sector of any block device
dd 0 ; 0012 pointer to buffers info structure 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 _lastdrive db 0 ; 0021 value of last drive
global _nul_dev global _nul_dev
_nul_dev: ; 0022 device chain root _nul_dev: ; 0022 device chain root
extern _con_dev extern _con_dev:wrt LGROUP
dw _con_dev, LGROUP dw _con_dev, seg _con_dev
; next is con_dev at init time. ; next is con_dev at init time.
dw 8004h ; attributes = char device, NUL bit set dw 8004h ; attributes = char device, NUL bit set
dw _nul_strtgy dw _nul_strtgy
@ -550,9 +330,8 @@ _nul_dev: ; 0022 device chain root
db 'NUL ' db 'NUL '
global _njoined global _njoined
_njoined db 0 ; 0034 number of joined devices _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] dw 0 ; 0035 DOS 4 pointer to special names (always zero in DOS 5)
global _setverPtr setverPtr dw 0,0 ; 0037 setver list
_setverPtr dw 0,0 ; 0037 setver list (far pointer, set by setver driver)
dw 0 ; 003B cs offset for fix a20 dw 0 ; 003B cs offset for fix a20
dw 0 ; 003D psp of last umb exec dw 0 ; 003D psp of last umb exec
global _LoL_nbuffers global _LoL_nbuffers
@ -621,26 +400,13 @@ _winStartupInfo:
dd 0 ; next startup info structure, 0:0h marks end 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 to name virtual device file or 0:0h
dd 0 ; far pointer, reference data for virtual device driver dd 0 ; far pointer, reference data for virtual device driver
%ifnidni __OUTPUT_FORMAT__, elf
dw instance_table,seg instance_table ; array of instance data 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 instance_table: ; should include stacks, Win may auto determine SDA region
; we simply include whole DOS data segment ; we simply include whole DOS data segment
%ifnidni __OUTPUT_FORMAT__, elf dw 0, seg _DATASTART ; [SEG:OFF] address of region's base
dw seg _DATASTART, 0 ; [SEG:OFF] address of region's base dw markEndInstanceData wrt seg _DATASTART ; size in bytes
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
dd 0 ; 0 marks end of table 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 dw 0 ; and 0 length for end of instance_table entry
global _winPatchTable global _winPatchTable
_winPatchTable: ; returns offsets to various internal variables _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 save_BX ; where BX stored during int21h dispatch
dw _InDOS ; offset of InDOS flag dw _InDOS ; offset of InDOS flag
dw _MachineId ; offset to variable containing MachineID 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 ; NOTE: this points to a null terminated
; array of offsets of critical section bytes ; array of offsets of critical section bytes
; to patch, for now we can just point this ; to patch, for now we just point this to
; to an empty table ; an empty table, purposely not _CritPatch
; ie we just point to a 0 word to mark end ; ie we just point to a 0 word to mark end
dw _uppermem_root ; seg of last arena header in conv memory dw _uppermem_root ; seg of last arena header in conv memory
; this matches MS DOS's location, but ; this matches MS DOS's location, but
@ -666,9 +432,7 @@ _winPatchTable: ; returns offsets to various internal variables
_firstsftt: _firstsftt:
dd -1 ; link to next dd -1 ; link to next
dw 5 ; count 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 ; Some references seem to indicate that this data should start at 01fbh in
; order to maintain 100% MS-DOS compatibility. ; order to maintain 100% MS-DOS compatibility.
times (01fbh - ($ - DATASTART)) db 0 times (01fbh - ($ - DATASTART)) db 0
@ -735,15 +499,13 @@ _net_name db ' ' ;-27 - 15 Character Network Name
global _return_code global _return_code
global _internal_data global _internal_data
; ensure offset of critical patch table remains fixed, some programs hard code offset
times (0315h - ($ - DATASTART)) db 0
global _CritPatch global _CritPatch
_CritPatch dw 0 ;-11 zero list of patched critical _CritPatch dw 0d0ch ;-11 zero list of patched critical
dw 0 ; section variables dw 0d0ch ; section variables
dw 0 ; DOS puts 0d0ch here but some dw 0d0ch
dw 0 ; progs really write to that addr. dw 0d0ch
dw 0 ;-03 - critical patch list terminator dw 0d0ch
db 90h ;-01 - unused, NOP pad byte db 0 ;-01 - unknown
_internal_data: ; <-- Address returned by INT21/5D06 _internal_data: ; <-- Address returned by INT21/5D06
_ErrorMode db 0 ; 00 - Critical Error Flag _ErrorMode db 0 ; 00 - Critical Error Flag
_InDOS db 0 ; 01 - Indos Flag _InDOS db 0 ; 01 - Indos Flag
@ -974,11 +736,6 @@ blk_stk_top:
times 128 dw 0 times 128 dw 0
clk_stk_top: clk_stk_top:
; int2fh private stack
global int2f_stk_top
times 128 dw 0
int2f_stk_top:
; Dynamic data: ; Dynamic data:
; member of the DOS DATA GROUP ; member of the DOS DATA GROUP
; and marks definitive end of all used data in kernel data segment ; and marks definitive end of all used data in kernel data segment
@ -1003,8 +760,7 @@ segment DYN_DATA
_Dyn: _Dyn:
DynAllocated dw 0 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 segment ID_B
@ -1056,32 +812,9 @@ __U4D:
LDIVMODU LDIVMODU
%endif %endif
%ifdef gcc resb 0xd0 - ($-begin_hma)
%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
; reserve space for far jump to cp/m routine ; reserve space for far jump to cp/m routine
times 5 db 0 resb 5
;End of HMA segment ;End of HMA segment
segment HMA_TEXT_END 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 ; The default stack (_TEXT:0) will overwrite the data area, so I create a dummy
; stack here to ease debugging. -- ror4 ; 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. ; will be only ever called, if HMA (DOS=HIGH) is enabled.
; for obvious reasons it should be located at the relocation table ; for obvious reasons it should be located at the relocation table
; ;
global _XMSDriverAddress
_XMSDriverAddress:
dw 0 ; XMS driver, if detected
dw 0
global _ENABLEA20 global _ENABLEA20
_ENABLEA20: _ENABLEA20:
mov ah,5 mov ah,5
UsingXMSdriver: UsingXMSdriver:
global _XMS_Enable_Patch
_XMS_Enable_Patch: ; SMC: patch to nop (90h) to enable use of XMS
retf
push bx push bx
call 0:0 ; (immediate far address patched) call far [cs:_XMSDriverAddress]
global _XMSDriverAddress
_XMSDriverAddress: equ $ - 4 ; XMS driver, if detected
pop bx pop bx
retf retf
@ -1230,6 +960,8 @@ _DISABLEA20:
mov ah,6 mov ah,6
jmp short UsingXMSdriver jmp short UsingXMSdriver
dslowmem dw 0
eshighmem dw 0ffffh
global forceEnableA20 global forceEnableA20
forceEnableA20: forceEnableA20:
@ -1237,55 +969,67 @@ forceEnableA20:
push ds push ds
push es push es
push ax push ax
push si
push di forceEnableA20retry:
push cx mov ds, [cs:dslowmem]
pushf mov es, [cs:eshighmem]
cld
mov ax, [ds:00000h]
cmp ax, [es:00010h]
jne forceEnableA20success
.retry: mov ax, [ds:00002h]
xor si, si ; = 0000h cmp ax, [es:00012h]
mov ds, si ; => low memory (IVT) jne forceEnableA20success
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
.success: mov ax, [ds:00004h]
popf cmp ax, [es:00014h]
pop cx jne forceEnableA20success
pop di
pop si 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 ax
pop es pop es
pop ds pop ds
retn ret
.enable: ;
; ok, we have to enable A20 (at least seems so)
push cs ; make far call stack frame
call _ENABLEA20
jmp short .retry
; global f*cking compatibility issues: ; global f*cking compatibility issues:
; ;
; very old brain dead software (PKLITE, copyright 1990) ; very old brain dead software (PKLITE, copyright 1990)
; forces us to execute with A20 disabled ; forces us to execute with A20 disabled
; ;
global _ExecUserDisableA20 global _ExecUserDisableA20
_ExecUserDisableA20: _ExecUserDisableA20:
push ax
push cs ; make far call stack frame cmp word [cs:_XMSDriverAddress], byte 0
call _DISABLEA20 ; (no-op if not in HMA, patched otherwise) jne NeedToDisable
cmp word [cs:_XMSDriverAddress+2], byte 0
je noNeedToDisable
NeedToDisable:
push ax
call far _DISABLEA20
pop ax pop ax
iret noNeedToDisable:
iret
;
; Default Int 24h handler -- always returns fail ; Default Int 24h handler -- always returns fail
; so we have not to relocate it (now) ; so we have not to relocate it (now)
; ;
@ -1306,7 +1050,3 @@ _TEXT_DGROUP dw DGROUP
segment INIT_TEXT segment INIT_TEXT
global _INIT_DGROUP global _INIT_DGROUP
_INIT_DGROUP dw 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. * Return value.
* SUCCESS, LHE_INVLDHNDL * 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); f_node_ptr fnp = xlt_fd(handle);
if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL; if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL;

View File

@ -51,25 +51,16 @@
; destroys: ; destroys:
; flags ; 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 ? test cx, cx ; divisor > 2^32-1 ?
jnz %%big_divisor ; yes, divisor > 2^16-1 jnz %%big_divisor ; yes, divisor > 32^32-1
cmp dx, bx ; only one division needed ? (cx = 0) cmp dx, bx ; only one division needed ? (ecx = 0)
jb %%one_div ; yes, one division sufficient jb %%one_div ; yes, one division sufficient
xchg cx, ax ; save dividend-lo in cx, ax=0 xchg cx, ax ; save dividend-lo in cx, ax=0
xchg ax, dx ; get dividend-hi in ax, dx=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 xchg ax, cx ; cx = quotient-hi, ax =dividend-lo
%%one_div: %%one_div:
@ -85,57 +76,37 @@
push dx ; save push dx ; save
push ax ; dividend push ax ; dividend
mov si, bx ; divisor now in mov si, bx ; divisor now in
mov di, cx ; di:si and cx:bx mov di, cx ; di:bx and cx:si
%%shift_loop: %%shift_loop:
shr dx, 1 ; shift both shr dx, 1 ; shift both
rcr ax, 1 ; dividend rcr ax, 1 ; divisor and
shr cx, 1 ; and divisor shr di, 1 ; and dividend
rcr bx, 1 ; right by 1 bit rcr bx, 1 ; right by 1 bit
jnz %%shift_loop ; loop if di non-zero (rcr does not touch ZF) 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 pop bx ; get dividend lo-word
mov cx, ax ; save quotient mov cx, ax ; save quotient
mul di ; quotient * divisor hi-word (low only) mul di ; quotient * divisor hi-word (low only)
pop dx ; dividend high push di ; save divisor hi-word
sub dx,ax ; dividend high - divisor high * quotient, no overflow (carry/borrow) possible here xchg ax, di ; save in di
push dx ; save dividend high
mov ax, cx ; ax=quotient mov ax, cx ; ax=quotient
mul si ; quotient * divisor lo-word 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 mov ax, cx ; get quotient
pop cx ; restore dividend hi-word 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 sbb dx, dx ; 0 if remainder > 0, else FFFFFFFFh
and si, dx ; nothing to add and si, dx ; nothing to add
and di, dx ; back if remainder positive di:si := di:si(cx:bx) & dx:dx and di, dx ; back if remainder positive
add bx, si ; correct remainder cx:bx += di:si add bx, si ; correct remaider
adc cx, di ; and adc cx, di ; and quotient if
add ax, dx ; quotient if necessary ax += dx add ax, dx ; necessary
xor dx, dx ; clear hi-word of quot (ax<=FFFFh) dx := 0 xor dx, dx ; clear hi-word of quot (ax<=FFFFFFFFh)
pop di ; restore temp pop di ; restore temp
pop si ; variables pop si ; variables
ret ret
%endmacro %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 #endif
static char copyright[] = 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" "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" "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" "GNU General Public License as published by the Free Software Foundation;\n"
"either version 2, or (at your option) any later version.\n"; "either version 2, or (at your option) any later version.\n";
struct _KernelConfig InitKernelConfig BSS_INIT({0});
STATIC VOID InitIO(void); STATIC VOID InitIO(void);
STATIC VOID update_dcb(struct dhdr FAR *); STATIC VOID update_dcb(struct dhdr FAR *);
@ -68,18 +70,10 @@ __segment DosTextSeg = 0;
struct lol FAR *LoL = &DATASTART; 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) VOID ASMCFUNC FreeDOSmain(void)
{ {
unsigned char drv; unsigned char drv;
unsigned char FAR *p; unsigned char FAR *p;
char * pp;
#ifdef _MSC_VER #ifdef _MSC_VER
extern FAR prn_dev; extern FAR prn_dev;
@ -98,8 +92,17 @@ VOID ASMCFUNC FreeDOSmain(void)
drv = LoL->BootDrive + 1; drv = LoL->BootDrive + 1;
p = MK_FP(0, 0x5e0); 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) if (drv >= 0x80)
@ -109,23 +112,6 @@ VOID ASMCFUNC FreeDOSmain(void)
/* install DOS API and other interrupt service routines, basic kernel functionality works */ /* install DOS API and other interrupt service routines, basic kernel functionality works */
setup_int_vectors(); 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(); CheckContinueBootFromHarddisk();
/* display copyright info and kernel emulation status */ /* display copyright info and kernel emulation status */
@ -172,7 +158,6 @@ STATIC void PSPInit(void)
/* Clear out new psp first */ /* Clear out new psp first */
fmemset(p, 0, sizeof(psp)); fmemset(p, 0, sizeof(psp));
/* high half is used as environment */
/* initialize all entries and exits */ /* initialize all entries and exits */
/* CP/M-like exit point */ /* CP/M-like exit point */
@ -215,9 +200,6 @@ STATIC void PSPInit(void)
/* open file table pointer */ /* open file table pointer */
p->ps_filetab = p->ps_files; 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 */ /* first command line argument */
/* p->ps_fcb1.fcb_drive = 0; already set */ /* p->ps_fcb1.fcb_drive = 0; already set */
fmemset(p->ps_fcb1.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE); 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 */ /* p->ps_fcb2.fcb_drive = 0; already set */
fmemset(p->ps_fcb2.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE); 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__ #ifndef __WATCOMC__
@ -256,41 +240,37 @@ STATIC void setup_int_vectors(void)
} vectors[] = } vectors[] =
{ {
/* all of these are in the DOS DS */ /* all of these are in the DOS DS */
{ 0x80 | 0x0, FP_OFF(int0_handler) }, /* zero divide */ { 0x0, FP_OFF(int0_handler) }, /* zero divide */
{ 0x80 | 0x1, FP_OFF(empty_handler) }, /* single step */ { 0x1, FP_OFF(empty_handler) }, /* single step */
{ 0x80 | 0x3, FP_OFF(empty_handler) }, /* debug breakpoint */ { 0x3, FP_OFF(empty_handler) }, /* debug breakpoint */
{ 0x80 | 0x6, FP_OFF(int6_handler) }, /* invalid opcode */ { 0x6, FP_OFF(int6_handler) }, /* invalid opcode */
{ 0x19, FP_OFF(int19_handler) }, /* BIOS bootstrap loader, vdisk */ { 0x19, FP_OFF(int19_handler) },
{ 0x20, FP_OFF(int20_handler) }, { 0x20, FP_OFF(int20_handler) },
{ 0x21, FP_OFF(int21_handler) }, /* primary DOS API */ { 0x21, FP_OFF(int21_handler) },
{ 0x22, FP_OFF(int22_handler) }, { 0x22, FP_OFF(int22_handler) },
{ 0x24, FP_OFF(int24_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) }, { 0x26, FP_OFF(low_int26_handler) },
{ 0x27, FP_OFF(int27_handler) }, { 0x27, FP_OFF(int27_handler) },
{ 0x28, FP_OFF(int28_handler) }, { 0x28, FP_OFF(int28_handler) },
{ 0x2a, FP_OFF(int2a_handler) }, { 0x2a, FP_OFF(int2a_handler) },
{ 0x2f, FP_OFF(int2f_handler) } /* multiplex int */ { 0x2f, FP_OFF(int2f_handler) }
}; };
struct vec *pvec; struct vec *pvec;
struct lowvec FAR *plvec; struct lowvec FAR *plvec;
int i; int i;
/* save current int vectors so can restore on reboot and call original directly */ for (plvec = intvec_table; plvec < intvec_table + 5; plvec++)
for (plvec = intvec_table; plvec < intvec_table + 6; plvec++)
plvec->isv = getvec(plvec->intno); plvec->isv = getvec(plvec->intno);
/* install default handlers */
for (i = 0x23; i <= 0x3f; i++) for (i = 0x23; i <= 0x3f; i++)
setvec(i, empty_handler); /* note: int 31h segment should be DOS DS */ setvec(i, empty_handler);
HaltCpuWhileIdle = 0; HaltCpuWhileIdle = 0;
for (pvec = vectors; pvec < vectors + (sizeof vectors/sizeof *pvec); pvec++) for (pvec = vectors; pvec < vectors + (sizeof vectors/sizeof *pvec); pvec++)
if ((pvec->intno & 0x80) == 0 || debugger_present == 0) setvec(pvec->intno, (intvec)MK_FP(FP_SEG(empty_handler), pvec->handleroff));
setvec(pvec->intno & 0x7F, (intvec)MK_FP(FP_SEG(empty_handler), pvec->handleroff));
pokeb(0, 0x30 * 4, 0xea); pokeb(0, 0x30 * 4, 0xea);
pokel(0, 0x30 * 4 + 1, (ULONG)cpm_entry); 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(0x1b, got_cbreak);
setvec(0x29, int29_handler); /* required for printf! */ setvec(0x29, int29_handler); /* required for printf! */
} }
@ -305,14 +285,7 @@ STATIC void init_kernel(void)
/* Init oem hook - returns memory size in KB */ /* Init oem hook - returns memory size in KB */
ram_top = init_oem(); ram_top = init_oem();
/* Note: HMA_TEXT and init code already moved higher in /* move kernel to high conventional RAM, just below the init code */
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
*/
#ifdef __WATCOMC__ #ifdef __WATCOMC__
lpTop = MK_FP(_CS, 0); lpTop = MK_FP(_CS, 0);
#else #else
@ -437,17 +410,6 @@ STATIC VOID FsConfig(VOID)
STATIC VOID signon() 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" printf("\r%S"
"Kernel compatibility %d.%d - " "Kernel compatibility %d.%d - "
#if defined(__BORLANDC__) #if defined(__BORLANDC__)
@ -468,8 +430,6 @@ STATIC VOID signon()
" - 80386 CPU required" " - 80386 CPU required"
#elif defined (I186) #elif defined (I186)
" - 80186 CPU required" " - 80186 CPU required"
#else
" - 808x compatible"
#endif #endif
#ifdef WITHFAT32 #ifdef WITHFAT32
@ -478,8 +438,6 @@ STATIC VOID signon()
"\n\n%s", "\n\n%s",
MK_FP(FP_SEG(LoL), FP_OFF(LoL->os_release)), MK_FP(FP_SEG(LoL), FP_OFF(LoL->os_release)),
MAJOR_RELEASE, MINOR_RELEASE, copyright); MAJOR_RELEASE, MINOR_RELEASE, copyright);
#endif
}
} }
STATIC void kernel() STATIC void kernel()
@ -487,7 +445,8 @@ STATIC void kernel()
CommandTail Cmd; CommandTail Cmd;
if (master_env[0] == '\0') /* some shells panic on empty master env. */ 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 */ /* process 0 */
/* Execute command.com from the drive we just booted from */ /* 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]; COUNT nunits = dhp->dh_name[0];
struct dpb FAR *dpb; 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) if (LoL->nblkdev == 0)
{ dpb = LoL->DPBp;
/* update root pointer to new end (our just allocated block) */
LoL->DPBp = dpb;
}
else else
{ {
struct dpb FAR *tmp_dpb; for (dpb = LoL->DPBp; (ULONG) dpb->dpb_next != 0xffffffffl;
/* find current end of dpb chain by following next pointers to end */ dpb = dpb->dpb_next)
for (tmp_dpb = LoL->DPBp; (ULONG) tmp_dpb->dpb_next != 0xffffffffl; tmp_dpb = dpb->dpb_next)
; ;
/* insert into chain [at end] */ dpb = dpb->dpb_next =
tmp_dpb->dpb_next = dpb; KernelAlloc(nunits * sizeof(struct dpb), 'E', Config.cfgDosDataUmb);
} }
/* dpb points to last block, one just allocated */
for (Index = 0; Index < nunits; Index++) for (Index = 0; Index < nunits; Index++)
{ {
/* printf("processing unit %i of %i nunits\n", Index, nunits); */ dpb->dpb_next = dpb + 1;
dpb->dpb_next = dpb + 1; /* memory allocated as array, so next is just next element */
dpb->dpb_unit = LoL->nblkdev; dpb->dpb_unit = LoL->nblkdev;
dpb->dpb_subunit = Index; dpb->dpb_subunit = Index;
dpb->dpb_device = dhp; 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].cdsDpb = dpb;
LoL->CDSp[LoL->nblkdev].cdsFlags = CDSPHYSDRV; LoL->CDSp[LoL->nblkdev].cdsFlags = CDSPHYSDRV;
} }
++dpb;
++dpb; /* dbp = dbp->dpb_next; */
++LoL->nblkdev; ++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; (dpb - 1)->dpb_next = (void FAR *)0xFFFFFFFFl;
/* printf("processed %i nunits\n", nunits); */
} }
/* If cmdLine is NULL, this is an internal driver */ /* If cmdLine is NULL, this is an internal driver */
@ -840,12 +775,8 @@ STATIC void CheckContinueBootFromHarddisk(void)
init_call_intr(0x13, &r); init_call_intr(0x13, &r);
{ {
#if __GNUC__
asm volatile("jmp $0,$0x7c00");
#else
void (far *reboot)(void) = (void (far*)(void)) MK_FP(0x0,0x7c00); void (far *reboot)(void) = (void (far*)(void)) MK_FP(0x0,0x7c00);
(*reboot)(); (*reboot)();
#endif
} }
} }

View File

@ -21,46 +21,39 @@ OBJS4=break.obj dosfns.obj fatdir.obj fatfs.obj fattab.obj fcbfns.obj \
inthndlr.obj inthndlr.obj
OBJS5=ioctl.obj memmgr.obj task.obj newstuff.obj nls.obj network.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 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 OBJS7=main.obj config.obj initoem.obj inithma.obj dyninit.obj iprf.obj \
OBJS8=initdisk.obj initclk.obj cpu.obj initdisk.obj initclk.obj cpu.obj
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS6) $(OBJS7) $(OBJS8) OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS6) $(OBJS7)
# *Explicit Rules* # *Explicit Rules*
production: ../bin/$(TARGET).sys production: ../bin/$(TARGET).sys ../bin/country.sys
../bin/$(TARGET).sys: kernel.sys ../bin/$(TARGET).sys: kernel.sys
$(CP) kernel.sys ..$(DIRSEP)bin $(CP) kernel.sys ..$(DIRSEP)bin
$(CP) kernel.sys ..$(DIRSEP)bin$(DIRSEP)$(TARGET).sys $(CP) kernel.sys ..$(DIRSEP)bin$(DIRSEP)$(TARGET).sys
$(CP) kernel.map ..$(DIRSEP)bin$(DIRSEP)$(TARGET).map $(CP) kernel.map ..$(DIRSEP)bin$(DIRSEP)$(TARGET).map
kernel.sys: kernel.exe ../utils/exeflat.exe ../utils/upxentry.bin ../utils/upxdevic.bin exeflat.rsp # -S to avoid showing expected relocations
..$(DIRSEP)utils$(DIRSEP)exeflat.exe kernel.exe kernel.sys $(LOADSEG) @exeflat.rsp # 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) kernel.exe: $(TARGET).lnk $(OBJS) $(LIBS)
$(LINK) @$(TARGET).lnk; $(LINK) @$(TARGET).lnk;
../bin/country.sys: country.asm
$(NASM) -o $*.sys country.asm
clobber: clean clobber: clean
-$(RM) kernel.exe kernel.sys status.me -$(RM) kernel.exe kernel.sys status.me
clean: 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 # XXX: This is a very ugly way of linking the kernel, forced upon us by the
# inability of Turbo `make' 2.0 to perform command line redirection. -- ror4 # inability of Turbo `make' 2.0 to perform command line redirection. -- ror4
# -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 $(TARGET).lnk: turboc.cfg makefile ../mkfiles/generic.mak ../mkfiles/$(COMPILER).mak
-$(RM) *.lnk -$(RM) *.lnk
$(ECHOTO) $(TARGET).lnk $(OBJS1)+ $(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 $(OBJS4)+
$(ECHOTO) $(TARGET).lnk $(OBJS5)+ $(ECHOTO) $(TARGET).lnk $(OBJS5)+
$(ECHOTO) $(TARGET).lnk $(OBJS6)+ $(ECHOTO) $(TARGET).lnk $(OBJS6)+
$(ECHOTO) $(TARGET).lnk $(OBJS7)+ $(ECHOTO) $(TARGET).lnk $(OBJS7)
$(ECHOTO) $(TARGET).lnk $(OBJS8)
$(ECHOTO) $(TARGET).lnk kernel.exe $(ECHOTO) $(TARGET).lnk kernel.exe
$(ECHOTO) $(TARGET).lnk kernel.map $(ECHOTO) $(TARGET).lnk kernel.map
$(ECHOTO) $(TARGET).lnk $(LIBS) $(ECHOTO) $(TARGET).lnk $(LIBS)
@ -97,7 +89,7 @@ serial.obj: serial.asm io.inc $(TARGET).lnk
HDRS=\ HDRS=\
$(HDR)portab.h $(HDR)device.h $(HDR)mcb.h $(HDR)pcb.h \ $(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)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)dirmatch.h $(HDR)file.h $(HDR)clock.h $(HDR)kbd.h $(HDR)error.h \
$(HDR)version.h dyndata.h $(HDR)version.h dyndata.h
@ -165,7 +157,7 @@ initclk.obj: initclk.c $(INITHEADERS) $(TARGET).lnk
#the string functions for INIT_TEXT #the string functions for INIT_TEXT
iasmsupt.obj: asmsupt.asm $(TARGET).lnk 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 #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 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) COUNT DosMemChange(UWORD para, UWORD size, UWORD * maxSize)
{ {
REG mcb FAR *p; mcb FAR * q; REG mcb FAR *p, FAR * q;
/* Initialize */ /* Initialize */
p = para2far(para - 1); /* pointer to MCB */ p = para2far(para - 1); /* pointer to MCB */

View File

@ -185,10 +185,7 @@ long DosMkTmp(BYTE FAR * pathname, UWORD attr)
*/ */
#define PATH_ERROR() \ #define PATH_ERROR goto errRet
fstrchr(src, '/') == 0 && fstrchr(src, '\\') == 0 \
? DE_FILENOTFND \
: DE_PATHNOTFND
#define PATHLEN 128 #define PATHLEN 128
@ -252,7 +249,7 @@ STATIC const char _DirChars[] = "\"[]:|<>+=;,";
#define addChar(c) \ #define addChar(c) \
{ \ { \
if (p >= dest + SFTMAX) return PATH_ERROR(); /* path too long */ \ if (p >= dest + SFTMAX) PATH_ERROR; /* path too long */ \
*p++ = c; \ *p++ = c; \
} }
@ -302,69 +299,9 @@ COUNT truename(const char FAR * src, char * dest, COUNT mode)
else else
result = default_drive; result = default_drive;
dhp = IsDevice(src);
cdsEntry = get_cds(result); cdsEntry = get_cds(result);
if (cdsEntry == NULL) if (cdsEntry == NULL)
{ return DE_PATHNOTFND;
/* 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)); fmemcpy(&TempCDS, cdsEntry, sizeof(TempCDS));
tn_printf(("CDS entry: #%u @%p (%u) '%s'\n", result, cdsEntry, tn_printf(("CDS entry: #%u @%p (%u) '%s'\n", result, cdsEntry,
@ -375,6 +312,7 @@ invalid_path:
if (TempCDS.cdsFlags & CDSNETWDRV) if (TempCDS.cdsFlags & CDSNETWDRV)
result |= IS_NETWORK; result |= IS_NETWORK;
dhp = IsDevice(src); /* returns header if -char- device */
if (dhp) if (dhp)
result |= IS_DEVICE; result |= IS_DEVICE;
@ -529,18 +467,14 @@ invalid_path:
if(*src == '.') if(*src == '.')
{ {
int dots = 1;
/* special directory component */ /* special directory component */
++src; ++src;
if (*src == '.') /* skip the second dot */ if (*src == '.') /* skip the second dot */
{
++src; ++src;
dots++;
}
if (*src == '/' || *src == '\\' || *src == '\0') if (*src == '/' || *src == '\\' || *src == '\0')
{ {
--p; /* backup the backslash */ --p; /* backup the backslash */
if (dots == 2) if (src[-2] == '.')
{ {
/* ".." entry */ /* ".." entry */
/* remove last path component */ /* remove last path component */
@ -552,9 +486,12 @@ invalid_path:
} }
/* ill-formed .* or ..* entries => return error */ /* ill-formed .* or ..* entries => return error */
errRet:
/* The error is either PATHNOTFND or FILENOTFND /* The error is either PATHNOTFND or FILENOTFND
depending on if it is not the last component */ 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 */ /* normal component */
@ -587,7 +524,7 @@ invalid_path:
if (c == '.') if (c == '.')
{ {
if (state & PNE_DOT) /* multiple dots are ill-formed */ if (state & PNE_DOT) /* multiple dots are ill-formed */
return PATH_ERROR(); PATH_ERROR;
/* strip trailing dot */ /* strip trailing dot */
if (*src == '/' || *src == '\\' || *src == '\0') if (*src == '/' || *src == '\\' || *src == '\0')
break; break;
@ -599,7 +536,7 @@ invalid_path:
state |= PNE_WILDCARD; state |= PNE_WILDCARD;
if (i) { /* name length in limits */ if (i) { /* name length in limits */
--i; --i;
if (!DirChar(c)) return PATH_ERROR(); if (!DirChar(c)) PATH_ERROR;
addChar(c); addChar(c);
} }
} }
@ -712,7 +649,7 @@ if exist report.out del report.out
cmdspy stop cmdspy stop
cmdspy flush cmdspy flush
cmdspy restart 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 stop
cmdspy report report.out cmdspy report report.out
more report.out more report.out
@ -732,11 +669,11 @@ more report.out
1123: IN: C:\TOOL\INT.COM [FAIL 0001] 1123: IN: C:\TOOL\INT.COM [FAIL 0001]
1123: OUT: C:\INTRSPY\SPY_INT.OUT 1123: OUT: C:\INTRSPY\SPY_INT.OUT
1123: orig buffer: C:\TOOL\INT.COM 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: 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: 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: orig buffer: C:\INTRSPY\SPY_INT.BAT
1123: IN: cmdspy.??? [FAIL 0001] 1123: IN: cmdspy.??? [FAIL 0001]
1123: OUT: C:\INTRSPY 1123: OUT: C:\INTRSPY
@ -758,7 +695,7 @@ DOSERR: 0000 (0)
*<es:di:128> { *<es:di:128> {
43(C) 3A(:) 5C(\) 49(I) 4E(N) 54(T) 52(R) 53(S) 50(P) 59(Y) 5C(\) 41(A) 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) 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) 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(() 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 "portab.h"
#include "globals.h" #include "globals.h"
#include "pcb.h" #include "pcb.h"
#include "nls.h" #include <nls.h>
#ifdef VERSION_STRINGS #ifdef VERSION_STRINGS
static BYTE *RcsId = static BYTE *RcsId =
@ -66,13 +66,8 @@ struct nlsInfoBlock ASM nlsInfo = {
#ifdef NLS_REORDER_POINTERS #ifdef NLS_REORDER_POINTERS
| NLS_CODE_REORDER_POINTERS | NLS_CODE_REORDER_POINTERS
#endif #endif
#ifdef __GNUC__
, {.seg=DosDataSeg, .off=&nlsPackageHardcoded} /* hardcoded first package */
, {.seg=DosDataSeg, .off=&nlsPackageHardcoded} /* first item in chain */
#else
, &nlsPackageHardcoded /* hardcoded first package */ , &nlsPackageHardcoded /* hardcoded first package */
, &nlsPackageHardcoded /* first item in chain */ , &nlsPackageHardcoded /* first item in chain */
#endif
}; };
/* getTableX return the pointer to the X'th table; X==subfct */ /* getTableX return the pointer to the X'th table; X==subfct */
@ -98,9 +93,6 @@ struct nlsInfoBlock ASM nlsInfo = {
***** MUX calling functions **************************************** ***** 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); extern long ASMPASCAL call_nls(UWORD, VOID FAR *, UWORD, UWORD, UWORD, UWORD);
/*== DS:SI _always_ points to global NLS info structure <-> no /*== DS:SI _always_ points to global NLS info structure <-> no
* subfct can use these registers for anything different. ==ska*/ * subfct can use these registers for anything different. ==ska*/
@ -667,54 +659,60 @@ VOID FAR *DosGetDBCS(void)
Return value: AL register to be returned Return value: AL register to be returned
if AL == 0, Carry must be cleared, otherwise set 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 */ 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 */ return DE_INVLDFUNC; /* no such package */
log(("NLS: MUX14(): NLS pkg found\n")); log(("NLS: MUX14(): NLS pkg found\n"));
switch (pr->AL) switch (AL)
{ {
case NLSFUNC_INSTALL_CHECK: case NLSFUNC_INSTALL_CHECK:
pr->BX = NLS_FREEDOS_NLSFUNC_ID; BX = NLS_FREEDOS_NLSFUNC_ID;
return SUCCESS; /* kernel just simulates default functions */ return SUCCESS; /* kernel just simulates default functions */
case NLSFUNC_DOS38: 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: 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: case NLSFUNC_DRDOS_GETDATA:
/* Does not pass buffer length */ /* 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: case NLSFUNC_LOAD_PKG:
return nlsLoadPackage(nls); return nlsLoadPackage(nls);
case NLSFUNC_LOAD_PKG2: case NLSFUNC_LOAD_PKG2:
return nlsSetPackage(nls); return nlsSetPackage(nls);
case NLSFUNC_YESNO: case NLSFUNC_YESNO:
return nlsYesNo(nls, pr->CX); return nlsYesNo(nls, CX);
case NLSFUNC_UPMEM: case NLSFUNC_UPMEM:
nlsUpMem(nls, MK_FP(pr->ES, pr->DI), pr->CX); nlsUpMem(nls, MK_FP(ES, DI), CX);
return SUCCESS; return SUCCESS;
case NLSFUNC_FILE_UPMEM: case NLSFUNC_FILE_UPMEM:
#ifdef NLS_DEBUG #ifdef NLS_DEBUG
{ {
unsigned j; unsigned j;
BYTE FAR *p; BYTE FAR *p;
log(("NLS: MUX14(FILE_UPMEM): len=%u, %04x:%04x=\"", pr->CX, log(("NLS: MUX14(FILE_UPMEM): len=%u, %04x:%04x=\"", CX, ES, DI));
pr->ES, pr->DI)); for (j = 0, p = MK_FP(ES, DI); j < CX; ++j)
for (j = 0, p = MK_FP(pr->ES, pr->DI); j < pr->CX; ++j)
printf("%c", p[j] > 32 ? p[j] : '.'); printf("%c", p[j] > 32 ? p[j] : '.');
printf("\"\n"); printf("\"\n");
} }
#endif #endif
nlsFUpMem(nls, MK_FP(pr->ES, pr->DI), pr->CX); nlsFUpMem(nls, MK_FP(ES, DI), CX);
return SUCCESS; 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 */ return DE_INVLDFUNC; /* no such function */
} }

View File

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

View File

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

View File

@ -31,10 +31,10 @@
%include "segs.inc" %include "segs.inc"
extern _user_r extern _user_r:wrt DGROUP
extern _break_flg ; break detected flag extern _break_flg:wrt DGROUP ; break detected flag
extern _int21_handler ; far call system services extern _int21_handler:wrt DGROUP ; far call system services
%include "stacks.inc" %include "stacks.inc"
@ -71,7 +71,7 @@ _exec_user:
; ;
POP$ALL POP$ALL
extern _ExecUserDisableA20 extern _ExecUserDisableA20
jmp DGROUP:_ExecUserDisableA20 jmp far _ExecUserDisableA20
do_iret: do_iret:
extern _int21_iret extern _int21_iret
jmp _int21_iret jmp _int21_iret
@ -263,7 +263,7 @@ _spawn_int23:
??int23_respawn: ??int23_respawn:
pop bp ;; Restore the original register pop bp ;; Restore the original register
jmp DGROUP:_int21_handler jmp far _int21_handler
; ;
; interrupt enable and disable routines ; 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); unsigned char check_handle_break(struct dhdr FAR **pdev);
void handle_break(struct dhdr FAR **pdev, int sft_out); void handle_break(struct dhdr FAR **pdev, int sft_out);
#ifdef __WATCOMC__ #ifdef __WATCOMC__
#pragma aux handle_break __aborts; #pragma aux handle_break aborts;
#endif #endif
/* chario.c */ /* chario.c */
@ -102,8 +102,8 @@ COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s);
COUNT DosChangeDir(BYTE FAR * s); COUNT DosChangeDir(BYTE FAR * s);
COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name); COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name);
COUNT DosFindNext(void); COUNT DosFindNext(void);
COUNT DosGetFtime(COUNT hndl, ddate * dp, dtime * tp); COUNT DosGetFtime(COUNT hndl, date * dp, time * tp);
COUNT DosSetFtimeSft(int sft_idx, ddate dp, dtime tp); COUNT DosSetFtimeSft(int sft_idx, date dp, time tp);
#define DosSetFtime(hndl, dp, tp) DosSetFtimeSft(get_sft_idx(hndl), (dp), (tp)) #define DosSetFtime(hndl, dp, tp) DosSetFtimeSft(get_sft_idx(hndl), (dp), (tp))
COUNT DosGetFattr(BYTE FAR * name); COUNT DosGetFattr(BYTE FAR * name);
COUNT DosSetFattr(BYTE FAR * name, UWORD attrp); 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); int idx_to_sft_(int SftIndex);
sft FAR *idx_to_sft(int SftIndex); sft FAR *idx_to_sft(int SftIndex);
int get_sft_idx(UCOUNT hndl); 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_cds(unsigned dsk);
struct cds FAR *get_cds1(unsigned dsk); struct cds FAR *get_cds1(unsigned dsk);
COUNT DosTruename(const char FAR * src, char FAR * dest); 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_int(void);
VOID ASMCFUNC DosIdle_hlt(void); VOID ASMCFUNC DosIdle_hlt(void);
#ifdef __WATCOMC__ #ifdef __WATCOMC__
#pragma aux (__cdecl) DosIdle_int __modify __exact [] #pragma aux (cdecl) DosIdle_int modify exact []
#pragma aux (__cdecl) DosIdle_hlt __modify __exact [] #pragma aux (cdecl) DosIdle_hlt modify exact []
#endif #endif
/* error.c */ /* error.c */
@ -158,8 +157,8 @@ COUNT dos_close(COUNT fd);
COUNT dos_delete(BYTE * path, int attrib); COUNT dos_delete(BYTE * path, int attrib);
COUNT dos_rmdir(BYTE * path); COUNT dos_rmdir(BYTE * path);
COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib); COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib);
ddate dos_getdate(void); date dos_getdate(void);
dtime dos_gettime(void); time dos_gettime(void);
COUNT dos_mkdir(BYTE * dir); COUNT dos_mkdir(BYTE * dir);
BOOL last_link(f_node_ptr fnp); BOOL last_link(f_node_ptr fnp);
COUNT map_cluster(REG f_node_ptr fnp, COUNT mode); COUNT map_cluster(REG f_node_ptr fnp, COUNT mode);
@ -218,13 +217,11 @@ void FcbCloseAll(void);
UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First); UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First);
/* intr.asm */ /* intr.asm */
UWORD ASMPASCAL call_intr(WORD nr, iregs FAR * rp);
COUNT ASMPASCAL res_DosExec(COUNT mode, exec_blk * ep, BYTE * lp); COUNT ASMPASCAL res_DosExec(COUNT mode, exec_blk * ep, BYTE * lp);
UCOUNT ASMPASCAL res_read(int fd, void *buf, UCOUNT count); UCOUNT ASMPASCAL res_read(int fd, void *buf, UCOUNT count);
#ifdef __WATCOMC__ #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_DosExec __modify __exact [__ax __bx __dx __es] #pragma aux (pascal) res_read modify exact [ax bx cx dx]
#pragma aux (__pascal) res_read __modify __exact [__ax __bx __cx __dx]
#endif #endif
/* ioctl.c */ /* ioctl.c */
@ -250,7 +247,7 @@ VOID mcb_print(mcb FAR * mcbp);
COUNT lfn_allocate_inode(VOID); COUNT lfn_allocate_inode(VOID);
COUNT lfn_free_inode(COUNT handle); 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_create_entries(COUNT handle, lfn_inode_ptr lip);
COUNT lfn_remove_entries(COUNT handle); COUNT lfn_remove_entries(COUNT handle);
@ -279,7 +276,7 @@ COUNT DosSetCountry(UWORD cntry);
COUNT DosGetCodepage(UWORD * actCP, UWORD * sysCP); COUNT DosGetCodepage(UWORD * actCP, UWORD * sysCP);
COUNT DosSetCodepage(UWORD actCP, UWORD sysCP); COUNT DosSetCodepage(UWORD actCP, UWORD sysCP);
VOID FAR *DosGetDBCS(void); VOID FAR *DosGetDBCS(void);
UWORD ASMCFUNC syscall_MUX14(iregs FAR *); UWORD ASMCFUNC syscall_MUX14(DIRECT_IREGS);
/* prf.c */ /* prf.c */
#ifdef DEBUG #ifdef DEBUG
@ -318,21 +315,21 @@ int /*ASMCFUNC*/ ASMPASCAL fmemcmp(const void FAR *m1, const void FAR *m2, size_
#ifdef __WATCOMC__ #ifdef __WATCOMC__
/* bx, cx, dx and es not used or clobbered for all asmsupt.asm functions except /* bx, cx, dx and es not used or clobbered for all asmsupt.asm functions except
(f)memchr/(f)strchr (which clobber dx) */ (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) fmemcpy
#pragma aux (pascal_ax) memcpy #pragma aux (pascal_ax) memcpy
#pragma aux (pascal_ax) fmemset #pragma aux (pascal_ax) fmemset
#pragma aux (pascal_ax) memset #pragma aux (pascal_ax) memset
#pragma aux (pascal_ax) fmemcmp __modify __nomemory #pragma aux (pascal_ax) fmemcmp modify nomemory
#pragma aux (pascal_ax) memcmp __modify __nomemory #pragma aux (pascal_ax) memcmp modify nomemory
#pragma aux (pascal_ax) fstrcpy #pragma aux (pascal_ax) fstrcpy
#pragma aux (pascal_ax) strcpy #pragma aux (pascal_ax) strcpy
#pragma aux (pascal_ax) fstrlen __modify __nomemory #pragma aux (pascal_ax) fstrlen modify nomemory
#pragma aux (pascal_ax) strlen __modify __nomemory #pragma aux (pascal_ax) strlen modify nomemory
#pragma aux (__pascal) memchr __modify __exact [__ax __dx] __nomemory #pragma aux (pascal) memchr modify exact [ax dx] nomemory
#pragma aux (__pascal) fmemchr __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) strchr modify exact [ax dx] nomemory
#pragma aux (__pascal) fstrchr __modify __exact [__ax __dx] __nomemory #pragma aux (pascal) fstrchr modify exact [ax dx] nomemory
#endif #endif
/* sysclk.c */ /* 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); 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_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(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_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_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) #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 %define WATCOM
%endif %endif
%ifidn __OUTPUT_FORMAT__, obj
group PGROUP PSP group PGROUP PSP
group LGROUP _IRQTEXT _LOWTEXT _IO_TEXT _IO_FIXED_DATA _TEXT group LGROUP _IRQTEXT _LOWTEXT _IO_TEXT _IO_FIXED_DATA _TEXT
group DGROUP _FIXED_DATA _BSS _DATA _DATAEND CONST CONST2 DCONST DYN_DATA group DGROUP _FIXED_DATA _BSS _DATA _DATAEND CONST CONST2 DCONST DYN_DATA
%ifdef WATCOM %ifdef WATCOM
group TGROUP HMA_TEXT_START HMA_TEXT HMA_TEXT_END INIT_TEXT_START INIT_TEXT INIT_TEXT_END 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 group I_GROUP ID_B I_DATA ICONST ICONST2 ID_E IB_B I_BSS IB_E
%else %else
group TGROUP HMA_TEXT_START HMA_TEXT HMA_TEXT_END group TGROUP HMA_TEXT_START HMA_TEXT HMA_TEXT_END
group IGROUP INIT_TEXT_START INIT_TEXT INIT_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 group I_GROUP ID_B ID ID_E IC IDATA IB_B IB IB_E
%endif %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 segment PSP class=PSP
segment _IRQTEXT class=LCODE
BITS 16 segment _LOWTEXT class=LCODE
; groups are defined in the linker script kernel.ld segment _IO_TEXT class=LCODE
extern PGROUP segment _IO_FIXED_DATA class=LCODE align=2
extern DGROUP segment _TEXT class=LCODE
extern LGROUP segment _FIXED_DATA class=FDATA align=16
extern TGROUP segment _BSS class=BSS align=2
extern IGROUP segment _DATA class=DATA align=2
extern I_GROUP segment _DATAEND class=DATA align=1
%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
;for WATCOM ;for WATCOM
segment CONST class(DATA) align=2 segment CONST class=DATA align=2
segment CONST2 class(DATA) align=2 segment CONST2 class=DATA align=2
;for MSC ;for MSC
segment DCONST class(DCONST) align=2 segment DCONST class=DCONST align=2
segment DYN_DATA class(DYN_DATA) segment DYN_DATA class=DYN_DATA
segment HMA_TEXT_START class(CODE) align=16 segment HMA_TEXT_START class=CODE align=16
segment HMA_TEXT class(CODE) exec segment HMA_TEXT class=CODE
segment HMA_TEXT_END class(CODE) align=16 segment HMA_TEXT_END class=CODE
segment INIT_TEXT_START class(CODE) align=16 segment INIT_TEXT_START class=CODE align=16
segment INIT_TEXT class(CODE) exec segment INIT_TEXT class=CODE
segment INIT_TEXT_END class(CODE) align=16 segment INIT_TEXT_END class=CODE
%ifdef WATCOM %ifdef WATCOM
segment ID_B class(FAR_DATA) align=16 segment ID_B class=FAR_DATA align=16
segment I_DATA class(FAR_DATA) align=2 segment I_DATA class=FAR_DATA align=2
segment ICONST class(FAR_DATA) align=2 segment ICONST class=FAR_DATA align=2
segment ICONST2 class(FAR_DATA) align=2 segment ICONST2 class=FAR_DATA align=2
segment ID_E class(FAR_DATA) align=2 segment ID_E class=FAR_DATA align=2
segment IB_B class(FAR_DATA) align=2 segment IB_B class=FAR_DATA align=2
segment I_BSS class(FAR_DATA) align=2 segment I_BSS class=FAR_DATA align=2
segment IB_E class(FAR_DATA) align=2 segment IB_E class=FAR_DATA align=2
%else %else
segment ID_B class(ID) align=16 segment ID_B class=ID align=16
segment ID class(ID) align=2 segment ID class=ID align=2
segment IDATA class(ID) align=2 segment IDATA class=ID align=2
segment ID_E class(ID) align=2 segment ID_E class=ID align=2
segment IC class(IC) align=2 segment IC class=IC align=2
segment IB_B class(IB) align=2 nobits segment IB_B class=IB align=2
segment IB class(IB) align=2 nobits segment IB class=IB align=2
segment IB_E class(IB) align=2 nobits segment IB_E class=IB align=2
%endif %endif

View File

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

View File

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

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