FreeDOS kernel current - 2041+svn1709
This commit is contained in:
parent
1cef75adce
commit
c431157156
92
RELEASE.BAT
Normal file
92
RELEASE.BAT
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
@ECHO OFF
|
||||||
|
IF "%1"=="" GOTO USAGE
|
||||||
|
REM goto to just below trunk and tags directory, assume ran in trunk directory
|
||||||
|
CD ..
|
||||||
|
|
||||||
|
ECHO tag SVN with release version - svn copy trunk/ tags/ke%1
|
||||||
|
svn copy https://freedos.svn.sourceforge.net/svnroot/freedos/kernel/trunk/ https://freedos.svn.sourceforge.net/svnroot/freedos/kernel/tags/ke%1 -m "Tag kernel release %1"
|
||||||
|
PAUSE
|
||||||
|
ECHO svn export to get clean tree
|
||||||
|
if EXIST SOURCE RMDIR /S /Q SOURCE > NUL
|
||||||
|
svn export https://freedos.svn.sourceforge.net/svnroot/freedos/kernel/tags/ke%1 SOURCE\ke%1
|
||||||
|
REM svn export https://freedos.svn.sourceforge.net/svnroot/freedos/kernel/trunk SOURCE\ke%1
|
||||||
|
|
||||||
|
SET VERSION=%1
|
||||||
|
SET LSMRET=SRC
|
||||||
|
SET LSMFILE=SOURCE\ke%1\docs\fdkernel.lsm
|
||||||
|
GOTO LSM
|
||||||
|
:SRC
|
||||||
|
ECHO zipping source
|
||||||
|
7z.exe a -tzip -mx9 -mpass15 -r ke%1s.zip SOURCE\*
|
||||||
|
ECHO creating APPINFO and expected packaging dir structure
|
||||||
|
ECHO using working configuration file
|
||||||
|
COPY trunk\CONFIG.BAT SOURCE\ke%1 > NUL
|
||||||
|
CD SOURCE\ke%1
|
||||||
|
|
||||||
|
ECHO build and packaging
|
||||||
|
SET VERSION=%1 (FAT12/FAT16)
|
||||||
|
SET FAT=16
|
||||||
|
SET BZKRET=F16
|
||||||
|
GOTO BZK
|
||||||
|
:F16
|
||||||
|
SET VERSION=%1 (FAT12/FAT16/FAT32)
|
||||||
|
SET FAT=32
|
||||||
|
SET BZKRET=F32
|
||||||
|
GOTO BZK
|
||||||
|
:F32
|
||||||
|
ECHO clean up
|
||||||
|
CD ..\..
|
||||||
|
RMDIR /S /Q SOURCE > NUL
|
||||||
|
ECHO Done.
|
||||||
|
SET BZKRET=
|
||||||
|
GOTO DONE
|
||||||
|
|
||||||
|
|
||||||
|
:BZK
|
||||||
|
ECHO build kernel %VERSION%
|
||||||
|
CALL build.bat /D KERNEL_VERSION /V "%1 " 86 upx fat%FAT%
|
||||||
|
DEL BIN\K??86??.sys
|
||||||
|
SET LSMRET=BZK_2
|
||||||
|
SET LSMFILE=docs\fdkernel.lsm
|
||||||
|
GOTO LSM
|
||||||
|
:BZK_2
|
||||||
|
SET LSMRET=
|
||||||
|
ECHO zipping FAT%FAT% release version
|
||||||
|
7z.exe a -tzip -mx9 -mpass15 -r ..\..\ke%1_86f%FAT%.zip BIN\* DOCS\*
|
||||||
|
ECHO restructuring and zipping update package
|
||||||
|
DEL BIN\K??86??.* > NUL
|
||||||
|
MKDIR DOC
|
||||||
|
MKDIR DOC\KERNEL
|
||||||
|
COPY DOCS\* DOC\KERNEL\
|
||||||
|
MKDIR APPINFO
|
||||||
|
MOVE DOC\KERNEL\*.lsm APPINFO\
|
||||||
|
7z.exe a -tzip -mx9 -mpass15 -r ..\..\kernel%FAT%.zip APPINFO\* BIN\* DOC\*
|
||||||
|
ECHO cleaning up between builds
|
||||||
|
CALL clobber.bat
|
||||||
|
RMDIR /S /Q DOC
|
||||||
|
RMDIR /S /Q APPINFO
|
||||||
|
GOTO %BZKRET%
|
||||||
|
|
||||||
|
:LSM
|
||||||
|
ECHO Begin3>%LSMFILE%
|
||||||
|
ECHO Title: The FreeDOS Kernel>>%LSMFILE%
|
||||||
|
ECHO Version: %VERSION%>>%LSMFILE%
|
||||||
|
ECHO Entered-date: %DATE%>>%LSMFILE%
|
||||||
|
ECHO Description: The FreeDOS Kernel>>%LSMFILE%
|
||||||
|
ECHO Keywords: kernel, FreeDOS, DOS, MSDOS>>%LSMFILE%
|
||||||
|
ECHO Author: (developers: can be reached on the freedos-kernel mailing list)>>%LSMFILE%
|
||||||
|
ECHO Maintained-by: freedos-kernel@lists.sourceforge.net>>%LSMFILE%
|
||||||
|
ECHO Primary-site: http://freedos.sourceforge.net/kernel/>>%LSMFILE%
|
||||||
|
ECHO Alternate-site: http://www.fdos.org/kernel/>>%LSMFILE%
|
||||||
|
ECHO Alternate-site: https://freedos.svn.sourceforge.net/svnroot/freedos>>%LSMFILE%
|
||||||
|
ECHO Original-site: http://www.gcfl.net/pub/FreeDOS/kernel>>%LSMFILE%
|
||||||
|
ECHO Platforms: DOS, FreeDOS, DOSEMU (OpenWatcom C or Turbo C, NASM, UPX)>>%LSMFILE%
|
||||||
|
ECHO Copying-policy: GPL2>>%LSMFILE%
|
||||||
|
ECHO End>>%LSMFILE%
|
||||||
|
SET LSMFILE=
|
||||||
|
SET VERSION=
|
||||||
|
GOTO %LSMRET%
|
||||||
|
|
||||||
|
:USAGE
|
||||||
|
ECHO Tag and build release kernels - usage: RELEASE {VERSION} e.g. RELEASE 2039
|
||||||
|
:DONE
|
3
bin/autoexec.bat
Normal file
3
bin/autoexec.bat
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
@echo off
|
||||||
|
echo Welcome to FreeDOS (http://www.freedos.org)!
|
||||||
|
path=a:\
|
5
bin/config.sys
Normal file
5
bin/config.sys
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
rem dos=high
|
||||||
|
rem device=fdxms.sys (or himem.sys)
|
||||||
|
files=20
|
||||||
|
buffers=20
|
||||||
|
rem screen=0x12
|
36
bin/install.bat
Normal file
36
bin/install.bat
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
@echo off
|
||||||
|
rem
|
||||||
|
rem Create a distribution floppy
|
||||||
|
rem
|
||||||
|
rem $Header$
|
||||||
|
|
||||||
|
set D=A:
|
||||||
|
if "%1" == "b:" set D=B:
|
||||||
|
if "%1" == "B:" set D=B:
|
||||||
|
if "%1" == "b" set D=B:
|
||||||
|
if "%1" == "B" set D=B:
|
||||||
|
|
||||||
|
echo This utility will create a distribution floppy on the disk in drive %D%
|
||||||
|
pause
|
||||||
|
|
||||||
|
rem try to transfer system files -- abort if it cannot.
|
||||||
|
sys %D%
|
||||||
|
if errorlevel 1 goto out
|
||||||
|
|
||||||
|
rem copy remaining files
|
||||||
|
echo copying remaining files...
|
||||||
|
echo copying autoexec.bat...
|
||||||
|
copy autoexec.bat %D%
|
||||||
|
echo copying config.sys..
|
||||||
|
copy config.sys %D%
|
||||||
|
echo copying sys.com..
|
||||||
|
copy sys.com %D%
|
||||||
|
label %D% freedos
|
||||||
|
|
||||||
|
rem exit methods
|
||||||
|
goto done
|
||||||
|
:out
|
||||||
|
echo Floppy creation aborted
|
||||||
|
:done
|
||||||
|
set D=
|
||||||
|
|
541
boot/boot.asm
Normal file
541
boot/boot.asm
Normal file
@ -0,0 +1,541 @@
|
|||||||
|
;
|
||||||
|
; File:
|
||||||
|
; boot.asm
|
||||||
|
; Description:
|
||||||
|
; DOS-C boot
|
||||||
|
;
|
||||||
|
; Copyright (c) 1997;
|
||||||
|
; Svante Frey
|
||||||
|
; All Rights Reserved
|
||||||
|
;
|
||||||
|
; This file is part of DOS-C.
|
||||||
|
;
|
||||||
|
; DOS-C is free software; you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation; either version
|
||||||
|
; 2, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; DOS-C is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||||
|
; the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public
|
||||||
|
; License along with DOS-C; see the file COPYING. If not,
|
||||||
|
; write to the Free Software Foundation, 675 Mass Ave,
|
||||||
|
; Cambridge, MA 02139, USA.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; +--------+ 1FE0:7E00
|
||||||
|
; |BOOT SEC|
|
||||||
|
; |RELOCATE|
|
||||||
|
; |--------| 1FE0:7C00
|
||||||
|
; |LBA PKT |
|
||||||
|
; |--------| 1FE0:7BC0
|
||||||
|
; |--------| 1FE0:7BA0
|
||||||
|
; |BS STACK|
|
||||||
|
; |--------|
|
||||||
|
; |4KBRDBUF| used to avoid crossing 64KB DMA boundary
|
||||||
|
; |--------| 1FE0:63A0
|
||||||
|
; | |
|
||||||
|
; |--------| 1FE0:3000
|
||||||
|
; | CLUSTER|
|
||||||
|
; | LIST |
|
||||||
|
; |--------| 1FE0:2000
|
||||||
|
; | |
|
||||||
|
; |--------| 0000:7E00
|
||||||
|
; |BOOT SEC| overwritten by max 128k FAT buffer
|
||||||
|
; |ORIGIN | and later by max 134k loaded kernel
|
||||||
|
; |--------| 0000:7C00
|
||||||
|
; | |
|
||||||
|
; |--------|
|
||||||
|
; |KERNEL | also used as max 128k FAT buffer
|
||||||
|
; |LOADED | before kernel loading starts
|
||||||
|
; |--------| 0060:0000
|
||||||
|
; | |
|
||||||
|
; +--------+
|
||||||
|
|
||||||
|
|
||||||
|
;%define ISFAT12 1
|
||||||
|
;%define ISFAT16 1
|
||||||
|
|
||||||
|
|
||||||
|
segment .text
|
||||||
|
|
||||||
|
%define BASE 0x7c00
|
||||||
|
|
||||||
|
org BASE
|
||||||
|
|
||||||
|
Entry: jmp short real_start
|
||||||
|
nop
|
||||||
|
|
||||||
|
; bp is initialized to 7c00h
|
||||||
|
%define bsOemName bp+0x03 ; OEM label
|
||||||
|
%define bsBytesPerSec bp+0x0b ; bytes/sector
|
||||||
|
%define bsSecPerClust bp+0x0d ; sectors/allocation unit
|
||||||
|
%define bsResSectors bp+0x0e ; # reserved sectors
|
||||||
|
%define bsFATs bp+0x10 ; # of fats
|
||||||
|
%define bsRootDirEnts bp+0x11 ; # of root dir entries
|
||||||
|
%define bsSectors bp+0x13 ; # sectors total in image
|
||||||
|
%define bsMedia bp+0x15 ; media descrip: fd=2side9sec, etc...
|
||||||
|
%define sectPerFat bp+0x16 ; # sectors in a fat
|
||||||
|
%define sectPerTrack bp+0x18 ; # sectors/track
|
||||||
|
%define nHeads bp+0x1a ; # heads
|
||||||
|
%define nHidden bp+0x1c ; # hidden sectors
|
||||||
|
%define nSectorHuge bp+0x20 ; # sectors if > 65536
|
||||||
|
%define drive bp+0x24 ; drive number
|
||||||
|
%define extBoot bp+0x26 ; extended boot signature
|
||||||
|
%define volid bp+0x27
|
||||||
|
%define vollabel bp+0x2b
|
||||||
|
%define filesys bp+0x36
|
||||||
|
|
||||||
|
%define LOADSEG 0x0060
|
||||||
|
|
||||||
|
%define FATBUF 0x2000 ; offset of temporary buffer for FAT
|
||||||
|
; chain
|
||||||
|
|
||||||
|
; Some extra variables
|
||||||
|
|
||||||
|
;%define StoreSI bp+3h ;temp store
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
times 0x3E-$+$$ db 0
|
||||||
|
|
||||||
|
; using bp-Entry+loadseg_xxx generates smaller code than using just
|
||||||
|
; loadseg_xxx, where bp is initialized to Entry, so bp-Entry equals 0
|
||||||
|
%define loadsegoff_60 bp-Entry+loadseg_off
|
||||||
|
%define loadseg_60 bp-Entry+loadseg_seg
|
||||||
|
|
||||||
|
%define LBA_PACKET bp-0x40
|
||||||
|
%define LBA_SIZE word [LBA_PACKET] ; size of packet, should be 10h
|
||||||
|
%define LBA_SECNUM word [LBA_PACKET+2] ; number of sectors to read
|
||||||
|
%define LBA_OFF LBA_PACKET+4 ; buffer to read/write to
|
||||||
|
%define LBA_SEG LBA_PACKET+6
|
||||||
|
%define LBA_SECTOR_0 word [LBA_PACKET+8 ] ; LBA starting sector #
|
||||||
|
%define LBA_SECTOR_16 word [LBA_PACKET+10]
|
||||||
|
%define LBA_SECTOR_32 word [LBA_PACKET+12]
|
||||||
|
%define LBA_SECTOR_48 word [LBA_PACKET+14]
|
||||||
|
|
||||||
|
%define READBUF 0x63A0 ; max 4KB buffer (min 2KB stack), == stacktop-0x1800
|
||||||
|
%define READADDR_OFF BP-0x60-0x1804 ; pointer within user buffer
|
||||||
|
%define READADDR_SEG BP-0x60-0x1802
|
||||||
|
|
||||||
|
%define PARAMS LBA_PACKET+0x10
|
||||||
|
;%define RootDirSecs PARAMS+0x0 ; # of sectors root dir uses
|
||||||
|
|
||||||
|
%define fat_start PARAMS+0x2 ; first FAT sector
|
||||||
|
|
||||||
|
%define root_dir_start PARAMS+0x6 ; first root directory sector
|
||||||
|
|
||||||
|
%define data_start PARAMS+0x0a ; first data sector
|
||||||
|
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
; ENTRY
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
real_start:
|
||||||
|
cli
|
||||||
|
cld
|
||||||
|
xor ax, ax
|
||||||
|
mov ds, ax
|
||||||
|
mov bp, BASE
|
||||||
|
|
||||||
|
|
||||||
|
; a reset should not be needed here
|
||||||
|
; int 0x13 ; reset drive
|
||||||
|
|
||||||
|
; int 0x12 ; get memory available in AX
|
||||||
|
; mov ax, 0x01e0
|
||||||
|
; mov cl, 6 ; move boot sector to higher memory
|
||||||
|
; shl ax, cl
|
||||||
|
; sub ax, 0x07e0
|
||||||
|
|
||||||
|
mov ax, 0x1FE0
|
||||||
|
mov es, ax
|
||||||
|
mov si, bp
|
||||||
|
mov di, bp
|
||||||
|
mov cx, 0x0100
|
||||||
|
rep movsw
|
||||||
|
jmp word 0x1FE0:cont
|
||||||
|
|
||||||
|
loadseg_off dw 0
|
||||||
|
loadseg_seg dw LOADSEG
|
||||||
|
|
||||||
|
cont:
|
||||||
|
mov ds, ax
|
||||||
|
mov ss, ax
|
||||||
|
lea sp, [bp-0x60]
|
||||||
|
sti
|
||||||
|
;
|
||||||
|
; Note: some BIOS implementations may not correctly pass drive number
|
||||||
|
; 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)
|
||||||
|
;
|
||||||
|
mov [drive], dl ; rely on BIOS drive number in DL
|
||||||
|
|
||||||
|
mov LBA_SIZE, 10h
|
||||||
|
mov LBA_SECNUM,1 ; initialise LBA packet constants
|
||||||
|
mov word [LBA_SEG],ds
|
||||||
|
mov word [LBA_OFF],READBUF
|
||||||
|
|
||||||
|
|
||||||
|
; GETDRIVEPARMS: Calculate start of some disk areas.
|
||||||
|
;
|
||||||
|
mov si, word [nHidden]
|
||||||
|
mov di, word [nHidden+2]
|
||||||
|
add si, word [bsResSectors]
|
||||||
|
adc di, byte 0 ; DI:SI = first FAT sector
|
||||||
|
|
||||||
|
mov word [fat_start], si
|
||||||
|
mov word [fat_start+2], di
|
||||||
|
|
||||||
|
mov al, [bsFATs]
|
||||||
|
cbw
|
||||||
|
mul word [sectPerFat] ; DX:AX = total number of FAT sectors
|
||||||
|
|
||||||
|
add si, ax
|
||||||
|
adc di, dx ; DI:SI = first root directory sector
|
||||||
|
mov word [root_dir_start], si
|
||||||
|
mov word [root_dir_start+2], di
|
||||||
|
|
||||||
|
; Calculate how many sectors the root directory occupies.
|
||||||
|
mov bx, [bsBytesPerSec]
|
||||||
|
mov cl, 5 ; divide BX by 32
|
||||||
|
shr bx, cl ; BX = directory entries per sector
|
||||||
|
|
||||||
|
mov ax, [bsRootDirEnts]
|
||||||
|
xor dx, dx
|
||||||
|
div bx
|
||||||
|
|
||||||
|
; mov word [RootDirSecs], ax ; AX = sectors per root directory
|
||||||
|
push ax
|
||||||
|
|
||||||
|
add si, ax
|
||||||
|
adc di, byte 0 ; DI:SI = first data sector
|
||||||
|
|
||||||
|
mov [data_start], si
|
||||||
|
mov [data_start+2], di
|
||||||
|
|
||||||
|
|
||||||
|
; FINDFILE: Searches for the file in the root directory.
|
||||||
|
;
|
||||||
|
; Returns:
|
||||||
|
; AX = first cluster of file
|
||||||
|
|
||||||
|
; First, read the whole root directory
|
||||||
|
; into the temporary buffer.
|
||||||
|
|
||||||
|
mov ax, word [root_dir_start]
|
||||||
|
mov dx, word [root_dir_start+2]
|
||||||
|
pop di ; mov di, word [RootDirSecs]
|
||||||
|
les bx, [loadsegoff_60] ; es:bx = 60:0
|
||||||
|
call readDisk
|
||||||
|
les di, [loadsegoff_60] ; es:di = 60:0
|
||||||
|
|
||||||
|
|
||||||
|
; Search for KERNEL.SYS file name, and find start cluster.
|
||||||
|
|
||||||
|
next_entry: mov cx, 11
|
||||||
|
mov si, filename
|
||||||
|
push di
|
||||||
|
repe cmpsb
|
||||||
|
pop di
|
||||||
|
mov ax, [es:di+0x1A]; get cluster number from directory entry
|
||||||
|
je ffDone
|
||||||
|
|
||||||
|
add di, byte 0x20 ; go to next directory entry
|
||||||
|
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
|
||||||
|
|
||||||
|
jc boot_error ; fail if not found
|
||||||
|
ffDone:
|
||||||
|
push ax ; store first cluster number
|
||||||
|
|
||||||
|
|
||||||
|
; GETFATCHAIN:
|
||||||
|
;
|
||||||
|
; Reads the FAT chain and stores it in a temporary buffer in the first
|
||||||
|
; 64 kb. The FAT chain is stored an array of 16-bit cluster numbers,
|
||||||
|
; ending with 0.
|
||||||
|
;
|
||||||
|
; The file must fit in conventional memory, so it can't be larger than
|
||||||
|
; 640 kb. The sector size must be at least 512 bytes, so the FAT chain
|
||||||
|
; can't be larger than 2.5 KB (655360 / 512 * 2 = 2560).
|
||||||
|
;
|
||||||
|
; Call with: AX = first cluster in chain
|
||||||
|
|
||||||
|
les bx, [loadsegoff_60] ; es:bx=60:0
|
||||||
|
mov di, [sectPerFat]
|
||||||
|
mov ax, word [fat_start]
|
||||||
|
mov dx, word [fat_start+2]
|
||||||
|
call readDisk
|
||||||
|
pop ax ; restore first cluster number
|
||||||
|
|
||||||
|
; Set ES:DI to the temporary storage for the FAT chain.
|
||||||
|
push ds
|
||||||
|
pop es
|
||||||
|
mov ds, [loadseg_60]
|
||||||
|
mov di, FATBUF
|
||||||
|
|
||||||
|
next_clust: stosw ; store cluster number
|
||||||
|
mov si, ax ; SI = cluster number
|
||||||
|
|
||||||
|
%ifdef ISFAT12
|
||||||
|
; This is a FAT-12 disk.
|
||||||
|
|
||||||
|
fat_12: add si, si ; multiply cluster number by 3...
|
||||||
|
add si, ax
|
||||||
|
shr si, 1 ; ...and divide by 2
|
||||||
|
lodsw
|
||||||
|
|
||||||
|
; If the cluster number was even, the cluster value is now in
|
||||||
|
; bits 0-11 of AX. If the cluster number was odd, the cluster
|
||||||
|
; 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.
|
||||||
|
|
||||||
|
jnc fat_even
|
||||||
|
mov cl, 4
|
||||||
|
shr ax, cl
|
||||||
|
|
||||||
|
fat_even: and ah, 0x0f ; mask off the highest 4 bits
|
||||||
|
cmp ax, 0x0ff8 ; check for EOF
|
||||||
|
jb next_clust ; continue if not EOF
|
||||||
|
|
||||||
|
%endif
|
||||||
|
%ifdef ISFAT16
|
||||||
|
; This is a FAT-16 disk. The maximal size of a 16-bit FAT
|
||||||
|
; is 128 kb, so it may not fit within a single 64 kb segment.
|
||||||
|
|
||||||
|
fat_16: mov dx, [loadseg_60]
|
||||||
|
add si, si ; multiply cluster number by two
|
||||||
|
jnc first_half ; if overflow...
|
||||||
|
add dh, 0x10 ; ...add 64 kb to segment value
|
||||||
|
|
||||||
|
first_half: mov ds, dx ; DS:SI = pointer to next cluster
|
||||||
|
lodsw ; AX = next cluster
|
||||||
|
|
||||||
|
cmp ax, 0xfff8 ; >= FFF8 = 16-bit EOF
|
||||||
|
jb next_clust ; continue if not EOF
|
||||||
|
%endif
|
||||||
|
|
||||||
|
finished: ; Mark end of FAT chain with 0, so we have a single
|
||||||
|
; EOF marker for both FAT-12 and FAT-16 systems.
|
||||||
|
|
||||||
|
xor ax, ax
|
||||||
|
stosw
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
|
||||||
|
; loadFile: Loads the file into memory, one cluster at a time.
|
||||||
|
|
||||||
|
les bx, [loadsegoff_60] ; set ES:BX to load address 60:0
|
||||||
|
|
||||||
|
mov si, FATBUF ; set DS:SI to the FAT chain
|
||||||
|
|
||||||
|
cluster_next: lodsw ; AX = next cluster to read
|
||||||
|
or ax, ax ; EOF?
|
||||||
|
jne load_next ; no, continue
|
||||||
|
mov bl,dl ; drive (left from readDisk)
|
||||||
|
jmp far [loadsegoff_60] ; yes, pass control to kernel
|
||||||
|
|
||||||
|
load_next: dec ax ; cluster numbers start with 2
|
||||||
|
dec ax
|
||||||
|
|
||||||
|
mov di, word [bsSecPerClust]
|
||||||
|
and di, 0xff ; DI = sectors per cluster
|
||||||
|
mul di
|
||||||
|
add ax, [data_start]
|
||||||
|
adc dx, [data_start+2] ; DX:AX = first sector to read
|
||||||
|
call readDisk
|
||||||
|
jmp short cluster_next
|
||||||
|
|
||||||
|
; shows text after the call to this function.
|
||||||
|
|
||||||
|
show: pop si
|
||||||
|
lodsb ; get character
|
||||||
|
push si ; stack up potential return address
|
||||||
|
mov ah,0x0E ; show character
|
||||||
|
int 0x10 ; via "TTY" mode
|
||||||
|
cmp al,'.' ; end of string?
|
||||||
|
jne show ; until done
|
||||||
|
ret
|
||||||
|
|
||||||
|
boot_error: call show
|
||||||
|
; db "Error! Hit a key to reboot."
|
||||||
|
db "Error!."
|
||||||
|
|
||||||
|
xor ah,ah
|
||||||
|
int 0x13 ; reset floppy
|
||||||
|
int 0x16 ; wait for a key
|
||||||
|
int 0x19 ; reboot the machine
|
||||||
|
|
||||||
|
|
||||||
|
; readDisk: Reads a number of sectors into memory.
|
||||||
|
;
|
||||||
|
; Call with: DX:AX = 32-bit DOS sector number
|
||||||
|
; DI = number of sectors to read
|
||||||
|
; ES:BX = destination buffer
|
||||||
|
;
|
||||||
|
; Returns: CF set on error
|
||||||
|
; ES:BX points one byte after the last byte read.
|
||||||
|
|
||||||
|
readDisk: push si
|
||||||
|
|
||||||
|
mov LBA_SECTOR_0,ax
|
||||||
|
mov LBA_SECTOR_16,dx
|
||||||
|
mov word [READADDR_SEG], es
|
||||||
|
mov word [READADDR_OFF], bx
|
||||||
|
|
||||||
|
call show
|
||||||
|
db "."
|
||||||
|
read_next:
|
||||||
|
|
||||||
|
;******************** LBA_READ *******************************
|
||||||
|
|
||||||
|
; check for LBA support
|
||||||
|
|
||||||
|
mov ah,041h ;
|
||||||
|
mov bx,055aah ;
|
||||||
|
mov dl, [drive]
|
||||||
|
|
||||||
|
; NOTE: sys must be updated if location changes!!!
|
||||||
|
test dl,dl ; don't use LBA addressing on A:
|
||||||
|
jz read_normal_BIOS ; might be a (buggy)
|
||||||
|
; CDROM-BOOT floppy emulation
|
||||||
|
|
||||||
|
int 0x13
|
||||||
|
jc read_normal_BIOS
|
||||||
|
|
||||||
|
shr cx,1 ; CX must have 1 bit set
|
||||||
|
|
||||||
|
sbb bx,0aa55h - 1 ; tests for carry (from shr) too!
|
||||||
|
jne read_normal_BIOS
|
||||||
|
|
||||||
|
|
||||||
|
; OK, drive seems to support LBA addressing
|
||||||
|
|
||||||
|
lea si,[LBA_PACKET]
|
||||||
|
|
||||||
|
; setup LBA disk block
|
||||||
|
mov LBA_SECTOR_32,bx ; bx is 0 if extended 13h mode supported
|
||||||
|
mov LBA_SECTOR_48,bx
|
||||||
|
|
||||||
|
mov ah,042h
|
||||||
|
jmp short do_int13_read
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
read_normal_BIOS:
|
||||||
|
|
||||||
|
;******************** END OF LBA_READ ************************
|
||||||
|
mov cx,LBA_SECTOR_0
|
||||||
|
mov dx,LBA_SECTOR_16
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; translate sector number to BIOS parameters
|
||||||
|
;
|
||||||
|
|
||||||
|
;
|
||||||
|
; abs = sector offset in track
|
||||||
|
; + head * sectPerTrack offset in cylinder
|
||||||
|
; + track * sectPerTrack * nHeads offset in platter
|
||||||
|
;
|
||||||
|
mov al, [sectPerTrack]
|
||||||
|
mul byte [nHeads]
|
||||||
|
xchg ax, cx
|
||||||
|
; cx = nHeads * sectPerTrack <= 255*63
|
||||||
|
; dx:ax = abs
|
||||||
|
div cx
|
||||||
|
; ax = track, dx = sector + head * sectPertrack
|
||||||
|
xchg ax, dx
|
||||||
|
; dx = track, ax = sector + head * sectPertrack
|
||||||
|
div byte [sectPerTrack]
|
||||||
|
; dx = track, al = head, ah = sector
|
||||||
|
mov cx, dx
|
||||||
|
; cx = track, al = head, ah = sector
|
||||||
|
|
||||||
|
; the following manipulations are necessary in order to
|
||||||
|
; properly place parameters into registers.
|
||||||
|
; ch = cylinder number low 8 bits
|
||||||
|
; cl = 7-6: cylinder high two bits
|
||||||
|
; 5-0: sector
|
||||||
|
mov dh, al ; save head into dh for bios
|
||||||
|
xchg ch, cl ; set cyl no low 8 bits
|
||||||
|
ror cl, 1 ; move track high bits into
|
||||||
|
ror cl, 1 ; bits 7-6 (assumes top = 0)
|
||||||
|
or cl, ah ; merge sector into cylinder
|
||||||
|
inc cx ; make sector 1-based (1-63)
|
||||||
|
|
||||||
|
les bx,[LBA_OFF]
|
||||||
|
mov ax, 0x0201
|
||||||
|
do_int13_read:
|
||||||
|
mov dl, [drive]
|
||||||
|
int 0x13
|
||||||
|
jc boot_error ; exit on error
|
||||||
|
|
||||||
|
mov ax, word [bsBytesPerSec]
|
||||||
|
|
||||||
|
push di
|
||||||
|
mov si,READBUF ; copy read in sector data to
|
||||||
|
les di,[READADDR_OFF] ; user provided buffer
|
||||||
|
mov cx, ax
|
||||||
|
; shr cx, 1 ; convert bytes to word count
|
||||||
|
; rep movsw
|
||||||
|
rep movsb
|
||||||
|
pop di
|
||||||
|
|
||||||
|
; div byte[LBA_PACKET] ; luckily 16 !!
|
||||||
|
mov cl, 4
|
||||||
|
shr ax, cl ; adjust segment pointer by increasing
|
||||||
|
add word [READADDR_SEG], ax ; by paragraphs read in (per sector)
|
||||||
|
|
||||||
|
add LBA_SECTOR_0, byte 1
|
||||||
|
adc LBA_SECTOR_16, byte 0 ; DX:AX = next sector to read
|
||||||
|
dec di ; if there is anything left to read,
|
||||||
|
jnz read_next ; continue
|
||||||
|
|
||||||
|
les bx, [READADDR_OFF]
|
||||||
|
; clear carry: unnecessary since adc clears it
|
||||||
|
pop si
|
||||||
|
ret
|
||||||
|
|
||||||
|
times 0x01f1-$+$$ db 0
|
||||||
|
|
||||||
|
filename db "KERNEL SYS",0,0
|
||||||
|
|
||||||
|
sign dw 0xAA55
|
||||||
|
|
||||||
|
%ifdef DBGPRNNUM
|
||||||
|
; DEBUG print hex digit routines
|
||||||
|
PrintLowNibble: ; Prints low nibble of AL, AX is destroyed
|
||||||
|
and AL, 0Fh ; ignore upper nibble
|
||||||
|
cmp AL, 09h ; if greater than 9, then don't base on '0', base on 'A'
|
||||||
|
jbe .printme
|
||||||
|
add AL, 7 ; convert to character A-F
|
||||||
|
.printme:
|
||||||
|
add AL, '0' ; convert to character 0-9
|
||||||
|
mov AH,0x0E ; show character
|
||||||
|
int 0x10 ; via "TTY" mode
|
||||||
|
retn
|
||||||
|
PrintAL: ; Prints AL, AX is preserved
|
||||||
|
push AX ; store value so we can process a nibble at a time
|
||||||
|
shr AL, 4 ; move upper nibble into lower nibble
|
||||||
|
call PrintLowNibble
|
||||||
|
pop AX ; restore for other nibble
|
||||||
|
push AX ; but save so we can restore original AX
|
||||||
|
call PrintLowNibble
|
||||||
|
pop AX ; restore for other nibble
|
||||||
|
retn
|
||||||
|
PrintNumber: ; Prints (in Hex) value in AX, AX is preserved
|
||||||
|
xchg AH, AL ; high byte 1st
|
||||||
|
call PrintAL
|
||||||
|
xchg AH, AL ; now low byte
|
||||||
|
call PrintAL
|
||||||
|
retn
|
||||||
|
%endif
|
||||||
|
|
392
boot/boot32.asm
Normal file
392
boot/boot32.asm
Normal file
@ -0,0 +1,392 @@
|
|||||||
|
; +--------+
|
||||||
|
; | |
|
||||||
|
; | |
|
||||||
|
; |--------| 4000:0000
|
||||||
|
; | |
|
||||||
|
; | FAT |
|
||||||
|
; | |
|
||||||
|
; |--------| 2000:0000
|
||||||
|
; |BOOT SEC|
|
||||||
|
; |RELOCATE|
|
||||||
|
; |--------| 1FE0:0000
|
||||||
|
; | |
|
||||||
|
; | |
|
||||||
|
; | |
|
||||||
|
; | |
|
||||||
|
; |--------|
|
||||||
|
; |BOOT SEC|
|
||||||
|
; |ORIGIN | 07C0:0000
|
||||||
|
; |--------|
|
||||||
|
; | |
|
||||||
|
; | |
|
||||||
|
; | |
|
||||||
|
; |--------|
|
||||||
|
; |KERNEL |
|
||||||
|
; |LOADED |
|
||||||
|
; |--------| 0060:0000
|
||||||
|
; | |
|
||||||
|
; +--------+
|
||||||
|
|
||||||
|
;%define MULTI_SEC_READ 1
|
||||||
|
|
||||||
|
|
||||||
|
segment .text
|
||||||
|
|
||||||
|
%define BASE 0x7c00
|
||||||
|
|
||||||
|
org BASE
|
||||||
|
|
||||||
|
Entry: jmp short real_start
|
||||||
|
nop
|
||||||
|
|
||||||
|
; bp is initialized to 7c00h
|
||||||
|
%define bsOemName bp+0x03 ; OEM label
|
||||||
|
%define bsBytesPerSec bp+0x0b ; bytes/sector
|
||||||
|
%define bsSecPerClust bp+0x0d ; sectors/allocation unit
|
||||||
|
%define bsResSectors bp+0x0e ; # reserved sectors
|
||||||
|
%define bsFATs bp+0x10 ; # of fats
|
||||||
|
%define bsRootDirEnts bp+0x11 ; # of root dir entries
|
||||||
|
%define bsSectors bp+0x13 ; # sectors total in image
|
||||||
|
%define bsMedia bp+0x15 ; media descrip: fd=2side9sec, etc...
|
||||||
|
%define sectPerFat bp+0x16 ; # sectors in a fat
|
||||||
|
%define sectPerTrack bp+0x18 ; # sectors/track
|
||||||
|
%define nHeads bp+0x1a ; # heads
|
||||||
|
%define nHidden bp+0x1c ; # hidden sectors
|
||||||
|
%define nSectorHuge bp+0x20 ; # sectors if > 65536
|
||||||
|
%define xsectPerFat bp+0x24 ; Sectors/Fat
|
||||||
|
%define xrootClst bp+0x2c ; Starting cluster of root directory
|
||||||
|
%define drive bp+0x40 ; Drive number
|
||||||
|
|
||||||
|
times 0x5a-$+$$ db 0
|
||||||
|
|
||||||
|
%define LOADSEG 0x0060
|
||||||
|
|
||||||
|
%define FATSEG 0x2000
|
||||||
|
|
||||||
|
%define fat_sector bp+0x48 ; last accessed sector of the FAT
|
||||||
|
|
||||||
|
%define loadsegoff_60 bp+loadseg_off-Entry ; FAR pointer = 60:0
|
||||||
|
%define loadseg_60 bp+loadseg_seg-Entry
|
||||||
|
|
||||||
|
%define fat_start bp+0x5e ; first FAT sector
|
||||||
|
%define data_start bp+0x62 ; first data sector
|
||||||
|
%define fat_secmask bp+0x66 ; number of clusters in a FAT sector - 1
|
||||||
|
%define fat_secshift bp+0x68 ; fat_secmask+1 = 2^fat_secshift
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
; ENTRY
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
real_start: cld
|
||||||
|
cli
|
||||||
|
sub ax, ax
|
||||||
|
mov ds, ax
|
||||||
|
mov bp, 0x7c00
|
||||||
|
|
||||||
|
mov ax, 0x1FE0
|
||||||
|
mov es, ax
|
||||||
|
mov si, bp
|
||||||
|
mov di, bp
|
||||||
|
mov cx, 0x0100
|
||||||
|
rep movsw ; move boot code to the 0x1FE0:0x0000
|
||||||
|
jmp word 0x1FE0:cont
|
||||||
|
|
||||||
|
loadseg_off dw 0
|
||||||
|
loadseg_seg dw LOADSEG
|
||||||
|
|
||||||
|
cont: mov ds, ax
|
||||||
|
mov ss, ax
|
||||||
|
lea sp, [bp-0x20]
|
||||||
|
sti
|
||||||
|
mov [drive], dl ; BIOS passes drive number in DL
|
||||||
|
|
||||||
|
; call print
|
||||||
|
; db "Loading ",0
|
||||||
|
|
||||||
|
; Calc Params
|
||||||
|
; Fat_Start
|
||||||
|
mov si, word [nHidden]
|
||||||
|
mov di, word [nHidden+2]
|
||||||
|
add si, word [bsResSectors]
|
||||||
|
adc di, byte 0
|
||||||
|
|
||||||
|
mov word [fat_start], si
|
||||||
|
mov word [fat_start+2], di
|
||||||
|
; Data_Start
|
||||||
|
mov al, [bsFATs]
|
||||||
|
cbw
|
||||||
|
push ax
|
||||||
|
mul word [xsectPerFat+2]
|
||||||
|
add di, ax
|
||||||
|
pop ax
|
||||||
|
mul word [xsectPerFat]
|
||||||
|
add ax, si
|
||||||
|
adc dx, di
|
||||||
|
mov word[data_start], ax
|
||||||
|
mov word[data_start+2], dx
|
||||||
|
; fat_secmask
|
||||||
|
mov ax, word[bsBytesPerSec]
|
||||||
|
shr ax, 1
|
||||||
|
shr ax, 1
|
||||||
|
dec ax
|
||||||
|
mov word [fat_secmask], ax
|
||||||
|
; fat_secshift
|
||||||
|
; cx = temp
|
||||||
|
; ax = fat_secshift
|
||||||
|
xchg ax, cx ; cx = 0 after movsw
|
||||||
|
inc cx
|
||||||
|
secshift: inc ax
|
||||||
|
shr cx, 1
|
||||||
|
cmp cx, 1
|
||||||
|
jne secshift
|
||||||
|
mov byte [fat_secshift], al
|
||||||
|
dec cx
|
||||||
|
|
||||||
|
; FINDFILE: Searches for the file in the root directory.
|
||||||
|
;
|
||||||
|
; Returns:
|
||||||
|
; DX:AX = first cluster of file
|
||||||
|
|
||||||
|
mov word [fat_sector], cx ; CX is 0 after "dec"
|
||||||
|
mov word [fat_sector + 2], cx
|
||||||
|
|
||||||
|
mov ax, word [xrootClst]
|
||||||
|
mov dx, word [xrootClst + 2]
|
||||||
|
ff_next_cluster:
|
||||||
|
push dx ; save cluster
|
||||||
|
push ax
|
||||||
|
call convert_cluster
|
||||||
|
jc boot_error ; EOC encountered
|
||||||
|
|
||||||
|
ff_next_sector:
|
||||||
|
push bx ; save sector count
|
||||||
|
|
||||||
|
les bx, [loadsegoff_60]
|
||||||
|
call readDisk
|
||||||
|
push dx ; save sector
|
||||||
|
push ax
|
||||||
|
|
||||||
|
mov ax, [bsBytesPerSec]
|
||||||
|
|
||||||
|
; Search for KERNEL.SYS file name, and find start cluster.
|
||||||
|
ff_next_entry: mov cx, 11
|
||||||
|
mov si, filename
|
||||||
|
mov di, ax
|
||||||
|
sub di, 0x20
|
||||||
|
repe cmpsb
|
||||||
|
jz ff_done
|
||||||
|
|
||||||
|
sub ax, 0x20
|
||||||
|
jnz ff_next_entry
|
||||||
|
pop ax ; restore sector
|
||||||
|
pop dx
|
||||||
|
pop bx ; restore sector count
|
||||||
|
dec bx
|
||||||
|
jnz ff_next_sector
|
||||||
|
ff_find_next_cluster:
|
||||||
|
pop ax ; restore current cluster
|
||||||
|
pop dx
|
||||||
|
call next_cluster
|
||||||
|
jmp short ff_next_cluster
|
||||||
|
ff_done:
|
||||||
|
|
||||||
|
mov ax, [es:di+0x1A-11] ; get cluster number
|
||||||
|
mov dx, [es:di+0x14-11]
|
||||||
|
c4:
|
||||||
|
sub bx, bx ; ES points to LOADSEG
|
||||||
|
c5: push dx
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
call convert_cluster
|
||||||
|
jc boot_success
|
||||||
|
mov di, bx
|
||||||
|
pop bx
|
||||||
|
c6:
|
||||||
|
call readDisk
|
||||||
|
dec di
|
||||||
|
jnz c6
|
||||||
|
pop ax
|
||||||
|
pop dx
|
||||||
|
call next_cluster
|
||||||
|
jmp short c5
|
||||||
|
|
||||||
|
boot_error:
|
||||||
|
xor ah,ah
|
||||||
|
int 0x16 ; wait for a key
|
||||||
|
int 0x19 ; reboot the machine
|
||||||
|
|
||||||
|
; input:
|
||||||
|
; DX:AX - cluster
|
||||||
|
; output:
|
||||||
|
; DX:AX - next cluster
|
||||||
|
; CX = 0
|
||||||
|
; modify:
|
||||||
|
; DI
|
||||||
|
next_cluster:
|
||||||
|
push es
|
||||||
|
mov di, ax
|
||||||
|
and di, [fat_secmask]
|
||||||
|
|
||||||
|
mov cx, [fat_secshift]
|
||||||
|
cn_loop:
|
||||||
|
shr dx,1
|
||||||
|
rcr ax,1
|
||||||
|
dec cx
|
||||||
|
jnz cn_loop ; DX:AX fat sector where our
|
||||||
|
; cluster resides
|
||||||
|
; DI - cluster index in this
|
||||||
|
; sector
|
||||||
|
|
||||||
|
shl di,1 ; DI - offset in the sector
|
||||||
|
shl di,1
|
||||||
|
add ax, [fat_start]
|
||||||
|
adc dx, [fat_start+2] ; DX:AX absolute fat sector
|
||||||
|
|
||||||
|
push bx
|
||||||
|
mov bx, FATSEG
|
||||||
|
mov es, bx
|
||||||
|
sub bx, bx
|
||||||
|
|
||||||
|
cmp ax, [fat_sector]
|
||||||
|
jne cn1 ; if the last fat sector we
|
||||||
|
; read was this, than skip
|
||||||
|
cmp dx,[fat_sector+2]
|
||||||
|
je cn_exit
|
||||||
|
cn1:
|
||||||
|
mov [fat_sector],ax ; save the fat sector number,
|
||||||
|
mov [fat_sector+2],dx ; we are going to read
|
||||||
|
call readDisk
|
||||||
|
cn_exit:
|
||||||
|
pop bx
|
||||||
|
mov ax, [es:di] ; DX:AX - next cluster
|
||||||
|
mov dx, [es:di + 2] ;
|
||||||
|
pop es
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
boot_success:
|
||||||
|
mov bl, [drive]
|
||||||
|
jmp far [loadsegoff_60]
|
||||||
|
|
||||||
|
; Convert cluster to the absolute sector
|
||||||
|
;input:
|
||||||
|
; DX:AX - target cluster
|
||||||
|
;output:
|
||||||
|
; DX:AX - absoulute sector
|
||||||
|
; BX - [bsSectPerClust]
|
||||||
|
;modify:
|
||||||
|
; CX
|
||||||
|
convert_cluster:
|
||||||
|
cmp dx,0x0fff
|
||||||
|
jne c3
|
||||||
|
cmp ax,0xfff8
|
||||||
|
jb c3 ; if cluster is EOC (carry is set), do ret
|
||||||
|
stc
|
||||||
|
ret
|
||||||
|
c3:
|
||||||
|
mov cx, dx ; sector = (cluster - 2)*clussize +
|
||||||
|
; + data_start
|
||||||
|
sub ax, 2
|
||||||
|
sbb cx, byte 0 ; CX:AX == cluster - 2
|
||||||
|
mov bl, [bsSecPerClust]
|
||||||
|
sub bh, bh
|
||||||
|
xchg cx, ax ; AX:CX == cluster - 2
|
||||||
|
mul bx ; first handle high word
|
||||||
|
; DX must be 0 here
|
||||||
|
xchg ax, cx ; then low word
|
||||||
|
mul bx
|
||||||
|
add dx, cx ; DX:AX target sector
|
||||||
|
add ax, [data_start]
|
||||||
|
adc dx, [data_start + 2]
|
||||||
|
ret
|
||||||
|
|
||||||
|
; prints text after call to this function.
|
||||||
|
|
||||||
|
print_1char:
|
||||||
|
xor bx, bx ; video page 0
|
||||||
|
mov ah, 0x0E ; else print it
|
||||||
|
int 0x10 ; via TTY mode
|
||||||
|
print: pop si ; this is the first character
|
||||||
|
print1: lodsb ; get token
|
||||||
|
push si ; stack up potential return address
|
||||||
|
cmp al, 0 ; end of string?
|
||||||
|
jne print_1char ; until done
|
||||||
|
ret ; and jump to it
|
||||||
|
|
||||||
|
;input:
|
||||||
|
; DX:AX - 32-bit DOS sector number
|
||||||
|
; ES:BX - destination buffer
|
||||||
|
;output:
|
||||||
|
; ES:BX points one byte after the last byte read.
|
||||||
|
; DX:AX - next sector
|
||||||
|
;modify:
|
||||||
|
; ES if DI * bsBytesPerSec >= 65536, CX
|
||||||
|
|
||||||
|
readDisk:
|
||||||
|
read_next: push dx
|
||||||
|
push ax
|
||||||
|
;
|
||||||
|
; translate sector number to BIOS parameters
|
||||||
|
;
|
||||||
|
|
||||||
|
;
|
||||||
|
; abs = sector offset in track
|
||||||
|
; + head * sectPerTrack offset in cylinder
|
||||||
|
; + track * sectPerTrack * nHeads offset in platter
|
||||||
|
;
|
||||||
|
xchg ax, cx
|
||||||
|
mov al, [sectPerTrack]
|
||||||
|
mul byte [nHeads]
|
||||||
|
xchg ax, cx
|
||||||
|
; cx = nHeads * sectPerTrack <= 255*63
|
||||||
|
; dx:ax = abs
|
||||||
|
div cx
|
||||||
|
; ax = track, dx = sector + head * sectPertrack
|
||||||
|
xchg ax, dx
|
||||||
|
; dx = track, ax = sector + head * sectPertrack
|
||||||
|
div byte [sectPerTrack]
|
||||||
|
; dx = track, al = head, ah = sector
|
||||||
|
mov cx, dx
|
||||||
|
; cx = track, al = head, ah = sector
|
||||||
|
|
||||||
|
; the following manipulations are necessary in order to
|
||||||
|
; properly place parameters into registers.
|
||||||
|
; ch = cylinder number low 8 bits
|
||||||
|
; cl = 7-6: cylinder high two bits
|
||||||
|
; 5-0: sector
|
||||||
|
mov dh, al ; save head into dh for bios
|
||||||
|
xchg ch, cl ; set cyl no low 8 bits
|
||||||
|
ror cl, 1 ; move track high bits into
|
||||||
|
ror cl, 1 ; bits 7-6 (assumes top = 0)
|
||||||
|
inc ah ; sector offset from 1
|
||||||
|
or cl, ah ; merge sector into cylinder
|
||||||
|
|
||||||
|
mov ax, 0x0201
|
||||||
|
mov dl, [drive]
|
||||||
|
int 0x13
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
pop dx
|
||||||
|
jnc read_ok ; jump if no error
|
||||||
|
xor ah, ah ; else, reset floppy
|
||||||
|
int 0x13
|
||||||
|
jmp short read_next
|
||||||
|
read_ok:
|
||||||
|
add bx, word [bsBytesPerSec]
|
||||||
|
|
||||||
|
jnc no_incr_es ; if overflow...
|
||||||
|
|
||||||
|
mov cx, es
|
||||||
|
add ch, 0x10 ; ...add 1000h to ES
|
||||||
|
mov es, cx
|
||||||
|
|
||||||
|
no_incr_es:
|
||||||
|
add ax,byte 1
|
||||||
|
adc dx,byte 0
|
||||||
|
ret
|
||||||
|
|
||||||
|
times 0x01f1-$+$$ db 0
|
||||||
|
|
||||||
|
filename db "KERNEL SYS",0,0
|
||||||
|
|
||||||
|
sign dw 0xAA55
|
403
boot/boot32lb.asm
Normal file
403
boot/boot32lb.asm
Normal file
@ -0,0 +1,403 @@
|
|||||||
|
; This is an LBA-enabled FreeDOS FAT32 boot sector (single sector!).
|
||||||
|
; You can use and copy source code and binaries under the terms of the
|
||||||
|
; GNU Public License (GPL), version 2 or newer. See www.gnu.org for more.
|
||||||
|
|
||||||
|
; Based on earlier work by FreeDOS kernel hackers, modified heavily by
|
||||||
|
; Eric Auer and Jon Gentle in 7 / 2003.
|
||||||
|
;
|
||||||
|
; Features: Uses LBA and calculates all variables from BPB/EBPB data,
|
||||||
|
; thus making partition move / resize / image-restore easier. FreeDOS
|
||||||
|
; can boot from FAT32 partitions which start > 8 GB boundary with this
|
||||||
|
; boot sector. Disk geometry knowledge is not needed for booting.
|
||||||
|
;
|
||||||
|
; Windows uses 2-3 sectors for booting (sector stage, statistics sector,
|
||||||
|
; filesystem stage). Only using 1 sector for FreeDOS makes multi-booting
|
||||||
|
; of FreeDOS and Windows on the same filesystem easier.
|
||||||
|
;
|
||||||
|
; Requirements: LBA BIOS and 386 or better CPU. Use the older CHS-only
|
||||||
|
; boot sector if you want FAT32 on really old PCs (problems: you cannot
|
||||||
|
; boot from > 8 GB boundary, cannot move / resize / ... without applying
|
||||||
|
; SYS again if you use the CHS-only FAT32 boot sector).
|
||||||
|
;
|
||||||
|
; FAT12 / FAT16 hints: Use the older CHS-only boot sector unless you
|
||||||
|
; have to boot from > 8 GB. The LBA-and-CHS FAT12 / FAT16 boot sector
|
||||||
|
; needs applying SYS again after move / resize / ... a variant of that
|
||||||
|
; boot sector without CHS support but with better move / resize / ...
|
||||||
|
; support would be good for use on LBA harddisks.
|
||||||
|
|
||||||
|
|
||||||
|
; Memory layout for the FreeDOS FAT32 single stage boot process:
|
||||||
|
|
||||||
|
; ...
|
||||||
|
; |-------| 1FE0:7E00
|
||||||
|
; |BOOTSEC|
|
||||||
|
; |RELOC. |
|
||||||
|
; |-------| 1FE0:7C00
|
||||||
|
; ...
|
||||||
|
; |-------| 2000:0200
|
||||||
|
; | FAT | (only 1 sector buffered)
|
||||||
|
; |-------| 2000:0000
|
||||||
|
; ...
|
||||||
|
; |-------| 0000:7E00
|
||||||
|
; |BOOTSEC| overwritten by the kernel, so the
|
||||||
|
; |ORIGIN | bootsector relocates itself up...
|
||||||
|
; |-------| 0000:7C00
|
||||||
|
; ...
|
||||||
|
; |-------|
|
||||||
|
; |KERNEL | maximum size 134k (overwrites bootsec origin)
|
||||||
|
; |LOADED | (holds 1 sector directory buffer before kernel load)
|
||||||
|
; |-------| 0060:0000
|
||||||
|
; ...
|
||||||
|
|
||||||
|
segment .text
|
||||||
|
|
||||||
|
org 0x7c00 ; this is a boot sector
|
||||||
|
|
||||||
|
Entry: jmp short real_start
|
||||||
|
nop
|
||||||
|
|
||||||
|
; bp is initialized to 7c00h
|
||||||
|
; %define bsOemName bp+0x03 ; OEM label (8)
|
||||||
|
%define bsBytesPerSec bp+0x0b ; bytes/sector (dw)
|
||||||
|
%define bsSecPerClust bp+0x0d ; sectors/allocation unit (db)
|
||||||
|
%define bsResSectors bp+0x0e ; # reserved sectors (dw)
|
||||||
|
%define bsFATs bp+0x10 ; # of fats (db)
|
||||||
|
; %define bsRootDirEnts bp+0x11 ; # of root dir entries (dw, 0 for FAT32)
|
||||||
|
; (FAT32 has root dir in a cluster chain)
|
||||||
|
; %define bsSectors bp+0x13 ; # sectors total in image (dw, 0 for FAT32)
|
||||||
|
; (if 0 use nSectorHuge even if FAT16)
|
||||||
|
; %define bsMedia bp+0x15 ; media descriptor: fd=2side9sec, etc... (db)
|
||||||
|
; %define sectPerFat bp+0x16 ; # sectors in a fat (dw, 0 for FAT32)
|
||||||
|
; (FAT32 always uses xsectPerFat)
|
||||||
|
%define sectPerTrack bp+0x18 ; # sectors/track
|
||||||
|
; %define nHeads bp+0x1a ; # heads (dw)
|
||||||
|
%define nHidden bp+0x1c ; # hidden sectors (dd)
|
||||||
|
; %define nSectorHuge bp+0x20 ; # sectors if > 65536 (dd)
|
||||||
|
%define xsectPerFat bp+0x24 ; Sectors/Fat (dd)
|
||||||
|
; +0x28 dw flags (for fat mirroring)
|
||||||
|
; +0x2a dw filesystem version (usually 0)
|
||||||
|
%define xrootClst bp+0x2c ; Starting cluster of root directory (dd)
|
||||||
|
; +0x30 dw -1 or sector number of fs.-info sector
|
||||||
|
; +0x32 dw -1 or sector number of boot sector backup
|
||||||
|
; (+0x34 .. +0x3f reserved)
|
||||||
|
%define drive bp+0x40 ; Drive number
|
||||||
|
%define loadsegoff_60 bp+loadseg_off-Entry
|
||||||
|
|
||||||
|
%define LOADSEG 0x0060
|
||||||
|
|
||||||
|
%define FATSEG 0x2000
|
||||||
|
|
||||||
|
%define fat_secshift fat_afterss-1 ; each fat sector describes 2^??
|
||||||
|
; clusters (db) (selfmodifying)
|
||||||
|
%define fat_sector bp+0x44 ; last accessed FAT sector (dd)
|
||||||
|
; (overwriting unused bytes)
|
||||||
|
%define fat_start bp+0x48 ; first FAT sector (dd)
|
||||||
|
; (overwriting unused bytes)
|
||||||
|
%define data_start bp+0x4c ; first data sector (dd)
|
||||||
|
; (overwriting unused bytes)
|
||||||
|
|
||||||
|
times 0x5a-$+$$ db 0
|
||||||
|
; not used: [0x42] = byte 0x29 (ext boot param flag)
|
||||||
|
; [0x43] = dword serial
|
||||||
|
; [0x47] = label (padded with 00, 11 bytes)
|
||||||
|
; [0x52] = "FAT32",32,32,32 (not used by Windows)
|
||||||
|
; ([0x5a] is where FreeDOS parts start)
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
; ENTRY
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
real_start: cld
|
||||||
|
cli
|
||||||
|
sub ax, ax
|
||||||
|
mov ds, ax
|
||||||
|
mov bp, 0x7c00
|
||||||
|
|
||||||
|
mov ax, 0x1FE0
|
||||||
|
mov es, ax
|
||||||
|
mov si, bp
|
||||||
|
mov di, bp
|
||||||
|
mov cx, 0x0100
|
||||||
|
rep movsw ; move boot code to the 0x1FE0:0x0000
|
||||||
|
jmp word 0x1FE0:cont
|
||||||
|
|
||||||
|
loadseg_off dw 0, LOADSEG
|
||||||
|
|
||||||
|
; -------------
|
||||||
|
|
||||||
|
cont: mov ds, ax
|
||||||
|
mov ss, ax ; stack and BP-relative moves up, too
|
||||||
|
lea sp, [bp-0x20]
|
||||||
|
sti
|
||||||
|
mov [drive], dl ; BIOS passes drive number in DL
|
||||||
|
|
||||||
|
mov si, msg_LoadFreeDOS
|
||||||
|
call print ; modifies AX BX SI
|
||||||
|
|
||||||
|
|
||||||
|
; -------------
|
||||||
|
|
||||||
|
; CALCPARAMS: figure out where FAT and DATA area starts
|
||||||
|
; (modifies EAX EDX, sets fat_start and data_start variables)
|
||||||
|
|
||||||
|
calc_params: xor eax, eax
|
||||||
|
mov [fat_sector], eax ; init buffer status
|
||||||
|
|
||||||
|
; first, find fat_start:
|
||||||
|
mov ax, [bsResSectors] ; no movzx eax, word... needed
|
||||||
|
add eax, [nHidden]
|
||||||
|
mov [fat_start], eax ; first FAT sector
|
||||||
|
mov [data_start], eax ; (only first part of value)
|
||||||
|
|
||||||
|
; next, find data_start:
|
||||||
|
mov eax, [bsFATs] ; no movzx ... byte needed:
|
||||||
|
; the 2 dw after the bsFATs db are 0 by FAT32 definition :-).
|
||||||
|
imul dword [xsectPerFat] ; (also changes edx)
|
||||||
|
add [data_start], eax ; first DATA sector
|
||||||
|
; (adding in RAM is shorter!)
|
||||||
|
|
||||||
|
; finally, find fat_secshift:
|
||||||
|
mov ax, 512 ; default sector size (means default shift)
|
||||||
|
; shift = log2(secSize) - log2(fatEntrySize)
|
||||||
|
;--- mov cl, 9-2 ; shift is 7 for 512 bytes per sector
|
||||||
|
fatss_scan: cmp ax, [bsBytesPerSec]
|
||||||
|
jz fatss_found
|
||||||
|
add ax,ax
|
||||||
|
;--- inc cx
|
||||||
|
inc word [fat_secshift] ;XXX ; initially 9-2 (byte!)
|
||||||
|
jmp short fatss_scan ; try other sector sizes
|
||||||
|
fatss_found:
|
||||||
|
;--- mov [fat_secshift], cl
|
||||||
|
|
||||||
|
; -------------
|
||||||
|
|
||||||
|
; FINDFILE: Searches for the file in the root directory.
|
||||||
|
; Returns: EAX = first cluster of file
|
||||||
|
|
||||||
|
mov eax, [xrootClst] ; root dir cluster
|
||||||
|
|
||||||
|
ff_next_clust: push eax ; save cluster
|
||||||
|
call convert_cluster
|
||||||
|
jc boot_error ; EOC encountered
|
||||||
|
; EDX is clust/sector, EAX is sector
|
||||||
|
|
||||||
|
ff_next_sector: les bx, [loadsegoff_60] ; load to loadseg:0
|
||||||
|
call readDisk
|
||||||
|
;--- push eax ; save sector
|
||||||
|
|
||||||
|
;--- xor ax, ax ; first dir. entry in this sector
|
||||||
|
xor di, di ;XXX
|
||||||
|
|
||||||
|
; Search for KERNEL.SYS file name, and find start cluster.
|
||||||
|
ff_next_entry: mov cx, 11
|
||||||
|
mov si, filename
|
||||||
|
;--- mov di, ax
|
||||||
|
repe cmpsb
|
||||||
|
jz ff_done ; note that di now is at dirent+11
|
||||||
|
|
||||||
|
;--- add ax, 0x20 ; next directory entry
|
||||||
|
;--- cmp ax, [bsBytesPerSec] ; end of sector reached?
|
||||||
|
add di, byte 0x20 ;XXX
|
||||||
|
and di, byte -0x20 ; 0xffe0 ;XXX
|
||||||
|
cmp di, [bsBytesPerSec] ;XXX
|
||||||
|
jnz ff_next_entry
|
||||||
|
|
||||||
|
;--- pop eax ; restore sector
|
||||||
|
dec dx ; next sector in cluster
|
||||||
|
jnz ff_next_sector
|
||||||
|
|
||||||
|
ff_walk_fat: pop eax ; restore current cluster
|
||||||
|
call next_cluster ; find next cluster
|
||||||
|
jmp ff_next_clust
|
||||||
|
|
||||||
|
ff_done: push word [es:di+0x14-11] ; get cluster number HI
|
||||||
|
push word [es:di+0x1A-11] ; get cluster number LO
|
||||||
|
pop eax ; convert to 32bit
|
||||||
|
|
||||||
|
sub bx, bx ; ES points to LOADSEG
|
||||||
|
; (kernel -> ES:BX)
|
||||||
|
|
||||||
|
; -------------
|
||||||
|
|
||||||
|
read_kernel: push eax
|
||||||
|
call convert_cluster
|
||||||
|
jc boot_success ; EOC encountered - done
|
||||||
|
; EDX is sectors in cluster, EAX is sector
|
||||||
|
|
||||||
|
rk_in_cluster: call readDisk
|
||||||
|
dec dx
|
||||||
|
jnz rk_in_cluster ; loop over sect. in cluster
|
||||||
|
|
||||||
|
rk_walk_fat: pop eax
|
||||||
|
call next_cluster
|
||||||
|
jmp read_kernel
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
boot_success: mov bl, [drive]
|
||||||
|
jmp far [loadsegoff_60]
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
boot_error: mov si, msg_BootError
|
||||||
|
call print ; modifies AX BX SI
|
||||||
|
|
||||||
|
wait_key: xor ah,ah
|
||||||
|
int 0x16 ; wait for a key
|
||||||
|
reboot: int 0x19 ; reboot the machine
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
; given a cluster number, find the number of the next cluster in
|
||||||
|
; the FAT chain. Needs fat_secshift and fat_start.
|
||||||
|
; input: EAX - cluster
|
||||||
|
; output: EAX - next cluster
|
||||||
|
|
||||||
|
next_cluster: push es
|
||||||
|
push di
|
||||||
|
push bx
|
||||||
|
|
||||||
|
mov di, ax
|
||||||
|
shl di, 2 ; 32bit FAT
|
||||||
|
|
||||||
|
push ax
|
||||||
|
mov ax, [bsBytesPerSec]
|
||||||
|
dec ax
|
||||||
|
and di, ax ; mask to sector size
|
||||||
|
pop ax
|
||||||
|
|
||||||
|
shr eax, 7 ; e.g. 9-2 for 512 by/sect.
|
||||||
|
fat_afterss: ; selfmodifying code: previous byte is patched!
|
||||||
|
; (to hold the fat_secshift value)
|
||||||
|
|
||||||
|
add eax, [fat_start] ; absolute sector number now
|
||||||
|
|
||||||
|
mov bx, FATSEG
|
||||||
|
mov es, bx
|
||||||
|
sub bx, bx
|
||||||
|
|
||||||
|
cmp eax, [fat_sector] ; already buffered?
|
||||||
|
jz cn_buffered
|
||||||
|
mov [fat_sector],eax ; number of buffered sector
|
||||||
|
call readDisk
|
||||||
|
|
||||||
|
cn_buffered: and byte [es:di+3],0x0f ; mask out top 4 bits
|
||||||
|
mov eax, [es:di] ; read next cluster number
|
||||||
|
|
||||||
|
pop bx
|
||||||
|
pop di
|
||||||
|
pop es
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
; Convert cluster number to the absolute sector number
|
||||||
|
; ... or return carry if EndOfChain! Needs data_start.
|
||||||
|
; input: EAX - target cluster
|
||||||
|
; output: EAX - absolute sector
|
||||||
|
; EDX - [bsSectPerClust] (byte)
|
||||||
|
; carry clear
|
||||||
|
; (if carry set, EAX/EDX unchanged, end of chain)
|
||||||
|
|
||||||
|
convert_cluster:
|
||||||
|
cmp eax, 0x0ffffff8 ; if end of cluster chain...
|
||||||
|
jnb end_of_chain
|
||||||
|
|
||||||
|
; sector = (cluster-2) * clustersize + data_start
|
||||||
|
dec eax
|
||||||
|
dec eax
|
||||||
|
|
||||||
|
movzx edx, byte [bsSecPerClust]
|
||||||
|
push edx
|
||||||
|
mul edx
|
||||||
|
pop edx
|
||||||
|
add eax, [data_start]
|
||||||
|
; here, carry is unset (unless parameters are wrong)
|
||||||
|
ret
|
||||||
|
|
||||||
|
end_of_chain: stc ; indicate EOC by carry
|
||||||
|
ret
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
; PRINT - prints string DS:SI
|
||||||
|
; modifies AX BX SI
|
||||||
|
|
||||||
|
printchar: xor bx, bx ; video page 0
|
||||||
|
mov ah, 0x0e ; print it
|
||||||
|
int 0x10 ; via TTY mode
|
||||||
|
print: lodsb ; get token
|
||||||
|
cmp al, 0 ; end of string?
|
||||||
|
jne printchar ; until done
|
||||||
|
ret ; return to caller
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
; Read a sector from disk, using LBA
|
||||||
|
; input: EAX - 32-bit DOS sector number
|
||||||
|
; ES:BX - destination buffer
|
||||||
|
; (will be filled with 1 sector of data)
|
||||||
|
; output: ES:BX points one byte after the last byte read.
|
||||||
|
; EAX - next sector
|
||||||
|
|
||||||
|
readDisk: push dx
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
|
||||||
|
read_next: push eax ; would ax be enough?
|
||||||
|
mov di, sp ; remember parameter block end
|
||||||
|
|
||||||
|
;--- db 0x66 ; operand size override (push dword)
|
||||||
|
push byte 0 ;XXX ; other half of the 32 bits at [C]
|
||||||
|
; (did not trust "o32 push byte 0" opcode)
|
||||||
|
push byte 0 ; [C] sector number high 32bit
|
||||||
|
push eax ; [8] sector number low 32bit
|
||||||
|
push es ; [6] buffer segment
|
||||||
|
push bx ; [4] buffer offset
|
||||||
|
push byte 1 ; [2] 1 sector (word)
|
||||||
|
push byte 16 ; [0] size of parameter block (word)
|
||||||
|
mov si, sp
|
||||||
|
mov dl, [drive]
|
||||||
|
mov ah, 42h ; disk read
|
||||||
|
int 0x13
|
||||||
|
|
||||||
|
mov sp, di ; remove parameter block from stack
|
||||||
|
; (without changing flags!)
|
||||||
|
pop eax ; would ax be enough?
|
||||||
|
|
||||||
|
jnc read_ok ; jump if no error
|
||||||
|
|
||||||
|
push ax ; !!
|
||||||
|
xor ah, ah ; else, reset and retry
|
||||||
|
int 0x13
|
||||||
|
pop ax ; !!
|
||||||
|
jmp read_next
|
||||||
|
|
||||||
|
read_ok: inc eax ; next sector
|
||||||
|
add bx, word [bsBytesPerSec]
|
||||||
|
jnc no_incr_es ; if overflow...
|
||||||
|
|
||||||
|
mov dx, es
|
||||||
|
add dh, 0x10 ; ...add 1000h to ES
|
||||||
|
mov es, dx
|
||||||
|
|
||||||
|
no_incr_es: pop di
|
||||||
|
pop si
|
||||||
|
pop dx
|
||||||
|
ret
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
msg_LoadFreeDOS db "Loading FreeDOS ",0
|
||||||
|
|
||||||
|
times 0x01ee-$+$$ db 0
|
||||||
|
|
||||||
|
msg_BootError db "No "
|
||||||
|
; currently, only "kernel.sys not found" gives a message,
|
||||||
|
; but read errors in data or root or fat sectors do not.
|
||||||
|
|
||||||
|
filename db "KERNEL SYS"
|
||||||
|
|
||||||
|
sign dw 0, 0xAA55
|
||||||
|
; Win9x uses all 4 bytes as magic value here.
|
33
boot/makefile
Normal file
33
boot/makefile
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#
|
||||||
|
# makefile for DOS-C boot
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
!include "../mkfiles/generic.mak"
|
||||||
|
|
||||||
|
production: fat12com.bin fat16com.bin fat32chs.bin fat32lba.bin oemfat12.bin oemfat16.bin
|
||||||
|
|
||||||
|
fat12com.bin: boot.asm
|
||||||
|
$(NASM) -dISFAT12 boot.asm -l$*.lst -ofat12com.bin
|
||||||
|
|
||||||
|
fat16com.bin: boot.asm
|
||||||
|
$(NASM) -dISFAT16 boot.asm -l$*.lst -ofat16com.bin
|
||||||
|
|
||||||
|
fat32chs.bin: boot32.asm
|
||||||
|
$(NASM) boot32.asm -l$*.lst -ofat32chs.bin
|
||||||
|
|
||||||
|
fat32lba.bin: boot32lb.asm
|
||||||
|
$(NASM) boot32lb.asm -l$*.lst -ofat32lba.bin
|
||||||
|
|
||||||
|
oemfat12.bin: oemboot.asm
|
||||||
|
$(NASM) -dISFAT12 oemboot.asm -l$*.lst -ooemfat12.bin
|
||||||
|
|
||||||
|
oemfat16.bin: oemboot.asm
|
||||||
|
$(NASM) -dISFAT16 oemboot.asm -l$*.lst -ooemfat16.bin
|
||||||
|
|
||||||
|
clobber: clean
|
||||||
|
-$(RM) *.bin status.me
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-$(RM) *.lst *.map *.bak *.obj
|
||||||
|
|
648
boot/oemboot.asm
Normal file
648
boot/oemboot.asm
Normal file
@ -0,0 +1,648 @@
|
|||||||
|
;
|
||||||
|
; File:
|
||||||
|
; oemboot.asm
|
||||||
|
; 2004, Kenneth J. Davis
|
||||||
|
; Copyright (c) 200?, <add name here>
|
||||||
|
; Description:
|
||||||
|
; OEM boot sector for FreeDOS compatible with IBM's (R) PC-DOS,
|
||||||
|
; and Microsoft's (R) MS-DOS. It may work with older OpenDOS/DR-DOS,
|
||||||
|
; although the standard FreeDOS boot sector is needed with ver 7+
|
||||||
|
; releases. May work with other versions of DOS that use
|
||||||
|
; IBMBIO.COM/IBMDOS.COM pair. This boot sector loads only up
|
||||||
|
; to 58 sectors (29KB) of the kernel (IBMBIO.COM) to 0x70:0 then
|
||||||
|
; jumps to it. As best I can tell, PC-DOS (and MS-DOS up to version
|
||||||
|
; 6.xx behaves similar) expects on entry for:
|
||||||
|
; ch = media id byte in the boot sector
|
||||||
|
; dl = BIOS drive booted from (0x00=A:, 0x80=C:, ...)
|
||||||
|
; ax:bx = the starting (LBA) sector of cluster 2 (ie the 1st
|
||||||
|
; data sector, which is 0x0000:0021 for FAT12)
|
||||||
|
; ?note? IBMBIO.COM/IO.SYS may use ax:bx and cluster # stored
|
||||||
|
; elsewhere (perhaps dir entry still at 0x50:0) to determine
|
||||||
|
; starting sector for full loading of kernel file.
|
||||||
|
; it also expects the boot sector (in particular the BPB)
|
||||||
|
; to still be at 0x0:7C00, the directory entry for IBMBIO.COM
|
||||||
|
; (generally first entry of first sector of the root directory)
|
||||||
|
; at 0x50:0 (DOS Data Area). The original boot sector may update
|
||||||
|
; the floppy disk parameter table (int 1Eh), but we don't so
|
||||||
|
; may fail for any systems where the changes (???) are needed.
|
||||||
|
; If the above conditions are not met, then IBMBIO.COM will
|
||||||
|
; print the not a bootable disk error message.
|
||||||
|
;
|
||||||
|
; For MS-DOS >= 7 (ie Win9x DOS) the following conditions
|
||||||
|
; must be met:
|
||||||
|
; bp = 0x7C00, ie offset boot sector loaded at
|
||||||
|
; [bp-4] = the starting (LBA) sector of cluster 2 (ie the 1st
|
||||||
|
; data sector [this is the same as ax:bx for earlier versions
|
||||||
|
; and dx:ax in Win9x boot sector]
|
||||||
|
; The starting cluster of the kernel file is stored in
|
||||||
|
; di for FAT 12/16 (where si is a don't care) and si:di
|
||||||
|
; for FAT 32.
|
||||||
|
; The values for ax,bx,cx,dx,ds and the stack do not
|
||||||
|
; seem to be important (used by IO.SYS) and so may be any value
|
||||||
|
; (though dx:ax=[data_start], cx=0, bx=0x0f00 on FAT12 or
|
||||||
|
; 0x0700 on FAT32, ds=0, ss:sp=0:7b??)
|
||||||
|
|
||||||
|
; the boot time stack may store the original int1E floppy
|
||||||
|
; parameter table, otherwise nothing else important seems
|
||||||
|
; stored there and I am unsure if even this value is used
|
||||||
|
; beyond boot sector code.
|
||||||
|
|
||||||
|
;
|
||||||
|
; This boot sector only supports FAT12/FAT16 as PC-DOS
|
||||||
|
; does not support FAT32 and newer FAT32 capable DOSes
|
||||||
|
; probably have different boot requirements; also do NOT
|
||||||
|
; use it to boot the FreeDOS kernel as it expects to be
|
||||||
|
; fully loaded by boot sector (> 29KB & usually to 0x60:0).
|
||||||
|
;
|
||||||
|
; WARNING: PC-DOS has additional requirements, in particular,
|
||||||
|
; it may expect that IBMBIO.COM and IBMDOS.COM be the 1st
|
||||||
|
; two entries in the root directory (even before the label)
|
||||||
|
; and that they occupy the 1st consecutive data sectors.
|
||||||
|
; Newer releases may support other positions, but still
|
||||||
|
; generally should occupy consecutive sectors. These conditions
|
||||||
|
; can usually be met by running sys on a freshly formatted
|
||||||
|
; and un-label'd disk.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; Derived From:
|
||||||
|
; boot.asm
|
||||||
|
; DOS-C boot
|
||||||
|
;
|
||||||
|
; Copyright (c) 1997, 2000-2004
|
||||||
|
; Svante Frey, Jim Hall, Jim Tabor, Bart Oldeman,
|
||||||
|
; Tom Ehlert, Eric Auer, Luchezar Georgiev, Jon Gentle
|
||||||
|
; and Michal H. Tyc (DR-DOS adaptation, boot26dr.asm)
|
||||||
|
; All Rights Reserved
|
||||||
|
;
|
||||||
|
; This file is part of FreeDOS.
|
||||||
|
;
|
||||||
|
; DOS-C is free software; you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation; either version
|
||||||
|
; 2, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; DOS-C is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||||
|
; the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public
|
||||||
|
; License along with DOS-C; see the file COPYING. If not,
|
||||||
|
; write to the Free Software Foundation, 675 Mass Ave,
|
||||||
|
; Cambridge, MA 02139, USA.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; +--------+
|
||||||
|
; | CLUSTER|
|
||||||
|
; | LIST |
|
||||||
|
; |--------| 0000:7F00
|
||||||
|
; |LBA PKT |
|
||||||
|
; |--------| 0000:7E00 (0:BP+200)
|
||||||
|
; |BOOT SEC| contains BPB
|
||||||
|
; |ORIGIN |
|
||||||
|
; |--------| 0000:7C00 (0:BP)
|
||||||
|
; |VARS | only known is 1st data sector (start of cluster 2)
|
||||||
|
; |--------| 0000:7BFC (DS:[BP-4])
|
||||||
|
; |STACK | minimal 256 bytes (1/2 sector)
|
||||||
|
; |- - - - |
|
||||||
|
; |KERNEL | kernel loaded here (max 58 sectors, 29KB)
|
||||||
|
; |LOADED | also used as FAT buffer
|
||||||
|
; |--------| 0070:0000 (0:0700)
|
||||||
|
; |DOS DA/ | DOS Data Area,
|
||||||
|
; |ROOT DIR| during boot contains directory entries
|
||||||
|
; |--------| 0000:0500
|
||||||
|
; |BDA | BIOS Data Area
|
||||||
|
; +--------+ 0000:0400
|
||||||
|
; |IVT | Interrupt Vector Table
|
||||||
|
; +--------+ 0000:0000
|
||||||
|
|
||||||
|
CPU 8086 ; enable assembler warnings to limit instruction set
|
||||||
|
|
||||||
|
;%define ISFAT12 1 ; only 1 of these should be set,
|
||||||
|
;%define ISFAT16 1 ; defines which FAT is supported
|
||||||
|
|
||||||
|
%define TRYLBAREAD 1 ; undefine to use only CHS int 13h
|
||||||
|
%define SETROOTDIR 1 ; if defined dir entry copied to 0:500
|
||||||
|
%define LOOPONERR 1 ; if defined on error simply loop forever
|
||||||
|
;%define RETRYALWAYS 1 ; if defined retries read forever
|
||||||
|
;%define WINBOOT 1 ; use win9x kernel calling conventions (name & jmp addr)
|
||||||
|
;%define MSCOMPAT 1 ; sets default filename to MSDOS IO.SYS
|
||||||
|
|
||||||
|
%ifdef WINBOOT ; if set also change from PC-DOS to
|
||||||
|
%ifndef MSCOMPAT ; kernel name to MS-DOS kernel name
|
||||||
|
%define MSCOMPAT
|
||||||
|
%endif
|
||||||
|
%endif
|
||||||
|
|
||||||
|
segment .text
|
||||||
|
|
||||||
|
%define BASE 0x7c00 ; boot sector originally at 0x0:BASE
|
||||||
|
%define LOADSEG 0x0070 ; segment to load kernel at LOADSEG:0
|
||||||
|
%define LOADEND 0x07b0 ; limit reads to below this segment
|
||||||
|
; LOADSEG+29KB, else data overwritten
|
||||||
|
|
||||||
|
%define FATBUF bp-0x7500 ; offset of temporary buffer for FAT
|
||||||
|
; chain 0:FATBUF = 0:0700 = LOADSEG:0
|
||||||
|
%define ROOTDIR bp-0x7700 ; offset to buffer for root directory
|
||||||
|
; entry of kernel 0:ROOTDIR
|
||||||
|
%define CLUSTLIST bp+0x0300 ; zero terminated list of clusters
|
||||||
|
; that the kernel occupies
|
||||||
|
|
||||||
|
; Some extra variables
|
||||||
|
; using bp-Entry+variable_name generates smaller code than using just
|
||||||
|
; variable_name, where bp is initialized to Entry, so bp-Entry equals 0
|
||||||
|
|
||||||
|
%define LBA_PACKET bp+0x0200 ; immediately after boot sector
|
||||||
|
%define LBA_SIZE word [LBA_PACKET] ; size of packet, should be 10h
|
||||||
|
%define LBA_SECNUM word [LBA_PACKET+2] ; number of sectors to read
|
||||||
|
%define LBA_OFF LBA_PACKET+4 ; buffer to read/write to
|
||||||
|
%define LBA_SEG LBA_PACKET+6
|
||||||
|
%define LBA_SECTOR_0 word [LBA_PACKET+8 ] ; LBA starting sector #
|
||||||
|
%define LBA_SECTOR_16 word [LBA_PACKET+10]
|
||||||
|
%define LBA_SECTOR_32 word [LBA_PACKET+12]
|
||||||
|
%define LBA_SECTOR_48 word [LBA_PACKET+14]
|
||||||
|
|
||||||
|
%define PARAMS LBA_PACKET+0x10
|
||||||
|
;%define RootDirSecs PARAMS+0x0 ; # of sectors root dir uses
|
||||||
|
%define fat_start PARAMS+0x2 ; first FAT sector
|
||||||
|
;%define root_dir_start PARAMS+0x6 ; first root directory sector
|
||||||
|
%define first_cluster PARAMS+0x0a ; starting cluster of kernel file
|
||||||
|
%define data_start bp-4 ; first data sector (win9x expects here)
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
org BASE
|
||||||
|
|
||||||
|
Entry: jmp short real_start
|
||||||
|
nop
|
||||||
|
|
||||||
|
; bp is initialized to 7c00h
|
||||||
|
%define bsOemName bp+0x03 ; OEM label
|
||||||
|
%define bsBytesPerSec bp+0x0b ; bytes/sector
|
||||||
|
%define bsSecPerClust bp+0x0d ; sectors/allocation unit
|
||||||
|
%define bsResSectors bp+0x0e ; # reserved sectors
|
||||||
|
%define bsFATs bp+0x10 ; # of fats
|
||||||
|
%define bsRootDirEnts bp+0x11 ; # of root dir entries
|
||||||
|
%define bsSectors bp+0x13 ; # sectors total in image
|
||||||
|
%define bsMedia bp+0x15 ; media descrip: fd=2side9sec, etc...
|
||||||
|
%define sectPerFat bp+0x16 ; # sectors in a fat
|
||||||
|
%define sectPerTrack bp+0x18 ; # sectors/track
|
||||||
|
%define nHeads bp+0x1a ; # heads
|
||||||
|
%define nHidden bp+0x1c ; # hidden sectors
|
||||||
|
%define nSectorHuge bp+0x20 ; # sectors if > 65536
|
||||||
|
%define drive bp+0x24 ; drive number
|
||||||
|
%define extBoot bp+0x26 ; extended boot signature
|
||||||
|
%define volid bp+0x27
|
||||||
|
%define vollabel bp+0x2b
|
||||||
|
%define filesys bp+0x36
|
||||||
|
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
; times 0x3E-$+$$ db 0
|
||||||
|
;
|
||||||
|
; Instead of zero-fill,
|
||||||
|
; initialize BPB with values suitable for a 1440 K floppy
|
||||||
|
;
|
||||||
|
db 'IBM 5.0' ; OEM label
|
||||||
|
dw 512 ; bytes per sector
|
||||||
|
db 1 ; sectors per cluster
|
||||||
|
dw 1 ; reserved sectors
|
||||||
|
db 2 ; number of FATs
|
||||||
|
dw 224 ; root directory entries
|
||||||
|
dw 80 * 36 ; total sectors on disk
|
||||||
|
db 0xF0 ; media descriptor
|
||||||
|
dw 9 ; sectors per 1 FAT copy
|
||||||
|
dw 18 ; sectors per track
|
||||||
|
dw 2 ; number of heads
|
||||||
|
dd 0 ; hidden sectors
|
||||||
|
dd 0 ; big total sectors
|
||||||
|
db 0 ; boot unit
|
||||||
|
db 0 ; reserved
|
||||||
|
db 0x29 ; extended boot record id
|
||||||
|
dd 0x12345678 ; volume serial number
|
||||||
|
db 'NO NAME '; volume label
|
||||||
|
db 'FAT12 ' ; filesystem id
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
; ENTRY
|
||||||
|
;-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
real_start:
|
||||||
|
cli ; disable interrupts until stack ready
|
||||||
|
cld ; all string operations increment
|
||||||
|
xor ax, ax ; ensure our segment registers ready
|
||||||
|
mov ds, ax ; cs=ds=es=ss=0x0000
|
||||||
|
mov es, ax
|
||||||
|
mov ss, ax
|
||||||
|
mov bp, BASE
|
||||||
|
lea sp, [bp-4] ; for DOS <7 this may be [bp]
|
||||||
|
|
||||||
|
; For compatibility, diskette parameter vector updated.
|
||||||
|
; lea di [bp+0x3E] ; use 7c3e([bp+3e]) for PC-DOS,
|
||||||
|
; ;lea di [bp] ; but 7c00([bp]) for DR-DOS 7 bug
|
||||||
|
; mov bx, 4 * 1eh ; stored at int 1E's vector
|
||||||
|
; lds si, [bx] ; fetch current int 1eh pointer
|
||||||
|
; push ds ; store original 1eh pointer at stack top
|
||||||
|
; push si ; so can restore later if needed
|
||||||
|
;
|
||||||
|
; Copy table to new location
|
||||||
|
; mov cl, 11 ; the parameter table is 11 bytes
|
||||||
|
; rep movsb ; and copy the parameter block
|
||||||
|
; mov ds, ax ; restore DS
|
||||||
|
;
|
||||||
|
; Note: make desired changes to table here
|
||||||
|
;
|
||||||
|
; Update int1E to new location
|
||||||
|
; mov [bx+2], 0 ; set to 0:bp or 0:bp+3e as appropriate
|
||||||
|
; mov word [bx], 0x7c3e ; (use 0x7c00 for DR-DOS)
|
||||||
|
|
||||||
|
sti ; enable interrupts
|
||||||
|
|
||||||
|
; If updated floppy parameter table then must notify BIOS
|
||||||
|
; Otherwise a reset should not be needed here.
|
||||||
|
; int 0x13 ; reset drive (AX=0)
|
||||||
|
|
||||||
|
;
|
||||||
|
; Note: some BIOS implementations may not correctly pass drive number
|
||||||
|
; 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)
|
||||||
|
;
|
||||||
|
mov [drive], dl ; rely on BIOS drive number in DL
|
||||||
|
|
||||||
|
|
||||||
|
; GETDRIVEPARMS: Calculate start of some disk areas.
|
||||||
|
;
|
||||||
|
mov si, word [nHidden]
|
||||||
|
mov di, word [nHidden+2]
|
||||||
|
add si, word [bsResSectors]
|
||||||
|
adc di, byte 0 ; DI:SI = first FAT sector
|
||||||
|
|
||||||
|
mov word [fat_start], si
|
||||||
|
mov word [fat_start+2], di
|
||||||
|
|
||||||
|
mov al, [bsFATs]
|
||||||
|
cbw
|
||||||
|
mul word [sectPerFat] ; DX:AX = total number of FAT sectors
|
||||||
|
|
||||||
|
add si, ax
|
||||||
|
adc di, dx ; DI:SI = first root directory sector
|
||||||
|
push di ; mov word [root_dir_start+2], di
|
||||||
|
push si ; mov word [root_dir_start], si
|
||||||
|
|
||||||
|
; Calculate how many sectors the root directory occupies.
|
||||||
|
mov bx, [bsBytesPerSec]
|
||||||
|
mov cl, 5 ; divide BX by 32
|
||||||
|
shr bx, cl ; BX = directory entries per sector
|
||||||
|
|
||||||
|
mov ax, [bsRootDirEnts]
|
||||||
|
xor dx, dx
|
||||||
|
div bx ; set AX = sectors per root directory
|
||||||
|
push ax ; mov word [RootDirSecs], ax
|
||||||
|
|
||||||
|
add si, ax
|
||||||
|
adc di, byte 0 ; DI:SI = first data sector
|
||||||
|
|
||||||
|
mov [data_start], si
|
||||||
|
mov [data_start+2], di
|
||||||
|
|
||||||
|
|
||||||
|
; FINDFILE: Searches for the file in the root directory.
|
||||||
|
;
|
||||||
|
; Returns:
|
||||||
|
; AX = first cluster of file
|
||||||
|
|
||||||
|
; First, read the root directory into buffer.
|
||||||
|
; into the temporary buffer. (max 29KB or overruns stuff)
|
||||||
|
|
||||||
|
pop di ; mov di, word [RootDirSecs]
|
||||||
|
pop ax ; mov ax, word [root_dir_start]
|
||||||
|
pop dx ; mov dx, word [root_dir_start+2]
|
||||||
|
lea bx, [ROOTDIR] ; es:bx = 0:0500
|
||||||
|
push es ; save pointer to ROOTDIR
|
||||||
|
call readDisk
|
||||||
|
pop es ; restore pointer to ROOTDIR
|
||||||
|
lea si, [ROOTDIR] ; ds:si = 0:0500
|
||||||
|
|
||||||
|
|
||||||
|
; Search for kernel file name, and find start cluster.
|
||||||
|
|
||||||
|
next_entry: mov cx, 11
|
||||||
|
mov di, filename
|
||||||
|
push si
|
||||||
|
repe cmpsb
|
||||||
|
pop si
|
||||||
|
mov ax, [si+0x1A]; get cluster number from directory entry
|
||||||
|
je ffDone
|
||||||
|
|
||||||
|
add si, byte 0x20 ; go to next directory entry
|
||||||
|
jc boot_error ; fail if not found and si wraps
|
||||||
|
cmp byte [si], 0 ; if the first byte of the name is 0,
|
||||||
|
jnz next_entry ; there are no more files in the directory
|
||||||
|
|
||||||
|
ffDone:
|
||||||
|
mov [first_cluster], ax ; store first cluster number
|
||||||
|
|
||||||
|
%ifdef SETROOTDIR
|
||||||
|
; copy over this portion of root dir to 0x0:500 for PC-DOS
|
||||||
|
; (this may allow IBMBIO.COM to start in any directory entry)
|
||||||
|
lea di, [ROOTDIR] ; es:di = 0:0500
|
||||||
|
mov cx, 32 ; limit to this 1 entry (rest don't matter)
|
||||||
|
rep movsw
|
||||||
|
%endif
|
||||||
|
|
||||||
|
; GETFATCHAIN:
|
||||||
|
;
|
||||||
|
; Reads the FAT chain and stores it in a temporary buffer in the first
|
||||||
|
; 64 kb. The FAT chain is stored an array of 16-bit cluster numbers,
|
||||||
|
; ending with 0.
|
||||||
|
;
|
||||||
|
; The file must fit in conventional memory, so it can't be larger than
|
||||||
|
; 640 kb. The sector size must be at least 512 bytes, so the FAT chain
|
||||||
|
; can't be larger than 2.5 KB (655360 / 512 * 2 = 2560).
|
||||||
|
;
|
||||||
|
; Call with: AX = first cluster in chain
|
||||||
|
|
||||||
|
; Load the complete FAT into memory. The FAT can't be larger
|
||||||
|
; than 128 kb
|
||||||
|
lea bx, [FATBUF] ; es:bx = 0:0700
|
||||||
|
mov di, [sectPerFat]
|
||||||
|
mov ax, word [fat_start]
|
||||||
|
mov dx, word [fat_start+2]
|
||||||
|
call readDisk
|
||||||
|
|
||||||
|
; Set ES:DI to the temporary storage for the FAT chain.
|
||||||
|
push ds
|
||||||
|
pop es
|
||||||
|
lea di, [CLUSTLIST]
|
||||||
|
; Set DS:0 to FAT data we loaded
|
||||||
|
mov ax, LOADSEG
|
||||||
|
mov ds, ax ; ds:0 = 0x70:0 = 0:FATBUF
|
||||||
|
|
||||||
|
mov ax, [first_cluster] ; restore first cluster number
|
||||||
|
push ds ; store LOADSEG
|
||||||
|
|
||||||
|
next_clust: stosw ; store cluster number
|
||||||
|
mov si, ax ; SI = cluster number
|
||||||
|
|
||||||
|
%ifdef ISFAT12
|
||||||
|
; This is a FAT-12 disk.
|
||||||
|
|
||||||
|
fat_12: add si, si ; multiply cluster number by 3...
|
||||||
|
add si, ax
|
||||||
|
shr si, 1 ; ...and divide by 2
|
||||||
|
lodsw
|
||||||
|
|
||||||
|
; If the cluster number was even, the cluster value is now in
|
||||||
|
; bits 0-11 of AX. If the cluster number was odd, the cluster
|
||||||
|
; 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.
|
||||||
|
|
||||||
|
jnc fat_even
|
||||||
|
mov cl, 4
|
||||||
|
shr ax, cl
|
||||||
|
|
||||||
|
fat_even: and ah, 0x0f ; mask off the highest 4 bits
|
||||||
|
cmp ax, 0x0ff8 ; check for EOF
|
||||||
|
jb next_clust ; continue if not EOF
|
||||||
|
|
||||||
|
%endif
|
||||||
|
%ifdef ISFAT16
|
||||||
|
; This is a FAT-16 disk. The maximal size of a 16-bit FAT
|
||||||
|
; is 128 kb, so it may not fit within a single 64 kb segment.
|
||||||
|
|
||||||
|
fat_16: mov dx, LOADSEG
|
||||||
|
add si, si ; multiply cluster number by two
|
||||||
|
jnc first_half ; if overflow...
|
||||||
|
add dh, 0x10 ; ...add 64 kb to segment value
|
||||||
|
|
||||||
|
first_half: mov ds, dx ; DS:SI = pointer to next cluster
|
||||||
|
lodsw ; AX = next cluster
|
||||||
|
|
||||||
|
cmp ax, 0xfff8 ; >= FFF8 = 16-bit EOF
|
||||||
|
jb next_clust ; continue if not EOF
|
||||||
|
%endif
|
||||||
|
|
||||||
|
finished: ; Mark end of FAT chain with 0, so we have a single
|
||||||
|
; EOF marker for both FAT-12 and FAT-16 systems.
|
||||||
|
|
||||||
|
xor ax, ax
|
||||||
|
stosw
|
||||||
|
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
|
||||||
|
; loadFile: Loads the file into memory, one cluster at a time.
|
||||||
|
|
||||||
|
pop es ; set ES:BX to load address 70:0
|
||||||
|
xor bx, bx
|
||||||
|
|
||||||
|
lea si, [CLUSTLIST] ; set DS:SI to the FAT chain
|
||||||
|
|
||||||
|
cluster_next: lodsw ; AX = next cluster to read
|
||||||
|
or ax, ax ; EOF?
|
||||||
|
jne load_next ; no, continue
|
||||||
|
|
||||||
|
; dl set to drive by readDisk
|
||||||
|
mov ch, [bsMedia] ; ch set to media id
|
||||||
|
mov ax, [data_start+2] ; ax:bx set to 1st data sector
|
||||||
|
mov bx, [data_start] ;
|
||||||
|
mov di, [first_cluster] ; set di (si:di on FAT32) to starting cluster #
|
||||||
|
%ifdef WINBOOT
|
||||||
|
jmp LOADSEG:0x0200 ; yes, pass control to kernel
|
||||||
|
%else
|
||||||
|
jmp LOADSEG:0000 ; yes, pass control to kernel
|
||||||
|
%endif
|
||||||
|
|
||||||
|
|
||||||
|
; failed to boot
|
||||||
|
boot_error:
|
||||||
|
call show
|
||||||
|
; db "Error! Hit a key to reboot."
|
||||||
|
db "):."
|
||||||
|
%ifdef LOOPONERR
|
||||||
|
jmp $
|
||||||
|
%else
|
||||||
|
|
||||||
|
; Note: should restore floppy paramater table address at int 0x1E
|
||||||
|
xor ah,ah
|
||||||
|
int 0x13 ; reset floppy
|
||||||
|
int 0x16 ; wait for a key
|
||||||
|
int 0x19 ; reboot the machine
|
||||||
|
%endif
|
||||||
|
|
||||||
|
|
||||||
|
load_next: dec ax ; cluster numbers start with 2
|
||||||
|
dec ax
|
||||||
|
|
||||||
|
mov di, word [bsSecPerClust]
|
||||||
|
and di, 0xff ; DI = sectors per cluster
|
||||||
|
mul di
|
||||||
|
add ax, [data_start]
|
||||||
|
adc dx, [data_start+2] ; DX:AX = first sector to read
|
||||||
|
call readDisk
|
||||||
|
jmp short cluster_next
|
||||||
|
|
||||||
|
|
||||||
|
; shows text after the call to this function.
|
||||||
|
|
||||||
|
show: pop si
|
||||||
|
lodsb ; get character
|
||||||
|
push si ; stack up potential return address
|
||||||
|
mov ah,0x0E ; show character
|
||||||
|
int 0x10 ; via "TTY" mode
|
||||||
|
cmp al,'.' ; end of string?
|
||||||
|
jne show ; until done
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; readDisk: Reads a number of sectors into memory.
|
||||||
|
;
|
||||||
|
; Call with: DX:AX = 32-bit DOS sector number
|
||||||
|
; DI = number of sectors to read
|
||||||
|
; ES:BX = destination buffer
|
||||||
|
;
|
||||||
|
; Returns: CF set on error
|
||||||
|
; ES:BX points one byte after the last byte read.
|
||||||
|
; Exits early if LBA_SEG == LOADEND.
|
||||||
|
|
||||||
|
readDisk: push si ; preserve cluster #
|
||||||
|
|
||||||
|
mov LBA_SECTOR_0,ax
|
||||||
|
mov LBA_SECTOR_16,dx
|
||||||
|
mov word [LBA_SEG], es
|
||||||
|
mov word [LBA_OFF], bx
|
||||||
|
|
||||||
|
call show
|
||||||
|
db "."
|
||||||
|
read_next:
|
||||||
|
|
||||||
|
; initialize constants
|
||||||
|
mov LBA_SIZE, 10h ; LBA packet is 16 bytes
|
||||||
|
mov LBA_SECNUM,1 ; reset LBA count if error
|
||||||
|
|
||||||
|
; limit kernel loading to 29KB, preventing stack & boot sector being overwritten
|
||||||
|
cmp word [LBA_SEG], LOADEND ; skip reading if past the end
|
||||||
|
je read_skip ; of kernel file buffer
|
||||||
|
|
||||||
|
;******************** LBA_READ *******************************
|
||||||
|
|
||||||
|
; check for LBA support
|
||||||
|
|
||||||
|
%ifdef TRYLBAREAD
|
||||||
|
mov ah,041h ;
|
||||||
|
mov bx,055aah ;
|
||||||
|
mov dl, [drive] ; BIOS drive, 0=A:, 80=C:
|
||||||
|
test dl,dl ; don't use LBA addressing on A:
|
||||||
|
jz read_normal_BIOS ; might be a (buggy)
|
||||||
|
; CDROM-BOOT floppy emulation
|
||||||
|
int 0x13
|
||||||
|
jc read_normal_BIOS
|
||||||
|
|
||||||
|
shr cx,1 ; CX must have 1 bit set
|
||||||
|
|
||||||
|
sbb bx,0aa55h - 1 ; tests for carry (from shr) too!
|
||||||
|
jne read_normal_BIOS
|
||||||
|
; OK, drive seems to support LBA addressing
|
||||||
|
lea si,[LBA_PACKET]
|
||||||
|
; setup LBA disk block
|
||||||
|
mov LBA_SECTOR_32,bx ; bx is 0 if extended 13h mode supported
|
||||||
|
mov LBA_SECTOR_48,bx
|
||||||
|
|
||||||
|
|
||||||
|
mov ah,042h
|
||||||
|
jmp short do_int13_read
|
||||||
|
%endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
read_normal_BIOS:
|
||||||
|
|
||||||
|
;******************** END OF LBA_READ ************************
|
||||||
|
mov cx, LBA_SECTOR_0
|
||||||
|
mov dx, LBA_SECTOR_16
|
||||||
|
|
||||||
|
;
|
||||||
|
; translate sector number to BIOS parameters
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; abs = sector offset in track
|
||||||
|
; + head * sectPerTrack offset in cylinder
|
||||||
|
; + track * sectPerTrack * nHeads offset in platter
|
||||||
|
;
|
||||||
|
mov al, [sectPerTrack]
|
||||||
|
mul byte [nHeads]
|
||||||
|
xchg ax, cx
|
||||||
|
; cx = nHeads * sectPerTrack <= 255*63
|
||||||
|
; dx:ax = abs
|
||||||
|
div cx
|
||||||
|
; ax = track, dx = sector + head * sectPertrack
|
||||||
|
xchg ax, dx
|
||||||
|
; dx = track, ax = sector + head * sectPertrack
|
||||||
|
div byte [sectPerTrack]
|
||||||
|
; dx = track, al = head, ah = sector
|
||||||
|
mov cx, dx
|
||||||
|
; cx = track, al = head, ah = sector
|
||||||
|
|
||||||
|
; the following manipulations are necessary in order to
|
||||||
|
; properly place parameters into registers.
|
||||||
|
; ch = cylinder number low 8 bits
|
||||||
|
; cl = 7-6: cylinder high two bits
|
||||||
|
; 5-0: sector
|
||||||
|
mov dh, al ; save head into dh for bios
|
||||||
|
xchg ch, cl ; set cyl no low 8 bits
|
||||||
|
ror cl, 1 ; move track high bits into
|
||||||
|
ror cl, 1 ; bits 7-6 (assumes top = 0)
|
||||||
|
or cl, ah ; merge sector into cylinder
|
||||||
|
inc cx ; make sector 1-based (1-63)
|
||||||
|
|
||||||
|
les bx,[LBA_OFF]
|
||||||
|
mov ax, 0x0201
|
||||||
|
do_int13_read:
|
||||||
|
mov dl, [drive]
|
||||||
|
int 0x13
|
||||||
|
|
||||||
|
read_finished:
|
||||||
|
%ifdef RETRYALWAYS
|
||||||
|
jnc read_ok ; jump if no error
|
||||||
|
xor ah, ah ; else, reset floppy
|
||||||
|
int 0x13
|
||||||
|
read_next_chained:
|
||||||
|
jmp short read_next ; read the same sector again
|
||||||
|
%else
|
||||||
|
jc boot_error ; exit on error
|
||||||
|
%endif
|
||||||
|
|
||||||
|
read_ok:
|
||||||
|
mov ax, word [bsBytesPerSec]
|
||||||
|
mov cl, 4 ; adjust segment pointer by increasing
|
||||||
|
shr ax, cl
|
||||||
|
add word [LBA_SEG], ax ; by paragraphs read in (per sector)
|
||||||
|
|
||||||
|
add LBA_SECTOR_0, byte 1
|
||||||
|
adc LBA_SECTOR_16, byte 0 ; DX:AX = next sector to read
|
||||||
|
dec di ; if there is anything left to read,
|
||||||
|
%ifdef RETRYALWAYS
|
||||||
|
jnz read_next_chained ; continue
|
||||||
|
%else
|
||||||
|
jnz read_next ; continue
|
||||||
|
%endif
|
||||||
|
|
||||||
|
read_skip:
|
||||||
|
mov es, word [LBA_SEG] ; load adjusted segment value
|
||||||
|
; clear carry: unnecessary since adc clears it
|
||||||
|
pop si
|
||||||
|
ret
|
||||||
|
|
||||||
|
times 0x01f1-$+$$ db 0
|
||||||
|
%ifdef MSCOMPAT
|
||||||
|
filename db "IO SYS"
|
||||||
|
%else
|
||||||
|
filename db "IBMBIO COM"
|
||||||
|
%endif
|
||||||
|
db 0,0
|
||||||
|
|
||||||
|
sign dw 0xAA55
|
||||||
|
|
178
build.bat
Normal file
178
build.bat
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
@echo off
|
||||||
|
rem batch file to build everything
|
||||||
|
rem IF NOTHING COMPILES, CHECK IF YOUR CVS CHECKOUT USES CORRECT DOS LINEBREAKS
|
||||||
|
|
||||||
|
if NOT "%1" == "/?" goto start
|
||||||
|
echo ":-----------------------------------------------------------------------"
|
||||||
|
echo ":- Syntax: BUILD [-r] [fat32|fat16] [msc|wc|tc|tcpp|bc] [86|186|386] "
|
||||||
|
echo ":- [debug] [lfnapi] [/L #] [/D value] [list] [upx] [win] "
|
||||||
|
echo ":- option case is significant !! "
|
||||||
|
echo ":- Note: Open Watcom (wc) is the preferred compiler "
|
||||||
|
echo ":-----------------------------------------------------------------------"
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:start
|
||||||
|
|
||||||
|
:- assume an error until successful build
|
||||||
|
set XERROR=1
|
||||||
|
if "%XERROR%" == "" goto noenv
|
||||||
|
|
||||||
|
if "%1" == "-r" call clobber.bat
|
||||||
|
if "%1" == "-r" shift
|
||||||
|
|
||||||
|
if not exist config.bat echo You must copy CONFIG.B to CONFIG.BAT and edit it to reflect your setup!
|
||||||
|
if not exist config.bat goto abort
|
||||||
|
|
||||||
|
call config.bat
|
||||||
|
:-if "%LAST%" == "" goto noenv
|
||||||
|
set dos4g=quiet
|
||||||
|
|
||||||
|
:-----------------------------------------------------------------------
|
||||||
|
:- following is command line handling
|
||||||
|
:- options on the commandline overwrite default settings
|
||||||
|
:-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
:loop_commandline
|
||||||
|
|
||||||
|
if "%1" == "fat32" set XFAT=32
|
||||||
|
if "%1" == "fat16" set XFAT=16
|
||||||
|
|
||||||
|
if "%1" == "msc" set COMPILER=MSCL8
|
||||||
|
if "%1" == "wc" set COMPILER=WATCOM
|
||||||
|
if "%1" == "tc" set COMPILER=TC2
|
||||||
|
if "%1" == "tcpp" set COMPILER=TURBOCPP
|
||||||
|
if "%1" == "bc" set COMPILER=BC
|
||||||
|
|
||||||
|
if "%1" == "86" set XCPU=86
|
||||||
|
if "%1" == "186" set XCPU=186
|
||||||
|
if "%1" == "386" set XCPU=386
|
||||||
|
if "%1" == "x86" goto setCPU
|
||||||
|
|
||||||
|
if "%1" == "upx" set XUPX=upx --8086 --best
|
||||||
|
|
||||||
|
if "%1" == "debug" set ALLCFLAGS=%ALLCFLAGS% -DDEBUG
|
||||||
|
if "%1" == "lfnapi" set ALLCFLAGS=%ALLCFLAGS% -DWITHLFNAPI
|
||||||
|
|
||||||
|
if "%1" == "win" set ALLCFLAGS=%ALLCFLAGS% -DWIN31SUPPORT
|
||||||
|
if "%1" == "win" set NASMFLAGS=%NASMFLAGS% -DWIN31SUPPORT
|
||||||
|
|
||||||
|
if "%1" == "list" set NASMFLAGS=%NASMFLAGS% -l$*.lst
|
||||||
|
|
||||||
|
if "%1" == "/L" goto setLoadSeg
|
||||||
|
if "%1" == "/D" goto setDefine
|
||||||
|
|
||||||
|
:nextOption
|
||||||
|
shift
|
||||||
|
if not "%1" == "" goto loop_commandline
|
||||||
|
|
||||||
|
call default.bat
|
||||||
|
:-if "%LAST%" == "" goto noenv
|
||||||
|
|
||||||
|
:-----------------------------------------------------------------------
|
||||||
|
:- finally - we are going to compile
|
||||||
|
:-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
echo USING OPTIONS of C=[%ALLCFLAGS%] ASM=[%NASMFLAGS%]
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Process UTILS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
echo.
|
||||||
|
cd utils
|
||||||
|
%MAKE% production
|
||||||
|
if errorlevel 1 goto abort-cd
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Process LIB ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
echo.
|
||||||
|
cd ..\lib
|
||||||
|
%MAKE%
|
||||||
|
if errorlevel 1 goto abort-cd
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Process DRIVERS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
echo.
|
||||||
|
cd ..\drivers
|
||||||
|
%MAKE% production
|
||||||
|
if errorlevel 1 goto abort-cd
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Process BOOT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
echo.
|
||||||
|
cd ..\boot
|
||||||
|
%MAKE% production
|
||||||
|
if errorlevel 1 goto abort-cd
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Process SYS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
echo.
|
||||||
|
cd ..\sys
|
||||||
|
%MAKE% production
|
||||||
|
if errorlevel 1 goto abort-cd
|
||||||
|
if NOT "%XUPX%" == "" %XUPX% ..\bin\sys.com
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Process KERNEL +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
echo.
|
||||||
|
cd ..\kernel
|
||||||
|
%MAKE% production
|
||||||
|
if errorlevel 1 goto abort-cd
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
set XERROR=
|
||||||
|
|
||||||
|
:- if you like, put finalizing commands (like copy to floppy) into build2.bat
|
||||||
|
if exist build2.bat call build2.bat
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Processing is done.
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
:setLoadSeg
|
||||||
|
shift
|
||||||
|
if "%1" == "" echo you MUST specify load segment eg 0x60 with /L option
|
||||||
|
if "%1" == "" goto abort
|
||||||
|
set LOADSEG=%1
|
||||||
|
goto nextOption
|
||||||
|
|
||||||
|
:setCPU
|
||||||
|
shift
|
||||||
|
if "%1" == "" echo you MUST specify compiler's cpu cmd line argument, eg -5
|
||||||
|
if "%1" == "" goto abort
|
||||||
|
set XCPU_EX=%1
|
||||||
|
goto nextOption
|
||||||
|
|
||||||
|
:setDefine
|
||||||
|
shift
|
||||||
|
:- Give extra compiler DEFINE flags here
|
||||||
|
if "%1" == "" echo you MUST specify value to define with /D option
|
||||||
|
if "%1" == "" echo such as /D DEBUG : extra DEBUG output
|
||||||
|
if "%1" == "" echo or /D DOSEMU : printf output goes to dosemu log
|
||||||
|
if "%1" == "" echo or /D WIN31SUPPORT : enable Win 3.x hooks
|
||||||
|
if "%1" == "" goto abort
|
||||||
|
if "%2" == "/V" goto :setDefineWithValue
|
||||||
|
set ALLCFLAGS=%ALLCFLAGS% -D%1
|
||||||
|
set NASMFLAGS=%NASMFLAGS% -D%1
|
||||||
|
goto nextOption
|
||||||
|
|
||||||
|
:setDefineWithValue
|
||||||
|
set ALLCFLAGS=%ALLCFLAGS% -D%1=%3
|
||||||
|
set NASMFLAGS=%NASMFLAGS% -D%1=%3
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
goto nextOption
|
||||||
|
|
||||||
|
:noenv
|
||||||
|
echo Unable to set necessary environment variables!
|
||||||
|
goto abort
|
||||||
|
|
||||||
|
:abort-cd
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
:abort
|
||||||
|
echo Compilation was aborted!
|
||||||
|
|
||||||
|
:end
|
||||||
|
call default.bat clearset
|
110
buildall.bat
Normal file
110
buildall.bat
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
@echo off
|
||||||
|
rem IF NOTHING COMPILES, CHECK IF YOUR CVS CHECKOUT USES CORRECT DOS LINEBREAKS
|
||||||
|
|
||||||
|
:- $Id: buildall.bat 1305 2006-10-31 21:13:02Z bartoldeman $
|
||||||
|
|
||||||
|
:----------------------------------------------------------
|
||||||
|
:- batch file to build _many_ KERNELS, hope build works.
|
||||||
|
:- takes 3 minutes on my(TE) Win2K/P700. your milage may vary :-)
|
||||||
|
:----------------------------------------------------------
|
||||||
|
|
||||||
|
if "%1" == "$SUMMARY" goto summary
|
||||||
|
|
||||||
|
set onerror=if not "%XERROR%" == "" goto daswarwohlnix
|
||||||
|
|
||||||
|
:***** MSCL kernels
|
||||||
|
|
||||||
|
call config.bat
|
||||||
|
set dos4g=quiet
|
||||||
|
|
||||||
|
if "%MS_BASE%" == "" goto no_ms
|
||||||
|
call build -r msc 386 fat16
|
||||||
|
%ONERROR%
|
||||||
|
call build -r msc 186 fat16
|
||||||
|
%ONERROR%
|
||||||
|
call build -r msc 86 fat16
|
||||||
|
%ONERROR%
|
||||||
|
call build -r msc 386 fat32
|
||||||
|
%ONERROR%
|
||||||
|
call build -r msc 186 fat32
|
||||||
|
%ONERROR%
|
||||||
|
call build -r msc 86 fat32
|
||||||
|
%ONERROR%
|
||||||
|
:no_ms
|
||||||
|
|
||||||
|
:***** TC 2.01 kernels
|
||||||
|
|
||||||
|
if "%TC2_BASE%" == "" goto no_tc
|
||||||
|
call build -r tc 186 fat16
|
||||||
|
%ONERROR%
|
||||||
|
call build -r tc 86 fat16
|
||||||
|
%ONERROR%
|
||||||
|
call build -r tc 186 fat32
|
||||||
|
%ONERROR%
|
||||||
|
call build -r tc 86 fat32
|
||||||
|
%ONERROR%
|
||||||
|
:no_tc
|
||||||
|
|
||||||
|
:***** (Open) Watcom kernels
|
||||||
|
|
||||||
|
if "%WATCOM%" == "" goto no_wc
|
||||||
|
call build -r wc 386 fat32
|
||||||
|
%ONERROR%
|
||||||
|
call build -r wc 386 fat16
|
||||||
|
%ONERROR%
|
||||||
|
call build -r wc 86 fat32
|
||||||
|
%ONERROR%
|
||||||
|
call build -r wc 86 fat16
|
||||||
|
%ONERROR%
|
||||||
|
:no_wc
|
||||||
|
|
||||||
|
:***** now rebuild the default kernel
|
||||||
|
|
||||||
|
call build -r
|
||||||
|
|
||||||
|
:**************************************************************
|
||||||
|
:* now we build a summary of all kernels HMA size + total size
|
||||||
|
:* Yes, I know - "mit Linux waer das nicht passiert" :-)
|
||||||
|
:* at least, it's possible with standard DOS tools
|
||||||
|
:**************************************************************
|
||||||
|
|
||||||
|
set Sumfile=bin\ksummary.txt
|
||||||
|
set TempSumfile=bin\tsummary.txt
|
||||||
|
|
||||||
|
:****echo >%TempSumfile% Summary of all kernels build
|
||||||
|
:****echo.|date >>%TempSumfile%
|
||||||
|
:****echo.|time >>%TempSumfile%
|
||||||
|
:****for %%i in (bin\k*.map) do call %0 $SUMMARY %%i
|
||||||
|
|
||||||
|
if exist %Sumfile% del %Sumfile%
|
||||||
|
if exist %TempSumfile% del %TempSumfile%
|
||||||
|
>ktemp.bat
|
||||||
|
for %%i in (bin\k*.map) do echo call %0 $SUMMARY %%i >>ktemp.bat
|
||||||
|
sort <ktemp.bat >ktemps.bat
|
||||||
|
call ktemps.bat
|
||||||
|
del ktemp.bat
|
||||||
|
del ktemps.bat
|
||||||
|
|
||||||
|
echo >>%Sumfile% Summary of all kernels build
|
||||||
|
echo.|date >>%Sumfile%
|
||||||
|
echo.|time >>%Sumfile%
|
||||||
|
find <%TempSumfile% "H" >>%Sumfile%
|
||||||
|
del %TempSumfile%
|
||||||
|
|
||||||
|
set TempSumfile=
|
||||||
|
set Sumfile=
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:summary
|
||||||
|
echo H************************************************* %2 >>%TempSumfile%
|
||||||
|
find<%2 " HMA_TEXT"|find/V "HMA_TEXT_START"|find/V "HMA_TEXT_END">>%TempSumfile%
|
||||||
|
find<%2 " STACK">>%TempSumfile%
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:************* done with summary *********************************
|
||||||
|
|
||||||
|
:daswarwohlnix
|
||||||
|
echo Sorry, something didn't work as expected :-(
|
||||||
|
set ONERROR=
|
||||||
|
|
||||||
|
:end
|
37
clean.bat
Normal file
37
clean.bat
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
:- batch file to clean everything
|
||||||
|
:- $Id: clean.bat 1181 2006-05-20 20:45:59Z mceric $
|
||||||
|
|
||||||
|
if not exist config.bat echo You must copy CONFIG.B to CONFIG.BAT and edit it to reflect your setup!
|
||||||
|
if not exist config.bat goto end
|
||||||
|
|
||||||
|
call config.bat
|
||||||
|
call default.bat
|
||||||
|
|
||||||
|
cd utils
|
||||||
|
%MAKE% clean
|
||||||
|
|
||||||
|
cd ..\lib
|
||||||
|
%MAKE% clean
|
||||||
|
|
||||||
|
cd ..\drivers
|
||||||
|
%MAKE% clean
|
||||||
|
|
||||||
|
cd ..\boot
|
||||||
|
%MAKE% clean
|
||||||
|
|
||||||
|
cd ..\sys
|
||||||
|
%MAKE% clean
|
||||||
|
|
||||||
|
cd ..\kernel
|
||||||
|
%MAKE% clean
|
||||||
|
|
||||||
|
cd ..\hdr
|
||||||
|
if exist *.bak del *.bak
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
if exist *.bak del *.bak
|
||||||
|
|
||||||
|
:end
|
||||||
|
default.bat clearset
|
38
clobber.bat
Normal file
38
clobber.bat
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
:- batch file to clobber everything
|
||||||
|
:- $Id: clobber.bat 1181 2006-05-20 20:45:59Z mceric $
|
||||||
|
|
||||||
|
if not exist config.bat echo You must copy CONFIG.B to CONFIG.BAT and edit it to reflect your setup!
|
||||||
|
if not exist config.bat goto end
|
||||||
|
|
||||||
|
call config.bat
|
||||||
|
call default.bat
|
||||||
|
|
||||||
|
cd utils
|
||||||
|
%MAKE% clobber
|
||||||
|
|
||||||
|
cd ..\lib
|
||||||
|
%MAKE% clobber
|
||||||
|
|
||||||
|
cd ..\drivers
|
||||||
|
%MAKE% clobber
|
||||||
|
|
||||||
|
cd ..\boot
|
||||||
|
%MAKE% clobber
|
||||||
|
|
||||||
|
cd ..\sys
|
||||||
|
%MAKE% clobber
|
||||||
|
|
||||||
|
cd ..\kernel
|
||||||
|
%MAKE% clobber
|
||||||
|
|
||||||
|
cd ..\hdr
|
||||||
|
if exist *.bak del *.bak
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
if exist *.bak del *.bak
|
||||||
|
if exist status.me del status.me
|
||||||
|
|
||||||
|
:end
|
||||||
|
default.bat clearset
|
119
config.b
Normal file
119
config.b
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
:-
|
||||||
|
:- batch file that is included in all other batch files for configuration
|
||||||
|
:-
|
||||||
|
|
||||||
|
:-****************************************************************
|
||||||
|
:- NOTICE! You must edit and rename this file to CONFIG.BAT! *
|
||||||
|
:-****************************************************************
|
||||||
|
|
||||||
|
:-*********************************************************************
|
||||||
|
:- determine your compiler settings
|
||||||
|
:-
|
||||||
|
:- you have to
|
||||||
|
:- search for XNASM - and set the path for NASM
|
||||||
|
:- search for COMPILER - and set your compiler
|
||||||
|
:- search for ??_BASE - and set the path to your compiler
|
||||||
|
:-
|
||||||
|
:-*********************************************************************
|
||||||
|
|
||||||
|
:-**********************************************************************
|
||||||
|
:-- define NASM executable - remember - it should not be protected
|
||||||
|
:- mode DJGPP version if you're using Windows NT/2k/XP to compile
|
||||||
|
:- also: DJGPP-nasm crashes when using protected mode Borland's make
|
||||||
|
:-**********************************************************************
|
||||||
|
|
||||||
|
set XNASM=c:\bin\nasm16
|
||||||
|
|
||||||
|
:**********************************************************************
|
||||||
|
:- define your COMPILER type here, pick one of them
|
||||||
|
:**********************************************************************
|
||||||
|
|
||||||
|
:- Turbo C 2.01
|
||||||
|
set COMPILER=TC2
|
||||||
|
:- Turbo C++ 1.01
|
||||||
|
:- set COMPILER=TURBOCPP
|
||||||
|
:- Turbo C 3.0
|
||||||
|
:- set COMPILER=TC3
|
||||||
|
:- Borland C
|
||||||
|
:- set COMPILER=BC5
|
||||||
|
:- Microsoft C
|
||||||
|
:- set COMPILER=MSCL8
|
||||||
|
:- Watcom C
|
||||||
|
:- set COMPILER=WATCOM
|
||||||
|
|
||||||
|
:-**********************************************************************
|
||||||
|
:-- where is the BASE dir of your compiler(s) ??
|
||||||
|
:-**********************************************************************
|
||||||
|
|
||||||
|
set TC2_BASE=c:\tc201
|
||||||
|
:- set TP1_BASE=c:\tcpp
|
||||||
|
:- set TC3_BASE=c:\tc3
|
||||||
|
:- set BC5_BASE=c:\bc5
|
||||||
|
:- set MS_BASE=c:\msvc
|
||||||
|
|
||||||
|
:- if WATCOM maybe you need to set your WATCOM environment variables
|
||||||
|
:- and path
|
||||||
|
:- if not \%WATCOM% == \ goto watcom_defined
|
||||||
|
:- set WATCOM=c:\watcom
|
||||||
|
:- set PATH=%PATH%;%WATCOM%\binw
|
||||||
|
:watcom_defined
|
||||||
|
|
||||||
|
:-**********************************************************************
|
||||||
|
:- where is UPX and which options to use?
|
||||||
|
:-**********************************************************************
|
||||||
|
set XUPX=upx --8086 --best
|
||||||
|
:- or use set XUPX=
|
||||||
|
:- if you don't want to use it
|
||||||
|
|
||||||
|
:-**********************************************************************
|
||||||
|
:- (optionally) which linker to use:
|
||||||
|
:- (otherwise will be determined automatically)
|
||||||
|
:-
|
||||||
|
:- WARNING TLINK needs to be in your PATH!
|
||||||
|
:-**********************************************************************
|
||||||
|
|
||||||
|
:- Turbo Link
|
||||||
|
:- set XLINK=tlink /m/c/s/l
|
||||||
|
:- Microsoft Link
|
||||||
|
:- set XLINK=d:\qb\link /ma
|
||||||
|
:- set XLINK=%MS_BASE%\bin\link /ONERROR:NOEXE /ma /nologo
|
||||||
|
:- WATCOM Link (wlinker is a batch file calling ms2wlink and wlink)
|
||||||
|
:- set XLINK=..\utils\wlinker /ma /nologo
|
||||||
|
|
||||||
|
:- set path for Turbo Link - use OLDPATH to restore normal path
|
||||||
|
:- set OLDPATH=%PATH%
|
||||||
|
:- set PATH=%PATH%;%TC2_BASE%
|
||||||
|
|
||||||
|
:**********************************************************************
|
||||||
|
:* optionally define your MAKE type here, if not then
|
||||||
|
:* it will be automatically determined, pick one of them
|
||||||
|
:* use MS nmake if you want to compile with MSCL
|
||||||
|
:**********************************************************************
|
||||||
|
|
||||||
|
:- Borland MAKE
|
||||||
|
:- set MAKE=%TC2_BASE%\make
|
||||||
|
:- Watcom MAKE in MS mode
|
||||||
|
:- set MAKE=%WATCOM%\binw\wmake /ms
|
||||||
|
:- Microsoft MAKE
|
||||||
|
:- set MAKE=%MS_BASE%\bin\nmake /nologo
|
||||||
|
|
||||||
|
:**********************************************************************
|
||||||
|
:* select your default target: required CPU and what FAT system to support
|
||||||
|
:**********************************************************************
|
||||||
|
|
||||||
|
set XCPU=86
|
||||||
|
:- set XCPU=186
|
||||||
|
:- set XCPU=386
|
||||||
|
|
||||||
|
set XFAT=16
|
||||||
|
:- set XFAT=32
|
||||||
|
|
||||||
|
:- Give extra compiler DEFINE flags here
|
||||||
|
:- such as -DDEBUG : extra DEBUG output
|
||||||
|
:- -DDOSEMU : printf output goes to dosemu log
|
||||||
|
:- set ALLCFLAGS=-DDEBUG
|
||||||
|
|
||||||
|
|
||||||
|
:-
|
||||||
|
:- $Id: config.b 864 2004-04-11 12:21:25Z bartoldeman $
|
||||||
|
:-
|
65
config.m
Normal file
65
config.m
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#
|
||||||
|
# Linux cross compilation only!
|
||||||
|
# config file that is included in the main makefile for configuration
|
||||||
|
#
|
||||||
|
|
||||||
|
#****************************************************************
|
||||||
|
# NOTICE! If you edit you must rename this file to config.mak!*
|
||||||
|
#****************************************************************
|
||||||
|
|
||||||
|
#**********************************************************************
|
||||||
|
#- define NASM executable
|
||||||
|
#**********************************************************************
|
||||||
|
XNASM=nasm
|
||||||
|
|
||||||
|
#**********************************************************************
|
||||||
|
#- where is the BASE dir of your compiler(s) ??
|
||||||
|
#**********************************************************************
|
||||||
|
|
||||||
|
# if WATCOM maybe you need to set your WATCOM environment variables
|
||||||
|
# and path
|
||||||
|
ifndef WATCOM
|
||||||
|
WATCOM=$(HOME)/watcom
|
||||||
|
PATH:=$(WATCOM)/binl:$(PATH)
|
||||||
|
endif
|
||||||
|
|
||||||
|
#**********************************************************************
|
||||||
|
# where is UPX and which options to use?
|
||||||
|
#**********************************************************************
|
||||||
|
XUPX=upx --8086 --best
|
||||||
|
|
||||||
|
# or use
|
||||||
|
#unexport XUPX
|
||||||
|
# without the # if you don't want to use it
|
||||||
|
|
||||||
|
#**********************************************************************
|
||||||
|
# (optionally) which linker to use:
|
||||||
|
# (otherwise will be determined automatically)
|
||||||
|
|
||||||
|
# WATCOM Link
|
||||||
|
#XLINK=wlink
|
||||||
|
|
||||||
|
#*********************************************************************
|
||||||
|
# optionally define your MAKE type here, if not then
|
||||||
|
# it will be automatically determined, pick one of them
|
||||||
|
# use MS nmake if you want to compile with MSCL
|
||||||
|
#*********************************************************************
|
||||||
|
|
||||||
|
# Watcom MAKE in MS mode
|
||||||
|
#MAKE=wmake -ms -h
|
||||||
|
|
||||||
|
#*********************************************************************
|
||||||
|
# select your default target: required CPU and what FAT system to support
|
||||||
|
#*********************************************************************
|
||||||
|
|
||||||
|
XCPU=86
|
||||||
|
# XCPU=186
|
||||||
|
# XCPU=386
|
||||||
|
|
||||||
|
XFAT=16
|
||||||
|
# XFAT=32
|
||||||
|
|
||||||
|
# Give extra compiler DEFINE flags here
|
||||||
|
# such as -DDEBUG : extra DEBUG output
|
||||||
|
# -DDOSEMU : printf output goes to dosemu log
|
||||||
|
# set ALLCFLAGS=-DDEBUG
|
82
default.bat
Normal file
82
default.bat
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
@echo off
|
||||||
|
:- $Id: default.bat 1482 2009-07-11 16:59:43Z perditionc $
|
||||||
|
|
||||||
|
:- with option clearset, clears all config.bat-made environment variables
|
||||||
|
:- without options, MAKE / LINK / ... are set to defaults based on COMPILER ...
|
||||||
|
|
||||||
|
if "%1" == "clearset" goto clearset
|
||||||
|
|
||||||
|
:-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
if not "%COMPILER%" == "" goto skip_cc
|
||||||
|
|
||||||
|
set COMPILER=WATCOM
|
||||||
|
|
||||||
|
echo No compiler specified, defaulting to Open Watcom
|
||||||
|
|
||||||
|
:skip_cc
|
||||||
|
|
||||||
|
:-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
if not "%MAKE%" == "" goto skip_make
|
||||||
|
|
||||||
|
if "%COMPILER%" == "TC2" set MAKE=%TC2_BASE%\make
|
||||||
|
if "%COMPILER%" == "TURBOCPP" set MAKE=%TP1_BASE%\bin\make
|
||||||
|
if "%COMPILER%" == "TC3" set MAKE=%TC3_BASE%\bin\make
|
||||||
|
if "%COMPILER%" == "BC5" set MAKE=%BC5_BASE%\bin\make
|
||||||
|
if "%COMPILER%" == "WATCOM" set MAKE=wmake /ms /h
|
||||||
|
if "%COMPILER%" == "MSCL8" set MAKE=%MS_BASE%\bin\nmake /nologo
|
||||||
|
|
||||||
|
echo Make is %MAKE%.
|
||||||
|
|
||||||
|
:skip_make
|
||||||
|
|
||||||
|
:-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
if not "%XLINK%" == "" goto skip_xlink
|
||||||
|
|
||||||
|
if "%COMPILER%" == "TC2" set XLINK=%TC2_BASE%\tlink /m/c
|
||||||
|
if "%COMPILER%" == "TURBOCPP" set XLINK=%TP1_BASE%\bin\tlink /m/c
|
||||||
|
if "%COMPILER%" == "TC3" set XLINK=%TC3_BASE%\bin\tlink /m/c
|
||||||
|
if "%COMPILER%" == "BC5" set XLINK=%BC5_BASE%\bin\tlink /m/c
|
||||||
|
if "%COMPILER%" == "WATCOM" set XLINK=..\utils\wlinker /ma/nologo
|
||||||
|
if "%COMPILER%" == "MSCL8" set XLINK=%MS_BASE%\bin\link /ONERROR:NOEXE /ma /nologo
|
||||||
|
|
||||||
|
echo Linker is %XLINK%.
|
||||||
|
|
||||||
|
:skip_xlink
|
||||||
|
|
||||||
|
:-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
if not "%XUPX%" == "" set UPXOPT=-U
|
||||||
|
if "%XUPX%" == "" set UPXOPT=
|
||||||
|
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
:clearset
|
||||||
|
|
||||||
|
if not "%OLDPATH%" == "" set PATH=%OLDPATH%
|
||||||
|
if not "%OLDPATH%" == "" set OLDPATH=
|
||||||
|
|
||||||
|
set MAKE=
|
||||||
|
set COMPILER=
|
||||||
|
set ALLCFLAGS=
|
||||||
|
set CFLAGS=
|
||||||
|
set XCPU=
|
||||||
|
set XCPU_EX=
|
||||||
|
set XFAT=
|
||||||
|
set XLINK=
|
||||||
|
set TC2_BASE=
|
||||||
|
set TP1_BASE=
|
||||||
|
set TC3_BASE=
|
||||||
|
set BC5_BASE=
|
||||||
|
set MS_BASE=
|
||||||
|
set XNASM=
|
||||||
|
set NASMFLAGS=
|
||||||
|
set XUPX=
|
||||||
|
set UPXOPT=
|
||||||
|
set LOADSEG=
|
||||||
|
|
||||||
|
:end
|
8
docs/bugs.txt
Normal file
8
docs/bugs.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
The current bug database is available on the web at
|
||||||
|
|
||||||
|
http://sourceforge.net/tracker/?group_id=5109&atid=105109
|
||||||
|
|
||||||
|
Please request an account if you want to report or
|
||||||
|
update bugs. Reading the database needs no login.
|
||||||
|
|
||||||
|
Thanks!
|
120
docs/build.txt
Normal file
120
docs/build.txt
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
Building on DOS or Windows:
|
||||||
|
===========================
|
||||||
|
|
||||||
|
To build the operating system a batch file (BUILD.BAT) is included
|
||||||
|
to make life easier. This file is in the FDKERNEL directory of the
|
||||||
|
distribution. In addition, there is a corresponding batch file
|
||||||
|
(CLEAN.BAT) to clean up the source directories.
|
||||||
|
|
||||||
|
There is a CONFIG.B file that specifies all the paths and names of
|
||||||
|
the compiler, assembler, etc. that you want to use. You MUST copy
|
||||||
|
it to CONFIG.BAT first, then edit it to reflect your setup.
|
||||||
|
|
||||||
|
The reason for this copying of files is that when new releases of the
|
||||||
|
kernel come out, you can extract them over your previous source, and
|
||||||
|
not have to worry about resetting up your configuration because your
|
||||||
|
CONFIG.BAT file will not get replaced!
|
||||||
|
|
||||||
|
Building on Linux:
|
||||||
|
==================
|
||||||
|
|
||||||
|
To cross compile on Linux you need to install Open Watcom 1.8 from
|
||||||
|
www.openwatcom.org and NASM which is probably included in your
|
||||||
|
distribution. You can then copy config.m to config.mak and adjust
|
||||||
|
for the same reasons mentioned above.
|
||||||
|
|
||||||
|
Use the following commands:
|
||||||
|
- to build:
|
||||||
|
make all
|
||||||
|
- to build, overriding a config.mak setting, e.g.:
|
||||||
|
make all XCPU=386
|
||||||
|
- to clean:
|
||||||
|
make clean
|
||||||
|
- to clobber (delete everything that was generated):
|
||||||
|
make clobber
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
======
|
||||||
|
The recommended compiler and assembler at the time of writing (2009/05/19)
|
||||||
|
are OpenWatcom 1.8 and NASM 2.05.01.
|
||||||
|
|
||||||
|
You may need to download the latest version of NASM and a C compiler
|
||||||
|
Be sure to edit the CONFIG.BAT file to reflect where you put the tools.
|
||||||
|
|
||||||
|
You can find NASM at http://nasm.sourceforge.net. Version 0.98.36 or
|
||||||
|
later is strongly recommended. The older 0.98 will also work fine, but
|
||||||
|
any version in between is likely to fail. It's best to use a NASM
|
||||||
|
that is native to your host; that is, when compiling in Windows, use
|
||||||
|
the win32 version. The DJGPP version is less likely to run out of
|
||||||
|
memory than the DOS version.
|
||||||
|
|
||||||
|
Optionally, the kernel can be compressed using UPX. You can find
|
||||||
|
UPX at http://upx.sourceforge.net. Simply adjust config.bat to
|
||||||
|
enable it.
|
||||||
|
|
||||||
|
This kernel compiles with Turbo C 2.01, Turbo C++ 1.01 (now freely
|
||||||
|
available!), Turbo C 3.0, Borland C 4.51 & 5.01. It should work with
|
||||||
|
other Borland and Microsoft compilers and (Open)Watcom C. GCC can
|
||||||
|
compile the kernel but the result does *not* work (no 16-bit x86 support).
|
||||||
|
|
||||||
|
The OpenWatcom 1.0 compiler (or later) for DOS can be downloaded at
|
||||||
|
www.openwatcom.org: you need at least the following zips from
|
||||||
|
ftp://ftp.openwatcom.org/watcom/zips/
|
||||||
|
(see ftp://ftp.openwatcom.org/watcom/zips/layout.txt)
|
||||||
|
|
||||||
|
cm_core_all - Core binaries (All hosts)
|
||||||
|
cm_core_dos - Core binaries (DOS host)
|
||||||
|
cm_core_doswin - Core binaries (DOS & Win hosts)
|
||||||
|
cm_clib_hdr - C runtime library header files
|
||||||
|
cm_clib_a16 - C runtime libraries (16-bit all targets)
|
||||||
|
cm_clib_d16 - C runtime libraries (16-bit DOS)
|
||||||
|
clib_a16 - C runtime libraries (16-bit all targets)
|
||||||
|
clib_d16 - C runtime libraries (16-bit DOS)
|
||||||
|
core_doswin - Core binaries (DOS & Win16 hosts)
|
||||||
|
c_doswin - C compiler (DOS & Win16 hosts)
|
||||||
|
ext_dos4gw - DOS/4GW DOS extender
|
||||||
|
|
||||||
|
Replace "dos" by "nt" for an NT/Win9x host or "os2" for an OS/2 host.
|
||||||
|
The host needs to be a 386+ with at least 8MB of memory.
|
||||||
|
|
||||||
|
If you feel hardy, read on to understand the directory structure. A
|
||||||
|
more complete description of the build environment is contained in a
|
||||||
|
companion book, "The FreeDOS Kernel" (ISBN: 0-87930-436-7) published
|
||||||
|
by R&D Books, an imprint of Miller Freeman of Lawrence, Kansas (USA)
|
||||||
|
and distributed in the USA and Canada by Publishers Group West. See
|
||||||
|
the file README.TXT for more details.
|
||||||
|
|
||||||
|
|
||||||
|
Directory Structure
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
fdkernel root directory
|
||||||
|
+-----bin holds image of distribution disk
|
||||||
|
+-----boot boot.bin (boot sector)
|
||||||
|
+-----docs documentation directory
|
||||||
|
+-----drivers DEVICE.LIB
|
||||||
|
+-----hdr common *.h files
|
||||||
|
+-----kernel The kernel itself
|
||||||
|
+-----lib LIBM.LIB and DEVICE.LIB
|
||||||
|
+-----sys SYS.COM and supporting programs
|
||||||
|
+-----utils Miscellaneous utilities
|
||||||
|
|
||||||
|
|
||||||
|
Organization in a nutshell
|
||||||
|
--------------------------
|
||||||
|
Each component or group of utilities is segregated into its own
|
||||||
|
directory. In order to build that component or utility, a makefile
|
||||||
|
exists in the directory that bears the component's or utility's
|
||||||
|
basename.
|
||||||
|
|
||||||
|
Each makefile has at least two targets, production and clean. The
|
||||||
|
target production builds the expected component or utility and the
|
||||||
|
component clean cleans up the directory for distribution. The
|
||||||
|
makefile may have at least one additional target that builds the
|
||||||
|
component. Study the makefile to better understand this.
|
||||||
|
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
$Id: build.txt 1387 2009-05-19 21:39:29Z bartoldeman $
|
||||||
|
|
||||||
|
|
480
docs/config.txt
Normal file
480
docs/config.txt
Normal file
@ -0,0 +1,480 @@
|
|||||||
|
Title: Config.sys Options
|
||||||
|
|
||||||
|
Configuring your DOS system for use:
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
When booting DOS, you will find it only supports a subset of
|
||||||
|
the devices available on many computers. To support additional
|
||||||
|
devices and advanced features, device specific driver and
|
||||||
|
memory resident software most be loaded. This allows the
|
||||||
|
kernel to be easily extended to support hardware not presently
|
||||||
|
available and take better advantage of installed hardware
|
||||||
|
without wasting resources on computers lacking it. This
|
||||||
|
software is generally loaded during the kernel initialization
|
||||||
|
phase, with details describing what to load expressed in the
|
||||||
|
file CONFIG.SYS. The FreeDOS kernel will first look for a
|
||||||
|
file named FDCONFIG.SYS, should it exist, it will will be used
|
||||||
|
instead of CONFIG.SYS; this allows the FreeDOS kernel to coexist
|
||||||
|
and be configured differently than another DOS kernel. There
|
||||||
|
are additional options available to adjust other aspects of the
|
||||||
|
kernel's behaviour. Note: some options listed below are FreeDOS
|
||||||
|
specific and will not work when using other/older DOS kernels.
|
||||||
|
Below is list of all documented FreeDOS config.sys supported
|
||||||
|
options; additional undocumented options may exist but are not
|
||||||
|
meant for normal usage.
|
||||||
|
|
||||||
|
|
||||||
|
BREAK
|
||||||
|
Usage: break=on|off
|
||||||
|
Set extended Control-C/Control-Break checking to on [default] or off.
|
||||||
|
When set to on, the kernel will perform the check (and invoke current
|
||||||
|
handler if pressed) prior to most int 21h calls. When set to off,
|
||||||
|
the kernel only performs the check on I/O calls using standard streams.
|
||||||
|
Example: break=off
|
||||||
|
|
||||||
|
BUFFERS
|
||||||
|
BUFFERSHIGH
|
||||||
|
Usage: buffers=nn[,m] where nn is in range 1-99 & m is in range 1-8
|
||||||
|
Memory buffers used by the kernel; primary[,secondary]
|
||||||
|
The secondary buffer option is available for compatibility with
|
||||||
|
other DOS kernels, but is ignored by the FreeDOS kernel. In MS DOS,
|
||||||
|
a secondary buffer can used to read-ahead data. FreeDOS does not do
|
||||||
|
this. Buffers are stored in HMA by FreeDOS, unless you select nn to
|
||||||
|
allocate more buffers than fit in HMA. If nn is smaller, unused HMA
|
||||||
|
space will be used for further buffers until something else allocates
|
||||||
|
the HMA space for something else. Even then, at least nn buffers will
|
||||||
|
always be available. You can set nn to a negative value to disable
|
||||||
|
the use of unused HMA space: BUFFERS=-10 only uses 10 buffers, further
|
||||||
|
free space in the HMA will just stay unused. Because the buffers can
|
||||||
|
use the HMA anyway, BUFFERSHIGH does the same as BUFFERS for now, but
|
||||||
|
shows a note about that to inform the user that it does not use UMB.
|
||||||
|
Example: buffers=20
|
||||||
|
|
||||||
|
COUNTRY
|
||||||
|
Usage: country=nnn[,[mmm][,[d:][path]file]]
|
||||||
|
Enables/sets international features of DOS by selecting a country
|
||||||
|
code and (only with the unstable / devel kernel) optionally also
|
||||||
|
a codepage and country file. The stable kernel only uses the nnn
|
||||||
|
value. For full support, use the unstable / devel kernel. You also
|
||||||
|
need a COUNTRY.SYS file for the latter, while the former ignores the
|
||||||
|
filename argument and only sets date/time/number formats, using values
|
||||||
|
compiled into the kernel for a few common countries. It does not set
|
||||||
|
sort order and upper/lower case translation tables. NLSFUNC can only
|
||||||
|
be used with the unstable kernel.
|
||||||
|
nnn is country code (001==US)
|
||||||
|
mmm is code page (437 is default, 850 is updated form, 1252 for Windows)
|
||||||
|
[drive][path]file specifies file with country specific data
|
||||||
|
Example: country=001,850,C:\FDOS\BIN\COUNTRY.SYS
|
||||||
|
|
||||||
|
DEVICE
|
||||||
|
Usage: device=[d:][path]file [options]
|
||||||
|
Load the device driver specified by d:path\file (into conventional
|
||||||
|
[low 640KB] memory). The options are for the driver itself; refer
|
||||||
|
to documentation that came with your particular device for supported
|
||||||
|
options and their usage.
|
||||||
|
Example: device=himem.sys
|
||||||
|
|
||||||
|
DEVICEHIGH
|
||||||
|
Usage: devicehigh=[d:][path]file [options]
|
||||||
|
This is just like device= statement, except it attempts to load
|
||||||
|
the device driver into high memory first (failing that it should
|
||||||
|
load it in conventional memory).
|
||||||
|
Note: The order you load devices may have a large impact on amount
|
||||||
|
of free memory available. In general try to load large (in memory
|
||||||
|
usage) programs into high memory first.
|
||||||
|
Important: You should have a high memory manager such as FDXMS or
|
||||||
|
HIMEM installed (prior device=FDXMS.SYS or device=HIMEM.SYS) before
|
||||||
|
using this option.
|
||||||
|
Example: devicehigh=xcdrom.sys /D:FDCD0001
|
||||||
|
|
||||||
|
DOS
|
||||||
|
Usage: dos=high|low,umb|noumb
|
||||||
|
Indicates whether the kernel should try to load itself into
|
||||||
|
high memory or only conventional (low), and whether to link
|
||||||
|
upper memory blocks in with normal memory or not.
|
||||||
|
Note: only one set need be given, ie dos=high and dos=noumb are ok.
|
||||||
|
Important: if you specify dos=high[,umb|noumb] then you must also
|
||||||
|
load a high memory manager (first), ie FDXMS or HIMEM
|
||||||
|
Example: dos=high,umb
|
||||||
|
Example: dos=low,noumb
|
||||||
|
|
||||||
|
DOSDATA
|
||||||
|
Usage: dosdata=umb
|
||||||
|
Try to load kernel data into Upper Memory Blocks; effectively
|
||||||
|
same as using the [name]HIGH variant of kernel parameters,
|
||||||
|
such as fileshigh, lastdrivehigh, and stackshigh (does not
|
||||||
|
effect drivers loaded using device= or install=).
|
||||||
|
Example: dosdata=umb
|
||||||
|
|
||||||
|
ECHO
|
||||||
|
Usage: ECHO Message to be displayed to user.
|
||||||
|
ECHO displays (echos) its arguments to the console during
|
||||||
|
config.sys processing when device drivers are loaded (when
|
||||||
|
DEVICE= lines are executed).
|
||||||
|
Example:
|
||||||
|
ECHO loading driver 1
|
||||||
|
device=Driver1.sys
|
||||||
|
ECHO driver1 successfully loaded
|
||||||
|
|
||||||
|
EECHO
|
||||||
|
Usage: EECHO Message with ANSI Escape Sequence
|
||||||
|
EECHO allows for echo-ing ANSI Escape Sequences
|
||||||
|
(redefines keyboard input for example). Use a dollar sign ($)
|
||||||
|
to represent the ANSI Escape character. Note: requires an
|
||||||
|
ANSI driver like NANSI loaded prior to use.
|
||||||
|
Example: EECHO feeling $[33;44;1m blue :-)
|
||||||
|
|
||||||
|
FCBS
|
||||||
|
Usage: fcbs=nnn
|
||||||
|
where nnn is in range 1-255
|
||||||
|
Sets the number of File Control Blocks to reserve room for.
|
||||||
|
As file control blocks have been replaced by file handles
|
||||||
|
(see files) and FreeDOS dynamically simulates FCBS from the
|
||||||
|
handle data as needed, nnn is simply ignored by FreeDOS.
|
||||||
|
Example: fcbs=4
|
||||||
|
|
||||||
|
FILES
|
||||||
|
FILESHIGH
|
||||||
|
Usage: files=nnn
|
||||||
|
where nnn is in range 8-255 (default 8)
|
||||||
|
Specifies how many files allowed open at once (reserves
|
||||||
|
memory necessary to support opening this many files).
|
||||||
|
Note: there are other restrictions, so a given program
|
||||||
|
may not be able to actually open this many
|
||||||
|
A good number is 20, though some programs suggest/require
|
||||||
|
30, 40, or even 255
|
||||||
|
Example: files=20
|
||||||
|
|
||||||
|
IDLEHALT
|
||||||
|
Usage: idlehalt=n
|
||||||
|
where n can be -1, 0, 1 or higher (default 0)
|
||||||
|
Activates built-in kernel energy saving functionality if n is
|
||||||
|
not 0. Value -1 enables all hooks, 1 enables only "safe" hooks,
|
||||||
|
CPU halted only if kernel is waiting for CON char device input.
|
||||||
|
Further hooks for n=-1 and n>0 depend on the kernel version:
|
||||||
|
In addition to the safe hooks, other hooks can get activated,
|
||||||
|
for example one for int 0x2f, ax=0x1680 "release time slice".
|
||||||
|
Note: In rare cases, entering or leaving HLT mode (which causes
|
||||||
|
big changes in CPU power consumption) can cause crashes if
|
||||||
|
cheap power supplies or mainboards cannot properly filter
|
||||||
|
the transients. Underclocking the whole system may help.
|
||||||
|
Linux always does a few HLT at boot time, to force a hang
|
||||||
|
on buggy systems early (boot with no-hlt to disable HLT).
|
||||||
|
P90 may have buggy HLT? www.tavi.co.uk/ps2pages/ohland/halt.html
|
||||||
|
|
||||||
|
INSTALL
|
||||||
|
INSTALLHIGH
|
||||||
|
Usage: install=[d:][path]file [options]
|
||||||
|
Load the program specified by d:path\file. Generally used to
|
||||||
|
load TSR (terminate and stay resident) programs with a minimal
|
||||||
|
environment block. The options are for the program itself; refer
|
||||||
|
to documentation that came with your particular software for
|
||||||
|
supported options and usage.
|
||||||
|
Example: install=nansi.com
|
||||||
|
|
||||||
|
KEYBUF
|
||||||
|
Usage: keybuf=n[,m]
|
||||||
|
where n is in 0xac-0xde or 0x106-0x1de range and m is max 0x200
|
||||||
|
Relocate keyboard buffer from the default location at
|
||||||
|
0x40:0x1e-0x3e to 0x40:n-m. The buffer must be more
|
||||||
|
than 32 bytes and must not touch offsets 0x100-0x105.
|
||||||
|
Default for m is "next multiple of 0x100 after n".
|
||||||
|
Note: Some BIOSes store data in the 0xac-0xff area. BASICA will
|
||||||
|
use the 0x106-0x120 area. Other hardware, drivers or apps
|
||||||
|
can collide with KEYBUF, too, so use it at your own risk.
|
||||||
|
A reasonably safe choice should be "keybuf=0x140,0x1c0".
|
||||||
|
|
||||||
|
LASTDRIVE
|
||||||
|
LASTDRIVEHIGH
|
||||||
|
Usage: lastdrive=x
|
||||||
|
where x is last drive letter available for use; A-Z
|
||||||
|
Example: lastdrive=z
|
||||||
|
|
||||||
|
MENU
|
||||||
|
Usage: menu [text]
|
||||||
|
where text is the text you want to be shown while running
|
||||||
|
config.sys. Menu displays a menu while running config.sys.
|
||||||
|
Use menudefault to set a time delayed default option.
|
||||||
|
Lines that begin with 1? will only be processed if the user
|
||||||
|
presses 1. Lines beginning with 23? will be loaded if the
|
||||||
|
user presses either 2 or 3. Options other than 0 can only
|
||||||
|
be selected if at least one "numbers?" line actually uses
|
||||||
|
them, as shown in the example below.
|
||||||
|
Example:
|
||||||
|
menu Please Select Configuration:
|
||||||
|
menu
|
||||||
|
menu Option 0 basic stuff only
|
||||||
|
menu Option 1 CD-ROM
|
||||||
|
menu Option 2 TROUSERS
|
||||||
|
menu Option 3 CD-ROM and TROUSERS
|
||||||
|
0?echo you selected option 0
|
||||||
|
13?device=xcdrom.sys /D:FDCD0001
|
||||||
|
23?install=trousers.com
|
||||||
|
|
||||||
|
MENUCOLOR
|
||||||
|
Usage: menucolor foreground[,background]
|
||||||
|
Use Menucolor before the menu config command, to create a
|
||||||
|
full screen menu which supports the arrow cursor keys.
|
||||||
|
The following colors can be used for foreground and background:
|
||||||
|
0=Black; 1=Blue; 2=Green; 3=Cyan; 4=Red; 5=Magenta;
|
||||||
|
6=Brown; 7=Light Gray
|
||||||
|
The following colors can only be used for the foreground:
|
||||||
|
8=Dark Gray; 9=Light Blue; 10=Light Green; 11=Light Cyan;
|
||||||
|
12=Light Red; 13=Light Magenta; 14=Yellow; 15=White.
|
||||||
|
If you do not use MENUCOLOR, the menu will not be full
|
||||||
|
screen, so some of the BIOS, bootloader and kernel init
|
||||||
|
messages (list of drives, version info...) stays visible.
|
||||||
|
To change the colour to white text on blue, use the following:
|
||||||
|
Example: menucolor 15,1
|
||||||
|
|
||||||
|
MENUDEFAULT
|
||||||
|
Usage: menudefault=defaultoption,delay
|
||||||
|
where delay is the delay time in seconds and defaultoption is the
|
||||||
|
used standard option if the delay time is over. Menudefault sets
|
||||||
|
a time delayed default option for a config.sys menu: If no key
|
||||||
|
has been pressed during [delay] seconds, the default choice is
|
||||||
|
activated. Pressing a key stops the countdown, the kernel will
|
||||||
|
wait infinitely for the user to make a selection. Note that some
|
||||||
|
virtual machines like Bochs can have broken (too fast) timing.
|
||||||
|
Example: menudefault=0,5
|
||||||
|
|
||||||
|
NUMLOCK
|
||||||
|
Usage: numlock=on|off
|
||||||
|
Set the keyboard number lock to on or off.
|
||||||
|
Example: numlock=off
|
||||||
|
|
||||||
|
REM
|
||||||
|
Usage: rem Your remarks!
|
||||||
|
This provides the ability to place comments within the configuration
|
||||||
|
file. The text following the rem until the end of the line is
|
||||||
|
reached is ignored. This may also be used to temporarily disable
|
||||||
|
loading a particular device or other option. A synonym for REM is
|
||||||
|
the semicolon, see the examples.
|
||||||
|
Example: REM DOS=HIGH,UMB
|
||||||
|
Example: ;DOS=HIGH,UMB
|
||||||
|
|
||||||
|
SCREEN
|
||||||
|
Usage: screen=xx
|
||||||
|
Switches into videomode xxx (INT10/11xx/000)
|
||||||
|
where xx should be 0x11 for 8x14 font (28 lines VGA, 25 lines EGA)
|
||||||
|
or 0x12 for 8x8 font (43 lines EGA, 50 lines VGA) or 0x14 for the
|
||||||
|
default VGA font (25 lines VGA). Some newer graphics cards may not
|
||||||
|
have 8x14 fonts in the BIOS. In that case, a driver can be loaded
|
||||||
|
to load a suitable font in RAM, but SCREEN=0x11 should not be used.
|
||||||
|
If xx is less than 15 (0x0f), it is treated as screen mode number,
|
||||||
|
for example 1 for CGA 40x25 color text or 7 for monochrome text.
|
||||||
|
Example: SCREEN=0x12
|
||||||
|
|
||||||
|
SET
|
||||||
|
Usage: set ENVVAR=value
|
||||||
|
Sets the environment variable to provided value.
|
||||||
|
Example: set HOME=C:\home\me
|
||||||
|
|
||||||
|
SHELL
|
||||||
|
SHELLHIGH
|
||||||
|
Usage: shell=[d:][path]file [options]
|
||||||
|
Indicates the shell to use; often used to alter COMMAND.COM's behavior.
|
||||||
|
Note: it is command.com that processes AUTOEXEC.BAT; by using the
|
||||||
|
shell option, you can get command.com to process a differently named
|
||||||
|
file (such as FDAUTO.BAT for coexisting with another DOS using different
|
||||||
|
configuration options) or run a completely different command interpreter
|
||||||
|
such as 4DOS or a (unix) sh variant.
|
||||||
|
Example: shell=C:\4DOS.COM /E:256 /P
|
||||||
|
Example: SHELL=C:\FDOS\bin\command.com C:\FDOS\bin /E:1024 /P=C:\fdauto.bat
|
||||||
|
|
||||||
|
STACKS
|
||||||
|
STACKSHIGH
|
||||||
|
Usage: stacks=nn,mmm
|
||||||
|
where nn is in range 0,8-64 and nnn is in range 32-512
|
||||||
|
Changes number and size of hardware interrupt stacks available
|
||||||
|
nn is number of different stacks and mmm is size in bytes of each one
|
||||||
|
In some cases you can use "stacks=0,0" to use only standard stacks
|
||||||
|
instead of letting DOS allocate extra stacks for hardware interrupts.
|
||||||
|
Example: stacks=16,256
|
||||||
|
|
||||||
|
SWITCHAR
|
||||||
|
Usage: switchar=c
|
||||||
|
Sets the default switchar to character c. Where c is a single character
|
||||||
|
that is used to indicate a command line parameter is an option switch.
|
||||||
|
The default is a forward slash (/). Note: This simply sets the value
|
||||||
|
returned by a get switchar query, it will not effect programs that use
|
||||||
|
hardcoded switch characters. The switch character is the sign used to
|
||||||
|
mark options, for example the "/" in "DIR /w". Good values: "/" and "-".
|
||||||
|
Example: switchar=-
|
||||||
|
|
||||||
|
SWITCHES
|
||||||
|
Usage: switches=/E[:xxx] /F /K /N /W
|
||||||
|
Adjusts boot time processing behaviour.
|
||||||
|
/E enables moving of EBDA (Extended BIOS Data Area), optionally a
|
||||||
|
size in kilobytes may be specified [xxx, in range of 48-1024]
|
||||||
|
/F skips the delay checking for F5/F8 keystroke before processing
|
||||||
|
config.sys [equivalent to SYS CONFIG skipconfigseconds=0]
|
||||||
|
F5 and F8 are only processed if pressed before DOS boots but
|
||||||
|
after the keyboard is set up - right moment is easy to miss.
|
||||||
|
/K forces treating of keyboard as 86 key keyboard, not 102/105 key.
|
||||||
|
Might be useful with BIOSes or drivers which have no or broken
|
||||||
|
handling for 102/105 key keyboards.
|
||||||
|
/N disables F5/F8 support [equivalent to kernel config (SYS CONFIG,
|
||||||
|
run SYS CONFIG /? for explanations) skipconfigseconds=-1]
|
||||||
|
F5 (skip config) and F8 (single step config.sys) are ignored.
|
||||||
|
/W is NOT supported in FreeDOS. This option in MS DOS would set a flag
|
||||||
|
for Windows 3.0 to skip loading wina20.386 from the root directory.
|
||||||
|
|
||||||
|
VERSION
|
||||||
|
Usage: version=x.y
|
||||||
|
FreeDOS specific command to specify what DOS version to report. For
|
||||||
|
a kernel with FAT32 support, 7.10 is a good choice. Otherwise, 5.0
|
||||||
|
and 6.22 are common values. FreeCOM command.com "ver /r" displays
|
||||||
|
both the reported and the FreeDOS internal version numbers.
|
||||||
|
Example: version=6.22
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Advanced - FreeDOS specific CONFIG.SYS menu processing:
|
||||||
|
-------------------------------------------------------
|
||||||
|
|
||||||
|
normal
|
||||||
|
FILES=20
|
||||||
|
DEVICE=MyNetWorkDriver.sys
|
||||||
|
|
||||||
|
'?' - ALWAYS ask if a single line shall be executed
|
||||||
|
FILES=20
|
||||||
|
DEVICE?=MyNetWorkDriver.sys
|
||||||
|
|
||||||
|
|
||||||
|
'!' - NEVER ask if a single line shall be executed, even if single stepping
|
||||||
|
!FILES=20
|
||||||
|
!DOS=HIGH,UMB
|
||||||
|
!BUFFERS=30
|
||||||
|
!DEVICE=MyNetWorkDriver.sys
|
||||||
|
|
||||||
|
|
||||||
|
configuration management - you may compose several configurations,
|
||||||
|
using following special commands:
|
||||||
|
|
||||||
|
MENU
|
||||||
|
MENU select your configuration
|
||||||
|
MENU
|
||||||
|
MENU use (1) for CDROM operation
|
||||||
|
MENU use (2) for NETWORK configuration
|
||||||
|
MENU use (3) to load neither CDROM nor NETWORK drivers
|
||||||
|
MENU
|
||||||
|
MENUDEFAULT=3,60 (configuration 3, wait 60 seconds)
|
||||||
|
|
||||||
|
rem CDROM
|
||||||
|
1? device=CDROM.SYS
|
||||||
|
|
||||||
|
rem NETWORK
|
||||||
|
2? device=MyNetworkDriver.SYS
|
||||||
|
|
||||||
|
rem Menu items can only be selected if at least one line uses them:
|
||||||
|
3? echo Basic configuration selected
|
||||||
|
|
||||||
|
Although this is different than MSDOS menuing possibilities, it
|
||||||
|
allows for selecting from multiple options during bootup while
|
||||||
|
remaining simple. It, however, does not allow for multi-level
|
||||||
|
menuing based configuration schemes.
|
||||||
|
|
||||||
|
|
||||||
|
It's also possible to combine menu options, to avoid writing thing every
|
||||||
|
time again.
|
||||||
|
constructions like 0?devicehigh?=cdrom.sys are also possible
|
||||||
|
("if menu option 0 chosen, ask if you want to load this driver")
|
||||||
|
|
||||||
|
the selected configuration can be determined in AUTOEXEC.BAT in the
|
||||||
|
environment variable CONFIG like
|
||||||
|
|
||||||
|
if %CONFIG% == 0 echo configuration 0 selected
|
||||||
|
|
||||||
|
however, if you have no MENUs in config.sys, then %config% has no value,
|
||||||
|
thus resulting in "IF == 0 echo configuration 0 selected."
|
||||||
|
(which causes syntax errors as there's nothing on the left side of == )
|
||||||
|
|
||||||
|
That's why you better use something like:
|
||||||
|
if [%config%]==[0] echo configuration 0 selected. -or-
|
||||||
|
if "%config%"=="0" echo configuration 0 selected.
|
||||||
|
|
||||||
|
then if there is no menu you have: "IF []==[0] echo configuration 0 selected."
|
||||||
|
(which will of course output nothing)
|
||||||
|
|
||||||
|
thus my config.sys now looks like
|
||||||
|
|
||||||
|
|
||||||
|
!files=20
|
||||||
|
!dos=high,umb
|
||||||
|
!break=off
|
||||||
|
!buffers=30
|
||||||
|
!screen=0x12
|
||||||
|
!lastdrive=z
|
||||||
|
!shell=\command.com /p /e:512 /MSG
|
||||||
|
|
||||||
|
MENU
|
||||||
|
MENU 0 - SoftIce+HIMEM+Network (default)
|
||||||
|
MENU 1 - SoftIce+HIMEM
|
||||||
|
MENU 2 - HIMEM+EMM386
|
||||||
|
MENU
|
||||||
|
MENUDEFAULT=0,0
|
||||||
|
|
||||||
|
|
||||||
|
01? DEVICE=C:\NUMEGA\S-ICE.EXE /TRA 3000 /SYM 400
|
||||||
|
012?DEVICE=himem.exe
|
||||||
|
01? DEVICE=UMBPCI.SYS
|
||||||
|
2? DEVICE=EMM386.EXE NOEMS
|
||||||
|
|
||||||
|
0?device=c:\ntclient\ifshlp.sys
|
||||||
|
|
||||||
|
DEVICE=xcdrom.sys /D:MSCD000
|
||||||
|
|
||||||
|
Full Screen Menus (thanks to Rune Espeseth)
|
||||||
|
|
||||||
|
Use MENUCOLOR=foreground[,background] to obtain a full screen menu
|
||||||
|
where you can use the arrow keys. Example (note that box drawing
|
||||||
|
characters are used that look strange in other character sets):
|
||||||
|
|
||||||
|
REM *** This is the FreeDos Config.sys ***
|
||||||
|
REM *** executed before autoexec.bat ***
|
||||||
|
|
||||||
|
REM *** Set white foreground, red background ***
|
||||||
|
menucolor=7,4
|
||||||
|
|
||||||
|
files=20
|
||||||
|
buffers=20
|
||||||
|
|
||||||
|
REM *** The Menu ***
|
||||||
|
MENU
|
||||||
|
MENU *-------------------------------------------------------*
|
||||||
|
MENU ! My Menu - FreeDOS rules! !
|
||||||
|
MENU *-------------------------------------------------------*
|
||||||
|
MENU ! !
|
||||||
|
MENU ! 1. Test with border !
|
||||||
|
MENU ! !
|
||||||
|
MENU ! 2. Another test... !
|
||||||
|
MENU ! !
|
||||||
|
MENU ! 3. Third choice !
|
||||||
|
MENU ! !
|
||||||
|
MENU ! 4. Fourth choice. !
|
||||||
|
MENU ! !
|
||||||
|
MENU *-------------------------------------------------------*
|
||||||
|
MENU
|
||||||
|
|
||||||
|
MENUDEFAULT=1,10 ( configuration 1, wait 10 seconds)
|
||||||
|
|
||||||
|
REM 1st choice
|
||||||
|
1?ECHO You selected menu #1
|
||||||
|
|
||||||
|
REM 2nd choice
|
||||||
|
2?ECHO You selected menu #2
|
||||||
|
|
||||||
|
REM 3rd choice
|
||||||
|
3?ECHO You selected menu #3
|
||||||
|
|
||||||
|
REM 4th choice
|
||||||
|
4?ECHO You selected menu #4
|
||||||
|
|
||||||
|
|
||||||
|
2002-11-28 - Tom Ehlert
|
||||||
|
2003-07-15 - Bernd Blaauw
|
||||||
|
2003-09-18 - Bart Oldeman
|
||||||
|
2004-07-24 - Jeremy Davis
|
||||||
|
...
|
||||||
|
2008-22-01 - Fritz Mueller / Eric Auer
|
44
docs/contrib.txt
Normal file
44
docs/contrib.txt
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
These are the known contributors of the FreeDOS kernel. If you have
|
||||||
|
contributed in any way to the kernel, but are not on this list, please
|
||||||
|
email the current kernel maintainer so we can add you to the list!
|
||||||
|
|
||||||
|
Thanks to all the following for contributing to the FreeDOS kernel:
|
||||||
|
|
||||||
|
Aitor Santamaria (aitor.sm@wanadoo.es)
|
||||||
|
Arkady Belousov (ark@mos.ru)
|
||||||
|
Bart Oldeman (bart@dosemu.org)
|
||||||
|
Bernd Blaauw (bblaauw@home.nl)
|
||||||
|
Brian Reifsnyder (reifsnyderb@mindspring.com)
|
||||||
|
Charles Dye (raster@highfiber.com)
|
||||||
|
Eduardo Casino (casino_e@terra.es)
|
||||||
|
Eric Auer (e.auer@jpberlin.de)
|
||||||
|
Eric Biederman (ebiederm+eric@ccr.net)
|
||||||
|
Eric Luttmann (ecl@users.sourceforge.net)
|
||||||
|
Fritz Mueller (fritz.mueller@mail.com)
|
||||||
|
Geraldo Netto (geraldonetto@gmail.com)
|
||||||
|
Helmut Fritsch (helmut.fritsch@gcd-hs.de)
|
||||||
|
James Tabor (jimtabor@infohwy.com)
|
||||||
|
Jason Hood (jadoxa@yahoo.com.au)
|
||||||
|
Jens Horstmeier (Jens.Horstmeier@abg1.siemens.de)
|
||||||
|
Jeremy Davis (jeremyd@fdos.org)
|
||||||
|
Jim Hall (jhall@freedos.org)
|
||||||
|
John Price (linux-guru@gcfl.net)
|
||||||
|
Kolya Ksenev (7207@mx.csd.tsu.ru)
|
||||||
|
Lixing Yuan (yuanlixg@china.com)
|
||||||
|
Luchezar Georgiev (lig@linux.tu-varna.acad.bg)
|
||||||
|
Martin Stromberg (ams@ludd.luth.se)
|
||||||
|
Michal Bakowski (mb@orad.pl)
|
||||||
|
Ron Cemer (roncemer@gte.net)
|
||||||
|
"ror4" (ror4@angelfire.com)
|
||||||
|
Rune Espeseth (re@icd.no)
|
||||||
|
Steffen Kaiser (Steffen.Kaiser@fh-rhein-sieg.de)
|
||||||
|
Steve Miller (SMiller@dsfx.com)
|
||||||
|
Tom Ehlert (te@drivesnapshot.de)
|
||||||
|
Victor Vlasenko (victor_vlasenko@hotbox.ru)
|
||||||
|
|
||||||
|
At this place we should also thank Ralf Brown for his interrupt list.
|
||||||
|
It is a truely invaluable resource for us.
|
||||||
|
|
||||||
|
And last, but not least, a big thanks to Pasquale J. Villani
|
||||||
|
(patv@iop.com), who is the original author of DOS-C, on which
|
||||||
|
the FreeDOS kernel is based.
|
340
docs/copying
Normal file
340
docs/copying
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
13
docs/fdkernel.lsm
Normal file
13
docs/fdkernel.lsm
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
Begin3
|
||||||
|
Title: The FreeDOS Kernel
|
||||||
|
Version: SVN
|
||||||
|
Entered-date: N/A
|
||||||
|
Description: The FreeDOS Kernel
|
||||||
|
Keywords: kernel, FreeDOS, DOS, MSDOS
|
||||||
|
Author: (developers: can be reached on the freedos-kernel mailing list)
|
||||||
|
Maintained-by: freedos-kernel@lists.sourceforge.net
|
||||||
|
Primary-site: http://freedos.sourceforge.net/kernel/
|
||||||
|
Original-site: http://www.gcfl.net/pub/FreeDOS/kernel
|
||||||
|
Platforms: DOS, FreeDOS, DOSEMU (OpenWatcom C or Turbo C, NASM, optionally UPX)
|
||||||
|
Copying-policy: GPL2
|
||||||
|
End
|
3911
docs/history.txt
Normal file
3911
docs/history.txt
Normal file
File diff suppressed because it is too large
Load Diff
198
docs/intfns.txt
Normal file
198
docs/intfns.txt
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
Technical Data
|
||||||
|
DOS-C Systems Calls
|
||||||
|
|
||||||
|
The following table represents the industry standard kernel DOS calls
|
||||||
|
currently supported by DOS-C. This list is for FreeDOS build 2036 (5/2006).
|
||||||
|
|
||||||
|
int 20: Terminated Current Process
|
||||||
|
Supported
|
||||||
|
|
||||||
|
int 21: DOS System Call
|
||||||
|
Supported. See table below.
|
||||||
|
|
||||||
|
int 21 Description State Ver Status
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
00h Terminate Program superseded 1.00 supported
|
||||||
|
01h Read Keyboard with Echo superseded 1.00 supported
|
||||||
|
02h Display Character superseded 1.00 supported
|
||||||
|
03h Auxilliary Input superseded 1.00 supported
|
||||||
|
04h Auxilliary Output superseded 1.00 supported
|
||||||
|
05h Print Character superseded 1.00 supported
|
||||||
|
06h Direct Console I/O active 1.00 supported
|
||||||
|
07h Direct Console Input active 1.00 supported
|
||||||
|
08h Read Keyboard Without Echo active 1.00 supported
|
||||||
|
09h Display String superseded 1.00 supported
|
||||||
|
0ah Buffered Keyboard Input superseded 1.00 supported
|
||||||
|
0bh Check Keyboard Status active 1.00 supported
|
||||||
|
0ch Flush Buffer, Read Keyboard active 1.00 supported
|
||||||
|
0dh Reset Drive active 1.00 supported
|
||||||
|
0eh Set Default Drive active 1.00 supported
|
||||||
|
0fh Open File with FCB superseded 1.00 supported
|
||||||
|
10h Close File with FCB superseded 1.00 supported
|
||||||
|
11h Find First File with FCB superseded 1.00 supported
|
||||||
|
12h Find Next File with FCB superseded 1.00 supported
|
||||||
|
13h Delete File with FCB superseded 1.00 supported
|
||||||
|
14h Sequential Read superseded 1.00 supported
|
||||||
|
15h Sequential Write superseded 1.00 supported
|
||||||
|
16h Create File with FCB superseded 1.00 supported
|
||||||
|
17h Rename File with FCB superseded 1.00 supported
|
||||||
|
18h CP/M compatibility obsolete 1.00 supported
|
||||||
|
19h Get Default Drive active 1.00 supported
|
||||||
|
1ah Set Disk Transfer Address active 1.00 supported
|
||||||
|
1bh Get Default Drive Data superseded 2.00 supported
|
||||||
|
1ch Get Drive Data superseded 2.00 supported
|
||||||
|
1dh CP/M compatibility obsolete 1.00 supported
|
||||||
|
1eh CP/M compatibility obsolete 1.00 supported
|
||||||
|
1fh Get Default DPB active 5.00 supported
|
||||||
|
20h CP/M compatibility obsolete 1.00 supported
|
||||||
|
21h Random Read superseded 1.00 supported
|
||||||
|
22h Random Write superseded 1.00 supported
|
||||||
|
23h Get File Size superseded 1.00 supported
|
||||||
|
24h Set Random Record Number superseded 1.00 supported
|
||||||
|
25h Set Interrupt Vector active 1.00 supported
|
||||||
|
26h Create New PSP superseded 1.00 supported
|
||||||
|
27h Random Block Read superseded 1.00 supported
|
||||||
|
28h Random Block Write superseded 1.00 supported
|
||||||
|
29h Parse Filename active 1.00 supported
|
||||||
|
2ah Get Date active 1.00 supported
|
||||||
|
2bh Set Date active 1.00 supported
|
||||||
|
2ch Get Time active 1.00 supported
|
||||||
|
2dh Set Time active 1.00 supported
|
||||||
|
2eh Set/Reset Verify Flag active 1.00 supported
|
||||||
|
2fh Get DTA active 2.00 supported
|
||||||
|
30h Get Version Number active 2.00 supported
|
||||||
|
31h Keep Program active 2.00 supported
|
||||||
|
32h Get DPB active 5.00 supported
|
||||||
|
3300h Get CTRL+C Check Flag active 2.00 supported
|
||||||
|
3301h Set CTRL+C Check Flag active 2.00 supported
|
||||||
|
3305h Get Startup Drive active 2.00 supported
|
||||||
|
3306h Get MS-DOS Version active 5.00 supported
|
||||||
|
33ffh Get DOS-C Release superset supported
|
||||||
|
34h Get InDOS Flag Address active 2.00 supported
|
||||||
|
35h Get Interrupt Vector active 2.00 supported
|
||||||
|
36h Get Disk Free Space active 2.00 supported
|
||||||
|
37h Get/Set Switchar undocumented 2.00 supported
|
||||||
|
38h Get/Set Country Information active 2.00 supported
|
||||||
|
39h Create Directory active 2.00 supported
|
||||||
|
3ah Remove Directory active 2.00 supported
|
||||||
|
3bh Change Current Directory active 2.00 supported
|
||||||
|
3ch Create File with Handle active 2.00 supported
|
||||||
|
3dh Open File with Handle active 2.00 supported
|
||||||
|
3eh Close File with Handle active 2.00 supported
|
||||||
|
3fh Read File or Device active 2.00 supported
|
||||||
|
40h Write File or Device active 2.00 supported
|
||||||
|
41h Delete File active 2.00 supported
|
||||||
|
42h Move File Pointer active 2.00 supported
|
||||||
|
4300h Get File Attributes active 2.00 supported
|
||||||
|
4301h Set File Attributes active 2.00 supported
|
||||||
|
44h Ioctl entry active 2.00 supported
|
||||||
|
45h Duplicate File Handle active 2.00 supported
|
||||||
|
46h Force Duplicate File Handle active 2.00 supported
|
||||||
|
47h Get Current Directory active 2.00 supported
|
||||||
|
48h Allocate Memory active 2.00 supported
|
||||||
|
49h Free Allocated Memory active 2.00 supported
|
||||||
|
4ah Set Memory Block Size active 2.00 supported
|
||||||
|
4b00h Load and Execute Program active 2.00 supported
|
||||||
|
4b01h Load Program active 5.00 supported
|
||||||
|
4b03h Load Overlay active 2.00 supported
|
||||||
|
4b05h Set Execution State active 5.00 PLANNED
|
||||||
|
4ch End Program active 2.00 supported
|
||||||
|
4dh Get Child-Program Return Value active 2.00 supported
|
||||||
|
4eh Find First File active 2.00 supported
|
||||||
|
4fh Find Next File active 2.00 supported
|
||||||
|
50h Set PSP Address active 2.00 supported
|
||||||
|
51h Get PSP Address active 2.00 supported
|
||||||
|
52h Get List of Lists undocumented 2.00 supported
|
||||||
|
53h Translate BPB to DPB undocumented supported
|
||||||
|
54h Get Verify State active 2.00 supported
|
||||||
|
55h Create New Psp undocumented 2.00 supported
|
||||||
|
56h Rename File active 2.00 supported
|
||||||
|
5700h Get File Date and Time active 2.00 supported
|
||||||
|
5701h Set File Date and Time active 2.00 supported
|
||||||
|
5800h Get Allocation Strategy active 3.00 supported
|
||||||
|
5801h Set Allocation Strategy active 3.00 supported
|
||||||
|
5802h Get Upper-Memory Link active 5.00 supported
|
||||||
|
5803h Set Upper-Memory Link active 5.00 supported
|
||||||
|
59h Get Extended Error active 3.00 supported
|
||||||
|
5ah Create Temporary File active 3.00 supported
|
||||||
|
5bh Create New File active 3.00 supported
|
||||||
|
5ch Lock/Unlock File active 3.10 supported
|
||||||
|
5d00h Server Function Call active 3.10 supported
|
||||||
|
5d01h Commit All Files active 3.10 NOTE 3
|
||||||
|
5d02h Close File by Name active 3.10 NOTE 3
|
||||||
|
5d03h Close All Files for Computer active 3.10 NOTE 3
|
||||||
|
5d04h Close All Files for Process active 3.10 NOTE 3
|
||||||
|
5d05h Get Open File List active 3.10 NOTE 3
|
||||||
|
5d06h Get Multiple SDA active 4.00 supported
|
||||||
|
5d07h Get Redirected Printer Mode active 3.10 supported
|
||||||
|
5d08h Set Redirected Printer Mode active 4.00 supported
|
||||||
|
5d09h Flush Redirected Printer Output active 4.00 supported
|
||||||
|
5d0ah Set Extended Error active 4.00 supported
|
||||||
|
5eh Generic Network Functions #1 active 3.10 supported
|
||||||
|
5fh Generic Network Functions #2 active 3.10 supported
|
||||||
|
60h Truename function undocumented 3.00 supported
|
||||||
|
61h UNUSED obsolete supported
|
||||||
|
62h Get current PSP active 3.00 supported
|
||||||
|
63h Multibyte char ops undocumented 3.20 NOTE 1
|
||||||
|
64h ? undocumented returns error
|
||||||
|
65h NLS Functions active 3.30 supported
|
||||||
|
66h Code Page Functions active 3.30 supported
|
||||||
|
67h Set Maximum Handle Count active 3.30 supported
|
||||||
|
68h Commit File active 3.30 supported
|
||||||
|
69h GET/SET DISK SERIAL NUMBER active 4.00 supported
|
||||||
|
6ah COMMIT FILE (same as 68h) active 4.00 supported
|
||||||
|
6bh NULL FUNCTION active 5.00 supported
|
||||||
|
6ch Extended Open/Create active 4.00 supported
|
||||||
|
71h LONG FILENAME FUNCTIONS active 7.00 NOTE 2
|
||||||
|
|
||||||
|
int 22: Program Termination Address.
|
||||||
|
Supported.
|
||||||
|
|
||||||
|
int 23: Ctrl-C/Ctrl_Break Handler.
|
||||||
|
Supported.
|
||||||
|
|
||||||
|
int 24: Critical Error Handler
|
||||||
|
Dummy routine default.
|
||||||
|
|
||||||
|
int 25: Absolute Disk Read
|
||||||
|
Supported.
|
||||||
|
|
||||||
|
int 26: Absolute Disk Write
|
||||||
|
Supported.
|
||||||
|
|
||||||
|
int 27: TSR
|
||||||
|
Supported.
|
||||||
|
|
||||||
|
int 28: DOS Idle.
|
||||||
|
Supported.
|
||||||
|
|
||||||
|
int 29: Fast Console Output.
|
||||||
|
Supported.
|
||||||
|
|
||||||
|
int 2F: DOS Multiplex.
|
||||||
|
Supported (not ALL functions, but MOST functions supported)
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
Note 1 - function 63 Returns error code and lead byte table pointer
|
||||||
|
DS:SI (function 0). Functions 1 and 2 return error code -1
|
||||||
|
(Korean Hangul keyboard input method not supported), but our
|
||||||
|
UNSTABLE kernels can contain more NLSFUNC / COUNTRY support.
|
||||||
|
|
||||||
|
Note 2 - for LFN support, you can load a separate driver like DOSLFN.
|
||||||
|
It will hook int 21 and provide long file name functionality.
|
||||||
|
|
||||||
|
Note 3 - planned, but the implementation will be in SHARE. The DOS
|
||||||
|
kernel only calls hooks (via far call) in a table which is
|
||||||
|
right before the SFT (list of lists [4] points to SFT). As
|
||||||
|
long as our SHARE does not support the hooks, they are not
|
||||||
|
supported either, the unused hook table would waste memory.
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
See COPYING in DOS-C root directory for license.
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
$Id: intfns.txt 1344 2007-07-28 18:29:50Z mceric $
|
21
docs/lfnapi.txt
Normal file
21
docs/lfnapi.txt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
FreeDOS LFN helper API.
|
||||||
|
|
||||||
|
struct lfn_inode
|
||||||
|
{
|
||||||
|
UNICODE name[261];
|
||||||
|
|
||||||
|
struct dirent l_dir; /* this file's dir entry image */
|
||||||
|
|
||||||
|
ULONG l_diroff; /* offset of the dir entry */
|
||||||
|
};
|
||||||
|
typedef struct lfn_inode FAR * lfn_inode_ptr;
|
||||||
|
|
||||||
|
COUNT lfn_allocate_inode(VOID);
|
||||||
|
COUNT lfn_free_inode(COUNT handle);
|
||||||
|
|
||||||
|
COUNT lfn_setup_inode(COUNT handle, ULONG dirstart, ULONG diroff);
|
||||||
|
|
||||||
|
COUNT lfn_create_entries(COUNT handle, lfn_inode_ptr lip);
|
||||||
|
|
||||||
|
COUNT lfn_dir_read(COUNT handle, lfn_inode_ptr lip);
|
||||||
|
COUNT lfn_dir_write(COUNT handle);
|
11
docs/mkboot.txt
Normal file
11
docs/mkboot.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
To create a bootable floppy suitable for copying the system to
|
||||||
|
another drive:
|
||||||
|
|
||||||
|
1. Change directory (if necessary) to where the FreeDOS Kernel BIN
|
||||||
|
directory.
|
||||||
|
|
||||||
|
3. Enter the command "install" to transfer the system files to the
|
||||||
|
diskette in drive A. If you want to install on drive B, type
|
||||||
|
"install b:"
|
||||||
|
|
||||||
|
4. Write protect this disk and use it to boot from.
|
191
docs/nls.txt
Normal file
191
docs/nls.txt
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
Current version: $Id: nls.txt 59 2000-08-06 04:42:32Z jimtabor $
|
||||||
|
|
||||||
|
This document describes all aspects of the implementation
|
||||||
|
of NLS in the FreeDOS kernel -- 2000/06/16 ska
|
||||||
|
|
||||||
|
Note:
|
||||||
|
At this time this document contains only an overall description
|
||||||
|
of how the FreeDOS NLS works; detailed implementation details are
|
||||||
|
found in HDR\NLS.H and KERNEL\NLS_LOAD.C. When the FreeDOS developers
|
||||||
|
finally adopted the current scheme, the larger comments of both
|
||||||
|
files will be merged into a single document -> this file.
|
||||||
|
|
||||||
|
= TOC
|
||||||
|
|
||||||
|
= Capabilites of the current implementation.
|
||||||
|
|
||||||
|
Tested is:
|
||||||
|
+ DOS-38 - Get Country Information
|
||||||
|
+ DOS-65-[2A][0-2] - upcase normal/filename characters
|
||||||
|
+ DOS-65-23 - YesNo prompt character
|
||||||
|
+ DOS-65-01 - Get Extended Country Information
|
||||||
|
+ DOS-65-0[24] - Get pointer to normal/filename upcase table
|
||||||
|
+ DOS-65-05 - Get pointer to filename terminator table
|
||||||
|
+ DOS-65-06 - Get pointer to collating sequence table
|
||||||
|
+ DOS-65-07 - Get pointer to DBCS table
|
||||||
|
Note: Because I don't know how this used, only an empty table
|
||||||
|
has been verified to work properly.
|
||||||
|
+ DOS-66-01 - Get active codepage
|
||||||
|
+ MUX-14-00 - Installation check
|
||||||
|
+ MUX-14-02 - Get extended country information
|
||||||
|
+ MUX-14-04 - Get country information
|
||||||
|
+ MUX-14-FE - DRDOS get extended country information
|
||||||
|
+ MUX-14-23 - validate Yes/No prompt (FreeDOS extension)
|
||||||
|
+ MUX-14-22 - upcase normal character area (FreeDOS extension)
|
||||||
|
+ MUX-14-A2 - upcase filename character area (FreeDOS extension)
|
||||||
|
|
||||||
|
Not implemented is:
|
||||||
|
+ DOS-65-00 - Change DOS-65-XX information
|
||||||
|
+ DOS-66-02 - Set active codepage
|
||||||
|
Note: The rough interface is available, but no code to actually
|
||||||
|
to change the codepage.
|
||||||
|
+ external TSR "NLSFUNC"
|
||||||
|
+ MUX-14-FF - DRDOS prepare codepage
|
||||||
|
|
||||||
|
Not validated is:
|
||||||
|
+ DOS-38 - Set Country code, because:
|
||||||
|
1) it relies on DOS-66-02 (Set active code page) and
|
||||||
|
2) requires external NLSFUNC.
|
||||||
|
+ COUNTRY= statement in CONFIG.SYS (code avilable, but not tested at all)
|
||||||
|
+ MUX-14-01 - change codepage & MUX-14-03 - Set codepage, because
|
||||||
|
the meaning of them is not intentional to me. Both function perform
|
||||||
|
the same request currently, to change the current codepage or country
|
||||||
|
code or both (though, see DOS-66-02).
|
||||||
|
|
||||||
|
|
||||||
|
= Supported NLS packages
|
||||||
|
|
||||||
|
A NLS package may contain data only or data and code.
|
||||||
|
|
||||||
|
If the NLS package shall not contain any code, it must conform to the
|
||||||
|
code already included within the kernel; otherwise an external TSR,
|
||||||
|
usually NLSFUNC, must provide all code by hooking and intercepting
|
||||||
|
the MUX-14-XX API.
|
||||||
|
|
||||||
|
In order to support the external NLSFUNC, all requests for DOS-XX are
|
||||||
|
re-routed through MUX-14; but because the NLS API must work, even if no
|
||||||
|
NLSFUNC has been loaded, the kernel implements a MUX-14 interface of its
|
||||||
|
own and performs all MUX-14 requests.
|
||||||
|
|
||||||
|
However, because the channeling of each request through the MUX chain
|
||||||
|
is considered a very heavy operation (aka time-consuming), flags are
|
||||||
|
introduced when to _bypass_ the MUX chain and directly call the
|
||||||
|
function, which would be activated, if the request would reach the
|
||||||
|
MUX-14 interface of the kernel.
|
||||||
|
|
||||||
|
Because the kernel can only load NLS packages structurally identical to
|
||||||
|
U.S.A./CP437 per definition, the kernel automatically sets those flags,
|
||||||
|
thus, retreives all information from them without to channel the request
|
||||||
|
through the MUX interrupt chain.
|
||||||
|
|
||||||
|
The term "structurally identical" is explained in NLS.H.
|
||||||
|
|
||||||
|
= Using NLS functions from within the kernel
|
||||||
|
|
||||||
|
There are functions to:
|
||||||
|
+ upcase normal characters: DosUpMem(), DosUpString(), DosUpChar()
|
||||||
|
+ upcase filename characters: DosUpFMem(), DosUpFString(), DosUpFChar()
|
||||||
|
+ verify yes/no prompt characters: DosYesNo()
|
||||||
|
+ retreive data (country informaion): DosGetData() [DOS-65-XX],
|
||||||
|
DosGetCountryInformation() [DOS-38]
|
||||||
|
|
||||||
|
They implement the usual DOS interface and refer to the country code and
|
||||||
|
codepage by the usual UWORD numbers; NLS_DEFAULT can be used to specify
|
||||||
|
"current country/codepage". The "Up*()" functions always use the currently
|
||||||
|
active NLS package.
|
||||||
|
|
||||||
|
These functions are also called by the INT-21 handler.
|
||||||
|
|
||||||
|
Because of the MUX chain support these functions more or less wrap the
|
||||||
|
real functions only and check the flags whether to call the internal
|
||||||
|
function directly or re-route the request through MUX.
|
||||||
|
|
||||||
|
Therefore NLS data must not be accessed directly from outside the NLS
|
||||||
|
implementation, but through these functions only.
|
||||||
|
|
||||||
|
CAUTION: The DOS NLS differs between "normal" characters and "filename"
|
||||||
|
characters, that's why one must call DosUpFString() to upcase a
|
||||||
|
filename rather than DosUpString()!
|
||||||
|
|
||||||
|
Note: The NLS subsystem is robust against any type of characters,
|
||||||
|
that means DosUpFMem() can be called with any type of junk, except
|
||||||
|
the pointer to the buffer must not be NULL.
|
||||||
|
|
||||||
|
= NLS and fileformats (UNF)
|
||||||
|
|
||||||
|
The current implementation does not implemented everything MS-DOS like,
|
||||||
|
this includes the internal NLS information block and the fileformat of
|
||||||
|
COUNTRY.SYS. Both structures shall be updated to increase performance,
|
||||||
|
rather than require the kernel to simulate old and obsolated interfaces.
|
||||||
|
To overcome the traditional problem with ever-changing structures
|
||||||
|
a toolset is provided to represent the NLS package in an implementation-
|
||||||
|
independed way and read/write/manipulate etc. pp. this data.
|
||||||
|
|
||||||
|
In the final state NLSFUNC will automatically detect the structures
|
||||||
|
and transform them into the structure required by the kernel.
|
||||||
|
|
||||||
|
To minimize the complexity of these data transformation processes
|
||||||
|
an independed fileformat called UNF (Uniform NLS file Format) has been
|
||||||
|
founded, which is totally plain text (except comments) and somewhat
|
||||||
|
human-readable. Tools will be provided to convert any or particular binary
|
||||||
|
forms of NLS packages into UNF and back.
|
||||||
|
|
||||||
|
Currently available tools:
|
||||||
|
GRAB_UNF: Extracts all information from the current NLS API and dumps it
|
||||||
|
into an UNF file. Supports standard information and DOS-65-03 (lowercase).
|
||||||
|
UNF2HC: Transforms an UNF file into the format of the hardcoded NLS package
|
||||||
|
ready to be used when the kernel is make'ed.
|
||||||
|
|
||||||
|
|
||||||
|
= Testing / Verifying NLS
|
||||||
|
|
||||||
|
Above mentioned UNF toolset includes:
|
||||||
|
GRAB_UNF: Dump NLS package into UNF file and
|
||||||
|
NLSUPTST: Test upcase API (DOS-65-2[0-2]).
|
||||||
|
|
||||||
|
Testing steps:
|
||||||
|
1) Generate an UpCase test verifaction file by running "NLSUPTST /c" on
|
||||||
|
a DOS computer that is entitled to run a good NLS.
|
||||||
|
Alternatively download an UP file corresponding to your locale,
|
||||||
|
that means <country>-<codepage>.UP (without the angle brackets).
|
||||||
|
Note: The numerical country code and codepage must match the settings
|
||||||
|
of your testee system!
|
||||||
|
2) Do the same an generate an sample UNF of a good NLS, by running
|
||||||
|
"GRAB_UNF.EXE" or download one from the internet. the filename is:
|
||||||
|
<country>-<codepage>.UNF
|
||||||
|
Note: If you manually edit the file, run "READ_UNF <filename>" to
|
||||||
|
check the file for errors and dump it in the very same format as
|
||||||
|
GRAB_UNF will.
|
||||||
|
3) Copy GRAB_UNF.EXE, NLSUPTST.EXE and the UP file onto the testee, e.g.
|
||||||
|
floppy. Make sure no .UNF file is located there.
|
||||||
|
4) Create the CONFIG.SYS with only the minimum settings, more than
|
||||||
|
a COUNTRY= and a SHELL= are usually NOT required.
|
||||||
|
5) Create an AUTOEXEC.BAT with this contents (strip leading tabs):
|
||||||
|
GRAB_UNF.EXE
|
||||||
|
NLSUPTST.EXE
|
||||||
|
Note: If you have NLS_DEBUG enabled, a lot of noise will be displayed!
|
||||||
|
6) Reboot the testee
|
||||||
|
7) The GRAB_UNF.EXE will display its success by:
|
||||||
|
"NLS info file for <country>-<codepage> has been created sucessfully"
|
||||||
|
In this case an UNF file has been created <-> the only way to see this
|
||||||
|
success status, if NLS_DEBUG is enabled within the kernel.
|
||||||
|
8) At some point you should see an error message or the good news:
|
||||||
|
"NLS passed all DOS-65-2[0-2] tests"
|
||||||
|
This means that NLSUPTST was successful, because there is no other
|
||||||
|
way to detect this, NLSUPTST must be placed last.
|
||||||
|
9) Compare the <country>-<codepage>.UNF file form the directory you
|
||||||
|
run GRAB_UNF.EXE in with the _equally_ named sample file.
|
||||||
|
Both must be 100% identical, even the number of spaces are.
|
||||||
|
|
||||||
|
If COMMAND.COM fails to run AUTOEXEC.BAT, change the SHELL= line within
|
||||||
|
CONFIG.SYS into:
|
||||||
|
SHELL=GRAB_UNF.EXE
|
||||||
|
-and-
|
||||||
|
SHELL=NLSUPTST.EXE
|
||||||
|
and boot the testee once with each line.
|
||||||
|
|
||||||
|
What do these tests miss?
|
||||||
|
+ None of these tests try to change neither country code nor code page.
|
||||||
|
+ By default, these tests cannot override the internal performance flags
|
||||||
|
and so either the direct-calling or the MUX-re-routing mechanism
|
||||||
|
is tested, but never both.
|
64
docs/readme.cvs
Normal file
64
docs/readme.cvs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
Thanks to Bart Oldeman for helping us with moving the FreeDOS source code
|
||||||
|
from CVS to Subversion! The old CVS repository is still available for
|
||||||
|
browsing, but will no longer be used for managing FreeDOS Projects - and
|
||||||
|
will probably be deleted later. Please use Subversion for the FreeDOS
|
||||||
|
kernel, FreeCOM (FreeDOS command.com), Install, and Mem.
|
||||||
|
|
||||||
|
Bart has also written a Subversion at SourceForge Mini How-to:
|
||||||
|
http://fd-doc.sourceforge.net/wiki/index.php?n=FdDocEn.SVN
|
||||||
|
|
||||||
|
This information was mostly lifted from SourceForge.net:
|
||||||
|
https://sourceforge.net/svn/?group_id
|
||||||
|
|
||||||
|
FreeDOS Subversion:
|
||||||
|
|
||||||
|
Subversion (SVN) is a tool used by many software developers to manage
|
||||||
|
changes within their source code tree. SVN provides the means to store not
|
||||||
|
only the current version of a piece of source code, but a record of all
|
||||||
|
changes (and who made those changes) that have occurred to that source code.
|
||||||
|
Use of SVN is particularly common on projects with multiple developers,
|
||||||
|
since SVN ensures changes made by one developer are not accidentally removed
|
||||||
|
when another developer posts their changes to the source tree.
|
||||||
|
|
||||||
|
In order to access a Subversion repository, you must install a special piece
|
||||||
|
of software called a Subversion client. Subversion clients are available for
|
||||||
|
most any operating system.
|
||||||
|
|
||||||
|
To get a working copy, do svn co URL freedos where URL is the complete path
|
||||||
|
to the trunk of the project you want. For example:
|
||||||
|
|
||||||
|
FreeDOS kernel
|
||||||
|
https://freedos.svn.sourceforge.net/svnroot/freedos/kernel/trunk
|
||||||
|
FreeDOS FreeCOM
|
||||||
|
https://freedos.svn.sourceforge.net/svnroot/freedos/freecom/trunk
|
||||||
|
FreeDOS MEM
|
||||||
|
https://freedos.svn.sourceforge.net/svnroot/freedos/mem/trunk
|
||||||
|
FreeDOS Install
|
||||||
|
https://freedos.svn.sourceforge.net/svnroot/freedos/install/trunk
|
||||||
|
|
||||||
|
Be careful NOT to use the top level
|
||||||
|
* https://freedos.svn.sourceforge.net/svnroot/freedos URL
|
||||||
|
instead of one of the trunk URLs. This will pull all modules, tags and/or
|
||||||
|
branches of the project - it will be huge. Instead, you will want to use
|
||||||
|
/trunk to the URL to check out only the trunk code (main development line).
|
||||||
|
|
||||||
|
Though Subversion repositories are most commonly accessed using a special
|
||||||
|
piece of software called a Subversion client, SourceForge also provides a
|
||||||
|
web-based interface to view Subversion repositories. Browsing the Subversion
|
||||||
|
tree gives you a great view into the current status of this project's code.
|
||||||
|
You may also view the complete history of any file in the repository.
|
||||||
|
|
||||||
|
* Browse Subversion repository
|
||||||
|
http://freedos.svn.sourceforge.net/viewvc/freedos/
|
||||||
|
|
||||||
|
FreeDOS is a trademark of Jim Hall.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Note: Readonly access via the old CVS interface worked as follows:
|
||||||
|
To check out the code, first log in:
|
||||||
|
cvs -z3 -d:pserver:anonymous@cvs.freedos.sourceforge.net:/cvsroot/freedos login
|
||||||
|
Password: Press the Enter key.
|
||||||
|
Then, to get the kernel code:
|
||||||
|
cvs -z3 -d:pserver:anonymous@cvs.freedos.sourceforge.net:/cvsroot/freedos checkout kernel
|
38
docs/readme.txt
Normal file
38
docs/readme.txt
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
INTRODUCTION
|
||||||
|
------------
|
||||||
|
|
||||||
|
This archive contains the current FreeDOS Kernel, also
|
||||||
|
known as DOS-C, originally written by Pasquale J. Villani.
|
||||||
|
|
||||||
|
The FreeDOS Kernel is available from 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_16.zip : binaries for 8086, FAT16
|
||||||
|
ke20xx_32.zip : binaries for 8086, FAT16, FAT32
|
||||||
|
ke20xxsrc.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
|
||||||
|
http://sourceforge.net/tracker/?group_id=5109&atid=105109
|
||||||
|
|
||||||
|
An archive of old (Bugzilla) items is at www.freedos.org/bugzilla/
|
||||||
|
|
||||||
|
There is also a feature request tracker on our SourceForge pages at
|
||||||
|
http://sourceforge.net/tracker/?atid=355109&group_id=5109&func=browse
|
||||||
|
|
||||||
|
|
||||||
|
Copyright
|
||||||
|
---------
|
||||||
|
|
||||||
|
DOS-C is (c) Copyright 1995, 1996 by Pasquale J. Villani
|
||||||
|
All Rights Reserved.
|
223
docs/sys.txt
Normal file
223
docs/sys.txt
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
FreeDOS System Installer v3.6e - Nov 13, 2009
|
||||||
|
documentation by:
|
||||||
|
Jeremy Davis
|
||||||
|
Bart Oldeman
|
||||||
|
|
||||||
|
SYS's standard behavior is very similar (though in
|
||||||
|
my opinion improved) to that of other DOSes.
|
||||||
|
SYS /? (or no options) should provide a general usage,
|
||||||
|
and SYS CONFIG /help (or SYS CONFIG /?) should
|
||||||
|
provide usage for the new configuration options.
|
||||||
|
|
||||||
|
The best documentation is the source itself, but
|
||||||
|
we try to keep this document updated.
|
||||||
|
|
||||||
|
|
||||||
|
Usage: SYS [source] drive: [bootsect] [{option}]
|
||||||
|
source = A:,B:,C:\KERNEL\BIN\,etc., or current directory if not given
|
||||||
|
dest = drive (A:,B:,C:,... or A,B,C,...) to install system to
|
||||||
|
bootsect = name of 512-byte boot sector file image for drive:
|
||||||
|
to write to *instead* of real boot sector
|
||||||
|
{option} is one or more of the following:
|
||||||
|
/BOTH : write to *both* the real boot sector and the image file
|
||||||
|
/BOOTONLY: do *not* copy kernel / shell, only update boot sector or image
|
||||||
|
/UPDATE : copy kernel and update boot sector (do *not* copy shell)
|
||||||
|
/OEM : indicates boot sector, filenames, and load segment to use
|
||||||
|
/OEM:FD use FreeDOS compatible settings
|
||||||
|
/OEM:DR use DR DOS 7+ compatible settings (same as /OEM)
|
||||||
|
/OEM:PC use PC-DOS compatible settings
|
||||||
|
/OEM:MS use MS-DOS compatible settings
|
||||||
|
/OEM:W9x use MS Win9x DOS compatible settings
|
||||||
|
default is /OEM:AUTO, select DOS based on existing files
|
||||||
|
/K name : name of kernel to use in boot sector instead of KERNEL.SYS
|
||||||
|
/L segm : hex load segment to use in boot sector instead of 0x60
|
||||||
|
/B btdrv : hex BIOS # of boot drive set in bs, 0=A:, 80=1st hd,...
|
||||||
|
/FORCE : override automatic selection of BIOS related settings
|
||||||
|
/FORCE:BSDRV (/FORCEDRV) use boot drive # set in bootsector
|
||||||
|
/FORCE:BIOSDRV use boot drive # provided by BIOS
|
||||||
|
/FORCE:AUTO select LBA or CHS depending on BIOS availability
|
||||||
|
/FORCE:LBA always use LBA
|
||||||
|
/FORCE:CHS always use CHS
|
||||||
|
/NOBAKBS : skips copying boot sector to backup bs, FAT32 only else ignored
|
||||||
|
/SKFN filename : copy from filename to KERNEL.SYS; settings same as /OEM:FD
|
||||||
|
/SCFN filename : copy from filename to COMMAND.COM
|
||||||
|
/BACKUPBS [path]filename : save current bs before overwriting
|
||||||
|
/DUMPBS [path]filename : save current bs and exit
|
||||||
|
/RESTORBS [path]filename : overwrite bs and exit
|
||||||
|
/VERBOSE : display additional (debug) output
|
||||||
|
|
||||||
|
SYS CONFIG /help
|
||||||
|
|
||||||
|
|
||||||
|
The simplest usage:
|
||||||
|
|
||||||
|
SYS dest:
|
||||||
|
|
||||||
|
dest should be the drive (A:, B:, C:, ...) you wish
|
||||||
|
to be bootable with FreeDOS (kernel & command.com)
|
||||||
|
When using this form, KERNEL.SYS and COMMAND.COM
|
||||||
|
must reside either in the current directory (which
|
||||||
|
is searched first) or in recent revisions may also
|
||||||
|
be in the root directory of the current drive.
|
||||||
|
|
||||||
|
Complete form:
|
||||||
|
|
||||||
|
SYS [source] dest: [bootsect [/BOTH]]
|
||||||
|
|
||||||
|
Here dest is the same as before, but this time
|
||||||
|
you specify where KERNEL.SYS and COMMAND.COM are.
|
||||||
|
Source may simply be a drive (in this case it
|
||||||
|
is similar to PC & MS SYS). The current directory
|
||||||
|
of the specified drive is first searched for
|
||||||
|
KERNEL.SYS & COMMAND.COM and if not found then
|
||||||
|
the root directory of the specified drive is tried.
|
||||||
|
Alternatively, you may specify a path (either fully
|
||||||
|
qualified or relative) to where KERNEL.SYS and
|
||||||
|
COMMAND.COM may be found; note that this should
|
||||||
|
only search this directory and will fail if they
|
||||||
|
are not found, ie it will not check for them on
|
||||||
|
the root directory of the drive specified when
|
||||||
|
a path is given. It should also fail if the
|
||||||
|
source and destination drive are both the same
|
||||||
|
and would result in trying to SYS from the root
|
||||||
|
to the root (ie trying to SYS from C:\ to C:\).
|
||||||
|
|
||||||
|
If you specify a name for "bootsect", for instance,
|
||||||
|
bootsect.fd, SYS will write to that file instead of
|
||||||
|
the real boot sector. You will obtain a 512-byte file
|
||||||
|
containing the boot sector, which can then be used
|
||||||
|
for dual booting or diagnostic purposes.
|
||||||
|
|
||||||
|
If you also specify BOTH, sys will write to both
|
||||||
|
the image file and the boot sector.
|
||||||
|
|
||||||
|
The FORCE options override the default actions
|
||||||
|
to use. On FAT32 drives /FORCE:LBA and /FORCE:CHS
|
||||||
|
will select which boot sector code is used (default
|
||||||
|
same as /FORCE:AUTO will choose based on query of
|
||||||
|
BIOS support for LBA extensions and use LBA if it
|
||||||
|
is supported else only CHS will be used). On FAT12
|
||||||
|
and FAT16 drives specifying /FORCE:LBA will ensure
|
||||||
|
even 1st floppy drive attempts to use LBA support
|
||||||
|
(note that CHS may still be used if LBA check fails)
|
||||||
|
and /FORCE:CHS will always bypass use of LBA extensions.
|
||||||
|
|
||||||
|
|
||||||
|
Kernel Configuration Options:
|
||||||
|
|
||||||
|
Simplest form:
|
||||||
|
|
||||||
|
SYS CONFIG
|
||||||
|
|
||||||
|
This will simply display the current settings
|
||||||
|
for the file KERNEL.SYS in the current directory.
|
||||||
|
It is useful to see what the options are currently
|
||||||
|
set to, what options are supported, and should
|
||||||
|
show valid values along with defaults (defaults are
|
||||||
|
the valid values with a '*' next to them).
|
||||||
|
|
||||||
|
Optionally specify file:
|
||||||
|
|
||||||
|
SYS CONFIG [drive][path]KERNEL.SYS
|
||||||
|
|
||||||
|
This form behaves as above, except will display
|
||||||
|
the settings for the kernel file you specify.
|
||||||
|
drive and path are optional, and generally just
|
||||||
|
a \ will be used to indicate root directory of
|
||||||
|
current drive. KERNEL.SYS specifies the filename
|
||||||
|
of the kernel, which may not be "KERNEL.SYS",
|
||||||
|
for example when testing you want to alter
|
||||||
|
KERNTEST.SYS and later copy (or rename) this to
|
||||||
|
KERNEL.SYS for booting.
|
||||||
|
|
||||||
|
|
||||||
|
Changing options:
|
||||||
|
|
||||||
|
SYS CONFIG OPTION1=value [OPTION2=value ...]
|
||||||
|
|
||||||
|
This form will read the current settings from
|
||||||
|
the kernel (KERNEL.SYS in the current directory)
|
||||||
|
and set the options specified to the value given.
|
||||||
|
If the value is potentially invalid (too large, too
|
||||||
|
small, etc) then a warning will be displayed, but
|
||||||
|
the change will still occur. The kernel file is
|
||||||
|
only updated if at least one option is different from the
|
||||||
|
current settings. If you wish to force the kernel
|
||||||
|
file to be written to, then set the same option
|
||||||
|
twice (OPTION1=oddvalue OPTION1=desiredvalue), with
|
||||||
|
the 1st time the value being different from the
|
||||||
|
current one and the rightmost one being the desired
|
||||||
|
value. Currently three options are supported.
|
||||||
|
Note: currently only the 1st three letters are
|
||||||
|
actually checked, so they may be abreviated to
|
||||||
|
DLA, SHO, and SKI and with my recent patch you may
|
||||||
|
specify the value as either a decimal number 0,10,255,...
|
||||||
|
or as a hexidecimal number 0x0,0xA, 0xFF...
|
||||||
|
|
||||||
|
DLASORT which may be set to 0 or 1
|
||||||
|
DLASORT=0 or DLASORT=1
|
||||||
|
This option is for specifying whether Drive Letter
|
||||||
|
Assignment should follow the normal MSDOS way of
|
||||||
|
all primary partitions across drives and then
|
||||||
|
extended partitions, or the more logical
|
||||||
|
all partitions (primary & extended) on the 1st
|
||||||
|
drive, then repeat for all following drives
|
||||||
|
(all primary & extended, then try next drive).
|
||||||
|
0 corresponds to MS way and 1 corresponds to first
|
||||||
|
drive completely, then next ...
|
||||||
|
|
||||||
|
SHOWDRIVEASSIGNMENT which may be 0 or 1
|
||||||
|
SHOWDRIVEASSIGNMENT=0 or SHOWDRIVEASSIGNMENT=1
|
||||||
|
If 1 then the normal drive assignment information
|
||||||
|
is displayed upon booting. If 0 then this information
|
||||||
|
is supressed (not shown).
|
||||||
|
|
||||||
|
SKIPCONFIGSECONDS which may be -128 to 127.
|
||||||
|
A negative value ( < 0 ) indicates that F5/F8
|
||||||
|
processing will be skipped (the kernel won't check
|
||||||
|
if you pressed these keys, so you can't skip config
|
||||||
|
file (CONFIG.SYS) processing). A 0 means you must
|
||||||
|
have pressed the key precisely for when the kernel
|
||||||
|
checks for it - essentially skipping, though a well
|
||||||
|
timed finger will still get to use it. And any value
|
||||||
|
greater than 0 is the number of seconds the kernel will
|
||||||
|
display the prompt and wait for you to press the key
|
||||||
|
before assuming you didn't.
|
||||||
|
|
||||||
|
FORCELBA which may be 0 or 1
|
||||||
|
FORCELBA=0 or FORCELBA=1
|
||||||
|
If 1 then the kernel will use LBA (extended INT13)
|
||||||
|
techniques to address all partitions if possible,
|
||||||
|
even if these have a non-LBA partition type and
|
||||||
|
are completely below cylinder 1023 (usually the 8GB
|
||||||
|
boundary). This is 0 by default, for compatibility
|
||||||
|
reasons. Setting this to 1 may bypass some buggy
|
||||||
|
BIOSes and gives slightly better performance.
|
||||||
|
|
||||||
|
GLOBALENABLELBASUPPORT which maybe 0 or 1
|
||||||
|
GLOBALENABLELBASUPPORT=0 or GLOBALENABLELBASUPPORT=1
|
||||||
|
If 0 then LBA will be completely disabled, irrespective
|
||||||
|
of the FORCELBA setting. You need this if FreeDOS thinks
|
||||||
|
you have LBA available, but in reality you do not.
|
||||||
|
This setting is set to 1 by default.
|
||||||
|
|
||||||
|
Example: To set the kernel in the current directory
|
||||||
|
to have a timeout of 5 seconds (default is 2) run
|
||||||
|
SYS CONFIG SKI=5
|
||||||
|
|
||||||
|
|
||||||
|
Changing options of specified file:
|
||||||
|
|
||||||
|
SYS CONFIG [drive][path]KERNEL.SYS OPTION1=value ...]
|
||||||
|
|
||||||
|
This is just like previous section on setting options,
|
||||||
|
except the first argument after CONFIG specifies which
|
||||||
|
kernel file to use. The filename is the same form used
|
||||||
|
for displaying options of specified kernel file described
|
||||||
|
above.
|
||||||
|
|
||||||
|
Example2: To set a kernel in the root directory to
|
||||||
|
not show drive assignment and change the timeout
|
||||||
|
to never check
|
||||||
|
SYS CONFIG \KERNEL.SYS SKI=-1 SHOWDRIVEASSIGNMENT=0x0
|
||||||
|
|
229
drivers/floppy.asm
Normal file
229
drivers/floppy.asm
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
;
|
||||||
|
; File:
|
||||||
|
; floppy.asm
|
||||||
|
; Description:
|
||||||
|
; floppy disk driver primitives
|
||||||
|
;
|
||||||
|
; Copyright (c) 1995
|
||||||
|
; Pasquale J. Villani
|
||||||
|
; All Rights Reserved
|
||||||
|
;
|
||||||
|
; This file is part of DOS-C.
|
||||||
|
;
|
||||||
|
; DOS-C is free software; you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation; either version
|
||||||
|
; 2, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; DOS-C is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||||
|
; the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public
|
||||||
|
; License along with DOS-C; see the file COPYING. If not,
|
||||||
|
; write to the Free Software Foundation, 675 Mass Ave,
|
||||||
|
; Cambridge, MA 02139, USA.
|
||||||
|
;
|
||||||
|
; $Id: floppy.asm 980 2004-06-19 19:41:47Z perditionc $
|
||||||
|
;
|
||||||
|
|
||||||
|
%include "../kernel/segs.inc"
|
||||||
|
segment HMA_TEXT
|
||||||
|
|
||||||
|
;
|
||||||
|
; BOOL ASMPASCAL fl_reset(WORD drive);
|
||||||
|
;
|
||||||
|
; Reset both the diskette and hard disk system.
|
||||||
|
; returns TRUE if successful.
|
||||||
|
;
|
||||||
|
|
||||||
|
global FL_RESET
|
||||||
|
FL_RESET:
|
||||||
|
pop ax ; return address
|
||||||
|
pop dx ; drive (DL only)
|
||||||
|
push ax ; restore address
|
||||||
|
mov ah,0 ; BIOS reset diskette & fixed disk
|
||||||
|
int 13h
|
||||||
|
|
||||||
|
sbb ax,ax ; carry set indicates error, AX=-CF={-1,0}
|
||||||
|
inc ax ; ...return TRUE (1) on success,
|
||||||
|
ret ; else FALSE (0) on failure
|
||||||
|
|
||||||
|
;
|
||||||
|
; COUNT ASMPASCAL fl_diskchanged(WORD drive);
|
||||||
|
;
|
||||||
|
; Read disk change line status.
|
||||||
|
; returns 1 if disk has changed, 0 if not, 0xFFFF if error.
|
||||||
|
;
|
||||||
|
|
||||||
|
global FL_DISKCHANGED
|
||||||
|
FL_DISKCHANGED:
|
||||||
|
pop ax ; return address
|
||||||
|
pop dx ; drive (DL only, 00h-7Fh)
|
||||||
|
push ax ; restore stack
|
||||||
|
|
||||||
|
push si ; preserve value
|
||||||
|
mov ah,16h ; read change status type
|
||||||
|
xor si,si ; RBIL: avoid crash on AT&T 6300
|
||||||
|
int 13h
|
||||||
|
pop si ; restore
|
||||||
|
|
||||||
|
sbb al,al ; AL=-CF={-1,0} where 0==no change
|
||||||
|
jnc fl_dc ; carry set on error or disk change
|
||||||
|
cmp ah,6 ; if AH==6 then disk change, else error
|
||||||
|
jne fl_dc ; if error, return -1
|
||||||
|
mov al, 1 ; set change occurred
|
||||||
|
fl_dc: cbw ; extend AL into AX, AX={1,0,-1}
|
||||||
|
ret ; note: AH=0 on no change, AL set above
|
||||||
|
|
||||||
|
;
|
||||||
|
; Format tracks (sector should be 0).
|
||||||
|
; COUNT ASMPASCAL fl_format(WORD drive, WORD head, WORD track, WORD sector, WORD count, UBYTE FAR *buffer);
|
||||||
|
; Reads one or more sectors.
|
||||||
|
; COUNT ASMPASCAL fl_read (WORD drive, WORD head, WORD track, WORD sector, WORD count, UBYTE FAR *buffer);
|
||||||
|
; Writes one or more sectors.
|
||||||
|
; COUNT ASMPASCAL fl_write (WORD drive, WORD head, WORD track, WORD sector, WORD count, UBYTE FAR *buffer);
|
||||||
|
; COUNT ASMPASCAL fl_verify(WORD drive, WORD head, WORD track, WORD sector, WORD count, UBYTE FAR *buffer);
|
||||||
|
;
|
||||||
|
; Returns 0 if successful, error code otherwise.
|
||||||
|
;
|
||||||
|
|
||||||
|
global FL_FORMAT
|
||||||
|
FL_FORMAT:
|
||||||
|
mov ah,5 ; format track
|
||||||
|
jmp short fl_common
|
||||||
|
|
||||||
|
global FL_READ
|
||||||
|
FL_READ:
|
||||||
|
mov ah,2 ; read sector(s)
|
||||||
|
jmp short fl_common
|
||||||
|
|
||||||
|
global FL_VERIFY
|
||||||
|
FL_VERIFY:
|
||||||
|
mov ah,4 ; verify sector(s)
|
||||||
|
jmp short fl_common
|
||||||
|
|
||||||
|
global FL_WRITE
|
||||||
|
FL_WRITE:
|
||||||
|
mov ah,3 ; write sector(s)
|
||||||
|
|
||||||
|
fl_common:
|
||||||
|
push bp ; setup stack frame
|
||||||
|
mov bp,sp
|
||||||
|
|
||||||
|
mov cx,[bp+0Ch] ; cylinder number
|
||||||
|
|
||||||
|
mov al,1 ; this should be an error code
|
||||||
|
cmp ch,3 ; this code can't write above 3FFh=1023
|
||||||
|
ja fl_error ; as cylinder # is limited to 10 bits.
|
||||||
|
|
||||||
|
xchg ch,cl ; ch=low 8 bits of cyl number
|
||||||
|
ror cl,1 ; bits 8-9 of cylinder number...
|
||||||
|
ror cl,1 ; ...to bits 6-7 in CL
|
||||||
|
or cl,[bp+0Ah] ; or in the sector number (bits 0-5)
|
||||||
|
|
||||||
|
mov al,[bp+08h] ; count of sectors to read/write/...
|
||||||
|
les bx,[bp+04h] ; Load 32 bit buffer ptr into ES:BX
|
||||||
|
|
||||||
|
mov dl,[bp+10h] ; drive (if or'ed 80h its a hard drive)
|
||||||
|
mov dh,[bp+0Eh] ; get the head number
|
||||||
|
|
||||||
|
int 13h ; process sectors
|
||||||
|
|
||||||
|
sbb al,al ; carry: al=ff, else al=0
|
||||||
|
and al,ah ; carry: error code, else 0
|
||||||
|
fl_error:
|
||||||
|
mov ah,0 ; extend AL into AX without sign extension
|
||||||
|
pop bp
|
||||||
|
ret 14
|
||||||
|
|
||||||
|
;
|
||||||
|
; COUNT ASMPASCAL fl_lba_ReadWrite(BYTE drive, WORD mode, void FAR * dap_p);
|
||||||
|
;
|
||||||
|
; Returns 0 if successful, error code otherwise.
|
||||||
|
;
|
||||||
|
|
||||||
|
global FL_LBA_READWRITE
|
||||||
|
FL_LBA_READWRITE:
|
||||||
|
push bp ; setup stack frame
|
||||||
|
mov bp,sp
|
||||||
|
|
||||||
|
push ds
|
||||||
|
push si ; wasn't in kernel < KE2024Bo6!!
|
||||||
|
|
||||||
|
mov dl,[bp+10] ; drive (if or'ed with 80h a hard drive)
|
||||||
|
mov ax,[bp+8] ; get the command
|
||||||
|
lds si,[bp+4] ; get far dap pointer
|
||||||
|
int 13h ; read from/write to drive
|
||||||
|
|
||||||
|
pop si
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
pop bp
|
||||||
|
|
||||||
|
mov al,ah ; place any error code into al
|
||||||
|
mov ah,0 ; zero out ah
|
||||||
|
ret 8
|
||||||
|
|
||||||
|
;
|
||||||
|
; void ASMPASCAL fl_readkey (void);
|
||||||
|
;
|
||||||
|
|
||||||
|
global FL_READKEY
|
||||||
|
FL_READKEY: xor ah, ah
|
||||||
|
int 16h
|
||||||
|
ret
|
||||||
|
|
||||||
|
;
|
||||||
|
; COUNT ASMPASCAL fl_setdisktype (WORD drive, WORD type);
|
||||||
|
;
|
||||||
|
|
||||||
|
global FL_SETDISKTYPE
|
||||||
|
FL_SETDISKTYPE:
|
||||||
|
pop bx ; return address
|
||||||
|
pop ax ; disk format type (al)
|
||||||
|
pop dx ; drive number (dl)
|
||||||
|
push bx ; restore stack
|
||||||
|
mov ah,17h ; floppy set disk type for format
|
||||||
|
int 13h
|
||||||
|
ret_AH:
|
||||||
|
mov al,ah ; place any error code into al
|
||||||
|
mov ah,0 ; zero out ah
|
||||||
|
ret
|
||||||
|
|
||||||
|
;
|
||||||
|
; COUNT ASMPASCAL fl_setmediatype (WORD drive, WORD tracks, WORD sectors);
|
||||||
|
;
|
||||||
|
global FL_SETMEDIATYPE
|
||||||
|
FL_SETMEDIATYPE:
|
||||||
|
pop ax ; return address
|
||||||
|
pop bx ; sectors/track
|
||||||
|
pop cx ; number of tracks
|
||||||
|
pop dx ; drive number
|
||||||
|
push ax ; restore stack
|
||||||
|
push di
|
||||||
|
|
||||||
|
dec cx ; number of cylinders - 1 (last cyl number)
|
||||||
|
xchg ch,cl ; CH=low 8 bits of last cyl number
|
||||||
|
|
||||||
|
ror cl,1 ; extract bits 8-9 of cylinder number...
|
||||||
|
ror cl,1 ; ...into cl bit 6-7
|
||||||
|
|
||||||
|
or cl,bl ; sectors/track (bits 0-5) or'd with high cyl bits 7-6
|
||||||
|
|
||||||
|
mov ah,18h ; disk set media type for format
|
||||||
|
int 13h
|
||||||
|
jc skipint1e
|
||||||
|
|
||||||
|
push es
|
||||||
|
xor dx,dx
|
||||||
|
mov es,dx
|
||||||
|
cli
|
||||||
|
pop word [es:0x1e*4+2] ; set int 0x1e table to es:di
|
||||||
|
mov [es:0x1e*4 ], di
|
||||||
|
sti
|
||||||
|
skipint1e:
|
||||||
|
pop di
|
||||||
|
jmp short ret_AH
|
||||||
|
|
49
drivers/makefile
Normal file
49
drivers/makefile
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#
|
||||||
|
# makefile for device.lib
|
||||||
|
#
|
||||||
|
# $Id: makefile 1387 2009-05-19 21:39:29Z bartoldeman $
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
!include "../mkfiles/generic.mak"
|
||||||
|
|
||||||
|
|
||||||
|
# MICROSOFT C
|
||||||
|
# -----------
|
||||||
|
#MODEL = s
|
||||||
|
#CFLAGS = /c /Gs /A$(MODEL)
|
||||||
|
#AFLAGS = /Mx /Dmem$(MODEL)=1
|
||||||
|
#TERM = ;
|
||||||
|
|
||||||
|
# BORLAND C
|
||||||
|
# -----------
|
||||||
|
#MODEL = s
|
||||||
|
#CFLAGS = -c -m$(MODEL)
|
||||||
|
#AFLAGS = /Mx /Dmem$(MODEL)=1
|
||||||
|
#LIBFLAGS = /c
|
||||||
|
|
||||||
|
OBJS = floppy.obj rdpcclk.obj wrpcclk.obj wratclk.obj
|
||||||
|
|
||||||
|
LIBOBJS= +floppy.obj +rdpcclk.obj +wrpcclk.obj +wratclk.obj
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Build the LIBRARY
|
||||||
|
# -----------------
|
||||||
|
all: production
|
||||||
|
|
||||||
|
production: ../lib/device.lib
|
||||||
|
|
||||||
|
../lib/device.lib: device.lib
|
||||||
|
$(CP) device.lib ..$(DIRSEP)lib
|
||||||
|
|
||||||
|
clobber: clean
|
||||||
|
-$(RM) device.lib status.me ..$(DIRSEP)lib$(DIRSEP)device.lib
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-$(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.cod *.err
|
||||||
|
|
||||||
|
device.lib : $(OBJS)
|
||||||
|
-$(RM) device.lib
|
||||||
|
$(LIBUTIL) $(LIBFLAGS) device $(LIBOBJS) $(LIBTERM)
|
||||||
|
|
53
drivers/rdpcclk.asm
Normal file
53
drivers/rdpcclk.asm
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
;
|
||||||
|
; File:
|
||||||
|
; rdpcclk.asm
|
||||||
|
; Description:
|
||||||
|
; read the PC style clock from bios
|
||||||
|
;
|
||||||
|
; Copyright (c) 1995
|
||||||
|
; Pasquale J. Villani
|
||||||
|
; All Rights Reserved
|
||||||
|
;
|
||||||
|
; This file is part of DOS-C.
|
||||||
|
;
|
||||||
|
; DOS-C is free software; you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation; either version
|
||||||
|
; 2, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; DOS-C is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||||
|
; the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public
|
||||||
|
; License along with DOS-C; see the file COPYING. If not,
|
||||||
|
; write to the Free Software Foundation, 675 Mass Ave,
|
||||||
|
; Cambridge, MA 02139, USA.
|
||||||
|
;
|
||||||
|
; $Header$
|
||||||
|
;
|
||||||
|
|
||||||
|
%include "../kernel/segs.inc"
|
||||||
|
|
||||||
|
segment HMA_TEXT
|
||||||
|
|
||||||
|
;
|
||||||
|
; ULONG ReadPCClock(void)
|
||||||
|
;
|
||||||
|
global READPCCLOCK
|
||||||
|
READPCCLOCK:
|
||||||
|
mov ah,0
|
||||||
|
int 1ah
|
||||||
|
extern _DaysSinceEpoch ; ; update days if necessary
|
||||||
|
|
||||||
|
; (ah is still 0, al contains midnight flag)
|
||||||
|
add word [_DaysSinceEpoch ],ax ; *some* BIOSes accumulate several days
|
||||||
|
adc word [_DaysSinceEpoch+2],byte 0;
|
||||||
|
|
||||||
|
; set return value dx:ax
|
||||||
|
xchg ax,cx ; ax=_cx, cx=_ax
|
||||||
|
xchg ax,dx ; dx=_cx, ax=_dx (cx=_ax)
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
63
drivers/wratclk.asm
Normal file
63
drivers/wratclk.asm
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
;
|
||||||
|
; File:
|
||||||
|
; wratclk.asm
|
||||||
|
; Description:
|
||||||
|
; WriteATClock - sysclock support
|
||||||
|
;
|
||||||
|
; Copyright (c) 1995
|
||||||
|
; Pasquale J. Villani
|
||||||
|
; All Rights Reserved
|
||||||
|
;
|
||||||
|
; This file is part of DOS-C.
|
||||||
|
;
|
||||||
|
; DOS-C is free software; you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation; either version
|
||||||
|
; 2, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; DOS-C is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||||
|
; the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public
|
||||||
|
; License along with DOS-C; see the file COPYING. If not,
|
||||||
|
; write to the Free Software Foundation, 675 Mass Ave,
|
||||||
|
; Cambridge, MA 02139, USA.
|
||||||
|
;
|
||||||
|
; $Header$
|
||||||
|
;
|
||||||
|
|
||||||
|
%include "../kernel/segs.inc"
|
||||||
|
|
||||||
|
segment HMA_TEXT
|
||||||
|
|
||||||
|
;
|
||||||
|
; VOID WriteATClock(bcdDays, bcdHours, bcdMinutes, bcdSeconds)
|
||||||
|
; BYTE *bcdDays;
|
||||||
|
; BYTE bcdHours;
|
||||||
|
; BYTE bcdMinutes;
|
||||||
|
; BYTE bcdSeconds;
|
||||||
|
;
|
||||||
|
global WRITEATCLOCK
|
||||||
|
WRITEATCLOCK:
|
||||||
|
push bp
|
||||||
|
mov bp,sp
|
||||||
|
; bcdSeconds = 4
|
||||||
|
; bcdMinutes = 6
|
||||||
|
; bcdHours = 8
|
||||||
|
; bcdDays = 10
|
||||||
|
mov ch,byte [bp+8] ;bcdHours
|
||||||
|
mov cl,byte [bp+6] ;bcdMinutes
|
||||||
|
mov dh,byte [bp+4] ;bcdSeconds
|
||||||
|
mov dl,0
|
||||||
|
mov ah,3
|
||||||
|
int 1ah
|
||||||
|
mov bx,word [bp+10] ;bcdDays
|
||||||
|
mov dx,word [bx]
|
||||||
|
mov cx,word [bx+2]
|
||||||
|
mov ah,5
|
||||||
|
int 1ah
|
||||||
|
pop bp
|
||||||
|
ret 8
|
||||||
|
|
49
drivers/wrpcclk.asm
Normal file
49
drivers/wrpcclk.asm
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
;
|
||||||
|
; File:
|
||||||
|
; wrpcclk.asm
|
||||||
|
; Description:
|
||||||
|
; WritePCClock - sysclock support
|
||||||
|
;
|
||||||
|
; Copyright (c) 1995
|
||||||
|
; Pasquale J. Villani
|
||||||
|
; All Rights Reserved
|
||||||
|
;
|
||||||
|
; This file is part of DOS-C.
|
||||||
|
;
|
||||||
|
; DOS-C is free software; you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation; either version
|
||||||
|
; 2, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; DOS-C is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||||
|
; the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public
|
||||||
|
; License along with DOS-C; see the file COPYING. If not,
|
||||||
|
; write to the Free Software Foundation, 675 Mass Ave,
|
||||||
|
; Cambridge, MA 02139, USA.
|
||||||
|
;
|
||||||
|
; $Header$
|
||||||
|
;
|
||||||
|
%include "../kernel/segs.inc"
|
||||||
|
|
||||||
|
segment HMA_TEXT
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; VOID WritePCClock(Ticks)
|
||||||
|
; ULONG Ticks;
|
||||||
|
;
|
||||||
|
global WRITEPCCLOCK
|
||||||
|
WRITEPCCLOCK:
|
||||||
|
; Ticks = 4
|
||||||
|
pop ax ; return address
|
||||||
|
pop dx
|
||||||
|
pop cx ; Ticks
|
||||||
|
push ax ; restore stack
|
||||||
|
mov ah,1
|
||||||
|
int 1ah
|
||||||
|
ret
|
||||||
|
|
153
filelist
Normal file
153
filelist
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
*/*/build.bat
|
||||||
|
*/*/buildall.bat
|
||||||
|
*/*/clean.bat
|
||||||
|
*/*/clobber.bat
|
||||||
|
*/*/config.b
|
||||||
|
*/*/filelist
|
||||||
|
*/*/default.bat
|
||||||
|
*/*/makefile
|
||||||
|
*/*/boot/boot.asm
|
||||||
|
*/*/boot/boot32.asm
|
||||||
|
*/*/boot/boot32lb.asm
|
||||||
|
*/*/boot/makefile
|
||||||
|
*/*/docs/bugs.txt
|
||||||
|
*/*/docs/build.txt
|
||||||
|
*/*/docs/config.txt
|
||||||
|
*/*/docs/contrib.txt
|
||||||
|
*/*/docs/copying
|
||||||
|
*/*/docs/fdkernel.lsm
|
||||||
|
*/*/docs/history.txt
|
||||||
|
*/*/docs/intfns.txt
|
||||||
|
*/*/docs/lfnapi.txt
|
||||||
|
*/*/docs/mkboot.txt
|
||||||
|
*/*/docs/nls.txt
|
||||||
|
*/*/docs/readme.cvs
|
||||||
|
*/*/docs/readme.txt
|
||||||
|
*/*/docs/sys.txt
|
||||||
|
*/*/drivers/floppy.asm
|
||||||
|
*/*/drivers/makefile
|
||||||
|
*/*/drivers/rdpcclk.asm
|
||||||
|
*/*/drivers/wratclk.asm
|
||||||
|
*/*/drivers/wrpcclk.asm
|
||||||
|
*/*/hdr/algnbyte.h
|
||||||
|
*/*/hdr/algndflt.h
|
||||||
|
*/*/hdr/buffer.h
|
||||||
|
*/*/hdr/cds.h
|
||||||
|
*/*/hdr/clock.h
|
||||||
|
*/*/hdr/date.h
|
||||||
|
*/*/hdr/dcb.h
|
||||||
|
*/*/hdr/device.h
|
||||||
|
*/*/hdr/dirmatch.h
|
||||||
|
*/*/hdr/error.h
|
||||||
|
*/*/hdr/exe.h
|
||||||
|
*/*/hdr/fat.h
|
||||||
|
*/*/hdr/fcb.h
|
||||||
|
*/*/hdr/file.h
|
||||||
|
*/*/hdr/fnode.h
|
||||||
|
*/*/hdr/kbd.h
|
||||||
|
*/*/hdr/kconfig.h
|
||||||
|
*/*/hdr/lol.h
|
||||||
|
*/*/hdr/mcb.h
|
||||||
|
*/*/hdr/network.h
|
||||||
|
*/*/hdr/nls.h
|
||||||
|
*/*/hdr/pcb.h
|
||||||
|
*/*/hdr/portab.h
|
||||||
|
*/*/hdr/process.h
|
||||||
|
*/*/hdr/sft.h
|
||||||
|
*/*/hdr/stacks.inc
|
||||||
|
*/*/hdr/tail.h
|
||||||
|
*/*/hdr/time.h
|
||||||
|
*/*/hdr/version.h
|
||||||
|
*/*/hdr/xstructs.h
|
||||||
|
*/*/kernel/nls/001-437.hc
|
||||||
|
*/*/kernel/nls/001-437.unf
|
||||||
|
*/*/kernel/nls/001-437.up
|
||||||
|
*/*/kernel/nls/049-850.hc
|
||||||
|
*/*/kernel/nls/049-850.unf
|
||||||
|
*/*/kernel/nls/049-850.up
|
||||||
|
*/*/kernel/nls/files
|
||||||
|
*/*/kernel/apisupt.asm
|
||||||
|
*/*/kernel/asmsupt.asm
|
||||||
|
*/*/kernel/blockio.c
|
||||||
|
*/*/kernel/break.c
|
||||||
|
*/*/kernel/chario.c
|
||||||
|
*/*/kernel/config.c
|
||||||
|
*/*/kernel/config.h
|
||||||
|
*/*/kernel/console.asm
|
||||||
|
*/*/kernel/dosfns.c
|
||||||
|
*/*/kernel/dosidle.asm
|
||||||
|
*/*/kernel/dosnames.c
|
||||||
|
*/*/kernel/dsk.c
|
||||||
|
*/*/kernel/dyndata.h
|
||||||
|
*/*/kernel/dyninit.c
|
||||||
|
*/*/kernel/entry.asm
|
||||||
|
*/*/kernel/error.c
|
||||||
|
*/*/kernel/execrh.asm
|
||||||
|
*/*/kernel/fatdir.c
|
||||||
|
*/*/kernel/fatfs.c
|
||||||
|
*/*/kernel/fattab.c
|
||||||
|
*/*/kernel/fcbfns.c
|
||||||
|
*/*/kernel/globals.h
|
||||||
|
*/*/kernel/init-dat.h
|
||||||
|
*/*/kernel/init-mod.h
|
||||||
|
*/*/kernel/initclk.c
|
||||||
|
*/*/kernel/initdisk.c
|
||||||
|
*/*/kernel/inithma.c
|
||||||
|
*/*/kernel/initoem.c
|
||||||
|
*/*/kernel/int2f.asm
|
||||||
|
*/*/kernel/inthndlr.c
|
||||||
|
*/*/kernel/intr.asm
|
||||||
|
*/*/kernel/makefile
|
||||||
|
*/*/kernel/io.asm
|
||||||
|
*/*/kernel/io.inc
|
||||||
|
*/*/kernel/ioctl.c
|
||||||
|
*/*/kernel/iprf.c
|
||||||
|
*/*/kernel/irqstack.asm
|
||||||
|
*/*/kernel/kernel.asm
|
||||||
|
*/*/kernel/kernel.cfg
|
||||||
|
*/*/kernel/lfnapi.c
|
||||||
|
*/*/kernel/ludivmul.inc
|
||||||
|
*/*/kernel/main.c
|
||||||
|
*/*/kernel/memdisk.asm
|
||||||
|
*/*/kernel/memmgr.c
|
||||||
|
*/*/kernel/misc.c
|
||||||
|
*/*/kernel/network.c
|
||||||
|
*/*/kernel/newstuff.c
|
||||||
|
*/*/kernel/nls.c
|
||||||
|
*/*/kernel/nls_hc.asm
|
||||||
|
*/*/kernel/nls_load.c
|
||||||
|
*/*/kernel/nlssupt.asm
|
||||||
|
*/*/kernel/prf.c
|
||||||
|
*/*/kernel/printer.asm
|
||||||
|
*/*/kernel/procsupt.asm
|
||||||
|
*/*/kernel/proto.h
|
||||||
|
*/*/kernel/segs.inc
|
||||||
|
*/*/kernel/serial.asm
|
||||||
|
*/*/kernel/strings.c
|
||||||
|
*/*/kernel/sysclk.c
|
||||||
|
*/*/kernel/syspack.c
|
||||||
|
*/*/kernel/systime.c
|
||||||
|
*/*/kernel/task.c
|
||||||
|
*/*/kernel/turboc.cfg
|
||||||
|
*/*/lib/makefile
|
||||||
|
*/*/mkfiles/generic.mak
|
||||||
|
*/*/mkfiles/bc5.mak
|
||||||
|
*/*/mkfiles/mscl8.mak
|
||||||
|
*/*/mkfiles/tc2.mak
|
||||||
|
*/*/mkfiles/tc3.mak
|
||||||
|
*/*/mkfiles/turbocpp.mak
|
||||||
|
*/*/mkfiles/watcom.mak
|
||||||
|
*/*/sys/fdkrncfg.c
|
||||||
|
*/*/sys/bin2c.c
|
||||||
|
*/*/sys/makefile
|
||||||
|
*/*/sys/sys.c
|
||||||
|
*/*/sys/talloc.c
|
||||||
|
*/*/utils/echoto.bat
|
||||||
|
*/*/utils/exeflat.c
|
||||||
|
*/*/utils/indent.ini
|
||||||
|
*/*/utils/makefile
|
||||||
|
*/*/utils/patchobj.c
|
||||||
|
*/*/utils/proto.bat
|
||||||
|
*/*/utils/relocinf.c
|
||||||
|
*/*/utils/rmfiles.bat
|
||||||
|
*/*/utils/wlinker.bat
|
13
hdr/algnbyte.h
Normal file
13
hdr/algnbyte.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#if _MSC_VER >= 700
|
||||||
|
#pragma warning(disable:4103)
|
||||||
|
#endif
|
||||||
|
#pragma pack(1)
|
||||||
|
#elif defined(_QC) || defined(__WATCOMC__) || defined(__GNUC__)
|
||||||
|
#pragma pack(1)
|
||||||
|
#elif defined(__ZTC__)
|
||||||
|
#pragma ZTC align 1
|
||||||
|
#elif defined(__TURBOC__) && (__TURBOC__ > 0x202)
|
||||||
|
#pragma option -a-
|
||||||
|
#endif
|
7
hdr/algndflt.h
Normal file
7
hdr/algndflt.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#if defined (_MSC_VER) || defined(_QC) || defined(__WATCOMC__) || defined(__GNUC__)
|
||||||
|
#pragma pack()
|
||||||
|
#elif defined (__ZTC__)
|
||||||
|
#pragma ZTC align
|
||||||
|
#elif defined(__TURBOC__) && (__TURBOC__ > 0x202)
|
||||||
|
#pragma option -a.
|
||||||
|
#endif
|
64
hdr/buffer.h
Normal file
64
hdr/buffer.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* buffer.h */
|
||||||
|
/* */
|
||||||
|
/* Sector buffer structure */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2001 */
|
||||||
|
/* Bart Oldeman */
|
||||||
|
/* */
|
||||||
|
/* Largely taken from globals.h: */
|
||||||
|
/* Copyright (c) 1995, 1996 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *buffer_hRcsId =
|
||||||
|
"$Id: buffer.h 1702 2012-02-04 08:46:16Z perditionc $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "dsk.h" /* only for MAX_SEC_SIZE */
|
||||||
|
#define BUFFERSIZE MAX_SEC_SIZE
|
||||||
|
|
||||||
|
struct buffer {
|
||||||
|
UWORD b_next; /* next buffer in LRU list */
|
||||||
|
UWORD b_prev; /* previous buffer in LRU list */
|
||||||
|
BYTE b_unit; /* disk for this buffer */
|
||||||
|
BYTE b_flag; /* buffer flags */
|
||||||
|
ULONG b_blkno; /* block for this buffer */
|
||||||
|
UBYTE b_copies; /* number of copies to write */
|
||||||
|
UWORD b_offset; /* offset in sectors between copies
|
||||||
|
to write for FAT sectors */
|
||||||
|
struct dpb FAR *b_dpbp; /* pointer to DPB */
|
||||||
|
UWORD b_remotesz; /* size of remote buffer if remote */
|
||||||
|
BYTE b_padding;
|
||||||
|
UBYTE b_buffer[BUFFERSIZE]; /* 512 byte sectors for now */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BFR_DIRTY 0x40 /* buffer modified */
|
||||||
|
#define BFR_VALID 0x20 /* buffer contains valid data */
|
||||||
|
#define BFR_DATA 0x08 /* buffer is from data area */
|
||||||
|
#define BFR_DIR 0x04 /* buffer is from dir area */
|
||||||
|
#define BFR_FAT 0x02 /* buffer is from fat area */
|
||||||
|
#define BFR_UNCACHE 0x01 /* buffer to be released ASAP */
|
||||||
|
|
91
hdr/cds.h
Normal file
91
hdr/cds.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* cds.h */
|
||||||
|
/* */
|
||||||
|
/* Current Directory structures */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_CDSPATH 67
|
||||||
|
|
||||||
|
struct cds {
|
||||||
|
BYTE cdsCurrentPath[MAX_CDSPATH];
|
||||||
|
UWORD cdsFlags; /* see below */
|
||||||
|
struct dpb FAR *cdsDpb; /* if != 0, associated DPB */
|
||||||
|
|
||||||
|
union {
|
||||||
|
BYTE FAR *_cdsRedirRec; /* IFS record */
|
||||||
|
struct {
|
||||||
|
UWORD _cdsStrtClst; /* if local path (Flags & CDSPHYSDRV):
|
||||||
|
start cluster of CWD; root == 0,
|
||||||
|
never access == 0xFFFF */
|
||||||
|
UWORD _cdsParam;
|
||||||
|
} _cdsRedir;
|
||||||
|
} _cdsUnion;
|
||||||
|
|
||||||
|
UWORD cdsStoreUData;
|
||||||
|
|
||||||
|
#define cdsJoinOffset cdsBackslashOffset
|
||||||
|
WORD cdsBackslashOffset; /* Position of "root directory" backslash for
|
||||||
|
this drive within CurrentPath[]
|
||||||
|
prerequisites:
|
||||||
|
+ ofs <= strlen(currentPath)
|
||||||
|
+ if UNC: ofs > share component
|
||||||
|
if local path: ofs > colon
|
||||||
|
*/
|
||||||
|
|
||||||
|
BYTE cdsNetFlag1; /* According to PCDOS 7 Tech Ref: IFS drive, 2=IFS, 4=NetUse */
|
||||||
|
BYTE FAR *cdsIfs; /* Pointer to Installable File System Header */
|
||||||
|
UWORD cdsNetFlags2; /* File System specific data */
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#define cdsStrtClst _cdsUnion._cdsRedir._cdsStrtClst
|
||||||
|
#define cdsRedirRec _cdsUnion._cdsRedirRec
|
||||||
|
#define cdsParam _cdsUnion._cdsRedir._cdsParam
|
||||||
|
|
||||||
|
/* Bits for cdsFlags (OR combination) */
|
||||||
|
#define CDSNETWDRV 0x8000
|
||||||
|
#define CDSPHYSDRV 0x4000
|
||||||
|
#define CDSJOINED 0x2000 /* not in combination with NETWDRV or SUBST */
|
||||||
|
#define CDSSUBST 0x1000 /* not in combination with NETWDRV or JOINED */
|
||||||
|
#define CDS_HIDDEN (1 << 7) /* hide drive from redirector's list */
|
||||||
|
|
||||||
|
/* NETWORK PHYSICAL meaning
|
||||||
|
0 0 drive not accessable
|
||||||
|
0 1 local file system
|
||||||
|
1 0 networked file system (UNC naming convention)
|
||||||
|
1 1 installable file system (IFS)
|
||||||
|
*/
|
||||||
|
#define CDSMODEMASK (CDSNETWDRV | CDSPHYSDRV)
|
||||||
|
|
||||||
|
/* #define CDSVALID (CDSNETWDRV | CDSPHYSDRV) */
|
||||||
|
#define CDSVALID CDSMODEMASK
|
||||||
|
|
||||||
|
#define IS_DEVICE 0x20
|
||||||
|
#define IS_NETWORK 0x40
|
||||||
|
|
||||||
|
#define CDS_MODE_SKIP_PHYSICAL 0x01 /* don't resolve SUBST, JOIN, NETW */
|
||||||
|
#define CDS_MODE_CHECK_DEV_PATH 0x02 /* check for existence of device path */
|
||||||
|
#define CDS_MODE_ALLOW_WILDCARDS 0x04 /* allow wildcards in "truename" */
|
47
hdr/clock.h
Normal file
47
hdr/clock.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* clock.h */
|
||||||
|
/* */
|
||||||
|
/* Clock Driver data structures & declarations */
|
||||||
|
/* */
|
||||||
|
/* November 26, 1991 */
|
||||||
|
/* */
|
||||||
|
/* Adapted to DOS/NT June 12, 1993 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *clock_hRcsId =
|
||||||
|
"$Id: clock.h 485 2002-12-09 00:17:15Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct ClockRecord {
|
||||||
|
UWORD clkDays; /* days since Jan 1, 1980. */
|
||||||
|
UBYTE clkMinutes; /* residual minutes. */
|
||||||
|
UBYTE clkHours; /* residual hours. */
|
||||||
|
UBYTE clkHundredths; /* residual hundredths of a second. */
|
||||||
|
UBYTE clkSeconds; /* residual seconds. */
|
||||||
|
};
|
||||||
|
|
57
hdr/date.h
Normal file
57
hdr/date.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* date.h */
|
||||||
|
/* */
|
||||||
|
/* DOS General Date Structure */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
/* TC 2.01 complains if `date' is defined twice. -- ror4 */
|
||||||
|
#ifndef DOSC_DATE_H
|
||||||
|
#define DOSC_DATE_H
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *date_hRcsId =
|
||||||
|
"$Id: date.h 485 2002-12-09 00:17:15Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* FAT file date - takes the form of yyyy yyym mmmd dddd where physical */
|
||||||
|
/* year=1980+yyyyyy */
|
||||||
|
|
||||||
|
#define DT_YEAR(d) (((d)>>9)&0x7f)
|
||||||
|
#define DT_MONTH(d) (((d)>>5)&0x0f)
|
||||||
|
#define DT_DAY(d) ((d)&0x1f)
|
||||||
|
|
||||||
|
#define DT_ENCODE(m,d,y) ((((m)&0x0f)<<5)|((d)&0x1f)|(((y)&0x7f)<<9))
|
||||||
|
|
||||||
|
#define EPOCH_WEEKDAY 2 /* Tuesday (i. e.- 0 == Sunday) */
|
||||||
|
#define EPOCH_MONTH 1 /* January */
|
||||||
|
#define EPOCH_DAY 1 /* 1 for January 1 */
|
||||||
|
#define EPOCH_YEAR 1980 /* for Tues 1-1-80 epoch */
|
||||||
|
|
||||||
|
typedef UWORD date;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
92
hdr/dcb.h
Normal file
92
hdr/dcb.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* dcb.h */
|
||||||
|
/* */
|
||||||
|
/* DOS Device Control Block Structure */
|
||||||
|
/* */
|
||||||
|
/* November 20, 1991 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *clock_hRcsId =
|
||||||
|
"$Id: dcb.h 485 2002-12-09 00:17:15Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Internal drive parameter block */
|
||||||
|
struct dpb {
|
||||||
|
BYTE dpb_unit; /* unit for error reporting */
|
||||||
|
BYTE dpb_subunit; /* the sub-unit for driver */
|
||||||
|
UWORD dpb_secsize; /* sector size */
|
||||||
|
UBYTE dpb_clsmask; /* mask (sectors/cluster-1) */
|
||||||
|
UBYTE dpb_shftcnt; /* log base 2 of cluster size */
|
||||||
|
UWORD dpb_fatstrt; /* FAT start sector */
|
||||||
|
UBYTE dpb_fats; /* # of FAT copies */
|
||||||
|
UWORD dpb_dirents; /* # of dir entries */
|
||||||
|
UWORD dpb_data; /* start of data area */
|
||||||
|
UWORD dpb_size; /* # of clusters+1 on media */
|
||||||
|
UWORD dpb_fatsize; /* # of sectors / FAT */
|
||||||
|
UWORD dpb_dirstrt; /* start sec. of root dir */
|
||||||
|
struct dhdr FAR * /* pointer to device header */
|
||||||
|
dpb_device;
|
||||||
|
UBYTE dpb_mdb; /* media descr. byte */
|
||||||
|
BYTE dpb_flags; /* -1 = force MEDIA CHK */
|
||||||
|
struct dpb FAR * /* next dpb in chain */
|
||||||
|
dpb_next; /* -1 = end */
|
||||||
|
UWORD dpb_cluster; /* cluster # of first free */
|
||||||
|
/* -1 if not known */
|
||||||
|
#ifndef WITHFAT32
|
||||||
|
UWORD dpb_nfreeclst; /* number of free clusters */
|
||||||
|
/* -1 if not known */
|
||||||
|
#else
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UWORD dpb_nfreeclst_lo;
|
||||||
|
UWORD dpb_nfreeclst_hi;
|
||||||
|
} dpb_nfreeclst_st;
|
||||||
|
ULONG _dpb_xnfreeclst; /* number of free clusters */
|
||||||
|
/* -1 if not known */
|
||||||
|
} dpb_nfreeclst_un;
|
||||||
|
#define dpb_nfreeclst dpb_nfreeclst_un.dpb_nfreeclst_st.dpb_nfreeclst_lo
|
||||||
|
#define dpb_xnfreeclst dpb_nfreeclst_un._dpb_xnfreeclst
|
||||||
|
|
||||||
|
UWORD dpb_xflags; /* extended flags, see bpb */
|
||||||
|
UWORD dpb_xfsinfosec; /* FS info sector number, */
|
||||||
|
/* 0xFFFF if unknown */
|
||||||
|
UWORD dpb_xbackupsec; /* backup boot sector number */
|
||||||
|
/* 0xFFFF if unknown */
|
||||||
|
ULONG dpb_xdata;
|
||||||
|
ULONG dpb_xsize; /* # of clusters+1 on media */
|
||||||
|
ULONG dpb_xfatsize; /* # of sectors / FAT */
|
||||||
|
ULONG dpb_xrootclst; /* starting cluster of root dir */
|
||||||
|
ULONG dpb_xcluster; /* cluster # of first free */
|
||||||
|
/* -1 if not known */
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#define UNKNCLUSTER 0x0000 /* see RBIL INT 21/AH=52 entry */
|
||||||
|
#define XUNKNCLSTFREE 0xffffffffl /* unknown for DOS */
|
||||||
|
#define UNKNCLSTFREE 0xffff /* unknown for DOS */
|
||||||
|
|
145
hdr/debug.h
Normal file
145
hdr/debug.h
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* debug.h */
|
||||||
|
/* */
|
||||||
|
/* Routines to assist in debugging the kernel */
|
||||||
|
/* */
|
||||||
|
/* January, 2005 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2005 */
|
||||||
|
/* FreeDOS kernel dev. */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifndef __DEBUG_H
|
||||||
|
#define __DEBUG_H
|
||||||
|
|
||||||
|
/* #define DEBUG (usually via 'build debug') to
|
||||||
|
enable debug support.
|
||||||
|
NOTE: this file included by INIT time code and normal
|
||||||
|
resident code, so use care for all memory references
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* allow output even in non-debug builds */
|
||||||
|
#if 0
|
||||||
|
#ifndef DEBUG_NEED_PRINTF
|
||||||
|
#define DEBUG_NEED_PRINTF
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* use to limit output to debug builds */
|
||||||
|
#ifdef DEBUG
|
||||||
|
#ifdef DEBUG_PRINT_COMPORT
|
||||||
|
#define DebugPrintf(x) dbgc_printf x
|
||||||
|
#else
|
||||||
|
#define DebugPrintf(x) printf x
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define DebugPrintf(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* use to disable a chunk of debug output, but
|
||||||
|
keep around for later use. */
|
||||||
|
#define DDebugPrintf(x)
|
||||||
|
|
||||||
|
|
||||||
|
/* enable or disable various chunks of debug output */
|
||||||
|
|
||||||
|
/* show stored IRQ vectors */
|
||||||
|
/* #define DEBUGIRQ */
|
||||||
|
|
||||||
|
/* show output related to moving kernel into HMA */
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define HMAInitPrintf(x) DebugPrintf(x)
|
||||||
|
#else
|
||||||
|
#define HMAInitPrintf(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* display output during kernel config processing phase */
|
||||||
|
/* #define DEBUGCFG */
|
||||||
|
#ifdef DEBUGCFG
|
||||||
|
#define CfgDbgPrintf(x) DebugPrintf(x)
|
||||||
|
#else
|
||||||
|
#define CfgDbgPrintf(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* display info on various DOS functions (dosfns.c) */
|
||||||
|
/* #define DEBUGDOSFNS */
|
||||||
|
#ifdef DEBUGDOSFNS
|
||||||
|
#define DFnsDbgPrintf(x) DebugPrintf(x)
|
||||||
|
#else
|
||||||
|
#define DFnsDbgPrintf(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* extra debug output related to chdir */
|
||||||
|
/* #define CHDIR_DEBUG */
|
||||||
|
|
||||||
|
/* extra debug output related to findfirst */
|
||||||
|
/* #define FIND_DEBUG */
|
||||||
|
|
||||||
|
/* display info on various DOS directory functions (fatdir.c) */
|
||||||
|
/* #define DEBUGFATDIR */
|
||||||
|
#ifdef DEBUGFATDIR
|
||||||
|
#define FDirDbgPrintf(x) DebugPrintf(x)
|
||||||
|
#else
|
||||||
|
#define FDirDbgPrintf(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* extra debug output when transferring I/O chunks of data */
|
||||||
|
/* #define DISPLAY_GETBLOCK */
|
||||||
|
|
||||||
|
/* extra output during read/write operations */
|
||||||
|
/* #define DSK_DEBUG */
|
||||||
|
|
||||||
|
/* display info on various FAT handling functions (fatfs.c) */
|
||||||
|
/* #define DEBUGFATFS */
|
||||||
|
#ifdef DEBUGFATFS
|
||||||
|
#define FatFSDbgPrintf(x) DebugPrintf(x)
|
||||||
|
#else
|
||||||
|
#define FatFSDbgPrintf(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* debug truename */
|
||||||
|
/* #define DEBUG_TRUENAME */
|
||||||
|
#ifdef DEBUG_TRUENAME
|
||||||
|
#define tn_printf(x) DebugPrintf(x)
|
||||||
|
#else
|
||||||
|
#define tn_printf(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ensure printf is prototyped */
|
||||||
|
#if defined(DEBUG) || defined(DEBUGIRQ) || defined(DEBUGCFG) || \
|
||||||
|
defined(DEBUGDOSFNS) || defined(CHDIR_DEBUG) || defined(FIND_DEBUG) || \
|
||||||
|
defined(DEBUGFATDIR) || defined(DEBUGFATFS) || \
|
||||||
|
defined(FORCEPRINTF)
|
||||||
|
#ifndef DEBUG_NEED_PRINTF
|
||||||
|
#define DEBUG_NEED_PRINTF
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_NEED_PRINTF
|
||||||
|
int VA_CDECL printf(CONST char * fmt, ...);
|
||||||
|
#ifdef DEBUG_PRINT_COMPORT
|
||||||
|
int VA_CDECL dbgc_printf(CONST char * fmt, ...);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __DEBUG_H */
|
506
hdr/device.h
Normal file
506
hdr/device.h
Normal file
@ -0,0 +1,506 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* device.h */
|
||||||
|
/* Device Driver Header File */
|
||||||
|
/* */
|
||||||
|
/* November 20, 1991 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Status Word Bits
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define S_ERROR 0x8000 /* Error bit */
|
||||||
|
#define S_BUSY 0x0200 /* Device busy bit */
|
||||||
|
#define S_DONE 0x0100 /* Device operation completed */
|
||||||
|
#define S_MASK 0x00ff /* Mask to extract error code */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MEDIA Descriptor Byte Bits
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MD_2SIDE 1 /* MEDIA is two sided */
|
||||||
|
#define MD_8SECTOR 2 /* MEDIA is eight sectored */
|
||||||
|
#define MD_REMOVABLE 4 /* MEDIA is removable (floppy) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Media Return Codes
|
||||||
|
*/
|
||||||
|
#define M_CHANGED -1 /* MEDIA was changed */
|
||||||
|
#define M_DONT_KNOW 0 /* MEDIA state unkown */
|
||||||
|
#define M_NOT_CHANGED 1 /* MEDIA was not changed */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Error Return Codes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define E_WRPRT 0 /* Write Protect */
|
||||||
|
#define E_UNIT 1 /* Unknown Unit */
|
||||||
|
#define E_NOTRDY 2 /* Device Not Ready */
|
||||||
|
#define E_CMD 3 /* Unknown Command */
|
||||||
|
#define E_CRC 4 /* Crc Error */
|
||||||
|
#define E_LENGTH 5 /* Bad Length */
|
||||||
|
#define E_SEEK 6 /* Seek Error */
|
||||||
|
#define E_MEDIA 7 /* Unknown MEDIA */
|
||||||
|
#define E_NOTFND 8 /* Sector Not Found */
|
||||||
|
#define E_PAPER 9 /* No Paper */
|
||||||
|
#define E_WRITE 10 /* Write Fault */
|
||||||
|
#define E_READ 11 /* Read Fault */
|
||||||
|
#define E_FAILURE 12 /* General Failure */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Command codes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define C_INIT 0x00 /* Initialize */
|
||||||
|
#define C_MEDIACHK 0x01 /* MEDIA Check */
|
||||||
|
#define C_BLDBPB 0x02 /* Build BPB */
|
||||||
|
#define C_IOCTLIN 0x03 /* Ioctl In */
|
||||||
|
#define C_INPUT 0x04 /* Input (Read) */
|
||||||
|
#define C_NDREAD 0x05 /* Non-destructive Read */
|
||||||
|
#define C_ISTAT 0x06 /* Input Status */
|
||||||
|
#define C_IFLUSH 0x07 /* Input Flush */
|
||||||
|
#define C_OUTPUT 0x08 /* Output (Write) */
|
||||||
|
#define C_OUTVFY 0x09 /* Output with verify */
|
||||||
|
#define C_OSTAT 0x0a /* Output */
|
||||||
|
#define C_OFLUSH 0x0b /* Output Flush */
|
||||||
|
#define C_IOCTLOUT 0x0c /* Ioctl Out */
|
||||||
|
#define C_OPEN 0x0d /* Device Open */
|
||||||
|
#define C_CLOSE 0x0e /* Device Close */
|
||||||
|
#define C_REMMEDIA 0x0f /* Removable MEDIA */
|
||||||
|
#define C_OUB 0x10 /* Output till busy */
|
||||||
|
#define C_GENIOCTL 0x13 /* Generic Ioctl */
|
||||||
|
#define C_GETLDEV 0x17 /* Get Logical Device */
|
||||||
|
#define C_SETLDEV 0x18 /* Set Logical Device */
|
||||||
|
#define C_IOCTLQRY 0x19 /* Ioctl Query */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convienence macros
|
||||||
|
*/
|
||||||
|
#define failure(x) (S_ERROR+S_DONE+x)
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* structures
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Device header */
|
||||||
|
|
||||||
|
struct dhdr {
|
||||||
|
struct dhdr
|
||||||
|
FAR *dh_next;
|
||||||
|
UWORD dh_attr;
|
||||||
|
VOID(*dh_strategy) (void);
|
||||||
|
VOID(*dh_interrupt) (void);
|
||||||
|
UBYTE dh_name[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ATTR_SUBST 0x8000
|
||||||
|
#define ATTR_CHAR 0x8000
|
||||||
|
#define ATTR_IOCTL 0x4000
|
||||||
|
#define ATTR_BLDFAT 0x2000
|
||||||
|
#define ATTR_REMOTE 0x1000
|
||||||
|
#define ATTR_EXCALLS 0x0800
|
||||||
|
#define ATTR_QRYIOCTL 0x0080
|
||||||
|
#define ATTR_GENIOCTL 0x0040
|
||||||
|
#define ATTR_RAW 0x0400
|
||||||
|
#define ATTR_FASTCON 0x0010
|
||||||
|
#define ATTR_CLOCK 0x0008
|
||||||
|
#define ATTR_NULL 0x0004
|
||||||
|
#define ATTR_CONOUT 0x0002
|
||||||
|
#define ATTR_HUGE 0x0002
|
||||||
|
#define ATTR_CONIN 0x0001
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* Bios Parameter Block structure */
|
||||||
|
/* */
|
||||||
|
|
||||||
|
#define FAT_NO_MIRRORING 0x80
|
||||||
|
|
||||||
|
#define BPB_SIZEOF 31 /* size of the standard BPB */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UWORD bpb_nbyte; /* Bytes per Sector */
|
||||||
|
UBYTE bpb_nsector; /* Sectors per Allocation Unit */
|
||||||
|
UWORD bpb_nreserved; /* # Reserved Sectors */
|
||||||
|
UBYTE bpb_nfat; /* # FATs */
|
||||||
|
UWORD bpb_ndirent; /* # Root Directory entries */
|
||||||
|
UWORD bpb_nsize; /* Size in sectors */
|
||||||
|
UBYTE bpb_mdesc; /* MEDIA Descriptor Byte */
|
||||||
|
UWORD bpb_nfsect; /* FAT size in sectors */
|
||||||
|
UWORD bpb_nsecs; /* Sectors per track */
|
||||||
|
UWORD bpb_nheads; /* Number of heads */
|
||||||
|
ULONG bpb_hidden; /* Hidden sectors */
|
||||||
|
ULONG bpb_huge; /* Size in sectors if */
|
||||||
|
/* bpb_nsize == 0 */
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
ULONG bpb_xnfsect; /* FAT size in sectors if */
|
||||||
|
/* bpb_nfsect == 0 */
|
||||||
|
UWORD bpb_xflags; /* extended flags */
|
||||||
|
/* bit 7: disable mirroring */
|
||||||
|
/* bits 6-4: reserved (0) */
|
||||||
|
/* bits 3-0: active FAT number */
|
||||||
|
UWORD bpb_xfsversion; /* filesystem version */
|
||||||
|
ULONG bpb_xrootclst; /* starting cluster of root dir */
|
||||||
|
UWORD bpb_xfsinfosec; /* FS info sector number, */
|
||||||
|
/* 0xFFFF if unknown */
|
||||||
|
UWORD bpb_xbackupsec; /* backup boot sector number */
|
||||||
|
/* 0xFFFF if unknown */
|
||||||
|
#endif
|
||||||
|
} bpb;
|
||||||
|
|
||||||
|
#define N_RETRY 5 /* number of retries permitted */
|
||||||
|
|
||||||
|
#include "dsk.h"
|
||||||
|
|
||||||
|
#define LBA_READ 0x4200
|
||||||
|
#define LBA_WRITE 0x4300
|
||||||
|
|
||||||
|
struct _bios_LBA_address_packet
|
||||||
|
/* Used to access a hard disk via LBA */
|
||||||
|
/* Added by Brian E. Reifsnyder */
|
||||||
|
{
|
||||||
|
unsigned char packet_size; /* size of this packet...set to 16 */
|
||||||
|
unsigned char reserved_1; /* set to 0...unused */
|
||||||
|
unsigned char number_of_blocks; /* 0 < number_of_blocks < 128 */
|
||||||
|
unsigned char reserved_2; /* set to 0...unused */
|
||||||
|
UBYTE far *buffer_address; /* addr of transfer buffer */
|
||||||
|
unsigned long block_address; /* LBA address */
|
||||||
|
unsigned long block_address_high; /* high bytes of LBA addr...unused */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CHS {
|
||||||
|
UWORD Cylinder;
|
||||||
|
UWORD Head;
|
||||||
|
UWORD Sector;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* DOS 4.0-7.0 drive data table (see RBIL at INT2F,AX=0803) */
|
||||||
|
typedef struct ddtstruct {
|
||||||
|
struct ddtstruct FAR *ddt_next;
|
||||||
|
/* pointer to next table (offset FFFFh if last table) */
|
||||||
|
UBYTE ddt_driveno; /* physical unit number (for INT 13) */
|
||||||
|
UBYTE ddt_logdriveno; /* logical drive number (0=A:) */
|
||||||
|
bpb ddt_bpb; /* BIOS Parameter Block */
|
||||||
|
UBYTE ddt_flags;
|
||||||
|
/* bit 6: 16-bit FAT instead of 12-bit
|
||||||
|
bit 7: unsupportable disk (all accesses will return Not Ready) */
|
||||||
|
UWORD ddt_FileOC; /* Count of Open files on Drv */
|
||||||
|
UBYTE ddt_type; /* device type */
|
||||||
|
UWORD ddt_descflags; /* bit flags describing drive */
|
||||||
|
UWORD ddt_ncyl; /* number of cylinders
|
||||||
|
(for partition only, if hard disk) */
|
||||||
|
bpb ddt_defbpb; /* BPB for default (highest) capacity supported */
|
||||||
|
UBYTE ddt_reserved[6]; /* (part of BPB above) */
|
||||||
|
UBYTE ddt_ltrack; /* last track accessed */
|
||||||
|
union {
|
||||||
|
ULONG ddt_lasttime; /* removable media: time of last access
|
||||||
|
in clock ticks (FFFFFFFFh if never) */
|
||||||
|
struct {
|
||||||
|
UWORD ddt_part; /* partition (FFFFh = primary, 0001h = extended)
|
||||||
|
always 0001h for DOS 5+ */
|
||||||
|
UWORD ddt_abscyl; /* absolute cylinder number of partition's
|
||||||
|
start on physical drive
|
||||||
|
(FFFFh if primary partition in DOS 4.x) */
|
||||||
|
} ddt_hd;
|
||||||
|
} ddt_fh;
|
||||||
|
UBYTE ddt_volume[12]; /* ASCIIZ volume label or "NO NAME " if none
|
||||||
|
(apparently taken from extended boot record
|
||||||
|
rather than root directory) */
|
||||||
|
ULONG ddt_serialno; /* serial number */
|
||||||
|
UBYTE ddt_fstype[9]; /* ASCIIZ filesystem type ("FAT12 " or "FAT16 ") */
|
||||||
|
ULONG ddt_offset; /* relative partition offset */
|
||||||
|
} ddt;
|
||||||
|
|
||||||
|
/* description flag bits */
|
||||||
|
#define DF_FIXED 0x001 /* fixed media, ie hard drive */
|
||||||
|
#define DF_CHANGELINE 0x002 /* door lock or disk change detection reported as supported */
|
||||||
|
#define DF_CURBPBLOCK 0x004 /* current BPB locked, use existing BPB instead of building one */
|
||||||
|
#define DF_SAMESIZE 0x008 /* all sectors in a track are the same size */
|
||||||
|
#define DF_MULTLOG 0x010 /* physical drive represents multiple logical ones, eg A: & B: */
|
||||||
|
#define DF_CURLOG 0x020 /* active (current) logical drive for this physical drive */
|
||||||
|
#define DF_DISKCHANGE 0x040 /* disk change was detected */
|
||||||
|
#define DF_DPCHANGED 0x080 /* device parameters changed */
|
||||||
|
#define DF_REFORMAT 0x100 /* disk formatted so BPB has changed */
|
||||||
|
#define DF_NOACCESS 0x200 /* don't allow access (read or write) to fixed media */
|
||||||
|
/* freedos specific flag bits */
|
||||||
|
#define DF_LBA 0x400
|
||||||
|
#define DF_WRTVERIFY 0x800
|
||||||
|
|
||||||
|
/* typedef struct ddtstruct ddt;*/
|
||||||
|
|
||||||
|
struct gblkio {
|
||||||
|
UBYTE gbio_spcfunbit;
|
||||||
|
UBYTE gbio_devtype;
|
||||||
|
UWORD gbio_devattrib;
|
||||||
|
UWORD gbio_ncyl;
|
||||||
|
UBYTE gbio_media;
|
||||||
|
bpb gbio_bpb;
|
||||||
|
UWORD gbio_nsecs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gblkfv /* for format / verify track */
|
||||||
|
{
|
||||||
|
UBYTE gbfv_spcfunbit;
|
||||||
|
UWORD gbfv_head;
|
||||||
|
UWORD gbfv_cyl;
|
||||||
|
UWORD gbfv_ntracks;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gblkrw /* for read / write track */
|
||||||
|
{
|
||||||
|
UBYTE gbrw_spcfunbit;
|
||||||
|
UWORD gbrw_head;
|
||||||
|
UWORD gbrw_cyl;
|
||||||
|
UWORD gbrw_sector;
|
||||||
|
UWORD gbrw_nsecs;
|
||||||
|
UBYTE FAR *gbrw_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Gioc_media {
|
||||||
|
WORD ioc_level;
|
||||||
|
ULONG ioc_serialno;
|
||||||
|
BYTE ioc_volume[11];
|
||||||
|
BYTE ioc_fstype[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Access_info {
|
||||||
|
BYTE AI_spec;
|
||||||
|
BYTE AI_Flag;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* Boot Block (Super Block) */
|
||||||
|
/* */
|
||||||
|
/* See BPB comments for the offsets below */
|
||||||
|
/* */
|
||||||
|
#define BT_JUMP 0
|
||||||
|
#define BT_OEM 3
|
||||||
|
#define BT_BPB 11
|
||||||
|
#define BT_SIZEOF 36
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
BYTE bt_jump[3]; /* Boot Jump opcodes */
|
||||||
|
BYTE bt_oem[8]; /* OEM Name */
|
||||||
|
bpb bt_bpb; /* BPB for this media/device */
|
||||||
|
WORD bt_nsecs; /* # Sectors per Track */
|
||||||
|
WORD bt_nheads; /* # Heads */
|
||||||
|
WORD bt_hidden; /* # Hidden sectors */
|
||||||
|
LONG bt_huge; /* use if nsecs == 0 */
|
||||||
|
BYTE bt_drvno;
|
||||||
|
BYTE bt_reserv;
|
||||||
|
BYTE bt_btid;
|
||||||
|
ULONG bt_serialno;
|
||||||
|
BYTE bt_volume[11];
|
||||||
|
BYTE bt_fstype[8];
|
||||||
|
} boot;
|
||||||
|
|
||||||
|
/* File system information structure */
|
||||||
|
struct fsinfo {
|
||||||
|
UDWORD fi_signature; /* must be 0x61417272 */
|
||||||
|
DWORD fi_nfreeclst; /* number of free clusters, -1 if unknown */
|
||||||
|
DWORD fi_cluster; /* most recently allocated cluster, -1 if unknown */
|
||||||
|
UBYTE fi_reserved[12];
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef boot super; /* Alias for boot structure */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UBYTE r_length; /* Request Header length */
|
||||||
|
UBYTE r_unit; /* Unit Code */
|
||||||
|
UBYTE r_command; /* Command Code */
|
||||||
|
UWORD r_status; /* Status */
|
||||||
|
BYTE r_reserved[8]; /* DOS Reserved Area */
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UBYTE _r_nunits; /* number of units */
|
||||||
|
BYTE FAR *_r_endaddr; /* Ending Address */
|
||||||
|
bpb *FAR * _r_bpbptr; /* ptr to BPB array */
|
||||||
|
UBYTE _r_firstunit;
|
||||||
|
} _r_init;
|
||||||
|
struct {
|
||||||
|
BYTE _r_meddesc; /* MEDIA Descriptor */
|
||||||
|
BYTE _r_retcode; /* Return Code */
|
||||||
|
BYTE FAR * _r_vid; /* volume id */
|
||||||
|
} _r_media;
|
||||||
|
struct {
|
||||||
|
BYTE _r_meddesc; /* MEDIA Descriptor */
|
||||||
|
boot FAR * _r_fat; /* boot sector pointer */
|
||||||
|
bpb FAR * _r_bpbpt; /* ptr to BPB table */
|
||||||
|
} _r_bpb;
|
||||||
|
struct {
|
||||||
|
BYTE _r_meddesc; /* MEDIA Descriptor */
|
||||||
|
BYTE FAR * _r_trans; /* Transfer Address */
|
||||||
|
UWORD _r_count; /* Byte/Sector Count */
|
||||||
|
UWORD _r_start; /* Starting Sector No. */
|
||||||
|
BYTE FAR * _r_vid; /* Pointer to volume id */
|
||||||
|
LONG _r_huge; /* for > 32Mb drives */
|
||||||
|
} _r_rw;
|
||||||
|
struct {
|
||||||
|
unsigned char _r_ndbyte; /* Byte Read From Device */
|
||||||
|
} _r_nd;
|
||||||
|
struct {
|
||||||
|
UBYTE _r_cat; /* Category code */
|
||||||
|
UBYTE _r_fun; /* Function code */
|
||||||
|
UWORD _r_si; /* Contents of SI and DI */
|
||||||
|
UWORD _r_di; /* (PC DOS 7 Technical Update, pp 104,105) */
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct gblkio FAR *_r_io;
|
||||||
|
struct gblkrw FAR *_r_rw;
|
||||||
|
struct gblkfv FAR *_r_fv;
|
||||||
|
struct Gioc_media FAR *_r_gioc;
|
||||||
|
struct Access_info FAR *_r_ai;
|
||||||
|
} _r_par; /* Pointer to param. block from 440C/440D */
|
||||||
|
} _r_gen;
|
||||||
|
} _r_x;
|
||||||
|
} request;
|
||||||
|
|
||||||
|
#define HUGECOUNT 0xffff
|
||||||
|
#define MAXSHORT 0xffffl
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Macros to assist request structure legibility
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Init packet macros */
|
||||||
|
#define r_nunits _r_x._r_init._r_nunits
|
||||||
|
#define r_endaddr _r_x._r_init._r_endaddr
|
||||||
|
#define r_bpbptr _r_x._r_init._r_bpbptr
|
||||||
|
#define r_firstunit _r_x._r_init._r_firstunit
|
||||||
|
|
||||||
|
/* MEDIA Check packet macros */
|
||||||
|
#define r_mcmdesc _r_x._r_media._r_meddesc
|
||||||
|
#define r_mcretcode _r_x._r_media._r_retcode
|
||||||
|
#define r_mcvid _r_x._r_media._r_vid
|
||||||
|
|
||||||
|
/* Build BPB packet macros */
|
||||||
|
#define r_bpmdesc _r_x._r_bpb._r_meddesc
|
||||||
|
#define r_bpfat _r_x._r_bpb._r_fat
|
||||||
|
#define r_bpptr _r_x._r_bpb._r_bpbpt
|
||||||
|
|
||||||
|
/* rw packet macros */
|
||||||
|
#define r_meddesc _r_x._r_rw._r_meddesc
|
||||||
|
#define r_trans _r_x._r_rw._r_trans
|
||||||
|
#define r_count _r_x._r_rw._r_count
|
||||||
|
#define r_start _r_x._r_rw._r_start
|
||||||
|
#define r_rwvid _r_x._r_rw._r_vid
|
||||||
|
#define r_huge _r_x._r_rw._r_huge
|
||||||
|
|
||||||
|
/* ndread packet macros */
|
||||||
|
#define r_ndbyte _r_x._r_nd._r_ndbyte
|
||||||
|
|
||||||
|
/* generic IOCTL and IOCTL query macros */
|
||||||
|
#define r_cat _r_x._r_gen._r_cat
|
||||||
|
#define r_fun _r_x._r_gen._r_fun
|
||||||
|
#define r_si _r_x._r_gen._r_si
|
||||||
|
#define r_di _r_x._r_gen._r_di
|
||||||
|
#define r_rw _r_x._r_gen._r_par._r_rw
|
||||||
|
#define r_io _r_x._r_gen._r_par._r_io
|
||||||
|
#define r_fv _r_x._r_gen._r_par._r_fv
|
||||||
|
#define r_gioc _r_x._r_gen._r_par._r_gioc
|
||||||
|
#define r_ai _r_x._r_gen._r_par._r_ai
|
||||||
|
|
||||||
|
/*
|
||||||
|
*interrupt support (spl & splx) support - IBM style
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define I_NONE 0 /* Initial value */
|
||||||
|
|
||||||
|
/* predefined interrupt levels - 8259 support */
|
||||||
|
#define IRQ0 0x01 /* Level 0 - highest */
|
||||||
|
#define IRQ1 0x02
|
||||||
|
#define IRQ2 0x04
|
||||||
|
#define IRQ3 0x08
|
||||||
|
#define IRQ4 0x10
|
||||||
|
#define IRQ5 0x20
|
||||||
|
#define IRQ6 0x40
|
||||||
|
#define IRQ7 0x80 /* Level 7 - lowest */
|
||||||
|
|
||||||
|
/* standard hardware configuration */
|
||||||
|
#define I_RTC IRQ0 /* Timer */
|
||||||
|
#define I_KBD IRQ1 /* Keyboard */
|
||||||
|
#define I_COM2 IRQ3 /* COM1: */
|
||||||
|
#define I_COM1 IRQ4 /* COM2: */
|
||||||
|
#define I_HDC IRQ5 /* Fixed disk */
|
||||||
|
#define I_FDC IRQ6 /* Diskette */
|
||||||
|
#define I_PRT IRQ7 /* Printer */
|
||||||
|
|
||||||
|
/* standard hardware vectors - 8259 defined */
|
||||||
|
#define V_RTC 0x08 /* Timer */
|
||||||
|
#define V_KBD 0x09 /* Keyboard */
|
||||||
|
#define V_LEV2 0x0a /* Level 2 - uncomitted */
|
||||||
|
#define V_COM2 0x0b /* COM1: */
|
||||||
|
#define V_COM1 0x0c /* COM2: */
|
||||||
|
#define V_HDC 0x0d /* Fixed disk */
|
||||||
|
#define V_FDC 0x0e /* Diskette */
|
||||||
|
#define V_PRT 0x0f /* Printer */
|
||||||
|
|
||||||
|
#define V_LEV0 0x08 /* Level 0 - highest */
|
||||||
|
#define V_LEV1 0x09
|
||||||
|
#define V_LEV2 0x0a /* Level 2 - uncomitted */
|
||||||
|
#define V_LEV3 0x0b
|
||||||
|
#define V_LEV4 0x0c
|
||||||
|
#define V_LEV5 0x0d
|
||||||
|
#define V_LEV6 0x0e
|
||||||
|
#define V_LEV7 0x0f /* Level 7 - lowest */
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
typedef request FAR *rqptr;
|
||||||
|
typedef bpb FAR *bpbptr;
|
||||||
|
typedef BYTE FAR *byteptr;
|
||||||
|
typedef struct dhdr FAR *dhdrptr;
|
||||||
|
|
||||||
|
extern request /* I/O Request packets */
|
||||||
|
ASM CharReqHdr, ASM IoReqHdr, ASM MediaReqHdr;
|
||||||
|
|
||||||
|
/* dsk.c */
|
||||||
|
COUNT ASMCFUNC FAR blk_driver(rqptr rp);
|
||||||
|
ddt * getddt(int dev);
|
||||||
|
|
||||||
|
/* error.c */
|
||||||
|
COUNT char_error(request * rq, struct dhdr FAR * lpDevice);
|
||||||
|
COUNT block_error(request * rq, COUNT nDrive, struct dhdr FAR * lpDevice, int mode);
|
||||||
|
/* sysclk.c */
|
||||||
|
WORD ASMCFUNC FAR clk_driver(rqptr rp);
|
||||||
|
|
||||||
|
/* execrh.asm */
|
||||||
|
#if defined(__WATCOMC__) && _M_IX86 >= 300
|
||||||
|
WORD execrh(request FAR *, struct dhdr FAR *);
|
||||||
|
#pragma aux execrh "^" parm reverse routine [] modify [ax bx cx dx es fs gs]
|
||||||
|
#else
|
||||||
|
WORD ASMPASCAL execrh(request FAR *, struct dhdr FAR *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* end of device.h
|
||||||
|
*/
|
||||||
|
|
54
hdr/dirmatch.h
Normal file
54
hdr/dirmatch.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* dirmatch.h */
|
||||||
|
/* */
|
||||||
|
/* FAT File System Match Data Structure */
|
||||||
|
/* */
|
||||||
|
/* January 4, 1992 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *dirmatch_hRcsId =
|
||||||
|
"$Id: dirmatch.h 1415 2009-06-02 13:18:24Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UBYTE dm_drive;
|
||||||
|
BYTE dm_name_pat[FNAME_SIZE + FEXT_SIZE];
|
||||||
|
UBYTE dm_attr_srch;
|
||||||
|
UWORD dm_entry;
|
||||||
|
CLUSTER dm_dircluster;
|
||||||
|
#ifndef WITHFAT32
|
||||||
|
UWORD reserved;
|
||||||
|
#endif
|
||||||
|
UWORD reserved2;
|
||||||
|
|
||||||
|
UBYTE dm_attr_fnd; /* found file attribute */
|
||||||
|
time dm_time; /* file time */
|
||||||
|
date dm_date; /* file date */
|
||||||
|
ULONG dm_size; /* file size */
|
||||||
|
BYTE dm_name[FNAME_SIZE + FEXT_SIZE + 2]; /* file name */
|
||||||
|
} dmatch;
|
31
hdr/dsk.h
Normal file
31
hdr/dsk.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* dsk.h */
|
||||||
|
/* Disk access Header File */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2012 */
|
||||||
|
/* FreeDOS */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MAX_SEC_SIZE
|
||||||
|
#define MAX_SEC_SIZE (1*512) /* max supported size of sector in bytes */
|
||||||
|
#endif
|
88
hdr/error.h
Normal file
88
hdr/error.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* error.h */
|
||||||
|
/* */
|
||||||
|
/* DOS-C error return codes */
|
||||||
|
/* */
|
||||||
|
/* December 1, 1991 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *error_hRcsId =
|
||||||
|
"$Id: error.h 485 2002-12-09 00:17:15Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Internal system error returns */
|
||||||
|
#define SUCCESS 0 /* Function was successful */
|
||||||
|
#define DE_INVLDFUNC -1 /* Invalid function number */
|
||||||
|
#define DE_FILENOTFND -2 /* File not found */
|
||||||
|
#define DE_PATHNOTFND -3 /* Path not found */
|
||||||
|
#define DE_TOOMANY -4 /* Too many open files */
|
||||||
|
#define DE_ACCESS -5 /* Access denied */
|
||||||
|
#define DE_INVLDHNDL -6 /* Invalid handle */
|
||||||
|
#define DE_MCBDESTRY -7 /* Memory control blocks shot */
|
||||||
|
#define DE_NOMEM -8 /* Insufficient memory */
|
||||||
|
#define DE_INVLDMCB -9 /* Invalid memory control block */
|
||||||
|
#define DE_INVLDENV -10 /* Invalid enviornement */
|
||||||
|
#define DE_INVLDFMT -11 /* Invalid format */
|
||||||
|
#define DE_INVLDACC -12 /* Invalid access */
|
||||||
|
#define DE_INVLDDATA -13 /* Invalid data */
|
||||||
|
#define DE_INVLDDRV -15 /* Invalid drive */
|
||||||
|
#define DE_RMVCUDIR -16 /* Attempt remove current dir */
|
||||||
|
#define DE_DEVICE -17 /* Not same device */
|
||||||
|
#define DE_NFILES -18 /* No more files */
|
||||||
|
#define DE_WRTPRTCT -19 /* No more files */
|
||||||
|
#define DE_BLKINVLD -20 /* invalid block */
|
||||||
|
#define DE_INVLDBUF -24 /* invalid buffer size, ext fnc */
|
||||||
|
#define DE_SEEK -25 /* error on file seek */
|
||||||
|
#define DE_HNDLDSKFULL -28 /* handle disk full (?) */
|
||||||
|
|
||||||
|
#define DE_INVLDPARM -0x57 /* invalid parameter */
|
||||||
|
|
||||||
|
#define DE_DEADLOCK -36
|
||||||
|
#define DE_LOCK -39
|
||||||
|
|
||||||
|
#define DE_FILEEXISTS -80 /* File exists */
|
||||||
|
|
||||||
|
/* Critical error flags */
|
||||||
|
#define EFLG_READ 0x00 /* Read error */
|
||||||
|
#define EFLG_WRITE 0x01 /* Write error */
|
||||||
|
#define EFLG_RSVRD 0x00 /* Error in rserved area */
|
||||||
|
#define EFLG_FAT 0x02 /* Error in FAT area */
|
||||||
|
#define EFLG_DIR 0x04 /* Error in dir area */
|
||||||
|
#define EFLG_DATA 0x06 /* Error in data area */
|
||||||
|
#define EFLG_ABORT 0x08 /* Handler can abort */
|
||||||
|
#define EFLG_RETRY 0x10 /* Handler can retry */
|
||||||
|
#define EFLG_IGNORE 0x20 /* Handler can ignore */
|
||||||
|
#define EFLG_CHAR 0x80 /* Error in char or FAT image */
|
||||||
|
|
||||||
|
/* error results returned after asking user */
|
||||||
|
/* MS-DOS compatible -- returned by CriticalError */
|
||||||
|
#define CONTINUE 0
|
||||||
|
#define RETRY 1
|
||||||
|
#define ABORT 2
|
||||||
|
#define FAIL 3
|
||||||
|
|
57
hdr/exe.h
Normal file
57
hdr/exe.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* exe.h */
|
||||||
|
/* */
|
||||||
|
/* DOS EXE Header Data Structure */
|
||||||
|
/* */
|
||||||
|
/* December 1, 1991 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *exe_hRcsId =
|
||||||
|
"$Id: exe.h 485 2002-12-09 00:17:15Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UWORD exSignature;
|
||||||
|
UWORD exExtraBytes;
|
||||||
|
UWORD exPages;
|
||||||
|
UWORD exRelocItems;
|
||||||
|
UWORD exHeaderSize;
|
||||||
|
UWORD exMinAlloc;
|
||||||
|
UWORD exMaxAlloc;
|
||||||
|
UWORD exInitSS;
|
||||||
|
UWORD exInitSP;
|
||||||
|
UWORD exCheckSum;
|
||||||
|
UWORD exInitIP;
|
||||||
|
UWORD exInitCS;
|
||||||
|
UWORD exRelocTable;
|
||||||
|
UWORD exOverlay;
|
||||||
|
} exe_header;
|
||||||
|
|
||||||
|
#define MAGIC 0x5a4d
|
||||||
|
#define OLD_MAGIC 0x4d5a
|
||||||
|
|
152
hdr/fat.h
Normal file
152
hdr/fat.h
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* fat.h */
|
||||||
|
/* */
|
||||||
|
/* FAT File System data structures & declarations */
|
||||||
|
/* */
|
||||||
|
/* November 26, 1991 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *fat_hRcsId =
|
||||||
|
"$Id: fat.h 1448 2009-06-16 21:45:17Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* FAT file system attribute bits */
|
||||||
|
#define D_NORMAL 0 /* normal */
|
||||||
|
#define D_RDONLY 0x01 /* read-only file */
|
||||||
|
#define D_HIDDEN 0x02 /* hidden */
|
||||||
|
#define D_SYSTEM 0x04 /* system */
|
||||||
|
#define D_VOLID 0x08 /* volume id */
|
||||||
|
#define D_DIR 0x10 /* subdir */
|
||||||
|
#define D_ARCHIVE 0x20 /* archive bit */
|
||||||
|
/* /// Added D_DEVICE bit. - Ron Cemer */
|
||||||
|
#define D_DEVICE 0x40 /* device bit */
|
||||||
|
|
||||||
|
#define D_LFN (D_RDONLY | D_HIDDEN | D_SYSTEM | D_VOLID)
|
||||||
|
#define D_ALL (D_RDONLY | D_HIDDEN | D_SYSTEM | D_DIR | D_ARCHIVE)
|
||||||
|
|
||||||
|
/* FAT file name constants */
|
||||||
|
#define FNAME_SIZE 8
|
||||||
|
#define FEXT_SIZE 3
|
||||||
|
|
||||||
|
/* FAT deleted flag */
|
||||||
|
#define DELETED '\x5' /* if first char, delete file */
|
||||||
|
#define EXT_DELETED '\xe5' /* external deleted flag */
|
||||||
|
|
||||||
|
/* Test for 16 bit or 12 bit FAT */
|
||||||
|
#define SIZEOF_CLST16 2
|
||||||
|
#define SIZEOF_CLST32 4
|
||||||
|
|
||||||
|
/* FAT cluster special flags */
|
||||||
|
#define FREE 0x000
|
||||||
|
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
#define LONG_LAST_CLUSTER 0x0FFFFFFFUL
|
||||||
|
#define LONG_BAD 0x0FFFFFF7UL
|
||||||
|
#else
|
||||||
|
#define LONG_LAST_CLUSTER 0xFFFF
|
||||||
|
#define LONG_BAD 0xFFF7
|
||||||
|
#endif
|
||||||
|
#define MASK16 0xFFF8
|
||||||
|
#define BAD16 0xFFF7
|
||||||
|
#define MASK12 0xFF8
|
||||||
|
#define BAD12 0xFF7
|
||||||
|
|
||||||
|
/* magic constants: even though FF7 is BAD so FF6 could be a valid cluster
|
||||||
|
no., MS docs specify that FF5 is the maximal possible cluster number
|
||||||
|
for FAT12; similar for 16 and 32 */
|
||||||
|
|
||||||
|
#define FAT_MAGIC 4085
|
||||||
|
#define FAT_MAGIC16 65525U
|
||||||
|
#define FAT_MAGIC32 268435455UL
|
||||||
|
|
||||||
|
/* int ISFAT32(struct dpb FAR *dpbp);*/
|
||||||
|
#define ISFAT32(x) _ISFAT32(x)
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define _ISFAT32(dpbp) (((dpbp)->dpb_size)>FAT_MAGIC16 && ((dpbp)->dpb_size)<=FAT_MAGIC32 )
|
||||||
|
*/
|
||||||
|
#define _ISFAT32(dpbp) (((dpbp)->dpb_fatsize)==0)
|
||||||
|
#define ISFAT16(dpbp) (((dpbp)->dpb_size)>FAT_MAGIC && ((dpbp)->dpb_size)<=FAT_MAGIC16 )
|
||||||
|
#define ISFAT12(dpbp) ((((dpbp)->dpb_size)-1)<FAT_MAGIC)
|
||||||
|
/* dpb_size == 0 for FAT32, hence doing -1 here */
|
||||||
|
|
||||||
|
/* FAT file system directory entry */
|
||||||
|
struct dirent {
|
||||||
|
char dir_name[FNAME_SIZE + FEXT_SIZE]; /* Filename + extension in FCB format */
|
||||||
|
UBYTE dir_attrib; /* File Attribute */
|
||||||
|
UBYTE dir_case; /* File case */
|
||||||
|
UBYTE dir_crtimems; /* Milliseconds */
|
||||||
|
UWORD dir_crtime; /* Creation time */
|
||||||
|
UWORD dir_crdate; /* Creation date */
|
||||||
|
UWORD dir_accdate; /* Last access date */
|
||||||
|
UWORD dir_start_high; /* High word of the cluster */
|
||||||
|
time dir_time; /* Time file created/updated */
|
||||||
|
date dir_date; /* Date file created/updated */
|
||||||
|
UWORD dir_start; /* Starting cluster */
|
||||||
|
/* 1st available = 2 */
|
||||||
|
ULONG dir_size; /* File size in bytes */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lfn_entry {
|
||||||
|
UBYTE lfn_id; /* Sequence number for this LFN entry */
|
||||||
|
UNICODE lfn_name0_4[5]; /* First 5 characters of LFN */
|
||||||
|
UBYTE lfn_attrib; /* LFN attribute, should be D_LFN == 0x0f */
|
||||||
|
UBYTE lfn_reserved1;
|
||||||
|
UBYTE lfn_checksum; /* Checksum for the corresponding 8.3 name */
|
||||||
|
UNICODE lfn_name5_10[6]; /* Next 6 characters of LFN */
|
||||||
|
UWORD lfn_reserved2;
|
||||||
|
UNICODE lfn_name11_12[2]; /* Last 2 characters of LFN */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* filesystem sizeof(dirent) - may be different from core */
|
||||||
|
/* */
|
||||||
|
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
struct dpb;
|
||||||
|
CLUSTER getdstart(struct dpb FAR *dpbp, struct dirent *dentry);
|
||||||
|
void setdstart(struct dpb FAR *dpbp, struct dirent *dentry, CLUSTER value);
|
||||||
|
#else
|
||||||
|
#define getdstart(dpbp, dentry) \
|
||||||
|
((dentry)->dir_start)
|
||||||
|
#define setdstart(dpbp, dentry, value) \
|
||||||
|
(((dentry)->dir_start) = (UWORD)(value))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DIR_NAME 0
|
||||||
|
#define DIR_EXT FNAME_SIZE
|
||||||
|
#define DIR_ATTRIB (FNAME_SIZE+FEXT_SIZE)
|
||||||
|
#define DIR_RESERVED (FNAME_SIZE+FEXT_SIZE+1)
|
||||||
|
#define DIR_START_HIGH (FNAME_SIZE+FEXT_SIZE+9)
|
||||||
|
#define DIR_TIME (FNAME_SIZE+FEXT_SIZE+11)
|
||||||
|
#define DIR_DATE (FNAME_SIZE+FEXT_SIZE+13)
|
||||||
|
#define DIR_START (FNAME_SIZE+FEXT_SIZE+15)
|
||||||
|
#define DIR_SIZE (FNAME_SIZE+FEXT_SIZE+17)
|
||||||
|
|
||||||
|
#define DIRENT_SIZE 32
|
||||||
|
|
120
hdr/fcb.h
Normal file
120
hdr/fcb.h
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* fcb.h */
|
||||||
|
/* */
|
||||||
|
/* FAT FCB and extended FCB data structures & declarations */
|
||||||
|
/* */
|
||||||
|
/* November 23, 1991 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *fcb_hRcsId =
|
||||||
|
"$Id: fcb.h 485 2002-12-09 00:17:15Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* fcb convience defines */
|
||||||
|
/* block device info */
|
||||||
|
#define FID_CHARDEV 0x80 /* 1 defines character device */
|
||||||
|
/* 0 defines block file */
|
||||||
|
#define FID_NOWRITE 0x40 /* 0 file dirty (write occured) */
|
||||||
|
/* 1 file has no changes */
|
||||||
|
#define FID_MASK 0x3f /* file # */
|
||||||
|
/* char device info */
|
||||||
|
#define FID_EOF 0x40 /* 1 = no eof detected */
|
||||||
|
/* 0 = end of file on input */
|
||||||
|
#define FID_BINARY 0x20 /* 1 = binary (raw) mode device */
|
||||||
|
/* 0 = ascii (cooked) mode device */
|
||||||
|
#define FID_CLOCK 0x08 /* Clock device */
|
||||||
|
#define FID_NULL 0x04 /* Null device */
|
||||||
|
#define FID_CONOUT 0x02 /* Console output device */
|
||||||
|
#define FID_CONIN 0x01 /* Console input device */
|
||||||
|
|
||||||
|
#ifndef FNAME_SIZE
|
||||||
|
#define FNAME_SIZE 8 /* limit on file name */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FEXT_SIZE
|
||||||
|
#define FEXT_SIZE 3 /* limit on extension */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FDFLT_DRIVE
|
||||||
|
#define FDFLT_DRIVE 0 /* default drive */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PARSE_SEP_STOP 0x01
|
||||||
|
#define PARSE_DFLT_DRIVE 0x02
|
||||||
|
#define PARSE_BLNK_FNAME 0x04
|
||||||
|
#define PARSE_BLNK_FEXT 0x08
|
||||||
|
|
||||||
|
#define PARSE_RET_NOWILD 0
|
||||||
|
#define PARSE_RET_WILD 1
|
||||||
|
#define PARSE_RET_BADDRIVE 0xff
|
||||||
|
|
||||||
|
#define FCB_READ 0
|
||||||
|
#define FCB_WRITE 1
|
||||||
|
|
||||||
|
/* File Control Block (FCB) */
|
||||||
|
typedef struct {
|
||||||
|
UBYTE fcb_drive; /* Drive number 0=default, 1=A, etc */
|
||||||
|
BYTE fcb_fname[FNAME_SIZE]; /* File name */
|
||||||
|
BYTE fcb_fext[FEXT_SIZE]; /* File name Extension */
|
||||||
|
UWORD fcb_cublock; /* Current block number of */
|
||||||
|
/* 128 records/block, for seq. r/w */
|
||||||
|
UWORD fcb_recsiz; /* Logical record size in bytes, */
|
||||||
|
/* default = 128 */
|
||||||
|
ULONG fcb_fsize; /* File size in bytes */
|
||||||
|
date fcb_date; /* Date file created */
|
||||||
|
time fcb_time; /* Time of last write */
|
||||||
|
/* the following are reserved by system */
|
||||||
|
BYTE fcb_sftno; /* Device ID */
|
||||||
|
BYTE fcb_attrib_hi; /* share info, dev attrib word hi */
|
||||||
|
BYTE fcb_attrib_lo; /* dev attrib word lo, open mode */
|
||||||
|
UWORD fcb_strtclst; /* file starting cluster */
|
||||||
|
UWORD fcb_dirclst; /* cluster of the dir entry */
|
||||||
|
UBYTE fcb_diroff_unused; /* offset of the dir entry */
|
||||||
|
/* end reserved */
|
||||||
|
UBYTE fcb_curec; /* Current block number of */
|
||||||
|
ULONG fcb_rndm; /* Current relative record number */
|
||||||
|
} fcb;
|
||||||
|
|
||||||
|
/* FAT extended fcb */
|
||||||
|
typedef struct {
|
||||||
|
UBYTE xfcb_flag; /* 0xff indicates Extended FCB */
|
||||||
|
BYTE xfcb_resvrd[5]; /* Reserved */
|
||||||
|
UBYTE xfcb_attrib; /* Attribute */
|
||||||
|
fcb xfcb_fcb;
|
||||||
|
} xfcb;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UBYTE renDriveID; /* drive no. */
|
||||||
|
BYTE renOldName[8]; /* Old Filename */
|
||||||
|
BYTE renOldExtent[3]; /* Old File Extension */
|
||||||
|
BYTE renReserved1[5];
|
||||||
|
BYTE renNewName[8]; /* New Filename */
|
||||||
|
BYTE renNewExtent[3]; /* New FileExtension */
|
||||||
|
BYTE renReserved2[9];
|
||||||
|
} rfcb;
|
||||||
|
|
81
hdr/file.h
Normal file
81
hdr/file.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* file.h */
|
||||||
|
/* */
|
||||||
|
/* DOS File mode flags */
|
||||||
|
/* */
|
||||||
|
/* December 1, 1991 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *file_hRcsId =
|
||||||
|
"$Id: file.h 831 2004-03-27 00:27:11Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 0 = CON, standard input, can be redirected */
|
||||||
|
/* 1 = CON, standard output, can be redirected */
|
||||||
|
/* 2 = CON, standard error */
|
||||||
|
/* 3 = AUX, auxiliary */
|
||||||
|
/* 4 = PRN, list device */
|
||||||
|
/* 5 = 1st user file ... */
|
||||||
|
#define STDIN 0
|
||||||
|
#define STDOUT 1
|
||||||
|
#define STDERR 2
|
||||||
|
#define STDAUX 3
|
||||||
|
#define STDPRN 4
|
||||||
|
|
||||||
|
/* mode bits */
|
||||||
|
#define O_VALIDMASK 0xfff3 /* valid open mask */
|
||||||
|
|
||||||
|
#define O_RDONLY 0x0000
|
||||||
|
#define O_WRONLY 0x0001
|
||||||
|
#define O_RDWR 0x0002
|
||||||
|
#define O_ACCMODE 0x0003
|
||||||
|
|
||||||
|
/* bits 2, 3 reserved */
|
||||||
|
|
||||||
|
/* bits 4, 5, 6 sharing modes */
|
||||||
|
#define O_SHAREMASK 0x0070 /* mask to isolate shared bits */
|
||||||
|
|
||||||
|
#define O_DENYALL 0x0010 /* sharing bits */
|
||||||
|
#define O_DENYWRITE 0x0020 /* " " */
|
||||||
|
#define O_DENYREAD 0x0030 /* " " */
|
||||||
|
#define O_DENYNONE 0x0040 /* " " */
|
||||||
|
#define O_NETFCB 0x0070 /* networked fcb */
|
||||||
|
|
||||||
|
#define O_NOINHERIT 0x0080
|
||||||
|
#define O_OPEN 0x0100 /* not */
|
||||||
|
#define O_TRUNC 0x0200 /* both */
|
||||||
|
#define O_CREAT 0x0400
|
||||||
|
#define O_LEGACY 0x0800
|
||||||
|
#define O_LARGEFILE 0x1000
|
||||||
|
#define O_NOCRIT 0x2000
|
||||||
|
#define O_SYNC 0x4000
|
||||||
|
#define O_FCB 0x8000
|
||||||
|
|
||||||
|
/* status for extended open */
|
||||||
|
enum {S_OPENED = 1, S_CREATED = 2, S_REPLACED = 3};
|
||||||
|
|
65
hdr/fnode.h
Normal file
65
hdr/fnode.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* fnode.h */
|
||||||
|
/* */
|
||||||
|
/* Internal File Node for FAT File System */
|
||||||
|
/* */
|
||||||
|
/* January 4, 1992 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *fnode_hRcsId =
|
||||||
|
"$Id: fnode.h 1432 2009-06-10 16:10:54Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct f_node {
|
||||||
|
UWORD f_flags; /* file flags */
|
||||||
|
|
||||||
|
dmatch *f_dmp; /* this file's dir match */
|
||||||
|
struct dirent f_dir; /* this file's dir entry image */
|
||||||
|
|
||||||
|
ULONG f_dirsector; /* the sector containing dir entry*/
|
||||||
|
UBYTE f_diridx; /* offset/32 of dir entry in sec*/
|
||||||
|
/* when dir is not root */
|
||||||
|
struct dpb FAR *f_dpb; /* the block device for file */
|
||||||
|
|
||||||
|
ULONG f_offset; /* byte offset for next op */
|
||||||
|
CLUSTER f_cluster_offset; /* relative cluster number within file */
|
||||||
|
CLUSTER f_cluster; /* the cluster we are at */
|
||||||
|
UBYTE f_sft_idx; /* corresponding SFT index */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct f_node *f_node_ptr;
|
||||||
|
|
||||||
|
struct lfn_inode {
|
||||||
|
UNICODE l_name[261]; /* Long file name string */
|
||||||
|
/* If the string is empty, */
|
||||||
|
/* then file has the 8.3 name */
|
||||||
|
struct dirent l_dir; /* Directory entry image */
|
||||||
|
UWORD l_diroff; /* Current directory entry offset */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct lfn_inode FAR * lfn_inode_ptr;
|
48
hdr/kbd.h
Normal file
48
hdr/kbd.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* kbd.h */
|
||||||
|
/* */
|
||||||
|
/* Buffered Keyboard Input data structures & declarations */
|
||||||
|
/* */
|
||||||
|
/* July 5, 1993 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *kbd_hRcsId =
|
||||||
|
"$Id: kbd.h 485 2002-12-09 00:17:15Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LINEBUFSIZECON 128
|
||||||
|
#define KBD_MAXLENGTH LINEBUFSIZECON+1 /* the above + LF */
|
||||||
|
#define LINEBUFSIZE0A 256 /* maximum length for int21/ah=0a */
|
||||||
|
|
||||||
|
/* Keyboard buffer */
|
||||||
|
typedef struct {
|
||||||
|
UBYTE kb_size; /* size of buffer in bytes */
|
||||||
|
UBYTE kb_count; /* number of bytes returned */
|
||||||
|
BYTE kb_buf[KBD_MAXLENGTH]; /* the buffer itself */
|
||||||
|
} keyboard;
|
||||||
|
|
36
hdr/kconfig.h
Normal file
36
hdr/kconfig.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
KConfig.h
|
||||||
|
|
||||||
|
DLASortByDriveNo
|
||||||
|
0 : Drive Letter Assignement ike MSDOS
|
||||||
|
1 : DLA - first drive completely first, then to next drive
|
||||||
|
|
||||||
|
InitDiskShowDriveAssignment
|
||||||
|
0 : don't show what drive/partition assigned to what drive letter
|
||||||
|
1 : show info
|
||||||
|
|
||||||
|
SkipConfigSeconds:
|
||||||
|
< 0 : not possible to skip config.sys
|
||||||
|
= 0 : only possible if already pressed before, no message
|
||||||
|
> 0 : wait so long for F5/F8
|
||||||
|
|
||||||
|
BootHarddiskSeconds: boots by default - and without user interaction - from HD
|
||||||
|
<= 0: normal
|
||||||
|
> 0:
|
||||||
|
display message
|
||||||
|
' hit any key to continue to boot from 'diskette or CD'
|
||||||
|
wait ## seconds
|
||||||
|
if no key hit, boot from HD
|
||||||
|
|
||||||
|
*/
|
||||||
|
typedef struct _KernelConfig {
|
||||||
|
char CONFIG[6]; /* "CONFIG" */
|
||||||
|
unsigned short ConfigSize;
|
||||||
|
|
||||||
|
unsigned char DLASortByDriveNo;
|
||||||
|
unsigned char InitDiskShowDriveAssignment;
|
||||||
|
signed char SkipConfigSeconds;
|
||||||
|
unsigned char ForceLBA;
|
||||||
|
unsigned char GlobalEnableLBAsupport; /* = 0 --> disable LBA support */
|
||||||
|
signed char BootHarddiskSeconds;
|
||||||
|
} KernelConfig;
|
91
hdr/lol.h
Normal file
91
hdr/lol.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* lol.h */
|
||||||
|
/* */
|
||||||
|
/* DOS List of Lists structure */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2003 */
|
||||||
|
/* Bart Oldeman */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; if not, write to the Free Software */
|
||||||
|
/* Foundation, Inc., 59 Temple Place, Suite 330, */
|
||||||
|
/* Boston, MA 02111-1307 USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
enum {LOC_CONV=0, LOC_HMA=1};
|
||||||
|
|
||||||
|
/* note: we start at DOSDS:0, but the "official" list of lists starts a
|
||||||
|
little later at DOSDS:26 (this is what is returned by int21/ah=52) */
|
||||||
|
|
||||||
|
struct lol {
|
||||||
|
char filler[0x22];
|
||||||
|
char *inputptr; /* -4 Pointer to unread CON input */
|
||||||
|
unsigned short first_mcb; /* -2 Start of user memory */
|
||||||
|
struct dpb far *DPBp; /* 0 First drive Parameter Block */
|
||||||
|
struct sfttbl far *sfthead; /* 4 System File Table head */
|
||||||
|
struct dhdr far *clock; /* 8 CLOCK$ device */
|
||||||
|
struct dhdr far *syscon; /* c console device */
|
||||||
|
unsigned short maxsecsize; /* 10 max bytes per sector for any blkdev */
|
||||||
|
void far *inforecptr; /* 12 pointer to disk buffer info record */
|
||||||
|
struct cds far *CDSp; /* 16 Current Directory Structure */
|
||||||
|
struct sfttbl far *FCBp; /* 1a FCB table pointer */
|
||||||
|
unsigned short nprotfcb; /* 1e number of protected fcbs */
|
||||||
|
unsigned char nblkdev; /* 20 number of block devices */
|
||||||
|
unsigned char lastdrive; /* 21 value of last drive */
|
||||||
|
struct dhdr nul_dev; /* 22 NUL device driver header(no pointer!)*/
|
||||||
|
unsigned char njoined; /* 34 number of joined devices */
|
||||||
|
unsigned short specialptr; /* 35 pointer to list of spec. prog(unused)*/
|
||||||
|
void far *setverPtr; /* 37 pointer to SETVER list */
|
||||||
|
void (*a20ptr)(void); /* 3b pointer to fix A20 ctrl */
|
||||||
|
unsigned short recentpsp; /* 3d PSP of most recently exec'ed prog */
|
||||||
|
unsigned short nbuffers; /* 3f Number of buffers */
|
||||||
|
unsigned short nlookahead; /* 41 Number of lookahead buffers */
|
||||||
|
unsigned char BootDrive; /* 43 bootdrive (1=A:) */
|
||||||
|
unsigned char cpu; /* 44 CPU family [was unused dword moves] */
|
||||||
|
unsigned short xmssize; /* 45 extended memory size in KB */
|
||||||
|
struct buffer far *firstbuf; /* 47 head of buffers linked list */
|
||||||
|
unsigned short dirtybuf; /* 4b number of dirty buffers */
|
||||||
|
struct buffer far *lookahead;/* 4d pointer to lookahead buffer */
|
||||||
|
unsigned short slookahead; /* 51 number of lookahead sectors */
|
||||||
|
unsigned char bufloc; /* 53 BUFFERS loc (1=HMA) */
|
||||||
|
char far *deblock_buf; /* 54 pointer to workspace buffer */
|
||||||
|
char filler2[5]; /* 58 ???/unused */
|
||||||
|
unsigned char int24fail; /* 5d int24 fail while making i/o stat call*/
|
||||||
|
unsigned char memstrat; /* 5e memory allocation strat during exec */
|
||||||
|
unsigned char a20count; /* 5f nr. of int21 calls for which a20 off */
|
||||||
|
unsigned char VgaSet; /* 60 bitflags switches=/w, int21/4b05 */
|
||||||
|
unsigned short unpack; /* 61 offset of unpack code start */
|
||||||
|
unsigned char uppermem_link; /* 63 UMB Link flag */
|
||||||
|
unsigned short min_pars; /* 64 minimum para req by program execed */
|
||||||
|
unsigned short uppermem_root;/* 66 Start of umb chain (usually 9fff) */
|
||||||
|
unsigned short last_para; /* 68 para: start scanning during memalloc */
|
||||||
|
/* ANY ITEM BELOW THIS POINT MAY CHANGE */
|
||||||
|
/* FreeDOS specific entries */
|
||||||
|
unsigned char os_setver_minor;/*6a settable minor DOS version */
|
||||||
|
unsigned char os_setver_major;/*6b settable major DOS version */
|
||||||
|
unsigned char os_minor; /* 6c minor DOS version */
|
||||||
|
unsigned char os_major; /* 6d major DOS version */
|
||||||
|
unsigned char rev_number; /* 6e DOS revision#, only 3 bits */
|
||||||
|
unsigned char version_flags; /* 6f DOS version flags */
|
||||||
|
char *os_release; /* 70 near pointer to os_release string */
|
||||||
|
#ifdef WIN31SUPPORT
|
||||||
|
unsigned short winInstanced; /* WinInit called */
|
||||||
|
unsigned long winStartupInfo[4];
|
||||||
|
unsigned short instanceTable[5];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
69
hdr/mcb.h
Normal file
69
hdr/mcb.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* mcb.h */
|
||||||
|
/* */
|
||||||
|
/* Memory Control Block data structures and declarations */
|
||||||
|
/* */
|
||||||
|
/* November 23, 1991 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *mcb_hRcsId =
|
||||||
|
"$Id: mcb.h 822 2004-03-25 00:20:20Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LARGEST -1
|
||||||
|
#define FIRST_FIT 0
|
||||||
|
#define BEST_FIT 1
|
||||||
|
#define LAST_FIT 2
|
||||||
|
#define FIRST_FIT_UO 0x40
|
||||||
|
#define BEST_FIT_UO 0x41
|
||||||
|
#define LAST_FIT_UO 0x42
|
||||||
|
#define FIRST_FIT_U 0x80
|
||||||
|
#define BEST_FIT_U 0x81
|
||||||
|
#define LAST_FIT_U 0x82
|
||||||
|
#define FIT_U_MASK 0xc0
|
||||||
|
#define FIT_MASK 0x3f
|
||||||
|
|
||||||
|
#define MCB_NORMAL 0x4d
|
||||||
|
#define MCB_LAST 0x5a
|
||||||
|
|
||||||
|
#define DOS_PSP 0x0060 /* 0x0008 What? seg 8 =0:0080 */
|
||||||
|
#define FREE_PSP 0
|
||||||
|
|
||||||
|
#define MCB_SIZE(x) ((((LONG)(x))<<4)+sizeof(mcb))
|
||||||
|
|
||||||
|
typedef UWORD seg;
|
||||||
|
typedef UWORD offset;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
BYTE m_type; /* mcb type - chain or end */
|
||||||
|
UWORD m_psp; /* owner id via psp segment */
|
||||||
|
UWORD m_size; /* size of segment in paragraphs */
|
||||||
|
BYTE m_fill[3];
|
||||||
|
BYTE m_name[8]; /* owner name limited to 8 bytes */
|
||||||
|
} mcb;
|
||||||
|
|
80
hdr/network.h
Normal file
80
hdr/network.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* network.h */
|
||||||
|
/* */
|
||||||
|
/* DOS Networking */
|
||||||
|
/* */
|
||||||
|
/* October 10, 1999 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1999 */
|
||||||
|
/* James Tabor */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
/* Defines for remote access functions */
|
||||||
|
#define REM_RMDIR 0x1101
|
||||||
|
#define REM_MKDIR 0x1103
|
||||||
|
#define REM_CHDIR 0x1105
|
||||||
|
#define REM_CLOSE 0x1106
|
||||||
|
#define REM_FLUSH 0x1107
|
||||||
|
#define REM_READ 0x1108
|
||||||
|
#define REM_WRITE 0x1109
|
||||||
|
#define REM_LOCK 0x110a
|
||||||
|
#define REM_UNLOCK 0x110b
|
||||||
|
#define REM_GETSPACE 0x110c
|
||||||
|
#define REM_SETATTR 0x110e
|
||||||
|
#define REM_GETATTRZ 0x110f
|
||||||
|
#define REM_RENAME 0x1111
|
||||||
|
#define REM_DELETE 0x1113
|
||||||
|
#define REM_OPEN 0x1116
|
||||||
|
#define REM_CREATE 0x1117
|
||||||
|
#define REM_CRTRWOCDS 0x1118
|
||||||
|
#define REM_FND1WOCDS 0x1119
|
||||||
|
#define REM_FINDFIRST 0x111B
|
||||||
|
#define REM_FINDNEXT 0x111C
|
||||||
|
#define REM_CLOSEALL 0x111d
|
||||||
|
#define REM_DOREDIRECT 0x111e
|
||||||
|
#define REM_PRINTSET 0x111f
|
||||||
|
#define REM_FLUSHALL 0x1120
|
||||||
|
#define REM_LSEEK 0x1121
|
||||||
|
#define REM_PROCESS_END 0x1122
|
||||||
|
#define REM_FILENAME 0x1123
|
||||||
|
#define REM_PRINTREDIR 0x1125
|
||||||
|
#define REM_EXTOC 0x112e
|
||||||
|
|
||||||
|
struct rgds {
|
||||||
|
UWORD r_spc;
|
||||||
|
UWORD r_navc;
|
||||||
|
UWORD r_bps;
|
||||||
|
UWORD r_nc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct remote_fileattrib {
|
||||||
|
UWORD rfa_file; /* File Attributes */
|
||||||
|
union {
|
||||||
|
ULONG rfa_filesize; /* file size */
|
||||||
|
struct {
|
||||||
|
UWORD rfa_filesize_lo; /* DI Low */
|
||||||
|
UWORD rfa_filesize_hi; /* BX High */
|
||||||
|
} _split_rfa_fz;
|
||||||
|
} rfa_fz_union;
|
||||||
|
UWORD rfa_time;
|
||||||
|
UWORD rfa_date;
|
||||||
|
};
|
628
hdr/nls.h
Normal file
628
hdr/nls.h
Normal file
@ -0,0 +1,628 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* NLS.H */
|
||||||
|
/* FreeDOS */
|
||||||
|
/* */
|
||||||
|
/* National Language Support data structures */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2000 */
|
||||||
|
/* Steffen Kaiser */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of FreeDOS. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
/* one byte alignment */
|
||||||
|
#include <algnbyte.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Description of the organization of NLS information -- 2000/02/13 ska
|
||||||
|
*
|
||||||
|
* Glossar:
|
||||||
|
* NLS package -- NLS information incl. any code required to access or
|
||||||
|
* correctly interprete this particular information
|
||||||
|
*
|
||||||
|
* Abbreviation:
|
||||||
|
* (NLS) pkg -- NLS package
|
||||||
|
*
|
||||||
|
* The code included into the kernel does "only" support NLS packages
|
||||||
|
* structurally compatible with the one of the U.S.A. / CP437.
|
||||||
|
* I guess that most NLS packages has been tweaked to be compatible,
|
||||||
|
* so that this is not a real limitation, but for all other packages
|
||||||
|
* the external NLSFUNC can supply every piece of code necessary.
|
||||||
|
* To allow this the interface between the kernel and NLSFUNC has been
|
||||||
|
* extended; at the same time the interface has been reduced, because some
|
||||||
|
* of the API functions do not seem to offer any functionality required
|
||||||
|
* for now. This, however, may be a misinterpretation because of
|
||||||
|
* lack of understanding.
|
||||||
|
*
|
||||||
|
* The supported structure consists of the following assumptions:
|
||||||
|
* 1) The pkg must contain the tables 2 (Upcase character), 4
|
||||||
|
* (Upcase filename character) and 5 (filename termination
|
||||||
|
* characters); because they are used internally.
|
||||||
|
* 2) The tables 2 and 4 must contain exactly 128 (0x80) characters.
|
||||||
|
* The character at index 0 corresponses to character 128 (0x80).
|
||||||
|
* The characters in the range of 0..0x7f are constructed out of
|
||||||
|
* the 7-bit US-ASCII (+ control characters) character set and are
|
||||||
|
* upcased not through the table, but by the expression:
|
||||||
|
* (ch >= 'a' && ch <= 'z')? ch - 'a' + 'A': ch
|
||||||
|
* with: 'a' == 97; 'z' == 122; 'A' == 65
|
||||||
|
* 3) The data to be returned by DOS-65 is enlisted in the
|
||||||
|
* nlsPointer[] array of the nlsPackage structure, including
|
||||||
|
* the DOS-65-01 data, which always must be last entry of the
|
||||||
|
* array.
|
||||||
|
* 4) DOS-38 returns the 34 bytes beginning with the byte at offset
|
||||||
|
* 4 behind the size field of DOS-65-01.
|
||||||
|
*
|
||||||
|
* It seems that pure DOS can internally maintain two NLS pkgs:
|
||||||
|
* NLS#1: The hardcoded pkg of U.S.A. on CP437, and
|
||||||
|
* NLS#2: the pkg loaded via COUNTRY= from within CONFIG.SYS.
|
||||||
|
* I do interprete this behaviour as follows:
|
||||||
|
* CONFIG.SYS is read in more passes; before COUTRY= can be evaluated,
|
||||||
|
* many actions must be performed, e.g. to load kernel at all, open
|
||||||
|
* CONFIG.SYS and begin reading. The kernel requires at least two
|
||||||
|
* NLS information _before_ COUNTRY= has been evaluated - both upcase
|
||||||
|
* tables. To not implement the same function multiple times, e.g.
|
||||||
|
* to upcase with and without table, the kernel uses the default
|
||||||
|
* NLS pkg until a more appropriate one can be loaded and hopes that
|
||||||
|
* the BIOS (and the user) can live with its outcome.
|
||||||
|
* Though, theoretically, the hardcoded NLS pkg could be purged
|
||||||
|
* or overwritten once the COUNTRY= statement has been evaluated.
|
||||||
|
* It would be possible that this NLS pkg internally performs different
|
||||||
|
* purposes, for now this behaviour will be kept.
|
||||||
|
*
|
||||||
|
* The current implementation extends the above "two maintained
|
||||||
|
* NLS pkgs" into that the kernel chains all NLS pkgs loaded in
|
||||||
|
* memory into one single linked list. When the user does neither
|
||||||
|
* wants to load other NLS pkgs without executing NLSFUNC and the
|
||||||
|
* loaded NLS pkgs do not contain code themselves, no other code is
|
||||||
|
* required, but some memory to store the NLS pkgs into.
|
||||||
|
*
|
||||||
|
* Furthermore, because the kernel needs to include the code for the
|
||||||
|
* hardcoded NLS pkg anyway, every NLS pkg can use it; so only
|
||||||
|
* NLS pkgs that structurally differ from U.S.A./CP437 actually need
|
||||||
|
* to add any code and residently install the MUX handler for NLSFUNC.
|
||||||
|
* This technique reduces the overhead calling the MUX handler, when
|
||||||
|
* it is not needed.
|
||||||
|
* However, NLSFUNC is always required if the user wants to return
|
||||||
|
* information about NLS pkgs _not_ loaded into memory.
|
||||||
|
*
|
||||||
|
*=== Attention: Because the nlsInfoBlock structure differs from the
|
||||||
|
*=== the "traditional" (aka MS) implementation, the MUX-14 interface
|
||||||
|
*=== is _not_ MS-compatible, although all the registers etc.
|
||||||
|
*=== do conform. -- 2000/02/26 ska
|
||||||
|
*
|
||||||
|
* Previous failed attempts to implement NLS handling and a full-
|
||||||
|
* featured MUX-14 supporting any-structured NLS pkgs suggest
|
||||||
|
* to keep the implement as simple as possible and keep the
|
||||||
|
* optimization direction off balance and to tend toward either
|
||||||
|
* an optimization for speed or size.
|
||||||
|
*
|
||||||
|
* The most problem is that the MUX interrupt chain is considered
|
||||||
|
* highly overcrowded, so if the kernels invokes it itself, the
|
||||||
|
* performance might decrease dramatically; on the other side, the
|
||||||
|
* more complex the interface between kernel and a _probably_ installed
|
||||||
|
* external NLSFUNC becomes the more difficult all the stuff is becoming
|
||||||
|
* and, most importantly, the size grows unnecessarily, because many
|
||||||
|
* people don't use NLSFUNC at all.
|
||||||
|
*
|
||||||
|
* The kernel uses the NLS pkg itself for two operations:
|
||||||
|
* 1) DOS-65-2x and DOS-65-Ax: Upcase character, string, memory area, &
|
||||||
|
* 2) whenever a filename is passed into the kernel, its components
|
||||||
|
* must be identified, invalid characters must be detected
|
||||||
|
* and, finally, all letters must be uppercased.
|
||||||
|
* I do not consider operation 1) an action critical for performance,
|
||||||
|
* because traditional DOS programming praxis says: Do it Yourself; so
|
||||||
|
* one can consider oneself lucky that a program aquires the upcase
|
||||||
|
* table once in its life time (I mean: lucky the program calls NLS at all).
|
||||||
|
* Operation 2), in opposite, might dramatically reduce performance, if
|
||||||
|
* it lacks proper implementations.
|
||||||
|
*
|
||||||
|
* Straight forward implementation:
|
||||||
|
* The basic implementation of the NLS channels all requests of DOS-65,
|
||||||
|
* DOS-66, and DOS-38 through MUX-14. Hereby, any external program, such
|
||||||
|
* as NLSFUNC, may (or may not) install a piece of code to filter
|
||||||
|
* one, few, or all requests in order to perform them itself, by default
|
||||||
|
* all requests will end within the root of the MUX interrupt, which is
|
||||||
|
* located within the kernel itself. An access path could look like this:
|
||||||
|
* 1. Call to DOS-65-XX, DOS-66-XX, or DOS-38.
|
||||||
|
* 2. The kernel is enterred through the usual INT-21 API handler.
|
||||||
|
* 3. The request is decoded and one of the NLS.C function is called.
|
||||||
|
* 4. This function packs a new request and calls MUX-14.
|
||||||
|
* 5. Every TSR/driver hooking INT-2F will check, if the request is
|
||||||
|
* directed for itself;
|
||||||
|
* 5.1. If not, the request is passed on to the next item of the MUX
|
||||||
|
* interrupt chain;
|
||||||
|
* 5.2. If so, the TSR, e.g. NLSFUNC, tests if the request is to be
|
||||||
|
* performed internally;
|
||||||
|
* 5.2.1. If so, the request is performed and the MUX-14 call is
|
||||||
|
* terminated (goto step 8.)
|
||||||
|
* 5.2.2. If not, the request is passed on (see step 5.1.)
|
||||||
|
* 6. If all TSRs had their chance to filter requests, but none decided
|
||||||
|
* to perform the request itself, the kernel is (re-)enterred
|
||||||
|
* through its INT-2F (MUX) API handler.
|
||||||
|
* 7. Here the request is decoded again and performed with the kernel-
|
||||||
|
* internal code; then the MUX-14 call is terminated.
|
||||||
|
* 8. When the MUX-14 call returns, it has setup all return parameters
|
||||||
|
* already, so the INT-21 call is terminated as well.
|
||||||
|
*
|
||||||
|
* Note: The traditional MUX-14 is NOT supported to offer functionality
|
||||||
|
* to the kernel at the first place, but to let the kernel access and
|
||||||
|
* return any values they must be loaded into memory, but the user may
|
||||||
|
* request information through the DOS-65 interface of NLS pkgs _not_
|
||||||
|
* already loaded. Theoretically, NLSFUNC needs not allocate any internal
|
||||||
|
* buffer to load the data into, because the user already supplied one;
|
||||||
|
* also if the kernel would instruct NLSFUNC to load the requested
|
||||||
|
* NLS pkg, more memory than necessary would be allocated. However, all
|
||||||
|
* except subfunction 1 return a _pointer_ to the data rather than the
|
||||||
|
* data itself; that means that NLSFUNC must cache the requested data
|
||||||
|
* somewhere, but how long?
|
||||||
|
*
|
||||||
|
* Performance tweaks:
|
||||||
|
* When the system -- This word applies to the combination of kernel and
|
||||||
|
* any loaded MUX-14 extension á la NLSFUNC here. -- uppercases
|
||||||
|
* _filenames_, it must perform a DOS-65-A2 internally. In the basic
|
||||||
|
* implementation this request would be channeled through MUX-14, even
|
||||||
|
* if there is no external NLSFUNC at all. Also, when a NLS pkg had
|
||||||
|
* been loaded by the kernel itself, it complies to above mentioned
|
||||||
|
* rules and it is very unlikely that it is necessary to probe if
|
||||||
|
* a MUX-14 TSR might want to perform the request itself. Therefore
|
||||||
|
* each NLS pkg contains some flags that allow the kernel to bypass
|
||||||
|
* the MUX-14 request and invoke the proper function directly. Both
|
||||||
|
* default NLS pkgs will have those flags enabled, because they are
|
||||||
|
* already loaded into memory and must comply to the rules.
|
||||||
|
*
|
||||||
|
* Note: Those flags do not alter the way the request is actually
|
||||||
|
* performed, but the MUX-14 call is omitted only (steps 4. through 6.).
|
||||||
|
*
|
||||||
|
* ======= Description of the API
|
||||||
|
*
|
||||||
|
* There are three APIs to be supported by NLS:
|
||||||
|
* 1) DOS API: DOS-38, DOS-65, DOS-66;
|
||||||
|
* 2) MUX-14, and
|
||||||
|
* 3) internal: upcasing filenames.
|
||||||
|
*
|
||||||
|
* 1) and 2) address the used NLS pkg by the country code / codepage pair.
|
||||||
|
* 3) uses the currently active NLS pkg only; furthermore, these functions
|
||||||
|
* more or less match DOS-64-A*. Therefore, the NLS system merges the
|
||||||
|
* interfaces 1) and 3) and offers function suitable for both ones.
|
||||||
|
*
|
||||||
|
* Both 1) and 3) must channel the request through the MUX chain, if
|
||||||
|
* appropriate, whereas 2) is the back-end and does natively process the
|
||||||
|
* request totally on its own.
|
||||||
|
*
|
||||||
|
* The API of 1) and 3) consists of:
|
||||||
|
* + DosUpChar(), DosUpString(), and DosUpMem(): to upcase an object
|
||||||
|
* (DOS-65-2[0-2]);
|
||||||
|
* + DosYesNo(): to check a character, if it is the yes or no prompt
|
||||||
|
* (DOS-65-23);
|
||||||
|
* + DosUpFChar(), DosUpFString(), and DosUpFMem(): to upcase an object
|
||||||
|
* for filenames (DOS-65-A[0-2]);
|
||||||
|
* + DosGetData(): to retreive certain information (DOS-38, all the
|
||||||
|
* other DOS-65-** subfunctions);
|
||||||
|
* + DosSetCountry(): to change the currently active country code
|
||||||
|
* (DOS-38);
|
||||||
|
* + DosSetCodepage(): to change the currently active codepage (DOS-66).
|
||||||
|
*
|
||||||
|
* The API of 2) consists of:
|
||||||
|
* + syscall_MUX14().
|
||||||
|
* This function is invoked for all MUX-14 requests and recieves the
|
||||||
|
* registers of the particular INT-2F call, it will then decode the
|
||||||
|
* registers and pass the request forth to a NLS-internal interface
|
||||||
|
* consisting of the following "static" functions:
|
||||||
|
* + nlsUpMem(): called for DosUp*(),
|
||||||
|
* + nlsUpFMem(): called for DosUpF*(),
|
||||||
|
* + nlsYesNo(): called for DosYesNo(),
|
||||||
|
* + nlsGetData(): called for DosGetData(),&
|
||||||
|
* + nlsSetPackage(): called for DosSetCountry() and DosSetCodepage().
|
||||||
|
* In opposite of the APIs 1) through 3) the NLS-internal functions address
|
||||||
|
* the NLS pkg to operate upon by a (struct nlsInfoBlock *) pointer.
|
||||||
|
*
|
||||||
|
* This designs supports to easily implement to bypass the MUX chain to
|
||||||
|
* speed up especially the internal API to upcase filenames, because
|
||||||
|
* the Dos*() functions can decide do not pass the request through MUX,
|
||||||
|
* but directly call the nls*() function instead. This way it is ensured
|
||||||
|
* that the performed actions are the same in both cases and, with repect
|
||||||
|
* to the functions that operate with the currently active NLS pkg, the
|
||||||
|
* performance is rather high, because one can use the globally available
|
||||||
|
* pointer to the current NLS pkg and need not search for a country code/
|
||||||
|
* codepage pair.
|
||||||
|
*
|
||||||
|
* ======== Compile-time options
|
||||||
|
*
|
||||||
|
* Win9x supports to change the individual portions of a NLS pkg
|
||||||
|
* through DOS-65-00; also there are no references what happens when
|
||||||
|
* a program changes the areas addressed by returned pointers. The
|
||||||
|
* current implementation does _not_ support changes of the NLS pkg
|
||||||
|
* except by invoking DOS-38 (Set Country Code) or DOS-66 (Set Codepage).
|
||||||
|
* Future implementations might offer this ability; to reduce the
|
||||||
|
* overhead introduced by this feature, the macro NLS_MODIFYABLE_DATA
|
||||||
|
* enables the appropriate code.
|
||||||
|
* NLS_MODIFYABLE_DATA is *disabled* by default.
|
||||||
|
*
|
||||||
|
* The tables 2 and 4 (upcase tables) are accessed relatively often,
|
||||||
|
* but theoretically these tables could be located at any position
|
||||||
|
* of the pointer array. If the macro NLS_REORDER_POINTERS is enabled,
|
||||||
|
* both NLSFUNC and the internal loader will reorder the pointers
|
||||||
|
* array so that mandatory tables are located at predictable indexes.
|
||||||
|
* This removes that the kernel must search for the table when
|
||||||
|
* one of the DOS-65-[2A]x functions is called or a filename has been
|
||||||
|
* passed in (which must be uppercased to be suitable for internal
|
||||||
|
* purpose). However, when some program try to tweak the internal
|
||||||
|
* tables this assumption could be wrong.
|
||||||
|
* This setting has any effect only, if the kernel tries to access
|
||||||
|
* information itself; it is ignored when the user calls DOS-65-0x
|
||||||
|
* to return such pointer.
|
||||||
|
* NLS_REORDER_POINTERS is *enabled* by default.
|
||||||
|
* UPDATE: With NLS_REORDER_POINTERS, now table 7 (DBCS) is also
|
||||||
|
* expected to be located at a predictable index. -- eca
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define if some user program possibly modifies the value of the internal
|
||||||
|
tables or the DOS-65-00 (Set Country Information) API function
|
||||||
|
is to be supported. */
|
||||||
|
/* Currently unimplemented! -- 2000/02/13 ska*/
|
||||||
|
/* #define NLS_MODIFYABLE_DATA */
|
||||||
|
|
||||||
|
/* Define if the pointer array shall be reordered to allow a quick
|
||||||
|
access to often used and mandatoryly present tables. */
|
||||||
|
#define NLS_REORDER_POINTERS
|
||||||
|
|
||||||
|
/*
|
||||||
|
* How the kernel and NLSFUNC communicate with each other
|
||||||
|
*/
|
||||||
|
/* Must be pased to and returned by NLSFUNC upon MUX-14-00 */
|
||||||
|
#define NLS_FREEDOS_NLSFUNC_ID 0x534b
|
||||||
|
/* What version of nlsInfo and accompanying associations
|
||||||
|
Must be passed to NLSFUNC upon MUX-14-00 to identify the
|
||||||
|
correct kernel to the tools. */
|
||||||
|
#define NLS_FREEDOS_NLSFUNC_VERSION 0xFD02
|
||||||
|
/* Represents a call to DOS-38 within DOS-65 handlers.
|
||||||
|
Current implementation relys on 0x101! */
|
||||||
|
#define NLS_DOS_38 0x101
|
||||||
|
/* NLSFUNC may return NLS_REDO to instruct the kernel to
|
||||||
|
try to perform the same action another time. This is most
|
||||||
|
useful if the kernel only loads the NLS pkg into memory so
|
||||||
|
the kernel will find it and will process the request internally
|
||||||
|
now. */
|
||||||
|
#define NLS_REDO 353
|
||||||
|
|
||||||
|
/* Codes of the subfunctions of external NLSFUNC */
|
||||||
|
#define NLSFUNC_INSTALL_CHECK 0
|
||||||
|
#define NLSFUNC_DOS38 4
|
||||||
|
#define NLSFUNC_GETDATA 2
|
||||||
|
#define NLSFUNC_DRDOS_GETDATA 0xfe
|
||||||
|
#define NLSFUNC_LOAD_PKG 3
|
||||||
|
#define NLSFUNC_LOAD_PKG2 1
|
||||||
|
#define NLSFUNC_UPMEM 0x22
|
||||||
|
#define NLSFUNC_YESNO 0x23
|
||||||
|
#define NLSFUNC_FILE_UPMEM 0xa2
|
||||||
|
|
||||||
|
/* The NLS implementation flags encode what feature is in effect;
|
||||||
|
a "1" in the bitfield means that the feature is active.
|
||||||
|
All currently non-defined bits are to be zero to allow future
|
||||||
|
useage. */
|
||||||
|
#define NLS_CODE_MODIFYABLE_DATA 0x0001
|
||||||
|
#define NLS_CODE_REORDER_POINTERS 0x0002
|
||||||
|
|
||||||
|
/* NLS package useage flags encode what feature is in effect for this
|
||||||
|
particular package:
|
||||||
|
a "1" in the bitfield means that the feature is active/enabled.
|
||||||
|
All currently non-defined bits are to be zero to allow future
|
||||||
|
useage. */
|
||||||
|
#define NLS_FLAG_DIRECT_UPCASE 0x0001 /* DOS-65-2[012], */
|
||||||
|
#define NLS_FLAG_DIRECT_FUPCASE 0x0002 /* DOS-65-A[012], internal */
|
||||||
|
#define NLS_FLAG_DIRECT_YESNO 0x0004 /* DOS-65-23 */
|
||||||
|
#define NLS_FLAG_DIRECT_GETDATA 0x0008 /* DOS-65-XX, DOS-38 */
|
||||||
|
|
||||||
|
#define NLS_FLAG_HARDCODED (NLS_FLAG_DIRECT_UPCASE \
|
||||||
|
| NLS_FLAG_DIRECT_FUPCASE \
|
||||||
|
| NLS_FLAG_DIRECT_YESNO \
|
||||||
|
| NLS_FLAG_DIRECT_GETDATA)
|
||||||
|
|
||||||
|
/* No codepage / country code given */
|
||||||
|
#define NLS_DEFAULT ((UWORD)-1)
|
||||||
|
|
||||||
|
struct CountrySpecificInfo {
|
||||||
|
short CountryID; /* = W1 W437 # Country ID & Codepage */
|
||||||
|
short CodePage;
|
||||||
|
short DateFormat; /* Date format: 0/1/2: U.S.A./Europe/Japan */
|
||||||
|
char CurrencyString[5]; /* '$' ,'EUR' */
|
||||||
|
char ThousandSeparator[2]; /* ',' # Thousand's separator */
|
||||||
|
char DecimalPoint[2]; /* '.' # Decimal point */
|
||||||
|
char DateSeparator[2]; /* '-' */
|
||||||
|
char TimeSeparator[2]; /* ':' */
|
||||||
|
char CurrencyFormat; /* = 0 # Currency format (bit array)
|
||||||
|
0Fh BYTE currency format
|
||||||
|
bit 2 = set if currency symbol replaces decimal point
|
||||||
|
bit 1 = number of spaces between value and currency symbol
|
||||||
|
bit 0 = 0 if currency symbol precedes value
|
||||||
|
1 if currency symbol follows value
|
||||||
|
*/
|
||||||
|
char CurrencyPrecision; /* = 2 # Currency precision */
|
||||||
|
char TimeFormat; /* = 0 # time format: 0/1: 12/24 houres */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the data in the exact order returned by DOS-65-01
|
||||||
|
*/
|
||||||
|
struct nlsExtCntryInfo {
|
||||||
|
UBYTE subfct; /* always 1 */
|
||||||
|
WORD size; /* size of this structure
|
||||||
|
without this WORD itself */
|
||||||
|
WORD countryCode; /* current country code */
|
||||||
|
WORD codePage; /* current code page (CP) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the data in the exact order as to return on
|
||||||
|
* DOS-38; it is also the most (important) part of DOS-65-01
|
||||||
|
*/
|
||||||
|
/* Note: The ASCIZ strings might become
|
||||||
|
a totally different understanding with
|
||||||
|
DBCS (Double Byte Character Support) */
|
||||||
|
WORD dateFmt; /* order of portions of date
|
||||||
|
0: mm/dd/yyyy (USA)
|
||||||
|
1: dd/mm/yyyy (Europe)
|
||||||
|
2: yyyy/mm/dd (Japan)
|
||||||
|
*/
|
||||||
|
char curr[5]; /* ASCIZ of currency string */
|
||||||
|
char thSep[2]; /* ASCIZ of thousand's separator */
|
||||||
|
char point[2]; /* ASCIZ of decimal point */
|
||||||
|
char dateSep[2]; /* ASCIZ of date separator */
|
||||||
|
char timeSep[2]; /* ASCIZ of time separator */
|
||||||
|
BYTE currFmt; /* format of currency:
|
||||||
|
bit 0: currency string is placed
|
||||||
|
0: before number
|
||||||
|
1: behind number
|
||||||
|
bit 1: currency string and number are
|
||||||
|
separated by a space
|
||||||
|
0: No
|
||||||
|
1: Yes
|
||||||
|
bit 2: currency string replaces decimal
|
||||||
|
sign
|
||||||
|
0: No
|
||||||
|
1: Yes
|
||||||
|
*/
|
||||||
|
BYTE prescision; /* of monetary numbers */
|
||||||
|
BYTE timeFmt; /* time format:
|
||||||
|
0: 12 hours (append AM/PM)
|
||||||
|
1: 24 houres
|
||||||
|
*/
|
||||||
|
VOID(FAR * upCaseFct) (VOID); /* far call to a function upcasing the
|
||||||
|
character in register AL */
|
||||||
|
char dataSep[2]; /* ASCIZ of separator in data records */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nlsPointer { /* Information of DOS-65-0X is addressed
|
||||||
|
by a pointer */
|
||||||
|
UBYTE subfct; /* number of the subfunction */
|
||||||
|
VOID FAR *pointer; /* the pointer to be returned when the subfunction
|
||||||
|
of DOS-65 is called (Note: won't work for
|
||||||
|
subfunctions 0, 1, 0x20, 0x21, 0x22, 0x23,
|
||||||
|
0xA0, 0xA1,& 0xA2 */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nlsPackage { /* the contents of one chain item of the
|
||||||
|
list of NLS packages */
|
||||||
|
struct nlsPackage FAR *nxt; /* next item in chain */
|
||||||
|
UWORD cntry, cp; /* country ID / codepage of this NLS pkg */
|
||||||
|
int flags; /* direct access and other flags */
|
||||||
|
/* Note: Depending on the flags above all remaining
|
||||||
|
portions may be omitted, if the external NLSFUNC-like
|
||||||
|
MUX-14 processor does not require them and performs
|
||||||
|
all actions itself, so that the kernel never tries to
|
||||||
|
fetch this information itself. */
|
||||||
|
UWORD yeschar; /* yes / no character DOS-65-23 */
|
||||||
|
UWORD nochar;
|
||||||
|
unsigned numSubfct; /* number of supported sub-functions */
|
||||||
|
struct nlsPointer nlsPointers[1]; /* grows dynamically */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nlsDBCS { /* The internal structure is unknown to me */
|
||||||
|
UWORD numEntries;
|
||||||
|
UWORD dbcsTbl[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nlsCharTbl {
|
||||||
|
/* table containing a list of characters */
|
||||||
|
UWORD numEntries; /* number of entries of this table.
|
||||||
|
If <= 0x80, the first element of
|
||||||
|
the table corresponse to character 0x80 */
|
||||||
|
unsigned char tbl[1]; /* grows dynamically */
|
||||||
|
};
|
||||||
|
#define nlsChBuf(len) struct nlsCharTbl##len { \
|
||||||
|
UWORD numEntries; \
|
||||||
|
unsigned char tbl[len]; \
|
||||||
|
}
|
||||||
|
nlsChBuf(128);
|
||||||
|
nlsChBuf(256);
|
||||||
|
|
||||||
|
/* in file names permittable characters for DOS-65-05 */
|
||||||
|
struct nlsFnamTerm {
|
||||||
|
WORD size; /* size of this structure */
|
||||||
|
BYTE dummy1;
|
||||||
|
char firstCh, lastCh; /* first, last permittable character */
|
||||||
|
BYTE dummy2;
|
||||||
|
char firstExcl, lastExcl; /* first, last excluded character */
|
||||||
|
BYTE dummy3;
|
||||||
|
BYTE numSep; /* number of file name separators */
|
||||||
|
char separators[1]; /* grows dynamically */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nlsInfoBlock { /* This block contains all information
|
||||||
|
shared by the kernel and the external NLSFUNC program */
|
||||||
|
char FAR *fname; /* filename from COUNTRY=;
|
||||||
|
maybe tweaked by NLSFUNC */
|
||||||
|
UWORD sysCodePage; /* system code page */
|
||||||
|
unsigned flags; /* implementation flags */
|
||||||
|
struct nlsPackage FAR *actPkg; /* current NLS package */
|
||||||
|
struct nlsPackage FAR *chain; /* first item of info chain --
|
||||||
|
hardcoded U.S.A./CP437 */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct nlsInfoBlock ASM nlsInfo;
|
||||||
|
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[];
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
***** Definitions & Declarations for COUNTRY.SYS **********************
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* Note: These definitions are shared among all tools accessing the
|
||||||
|
COUNTRY.SYS file as well -- 2000/06/11 ska*/
|
||||||
|
|
||||||
|
/* File structure:
|
||||||
|
S0: Base (Primary) structure -- file header
|
||||||
|
Offset Size Meaning
|
||||||
|
0 array ID string "FreeDOS COUNTRY.SYS v1.0\r\n"
|
||||||
|
26 array Copyright etc. (plain 7bit ASCII text)
|
||||||
|
26+N 2byte \x1a\0
|
||||||
|
26+N+2 array padded with \0 upto next offset
|
||||||
|
128 word number of country/codepage pairs (N1)
|
||||||
|
130 8byte country code / codepage entries (S1)
|
||||||
|
130+8*N1 end of array
|
||||||
|
===
|
||||||
|
S1: structure of country/codepage pair
|
||||||
|
Offset Size Meaning
|
||||||
|
0 dword relative position of table definition (S2)
|
||||||
|
4 word codepage ID
|
||||||
|
6 word country code
|
||||||
|
8 end of structure
|
||||||
|
===
|
||||||
|
S2: table definition of one country/codepage pair
|
||||||
|
Offset Size Meaning
|
||||||
|
0 word number of function entries (N2)
|
||||||
|
2 8byte function definition (S3)
|
||||||
|
2+8*N2 end of array
|
||||||
|
===
|
||||||
|
S3: function definition
|
||||||
|
Offset Size Meaning
|
||||||
|
0 dword relative position of function data (see S4)
|
||||||
|
4 word number of bytes of data
|
||||||
|
6 byte function ID (same as passed to DOS-65-XX)
|
||||||
|
7 byte reserved for future use (currently 0 (zero))
|
||||||
|
8 end of structure
|
||||||
|
===
|
||||||
|
S4: function data
|
||||||
|
In opposite of the structures and arrays, the function data
|
||||||
|
is just a structure-less stream of bytes, which is used as it is.
|
||||||
|
Currently no validation check is performed over this data.
|
||||||
|
That means, for instance, that a definition of function 2 (upcase
|
||||||
|
table) has length 130 and the data consists of a word value with
|
||||||
|
the length (128) and 128 bytes individual information.
|
||||||
|
That way the DBCS is implemented exactly the same way as all the
|
||||||
|
other tables; the only exception is pseudo-table 0x23.
|
||||||
|
===
|
||||||
|
"relative position" means this DWord specifies the amount of bytes
|
||||||
|
between end of the current structure and the data the pointer is
|
||||||
|
referring to. This shall enable future implementations to embed
|
||||||
|
COUNTRY.SYS into other files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CSYS_FD_IDSTRING "FreeDOS COUNTRY.SYS v1.0\r\n\x1a"
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
struct csys_function { /* S3: function definition */
|
||||||
|
UDWORD csys_rpos; /* relative position to actual data */
|
||||||
|
UWORD csys_length;
|
||||||
|
UBYTE csys_fctID; /* As passed to DOS-65-XX */
|
||||||
|
UBYTE csys_reserved1; /* always 0, reserved for future use */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct csys_ccDefinition { /* S1: country/codepage reference */
|
||||||
|
UDWORD csys_rpos; /* moving the 4byte value to the front
|
||||||
|
can increase performance */
|
||||||
|
UWORD csys_cp;
|
||||||
|
UWORD csys_cntry;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct csys_ccDefinition { /* country/codepage reference */
|
||||||
|
UDWORD csys_pos; /* moving the 4byte value to the front
|
||||||
|
can increase performance */
|
||||||
|
UWORD csys_cntry;
|
||||||
|
UWORD csys_cp;
|
||||||
|
UWORD csys_size1; /* size of nlsPackage struct rpos is pointing to */
|
||||||
|
|
||||||
|
/* initially the object rpos is pointing to conforms to a
|
||||||
|
struct nlsPackage, where:
|
||||||
|
struct nlsPackage FAR *nxt; is missing
|
||||||
|
UWORD cntry, cp; is missing
|
||||||
|
int flags; is NLS_FLAG_HARDCODED, if the
|
||||||
|
kernel is to handle the data of its own
|
||||||
|
UWORD yeschar; is filled
|
||||||
|
UWORD nochar; is filled
|
||||||
|
unsigned numSubfct; is filled
|
||||||
|
struct nlsPointer nlsPointers[1]; is filled
|
||||||
|
the pointer member is the absolute
|
||||||
|
position of the data within the file
|
||||||
|
of this structure:
|
||||||
|
UWORD count
|
||||||
|
count bytes
|
||||||
|
The "count" value is not a part
|
||||||
|
of the data itself.
|
||||||
|
Also: The data must be ordered corresponding to
|
||||||
|
NLS_CODE_REORDER_POINTERS.
|
||||||
|
Also: The last nlsPointer is subfct #1 _incl_ all its
|
||||||
|
data [is the extended country information: struct nlsExtCntryInfo]
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
struct csys_numEntries { /* helper structure for "number of entries" */
|
||||||
|
UWORD csys_entries;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Header of the COUNTRY.SYS file */
|
||||||
|
struct nlsCSys_fileHeader { /* COUNTRY.SYS header */
|
||||||
|
unsigned char csys_idstring[sizeof(CSYS_FD_IDSTRING)];
|
||||||
|
UWORD csys_maxTotalSize; /* maximal size of the total amount of
|
||||||
|
any individual definition, that includes
|
||||||
|
the nlsPackage skeleton and the sum of
|
||||||
|
all bytes required to load all the
|
||||||
|
subfunctions individually.
|
||||||
|
--> The code is to allocate maxTotalSize
|
||||||
|
and load any country definition of this
|
||||||
|
file into this buffer without any
|
||||||
|
overflow. */
|
||||||
|
DWORD csys_posIndex; /* absolute position of index table */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Structure created by CountryInfoLoad() */
|
||||||
|
struct nlsCSys_loadPackage {
|
||||||
|
UWORD csys_size;
|
||||||
|
struct nlsPackage csys_pkg;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* standard alignment */
|
||||||
|
#include <algndflt.h>
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
/* Enable debugging of NLS part */
|
||||||
|
|
||||||
|
/* Caution: Enabling NLS debugging usually generates
|
||||||
|
_a_lot_ of noise. */
|
||||||
|
/*& #define NLS_DEBUG */
|
||||||
|
|
||||||
|
#endif
|
172
hdr/pcb.h
Normal file
172
hdr/pcb.h
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* pcb.h */
|
||||||
|
/* */
|
||||||
|
/* Process Control and Interrupt data structures */
|
||||||
|
/* */
|
||||||
|
/* November 26, 1991 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
2000/03/22 ska
|
||||||
|
There is a newly documented (though used previously) side effect
|
||||||
|
of the definitions and assumptions made herein:
|
||||||
|
The assembly sources may use a macro named "PUSH$ALL" to push
|
||||||
|
all processor registers onto the stack, see example below:
|
||||||
|
PUSH$ALL
|
||||||
|
mov ax, sp
|
||||||
|
...
|
||||||
|
push ax
|
||||||
|
call _c_function
|
||||||
|
pop cx
|
||||||
|
The stack pointer immediately after the PUSH$ALL macro shall point to
|
||||||
|
a structure used as an "iregs" structure within the C language.
|
||||||
|
Therefore the internal of the structure "iregs" _must_ always
|
||||||
|
match the implementation of the macro "PUSH$ALL".
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PCB_H
|
||||||
|
#define __PCB_H
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *pcb_hRcsId =
|
||||||
|
"$Id: pcb.h 1316 2007-05-15 17:48:47Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Force one-byte alignment for all the internal structures, see above */
|
||||||
|
#include <algnbyte.h>
|
||||||
|
/* */
|
||||||
|
/* interrupt handler structure definition */
|
||||||
|
/* */
|
||||||
|
typedef union {
|
||||||
|
UWORD x; /* access mode for ax, bx, etc. */
|
||||||
|
struct {
|
||||||
|
UBYTE l; /* access mode for al, bl, etc. */
|
||||||
|
UBYTE h; /* access mode for ah, bh, etc. */
|
||||||
|
} b;
|
||||||
|
} xreg;
|
||||||
|
|
||||||
|
/* The structure assumes that:
|
||||||
|
1) An interrupt was invoked, &
|
||||||
|
2) the PUSH$ALL macro was invoked immediately after that.
|
||||||
|
Furthermore, the PUSH$ALL macro must push ES first and AX last.
|
||||||
|
-- 2000/03/22 ska*/
|
||||||
|
/* maps MS-DOS unique stacking order */
|
||||||
|
typedef struct _iregss {
|
||||||
|
xreg a, b, c, d;
|
||||||
|
UWORD si, di, bp, ds, es;
|
||||||
|
UWORD ip, cs, flags;
|
||||||
|
} iregs;
|
||||||
|
|
||||||
|
/* struct used for local copy of registers */
|
||||||
|
typedef struct {
|
||||||
|
xreg a, b, c, d;
|
||||||
|
UWORD si, di, ds, es;
|
||||||
|
} lregs;
|
||||||
|
|
||||||
|
/* Registers directly passed to syscall;
|
||||||
|
must be the same order as iregs!
|
||||||
|
Is used to define parameters. */
|
||||||
|
#define DIRECT_IREGS \
|
||||||
|
xreg a, xreg b, xreg c, xreg d, \
|
||||||
|
UWORD si, UWORD di, UWORD bp, UWORD ds, UWORD es, \
|
||||||
|
UWORD ip, UWORD cs, UWORD flags
|
||||||
|
|
||||||
|
/* Process control block for task switching */
|
||||||
|
typedef struct {
|
||||||
|
UWORD pc_ss;
|
||||||
|
UWORD pc_sp;
|
||||||
|
iregs pc_regs;
|
||||||
|
} pcb;
|
||||||
|
|
||||||
|
/* Note: The following figure is not made by myself and I assume that
|
||||||
|
the order of "ES" through "AX" are misinterpreted?! -- 2000/03/22 ska*/
|
||||||
|
|
||||||
|
/* For MSC, the following offsets must match the assembly process */
|
||||||
|
/* support offsets */
|
||||||
|
/* NOTE: Alignemnts must be set to 1 (-Zp1) */
|
||||||
|
/* ss: 0 */
|
||||||
|
/* sp: 2 */
|
||||||
|
/* es: 4 */
|
||||||
|
/* ds: 6 */
|
||||||
|
/* di: 8 */
|
||||||
|
/* si: 10 */
|
||||||
|
/* bp: 12 */
|
||||||
|
/* sp: 14 NOTE: not used in this structure */
|
||||||
|
/* bx: 16 */
|
||||||
|
/* dx: 18 */
|
||||||
|
/* cx: 20 */
|
||||||
|
/* ax: 22 */
|
||||||
|
/* ip: 24 */
|
||||||
|
/* cs: 26 */
|
||||||
|
/* flags: 28 */
|
||||||
|
/* */
|
||||||
|
/* For Borland C, the following offsets must match the assembly process */
|
||||||
|
/* support offsets */
|
||||||
|
/* ss: 0 */
|
||||||
|
/* sp: 2 */
|
||||||
|
/* bp: 4 */
|
||||||
|
/* di: 6 */
|
||||||
|
/* si: 8 */
|
||||||
|
/* ds: 10 */
|
||||||
|
/* es: 12 */
|
||||||
|
/* dx: 14 */
|
||||||
|
/* cx: 16 */
|
||||||
|
/* bx: 18 */
|
||||||
|
/* ax: 20 */
|
||||||
|
/* ip: 22 */
|
||||||
|
/* cs: 24 */
|
||||||
|
/* flags: 26 */
|
||||||
|
|
||||||
|
#define BP bp
|
||||||
|
#define DI di
|
||||||
|
#define SI si
|
||||||
|
#define DS ds
|
||||||
|
#define ES es
|
||||||
|
#define DX d.x
|
||||||
|
#define CX c.x
|
||||||
|
#define BX b.x
|
||||||
|
#define AX a.x
|
||||||
|
#define DH d.b.h
|
||||||
|
#define CH c.b.h
|
||||||
|
#define BH b.b.h
|
||||||
|
#define AH a.b.h
|
||||||
|
#define DL d.b.l
|
||||||
|
#define CL c.b.l
|
||||||
|
#define BL b.b.l
|
||||||
|
#define AL a.b.l
|
||||||
|
#define IP ip
|
||||||
|
#define CS cs
|
||||||
|
#define FLAGS flags
|
||||||
|
|
||||||
|
#define FLG_ZERO 0x0040
|
||||||
|
#define FLG_CARRY 0x0001
|
||||||
|
|
||||||
|
/* Allow default alignment from now on */
|
||||||
|
#include <algndflt.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
325
hdr/portab.h
Normal file
325
hdr/portab.h
Normal file
@ -0,0 +1,325 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* portab.h */
|
||||||
|
/* */
|
||||||
|
/* DOS-C portability typedefs, etc. */
|
||||||
|
/* */
|
||||||
|
/* May 1, 1995 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static char *portab_hRcsId =
|
||||||
|
"$Id: portab.h 1121 2005-03-15 15:25:08Z perditionc $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* Machine dependant portable types. Note that this section is */
|
||||||
|
/* used primarily for segmented architectures. Common types and */
|
||||||
|
/* types used relating to segmented operations are found here. */
|
||||||
|
/* */
|
||||||
|
/* Be aware that segmented architectures impose on linear */
|
||||||
|
/* architectures because they require special types to be used */
|
||||||
|
/* throught the code that must be reduced to empty preprocessor */
|
||||||
|
/* replacements in the linear machine. */
|
||||||
|
/* */
|
||||||
|
/* #ifdef <segmeted machine> */
|
||||||
|
/* # define FAR far */
|
||||||
|
/* # define NEAR near */
|
||||||
|
/* #endif */
|
||||||
|
/* */
|
||||||
|
/* #ifdef <linear machine> */
|
||||||
|
/* # define FAR */
|
||||||
|
/* # define NEAR */
|
||||||
|
/* #endif */
|
||||||
|
/* */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
/* commandline overflow - removing -DI86 TE */
|
||||||
|
#if defined(__TURBOC__)
|
||||||
|
|
||||||
|
#define I86
|
||||||
|
#define CDECL cdecl
|
||||||
|
#if __TURBOC__ > 0x202
|
||||||
|
/* printf callers do the right thing for tc++ 1.01 but not tc 2.01 */
|
||||||
|
#define VA_CDECL
|
||||||
|
#else
|
||||||
|
#define VA_CDECL cdecl
|
||||||
|
#endif
|
||||||
|
#define PASCAL pascal
|
||||||
|
void __int__(int);
|
||||||
|
#ifndef FORSYS
|
||||||
|
void __emit__(char, ...);
|
||||||
|
#define disable() __emit__(0xfa)
|
||||||
|
#define enable() __emit__(0xfb)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined (_MSC_VER)
|
||||||
|
|
||||||
|
#define I86
|
||||||
|
#define asm __asm
|
||||||
|
#pragma warning(disable: 4761) /* "integral size mismatch in argument;
|
||||||
|
conversion supplied" */
|
||||||
|
#define CDECL _cdecl
|
||||||
|
#define VA_CDECL
|
||||||
|
#define PASCAL pascal
|
||||||
|
#define __int__(intno) asm int intno;
|
||||||
|
#define disable() asm cli
|
||||||
|
#define enable() asm sti
|
||||||
|
#define _CS getCS()
|
||||||
|
static unsigned short __inline getCS(void)
|
||||||
|
{
|
||||||
|
asm mov ax, cs;
|
||||||
|
}
|
||||||
|
#define _SS getSS()
|
||||||
|
static unsigned short __inline getSS(void)
|
||||||
|
{
|
||||||
|
asm mov ax, ss;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__WATCOMC__) /* don't know a better way */
|
||||||
|
|
||||||
|
#define I86
|
||||||
|
#define __int__(intno) asm int intno;
|
||||||
|
void disable(void);
|
||||||
|
#pragma aux disable = "cli" modify exact [];
|
||||||
|
void enable(void);
|
||||||
|
#pragma aux enable = "sti" modify exact [];
|
||||||
|
#define asm __asm
|
||||||
|
#define far __far
|
||||||
|
#define CDECL __cdecl
|
||||||
|
#define VA_CDECL
|
||||||
|
#define PASCAL pascal
|
||||||
|
#define _CS getCS()
|
||||||
|
unsigned short getCS(void);
|
||||||
|
#pragma aux getCS = "mov dx,cs" value [dx] modify exact[dx];
|
||||||
|
#define _SS getSS()
|
||||||
|
unsigned short getSS(void);
|
||||||
|
#pragma aux getSS = "mov dx,ss" value [dx] modify exact[dx];
|
||||||
|
#if !defined(FORSYS) && !defined(EXEFLAT) && _M_IX86 >= 300
|
||||||
|
#pragma aux default parm [ax dx cx] modify [ax dx es fs] /* min.unpacked size */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* enable Possible loss of precision warning for compatibility with Borland */
|
||||||
|
#pragma enable_message(130)
|
||||||
|
|
||||||
|
#if _M_IX86 >= 300 || defined(M_I386)
|
||||||
|
#define I386
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined (_MYMC68K_COMILER_)
|
||||||
|
|
||||||
|
#define MC68K
|
||||||
|
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
/* for warnings only ! */
|
||||||
|
#define MC68K
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error Unknown compiler
|
||||||
|
We might even deal with a pre-ANSI compiler. This will certainly not compile.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef I86
|
||||||
|
#if _M_IX86 >= 300 || defined(M_I386)
|
||||||
|
#define I386
|
||||||
|
#elif _M_IX86 >= 100 || defined(M_I286)
|
||||||
|
#define I186
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MC68K
|
||||||
|
#define far /* No far type */
|
||||||
|
#define interrupt /* No interrupt type */
|
||||||
|
#define VOID void
|
||||||
|
#define FAR /* linear architecture */
|
||||||
|
#define NEAR /* " " */
|
||||||
|
#define INRPT interrupt
|
||||||
|
#define REG register
|
||||||
|
#define API int /* linear architecture */
|
||||||
|
#define NONNATIVE
|
||||||
|
#define PARASIZE 4096 /* "paragraph" size */
|
||||||
|
#define CDECL
|
||||||
|
#define PASCAL
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define CONST const
|
||||||
|
#define PROTO
|
||||||
|
typedef __SIZE_TYPE__ size_t;
|
||||||
|
#else
|
||||||
|
#define CONST
|
||||||
|
typedef unsigned size_t;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef I86
|
||||||
|
#define VOID void
|
||||||
|
#define FAR far /* segment architecture */
|
||||||
|
#define NEAR near /* " " */
|
||||||
|
#define INRPT interrupt
|
||||||
|
#define CONST const
|
||||||
|
#define REG register
|
||||||
|
#define API int far pascal /* segment architecture */
|
||||||
|
#define NATIVE
|
||||||
|
#define PARASIZE 16 /* "paragraph" size */
|
||||||
|
typedef unsigned size_t;
|
||||||
|
#endif
|
||||||
|
/* functions, that are shared between C and ASM _must_
|
||||||
|
have a certain calling standard. These are declared
|
||||||
|
as 'ASMCFUNC', and is (and will be ?-) cdecl */
|
||||||
|
#define ASMCFUNC CDECL
|
||||||
|
#define ASMPASCAL PASCAL
|
||||||
|
#define ASM ASMCFUNC
|
||||||
|
/* */
|
||||||
|
/* Boolean type & definitions of TRUE and FALSE boolean values */
|
||||||
|
/* */
|
||||||
|
typedef int BOOL;
|
||||||
|
#define FALSE (1==0)
|
||||||
|
#define TRUE (1==1)
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* Common pointer types */
|
||||||
|
/* */
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* Convienence defines */
|
||||||
|
/* */
|
||||||
|
#define FOREVER while(TRUE)
|
||||||
|
#ifndef max
|
||||||
|
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
#ifndef min
|
||||||
|
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* Common byte, 16 bit and 32 bit types */
|
||||||
|
/* */
|
||||||
|
typedef char BYTE;
|
||||||
|
typedef short WORD;
|
||||||
|
typedef long DWORD;
|
||||||
|
|
||||||
|
typedef unsigned char UBYTE;
|
||||||
|
typedef unsigned short UWORD;
|
||||||
|
typedef unsigned long UDWORD;
|
||||||
|
|
||||||
|
typedef short SHORT;
|
||||||
|
|
||||||
|
typedef unsigned int BITS; /* for use in bit fields(!) */
|
||||||
|
|
||||||
|
typedef int COUNT;
|
||||||
|
typedef unsigned int UCOUNT;
|
||||||
|
typedef unsigned long ULONG;
|
||||||
|
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
typedef unsigned long CLUSTER;
|
||||||
|
#else
|
||||||
|
typedef unsigned short CLUSTER;
|
||||||
|
#endif
|
||||||
|
typedef unsigned short UNICODE;
|
||||||
|
|
||||||
|
#if defined(STATICS) || defined(__WATCOMC__)
|
||||||
|
#define STATIC static /* local calls inside module */
|
||||||
|
#else
|
||||||
|
#define STATIC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef UNIX
|
||||||
|
typedef char FAR *ADDRESS;
|
||||||
|
#else
|
||||||
|
typedef void FAR *ADDRESS;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STRICT
|
||||||
|
typedef signed long LONG;
|
||||||
|
#else
|
||||||
|
#define LONG long
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MK_UWORD(hib,lob) (((UWORD)(hib) << 8u) | (UBYTE)(lob))
|
||||||
|
#define MK_ULONG(hiw,low) (((ULONG)(hiw) << 16u) | (UWORD)(low))
|
||||||
|
|
||||||
|
/* General far pointer macros */
|
||||||
|
#ifdef I86
|
||||||
|
#ifndef MK_FP
|
||||||
|
|
||||||
|
#if defined(__WATCOMC__)
|
||||||
|
#define MK_FP(seg,ofs) (((UWORD)(seg)):>((VOID *)(ofs)))
|
||||||
|
#elif defined(__TURBOC__) && (__TURBOC__ > 0x202)
|
||||||
|
#define MK_FP(seg,ofs) ((void _seg *)(seg) + (void near *)(ofs))
|
||||||
|
#else
|
||||||
|
#define MK_FP(seg,ofs) ((void FAR *)(((ULONG)(seg)<<16)|(UWORD)(ofs)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define pokeb(seg, ofs, b) (*((unsigned char far *)MK_FP(seg,ofs)) = b)
|
||||||
|
#define poke(seg, ofs, w) (*((unsigned far *)MK_FP(seg,ofs)) = w)
|
||||||
|
#define pokew poke
|
||||||
|
#define pokel(seg, ofs, l) (*((unsigned long far *)MK_FP(seg,ofs)) = l)
|
||||||
|
#define peekb(seg, ofs) (*((unsigned char far *)MK_FP(seg,ofs)))
|
||||||
|
#define peek(seg, ofs) (*((unsigned far *)MK_FP(seg,ofs)))
|
||||||
|
#define peekw peek
|
||||||
|
#define peekl(seg, ofs) (*((unsigned long far *)MK_FP(seg,ofs)))
|
||||||
|
|
||||||
|
#if defined(__TURBOC__) && (__TURBOC__ > 0x202)
|
||||||
|
#define FP_SEG(fp) ((unsigned)(void _seg *)(void far *)(fp))
|
||||||
|
#else
|
||||||
|
#define FP_SEG(fp) ((unsigned)((ULONG)(VOID FAR *)(fp)>>16))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FP_OFF(fp) ((unsigned)(fp))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MC68K
|
||||||
|
#define MK_FP(seg,ofs) ((VOID *)(&(((BYTE *)(size_t)(seg))[(ofs)])))
|
||||||
|
#define FP_SEG(fp) (0)
|
||||||
|
#define FP_OFF(fp) ((size_t)(fp))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef VOID (FAR ASMCFUNC * intvec) (void);
|
||||||
|
|
||||||
|
#define MK_PTR(type,seg,ofs) ((type FAR*) MK_FP (seg, ofs))
|
||||||
|
#if __TURBOC__ > 0x202
|
||||||
|
# define MK_SEG_PTR(type,seg) ((type _seg*) (seg))
|
||||||
|
#else
|
||||||
|
# define _seg FAR
|
||||||
|
# define MK_SEG_PTR(type,seg) MK_PTR (type, seg, 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
this suppresses the warning
|
||||||
|
unreferenced parameter 'x'
|
||||||
|
and (hopefully) generates no code
|
||||||
|
*/
|
||||||
|
#define UNREFERENCED_PARAMETER(x) (void)x;
|
||||||
|
|
||||||
|
#ifdef I86 /* commandline overflow - removing /DPROTO TE */
|
||||||
|
#define PROTO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LENGTH(x) (sizeof(x)/sizeof(x[0]))
|
110
hdr/process.h
Normal file
110
hdr/process.h
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* process.h */
|
||||||
|
/* */
|
||||||
|
/* DOS exec data structures & declarations */
|
||||||
|
/* */
|
||||||
|
/* November 23, 1991 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* Modes available as first argument to the spawnxx functions. */
|
||||||
|
|
||||||
|
#define P_WAIT 0 /* child runs separately, parent waits until exit */
|
||||||
|
#define P_NOWAIT 1 /* both concurrent -- not implemented */
|
||||||
|
#define P_OVERLAY 2 /* child replaces parent, parent no longer exists */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UWORD load_seg;
|
||||||
|
UWORD reloc;
|
||||||
|
} _load;
|
||||||
|
struct {
|
||||||
|
UWORD env_seg;
|
||||||
|
CommandTail FAR *cmd_line;
|
||||||
|
fcb FAR *fcb_1;
|
||||||
|
fcb FAR *fcb_2;
|
||||||
|
BYTE FAR *stack;
|
||||||
|
BYTE FAR *start_addr;
|
||||||
|
} _exec;
|
||||||
|
} ldata;
|
||||||
|
} exec_blk;
|
||||||
|
|
||||||
|
#define exec ldata._exec
|
||||||
|
#define load ldata._load
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UWORD ps_exit; /* 00 CP/M-like exit point: int 20 */
|
||||||
|
UWORD ps_size; /* 02 segment of first byte beyond */
|
||||||
|
/* memory allocated to program */
|
||||||
|
BYTE ps_fill1; /* 04 single char fill=0 */
|
||||||
|
|
||||||
|
/* CP/M-like entry point */
|
||||||
|
/* offsets 5-9 are a far call to absolute address 0:00C0h
|
||||||
|
encoded using 1MB wrap form of address (e.g. 0F01D:FEF0h)
|
||||||
|
for compatiblity with CP/M apps that do a near call to psp:5
|
||||||
|
and expect size (KB) of allocated segment in word at offset 6 */
|
||||||
|
UBYTE ps_farcall; /* 05 far call opcode */
|
||||||
|
VOID(FAR ASMCFUNC * ps_reentry) (void); /* 06 re-entry point */
|
||||||
|
|
||||||
|
intvec ps_isv22, /* 0a terminate address */
|
||||||
|
ps_isv23, /* 0e ctrl-break address */
|
||||||
|
ps_isv24; /* 12 critical error address */
|
||||||
|
UWORD ps_parent; /* 16 parent psp segment */
|
||||||
|
UBYTE ps_files[20]; /* 18 file table - 0xff is unused */
|
||||||
|
UWORD ps_environ; /* 2c environment paragraph */
|
||||||
|
BYTE FAR *ps_stack; /* 2e user stack pointer - int 21 */
|
||||||
|
UWORD ps_maxfiles; /* 32 maximum open files */
|
||||||
|
UBYTE FAR *ps_filetab; /* 34 open file table pointer */
|
||||||
|
VOID FAR *ps_prevpsp; /* 38 previous psp pointer */
|
||||||
|
UBYTE ps_fill2; /* 3c unused */
|
||||||
|
UBYTE ps_truename; /* 3d [unused] append truename flag int2f/B711h */
|
||||||
|
UBYTE ps_netx_taskid[2]; /* 3e [Novell only field] task id */
|
||||||
|
UWORD ps_retdosver; /* 40 [unused] version to return on int21/30h */
|
||||||
|
UWORD pdb_next; /* 42 [Win only field] PSP chain */
|
||||||
|
UBYTE ps_fill2b[4]; /* 44 unused, 4 bytes */
|
||||||
|
UBYTE ps_olddos; /* 48 [Win only field] DOS/Win program */
|
||||||
|
UBYTE ps_fill2c[7]; /* 49 unused, 7 bytes */
|
||||||
|
UBYTE ps_unix[3]; /* 50 unix style call - 0xcd 0x21 0xcb */
|
||||||
|
BYTE ps_fill3[9]; /* 53 */
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
fcb _ps_fcb1; /* 5c first command line argument */
|
||||||
|
} _u1;
|
||||||
|
struct {
|
||||||
|
BYTE fill4[16];
|
||||||
|
fcb _ps_fcb2; /* second command line argument */
|
||||||
|
} _u2;
|
||||||
|
struct {
|
||||||
|
BYTE fill5[36];
|
||||||
|
CommandTail _ps_cmd;
|
||||||
|
} _u3;
|
||||||
|
} _u;
|
||||||
|
} psp;
|
||||||
|
|
||||||
|
#define ps_fcb1 _u._u1._ps_fcb1
|
||||||
|
#define ps_fcb2 _u._u2._ps_fcb2
|
||||||
|
#define ps_cmd _u._u3._ps_cmd
|
||||||
|
|
143
hdr/sft.h
Normal file
143
hdr/sft.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* sft.h */
|
||||||
|
/* DOS-C */
|
||||||
|
/* */
|
||||||
|
/* DOS System File Table Structure */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995, 1996 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *sft_hRcsId =
|
||||||
|
"$Id: sft.h 1429 2009-06-09 18:50:03Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SFTMAX 128
|
||||||
|
|
||||||
|
/* Handle Definition entry */
|
||||||
|
typedef struct {
|
||||||
|
WORD sft_count; /* 00 - reference count */
|
||||||
|
WORD sft_mode; /* 02 - open mode - see below */
|
||||||
|
BYTE sft_attrib; /* 04 - file attribute - dir style */
|
||||||
|
|
||||||
|
union /* 05 */
|
||||||
|
{
|
||||||
|
WORD _sft_flags;
|
||||||
|
struct {
|
||||||
|
BYTE _sft_flags_lo;
|
||||||
|
BYTE _sft_flags_hi;
|
||||||
|
} _split_sft_flags;
|
||||||
|
} sft_flags_union;
|
||||||
|
|
||||||
|
union /* 07 */
|
||||||
|
{
|
||||||
|
struct dpb FAR *_sft_dcb; /* The device control block */
|
||||||
|
struct dhdr FAR *_sft_dev; /* device driver for char dev */
|
||||||
|
} sft_dcb_or_dev;
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
UWORD sft_relclust_high; /* 0b - High part of relative cluster */
|
||||||
|
#else
|
||||||
|
CLUSTER sft_stclust; /* 0b - Starting cluster */
|
||||||
|
#endif
|
||||||
|
time sft_time; /* 0d - File time */
|
||||||
|
date sft_date; /* 0f - File date */
|
||||||
|
ULONG sft_size; /* 11 - File size */
|
||||||
|
ULONG sft_posit; /* 15 - Current file position */
|
||||||
|
UWORD sft_relclust; /* 19 - File relative cluster (low part) */
|
||||||
|
ULONG sft_dirsector; /* 1b - Sector containing cluster */
|
||||||
|
UBYTE sft_diridx; /* 1f - directory index */
|
||||||
|
BYTE sft_name[11]; /* 20 - dir style file name */
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
CLUSTER sft_stclust; /* 2b - Starting cluster */
|
||||||
|
#else
|
||||||
|
BYTE FAR *sft_bshare; /* 2b - backward link of file sharing sft */
|
||||||
|
#endif
|
||||||
|
WORD sft_mach; /* 2f - machine number - network apps */
|
||||||
|
WORD sft_psp; /* 31 - owner psp */
|
||||||
|
WORD sft_shroff; /* 33 - Sharing offset */
|
||||||
|
CLUSTER sft_cuclust; /* 35 - File current cluster */
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
UWORD sft_pad;
|
||||||
|
#else
|
||||||
|
BYTE FAR *sft_ifsptr; /* 37 - pointer to IFS driver for file, 0000000h if native DOS */
|
||||||
|
#endif
|
||||||
|
} sft;
|
||||||
|
|
||||||
|
/* SFT Table header definition */
|
||||||
|
typedef struct _sftheader {
|
||||||
|
struct sfttbl FAR * /* link to next table in list */
|
||||||
|
sftt_next;
|
||||||
|
WORD sftt_count; /* # of handle definition */
|
||||||
|
/* entries, this table */
|
||||||
|
} sftheader;
|
||||||
|
|
||||||
|
/* System File Definition List */
|
||||||
|
typedef struct sfttbl {
|
||||||
|
struct sfttbl FAR * /* link to next table in list */
|
||||||
|
sftt_next;
|
||||||
|
WORD sftt_count; /* # of handle definition */
|
||||||
|
/* entries, this table */
|
||||||
|
sft sftt_table[SFTMAX]; /* The array of sft for block */
|
||||||
|
} sfttbl;
|
||||||
|
|
||||||
|
/* defines for sft use */
|
||||||
|
#define SFT_MASK 0x0060 /* splits device data */
|
||||||
|
|
||||||
|
/* flag bits */
|
||||||
|
|
||||||
|
/* the following bit is for redirection */
|
||||||
|
#define SFT_FSHARED 0x8000 /* Networked access */
|
||||||
|
|
||||||
|
/* the following entry differntiates char & block access */
|
||||||
|
#define SFT_FDEVICE 0x0080 /* device entry */
|
||||||
|
|
||||||
|
/* the following bits are file (block) unique */
|
||||||
|
#define SFT_FDATE 0x4000 /* File date set */
|
||||||
|
#define SFT_FCLEAN 0x0040 /* File has not been written to */
|
||||||
|
#define SFT_FDMASK 0x003f /* File mask for drive no */
|
||||||
|
|
||||||
|
/* the following bits are device (char) unique */
|
||||||
|
#define SFT_FIOCTL 0x4000 /* IOCTL support - device */
|
||||||
|
#define SFT_FOCRM 0x0800 /* Open/Close/RM bit in device attribute*/
|
||||||
|
#define SFT_FEOF 0x0040 /* device eof */
|
||||||
|
#define SFT_FBINARY 0x0020 /* device binary mode */
|
||||||
|
#define SFT_FSPECIAL 0x0010 /* int 29 support */
|
||||||
|
#define SFT_FCLOCK 0x0008 /* device is clock */
|
||||||
|
#define SFT_FNUL 0x0004 /* device is nul */
|
||||||
|
#define SFT_FCONOUT 0x0002 /* device is console output */
|
||||||
|
#define SFT_FCONIN 0x0001 /* device is console input */
|
||||||
|
|
||||||
|
/* Convenience defines */
|
||||||
|
#define sft_dcb sft_dcb_or_dev._sft_dcb
|
||||||
|
#define sft_dev sft_dcb_or_dev._sft_dev
|
||||||
|
|
||||||
|
#define sft_flags sft_flags_union._sft_flags
|
||||||
|
#define sft_flags_hi sft_flags_union._split_sft_flags._sft_flags_hi
|
||||||
|
#define sft_flags_lo sft_flags_union._split_sft_flags._sft_flags_lo
|
||||||
|
|
||||||
|
/* defines for LSEEK */
|
||||||
|
#define SEEK_SET 0u
|
||||||
|
#define SEEK_CUR 1u
|
||||||
|
#define SEEK_END 2u
|
198
hdr/stacks.inc
Normal file
198
hdr/stacks.inc
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
;
|
||||||
|
; File:
|
||||||
|
; stacks.inc
|
||||||
|
; Description:
|
||||||
|
; Macro support for register stack frame
|
||||||
|
;
|
||||||
|
; Copyright (c) 1998
|
||||||
|
; Pasquale J. Villani
|
||||||
|
; All Rights Reserved
|
||||||
|
;
|
||||||
|
; This file is part of DOS-C.
|
||||||
|
;
|
||||||
|
; DOS-C is free software; you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation; either version
|
||||||
|
; 2, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; DOS-C is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||||
|
; the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public
|
||||||
|
; License along with DOS-C; see the file COPYING. If not,
|
||||||
|
; write to the Free Software Foundation, 675 Mass Ave,
|
||||||
|
; Cambridge, MA 02139, USA.
|
||||||
|
;
|
||||||
|
; $Id: stacks.inc 1591 2011-05-06 01:46:55Z bartoldeman $
|
||||||
|
;
|
||||||
|
|
||||||
|
;
|
||||||
|
; Standard stack frame used throughout DOS-C
|
||||||
|
;
|
||||||
|
; MS-DOS specific
|
||||||
|
;
|
||||||
|
; +---------------+
|
||||||
|
; | irp hi | 26
|
||||||
|
; +---------------+
|
||||||
|
; | irp low | 24
|
||||||
|
; +---------------+
|
||||||
|
; | flags | 22
|
||||||
|
; +---------------+
|
||||||
|
; | cs | 20
|
||||||
|
; +---------------+
|
||||||
|
; | ip | 18
|
||||||
|
; +---------------+
|
||||||
|
; | es | 16
|
||||||
|
; +---------------+
|
||||||
|
; | ds | 14
|
||||||
|
; +---------------+
|
||||||
|
; | bp | 12
|
||||||
|
; +---------------+
|
||||||
|
; | di | 10
|
||||||
|
; +---------------+
|
||||||
|
; | si | 8
|
||||||
|
; +---------------+
|
||||||
|
; | dx | 6
|
||||||
|
; +---------------+
|
||||||
|
; | cx | 4
|
||||||
|
; +---------------+
|
||||||
|
; | bx | 2
|
||||||
|
; +---------------+
|
||||||
|
; | ax | 0
|
||||||
|
; +---------------+
|
||||||
|
;
|
||||||
|
|
||||||
|
;; Note: The order of the pushed registers _must_ match with the definition
|
||||||
|
;; of the "iregs" structure within PCB.H, because a pointer to the last
|
||||||
|
;; pushed register is used as a pointer to a "iregs" structure within the
|
||||||
|
;; called C sources! -- 2000/03/22 ska
|
||||||
|
|
||||||
|
; Don't use `struc RegFrame' etc. here because it interferes with segment
|
||||||
|
; definitions.
|
||||||
|
reg_ax equ 0
|
||||||
|
reg_bx equ 2
|
||||||
|
reg_cx equ 4
|
||||||
|
reg_dx equ 6
|
||||||
|
reg_si equ 8
|
||||||
|
reg_di equ 10
|
||||||
|
reg_bp equ 12
|
||||||
|
reg_ds equ 14
|
||||||
|
reg_es equ 16
|
||||||
|
reg_ip equ 18
|
||||||
|
reg_cs equ 20
|
||||||
|
reg_flags equ 22
|
||||||
|
irp_low equ 24
|
||||||
|
irp_hi equ 26
|
||||||
|
|
||||||
|
%macro PUSH$ALL 0
|
||||||
|
push es
|
||||||
|
push ds
|
||||||
|
push bp
|
||||||
|
push di
|
||||||
|
push si
|
||||||
|
push dx
|
||||||
|
push cx
|
||||||
|
push bx
|
||||||
|
push ax
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro POP$ALL 0
|
||||||
|
pop ax
|
||||||
|
pop bx
|
||||||
|
pop cx
|
||||||
|
pop dx
|
||||||
|
pop si
|
||||||
|
pop di
|
||||||
|
pop bp
|
||||||
|
pop ds
|
||||||
|
pop es
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; I386.inc - 10/25/01 by tom ehlert
|
||||||
|
;
|
||||||
|
; compiling the kernel for 386 will (sometimes) change the
|
||||||
|
; high part of (some) registers, which will be (sometimes) be used
|
||||||
|
; later
|
||||||
|
;
|
||||||
|
; assumption:
|
||||||
|
; we have never seen MSVC to use anything but eax, ecx, edx,
|
||||||
|
; nor have we seen Borland C to use anything but eax, ebx, edx,
|
||||||
|
; so we only protect eax, ebx or ecx, edx to conserve stack space
|
||||||
|
;
|
||||||
|
; to save even more stack space, we save only HIGH part of regs
|
||||||
|
; at some expense of slower execution. it's easier anyway :-)
|
||||||
|
;
|
||||||
|
; WATCOM only uses FS: and GS: (using -zff and -zgf) and never
|
||||||
|
; any high part of the 386 registers
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
%IF XCPU < 386
|
||||||
|
; no need to save/restore anything
|
||||||
|
|
||||||
|
; error 1 2 3
|
||||||
|
%macro Protect386Registers 0
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro RestoreSP 0
|
||||||
|
mov sp, bp
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro Restore386Registers 0
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%ELSE
|
||||||
|
%ifdef WATCOM
|
||||||
|
|
||||||
|
%macro Protect386Registers 0
|
||||||
|
push fs
|
||||||
|
push gs
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro RestoreSP 0
|
||||||
|
lea sp, [bp-4]
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro Restore386Registers 0
|
||||||
|
pop gs
|
||||||
|
pop fs
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%else
|
||||||
|
|
||||||
|
%macro Protect386Registers 0
|
||||||
|
push eax
|
||||||
|
pop ax
|
||||||
|
%ifdef MSCL8
|
||||||
|
push ecx
|
||||||
|
pop cx
|
||||||
|
%else ;BC5
|
||||||
|
push ebx
|
||||||
|
pop bx
|
||||||
|
%endif
|
||||||
|
push edx
|
||||||
|
pop dx
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro RestoreSP 0
|
||||||
|
lea sp, [bp-6]
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro Restore386Registers 0
|
||||||
|
push dx
|
||||||
|
pop edx
|
||||||
|
%ifdef MSCL8
|
||||||
|
push cx
|
||||||
|
pop ecx
|
||||||
|
%else ;BC5
|
||||||
|
push bx
|
||||||
|
pop ebx
|
||||||
|
%endif
|
||||||
|
push ax
|
||||||
|
pop eax
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%endif
|
||||||
|
%ENDIF
|
44
hdr/tail.h
Normal file
44
hdr/tail.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* tail.h */
|
||||||
|
/* */
|
||||||
|
/* Command tail data structures */
|
||||||
|
/* */
|
||||||
|
/* July 1, 1993 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *tail_hRcsId =
|
||||||
|
"$Id: tail.h 485 2002-12-09 00:17:15Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CTBUFFERSIZE 127
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UBYTE ctCount; /* number of bytes returned */
|
||||||
|
char ctBuffer[CTBUFFERSIZE]; /* the buffer itself */
|
||||||
|
} CommandTail;
|
||||||
|
|
56
hdr/time.h
Normal file
56
hdr/time.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* time.h */
|
||||||
|
/* */
|
||||||
|
/* DOS General Time Structure */
|
||||||
|
/* */
|
||||||
|
/* January 21, 1993 */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
/* TC 2.01 complains if `time' is defined twice. -- ror4 */
|
||||||
|
#ifndef DOSC_TIME_H
|
||||||
|
#define DOSC_TIME_H
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *time_hRcsId =
|
||||||
|
"$Id: time.h 942 2004-05-23 15:00:37Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef UWORD time;
|
||||||
|
|
||||||
|
struct dostime
|
||||||
|
{
|
||||||
|
unsigned char minute, hour, hundredth, second;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dosdate
|
||||||
|
{
|
||||||
|
unsigned short year;
|
||||||
|
unsigned char monthday, month;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
51
hdr/version.h
Normal file
51
hdr/version.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* version.h */
|
||||||
|
/* */
|
||||||
|
/* Common version information */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1997 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
/* The version the kernel reports as compatible with */
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
#define MAJOR_RELEASE 7
|
||||||
|
#define MINOR_RELEASE 10
|
||||||
|
#else
|
||||||
|
#define MAJOR_RELEASE 6
|
||||||
|
#define MINOR_RELEASE 22
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The actual kernel revision, 2000+REVISION_SEQ = 2.REVISION_SEQ */
|
||||||
|
#define REVISION_SEQ 42 /* returned in BL by int 21 function 30 */
|
||||||
|
#define OEM_ID 0xfd /* FreeDOS, returned in BH by int 21 30 */
|
||||||
|
|
||||||
|
/* Used for version information displayed to user at boot (& stored in os_release string) */
|
||||||
|
#ifndef KERNEL_VERSION
|
||||||
|
#define KERNEL_VERSION "- SVN "
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* actual version string */
|
||||||
|
#define KVS(v,s,o) "FreeDOS kernel " v "(build 20" #s " OEM:" #o ") [compiled " __DATE__ "]\n"
|
||||||
|
#define xKVS(v,s,o) KVS(v,s,o)
|
||||||
|
#define KERNEL_VERSION_STRING xKVS(KERNEL_VERSION, REVISION_SEQ, OEM_ID)
|
||||||
|
|
39
hdr/win.h
Normal file
39
hdr/win.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef __WINSUPPORT_H
|
||||||
|
#define __WINSUPPORT_H
|
||||||
|
#ifdef WIN31SUPPORT /* defined to enable kernel hooks for win3.x compatibility */
|
||||||
|
|
||||||
|
|
||||||
|
extern UWORD winInstanced; /* internal flag marking if Windows is active */
|
||||||
|
|
||||||
|
/* contains information about data that must be kept for each active DOS
|
||||||
|
instance, ie data that can NOT be shared between multiple VMs.
|
||||||
|
*/
|
||||||
|
struct WinStartupInfo
|
||||||
|
{
|
||||||
|
UWORD winver; /* this structure version, matches Windows version */
|
||||||
|
ULONG next; /* far pointer to next WinStartupInfo structure or NULL */
|
||||||
|
ULONG vddName; /* far pointer to ASCIIZ pathname of virtual device driver */
|
||||||
|
ULONG vddInfo; /* far pointer to vdd reference data or NULL if vddName=NULL */
|
||||||
|
ULONG instanceTable; /* far pointer to array of instance data */
|
||||||
|
ULONG optInstanceTable; /* used only if winver set to 0x400 (w95)*/
|
||||||
|
};
|
||||||
|
extern struct WinStartupInfo winStartupInfo;
|
||||||
|
|
||||||
|
/* contains a list of offsets relative to DOS data segment of
|
||||||
|
various internal variables.
|
||||||
|
*/
|
||||||
|
struct WinPatchTable
|
||||||
|
{
|
||||||
|
UWORD dosver;
|
||||||
|
UWORD OffTempDS;
|
||||||
|
UWORD OffTempBX;
|
||||||
|
UWORD OffInDOS;
|
||||||
|
UWORD OffMachineID;
|
||||||
|
UWORD OffCritSectPatches;
|
||||||
|
UWORD OffLastMCBSeg; /* used by Win 3.1 if DOS version 5 or higher */
|
||||||
|
};
|
||||||
|
extern struct WinPatchTable winPatchTable;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* WIN31SUPPORT */
|
||||||
|
#endif /* __WINSUPPORT_H */
|
83
hdr/xstructs.h
Normal file
83
hdr/xstructs.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* xstructs.h */
|
||||||
|
/* */
|
||||||
|
/* Extended DOS 7.0+ structures */
|
||||||
|
/* */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *XStructs_hRcsId =
|
||||||
|
"$Id: xstructs.h 1457 2009-06-26 20:00:41Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct xdpbdata {
|
||||||
|
UWORD xdd_dpbsize;
|
||||||
|
struct dpb xdd_dpb;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct xfreespace {
|
||||||
|
UWORD xfs_datasize; /* size of this structure */
|
||||||
|
union {
|
||||||
|
UWORD requested; /* requested structure version */
|
||||||
|
UWORD actual; /* actual structure version */
|
||||||
|
} xfs_version;
|
||||||
|
ULONG xfs_clussize; /* number of sectors per cluster */
|
||||||
|
ULONG xfs_secsize; /* number of bytes per sector */
|
||||||
|
ULONG xfs_freeclusters; /* number of available clusters */
|
||||||
|
ULONG xfs_totalclusters; /* total number of clusters on the drive */
|
||||||
|
ULONG xfs_freesectors; /* number of physical sectors available */
|
||||||
|
ULONG xfs_totalsectors; /* total number of physical sectors */
|
||||||
|
ULONG xfs_freeunits; /* number of available allocation units */
|
||||||
|
ULONG xfs_totalunits; /* total allocation units */
|
||||||
|
UBYTE xfs_reserved[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct xdpbforformat {
|
||||||
|
UWORD xdff_datasize; /* size of this structure */
|
||||||
|
union {
|
||||||
|
UWORD requested; /* requested structure version */
|
||||||
|
UWORD actual; /* actual structure version */
|
||||||
|
} xdff_version;
|
||||||
|
UDWORD xdff_function; /* function number:
|
||||||
|
00h invalidate DPB counts
|
||||||
|
01h rebuild DPB from BPB
|
||||||
|
02h force media change
|
||||||
|
03h get/set active FAT number and mirroring
|
||||||
|
04h get/set root directory cluster number
|
||||||
|
*/
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
DWORD nfreeclst; /* # free clusters
|
||||||
|
(-1 - unknown, 0 - don't change) */
|
||||||
|
DWORD cluster; /* cluster # of first free
|
||||||
|
(-1 - unknown, 0 - don't change) */
|
||||||
|
UDWORD reserved[2];
|
||||||
|
} setdpbcounts;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
UDWORD unknown;
|
||||||
|
bpb FAR *bpbp;
|
||||||
|
UDWORD reserved[2];
|
||||||
|
} rebuilddpb;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
DWORD new; /* new active FAT/mirroring state, or -1 to get
|
||||||
|
bits 3-0: the 0-based FAT number of the active FAT
|
||||||
|
bits 6-4: reserved (0)
|
||||||
|
bit 7: do not mirror active FAT to inactive FATs
|
||||||
|
or:
|
||||||
|
set new root directory cluster, -1 - get current
|
||||||
|
*/
|
||||||
|
DWORD old; /* previous active FAT/mirroring state (as above)
|
||||||
|
or
|
||||||
|
get previous root directory cluster
|
||||||
|
*/
|
||||||
|
UDWORD reserved[2];
|
||||||
|
} setget;
|
||||||
|
} xdff_f;
|
||||||
|
};
|
||||||
|
|
||||||
|
COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp);
|
130
kernel/apisupt.asm
Normal file
130
kernel/apisupt.asm
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
; File:
|
||||||
|
; apisupt.asm
|
||||||
|
; Description:
|
||||||
|
; Assembly support routines for stack manipulation, etc.
|
||||||
|
;
|
||||||
|
; Copyright (c) 1995, 1998
|
||||||
|
; Pasquale J. Villani
|
||||||
|
; All Rights Reserved
|
||||||
|
;
|
||||||
|
; This file is part of DOS-C.
|
||||||
|
;
|
||||||
|
; DOS-C is free software; you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation; either version
|
||||||
|
; 2, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; DOS-C is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||||
|
; the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public
|
||||||
|
; License along with DOS-C; see the file COPYING. If not,
|
||||||
|
; write to the Free Software Foundation, 675 Mass Ave,
|
||||||
|
; Cambridge, MA 02139, USA.
|
||||||
|
;
|
||||||
|
; $Id: apisupt.asm 538 2003-03-12 22:43:53Z bartoldeman $
|
||||||
|
;
|
||||||
|
|
||||||
|
%include "segs.inc"
|
||||||
|
|
||||||
|
segment HMA_TEXT
|
||||||
|
%if 0
|
||||||
|
|
||||||
|
extern _api_sp:wrt DGROUP ; api stacks - for context
|
||||||
|
extern _api_ss:wrt DGROUP ; switching
|
||||||
|
extern _usr_sp:wrt DGROUP ; user stacks
|
||||||
|
extern _usr_ss:wrt DGROUP
|
||||||
|
|
||||||
|
global _set_stack
|
||||||
|
;
|
||||||
|
; void set_stack(void) -
|
||||||
|
; save current stack and setup our local stack
|
||||||
|
;
|
||||||
|
_set_stack:
|
||||||
|
|
||||||
|
; save foreground stack
|
||||||
|
|
||||||
|
; we need to get the return values from the stack
|
||||||
|
; since the current stack will change
|
||||||
|
pop ax ;get return offset
|
||||||
|
|
||||||
|
; Save the flags so that we can restore correct interrupt
|
||||||
|
; state later. We need to disable interrupts so that we
|
||||||
|
; don't trash memory with new sp-old ss combination
|
||||||
|
pushf
|
||||||
|
pop dx
|
||||||
|
cli
|
||||||
|
|
||||||
|
; save bp
|
||||||
|
push bp
|
||||||
|
|
||||||
|
mov cx, sp
|
||||||
|
neg cx
|
||||||
|
|
||||||
|
; save away foreground process' stack
|
||||||
|
push word [_usr_ss]
|
||||||
|
push word [_usr_sp]
|
||||||
|
|
||||||
|
mov word [_usr_ss],ss
|
||||||
|
mov word [_usr_sp],sp
|
||||||
|
|
||||||
|
; setup our local stack
|
||||||
|
mov ss,word [_api_ss]
|
||||||
|
mov sp,word [_api_sp]
|
||||||
|
|
||||||
|
add cx, sp
|
||||||
|
add bp, cx
|
||||||
|
|
||||||
|
; setup for ret
|
||||||
|
push ax
|
||||||
|
|
||||||
|
; now restore interrupt state
|
||||||
|
push dx
|
||||||
|
popf
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
;
|
||||||
|
; void restore_stack(void) -
|
||||||
|
; restore foreground stack, throw ours away
|
||||||
|
;
|
||||||
|
global _restore_stack
|
||||||
|
_restore_stack:
|
||||||
|
|
||||||
|
; we need to get the return values from the stack
|
||||||
|
; since the current stack will change
|
||||||
|
pop cx ;get return offset
|
||||||
|
|
||||||
|
; Save the flags so that we can restore correct interrupt
|
||||||
|
; state later. We need to disable interrupts so that we
|
||||||
|
; don't trash memory with new sp-old ss combination
|
||||||
|
pushf
|
||||||
|
pop dx
|
||||||
|
cli
|
||||||
|
|
||||||
|
; save background stack
|
||||||
|
mov word [_api_ss],ss
|
||||||
|
mov word [_api_sp],sp
|
||||||
|
|
||||||
|
; restore foreground stack here
|
||||||
|
mov ss,word [_usr_ss]
|
||||||
|
mov sp,word [_usr_sp]
|
||||||
|
|
||||||
|
pop word [_usr_sp]
|
||||||
|
pop word [_usr_ss]
|
||||||
|
|
||||||
|
; make bp relative to our stack frame
|
||||||
|
pop bp
|
||||||
|
;mov bp,sp
|
||||||
|
|
||||||
|
; setup for ret
|
||||||
|
push cx
|
||||||
|
|
||||||
|
; now restore interrupt state
|
||||||
|
push dx
|
||||||
|
popf
|
||||||
|
|
||||||
|
ret
|
||||||
|
%endif
|
554
kernel/asmsupt.asm
Normal file
554
kernel/asmsupt.asm
Normal file
@ -0,0 +1,554 @@
|
|||||||
|
; File:
|
||||||
|
; asmsupt.asm
|
||||||
|
; Description:
|
||||||
|
; Assembly support routines for miscellaneous functions
|
||||||
|
;
|
||||||
|
; Copyright (c) 1995, 1998
|
||||||
|
; Pasquale J. Villani
|
||||||
|
; All Rights Reserved
|
||||||
|
;
|
||||||
|
; This file is part of DOS-C.
|
||||||
|
;
|
||||||
|
; DOS-C is free software; you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation; either version
|
||||||
|
; 2, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; DOS-C is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||||
|
; the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public
|
||||||
|
; License along with DOS-C; see the file COPYING. If not,
|
||||||
|
; write to the Free Software Foundation, 675 Mass Ave,
|
||||||
|
; Cambridge, MA 02139, USA.
|
||||||
|
;
|
||||||
|
; version 1.4 by tom.ehlert@ginko.de
|
||||||
|
; added some more functions
|
||||||
|
; changed bcopy, scopy, sncopy,...
|
||||||
|
; to memcpy, strcpy, strncpy
|
||||||
|
; Bart Oldeman: optimized a bit: see /usr/include/bits/string.h from
|
||||||
|
; glibc 2.2
|
||||||
|
;
|
||||||
|
; $Id: asmsupt.asm 1568 2011-04-09 02:42:51Z bartoldeman $
|
||||||
|
;
|
||||||
|
|
||||||
|
; for OW on Linux:
|
||||||
|
%ifdef owlinux
|
||||||
|
%define WATCOM
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%ifdef WATCOM
|
||||||
|
%ifdef _INIT
|
||||||
|
%define WATCOM_INIT ; no seperate init segment for watcom.
|
||||||
|
%endif
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%ifndef WATCOM_INIT
|
||||||
|
|
||||||
|
%include "segs.inc"
|
||||||
|
|
||||||
|
%ifdef _INIT
|
||||||
|
|
||||||
|
segment INIT_TEXT
|
||||||
|
%define FMEMCPYBACK INIT_FMEMCPYBACK
|
||||||
|
%define MEMCPY INIT_MEMCPY
|
||||||
|
%define FMEMCPY INIT_FMEMCPY
|
||||||
|
%define MEMSET INIT_MEMSET
|
||||||
|
%define FMEMSET INIT_FMEMSET
|
||||||
|
%define STRCPY INIT_STRCPY
|
||||||
|
%define FSTRCPY INIT_FSTRCPY
|
||||||
|
%define STRLEN INIT_STRLEN
|
||||||
|
%define FSTRLEN INIT_FSTRLEN
|
||||||
|
%define FMEMCHR INIT_FMEMCHR
|
||||||
|
%define FSTRCHR INIT_FSTRCHR
|
||||||
|
%define STRCHR INIT_STRCHR
|
||||||
|
%define FSTRCMP INIT_FSTRCMP
|
||||||
|
%define STRCMP INIT_STRCMP
|
||||||
|
%define FSTRNCMP INIT_FSTRNCMP
|
||||||
|
%define STRNCMP INIT_STRNCMP
|
||||||
|
%define FMEMCMP INIT_FMEMCMP
|
||||||
|
%define MEMCMP INIT_MEMCMP
|
||||||
|
|
||||||
|
%else
|
||||||
|
|
||||||
|
segment HMA_TEXT
|
||||||
|
|
||||||
|
%endif
|
||||||
|
|
||||||
|
;*********************************************************************
|
||||||
|
; this implements some of the common string handling functions
|
||||||
|
;
|
||||||
|
; every function has 1 entry
|
||||||
|
;
|
||||||
|
; NEAR FUNC()
|
||||||
|
;
|
||||||
|
; currently done:
|
||||||
|
;
|
||||||
|
; fmemcpyBack(void FAR *dest, void FAR *src, int count)
|
||||||
|
; memcpy(void *dest, void *src, int count)
|
||||||
|
; fmemcpy(void FAR *dest, void FAR *src, int count)
|
||||||
|
; memset(void *dest, int ch, int count);
|
||||||
|
; fmemset(void FAR *dest, int ch, int count);
|
||||||
|
; strcpy (void *dest, void *src);
|
||||||
|
; fstrcpy (void FAR*dest, void FAR *src);
|
||||||
|
; strlen (void *dest);
|
||||||
|
; fstrlen (void FAR*dest);
|
||||||
|
; fmemchr (BYTE FAR *src , int ch);
|
||||||
|
; fstrchr (BYTE FAR *src , int ch);
|
||||||
|
; strchr (BYTE *src , int ch);
|
||||||
|
; fstrcmp (BYTE FAR *s1 , BYTE FAR *s2);
|
||||||
|
; strcmp (BYTE *s1 , BYTE *s2);
|
||||||
|
; fstrncmp(BYTE FAR *s1 , BYTE FAR *s2, int count);
|
||||||
|
; strncmp(BYTE *s1 , BYTE *s2, int count);
|
||||||
|
; fmemcmp(BYTE FAR *s1 , BYTE FAR *s2, int count);
|
||||||
|
; memcmp(BYTE *s1 , BYTE *s2, int count);
|
||||||
|
|
||||||
|
;***********************************************
|
||||||
|
; pascal_setup - set up the standard calling frame for C-functions
|
||||||
|
; and save registers needed later
|
||||||
|
; also preload the args for the near functions
|
||||||
|
; di=arg1
|
||||||
|
; si=arg2
|
||||||
|
; cx=arg3
|
||||||
|
;
|
||||||
|
pascal_setup:
|
||||||
|
pop ax ; get return address
|
||||||
|
|
||||||
|
push bp ; Standard C entry
|
||||||
|
mov bp,sp
|
||||||
|
%ifdef WATCOM
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push es
|
||||||
|
%endif
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push ds
|
||||||
|
; Set both ds and es to same segment (for near copy)
|
||||||
|
push ds
|
||||||
|
pop es
|
||||||
|
|
||||||
|
; Set direction to autoincrement
|
||||||
|
cld
|
||||||
|
|
||||||
|
mov bl,6 ; majority (4) wants that
|
||||||
|
mov cx,[4+bp] ; majority (8) wants that (near and far)
|
||||||
|
mov si,[6+bp] ; majority (3) wants that (near)
|
||||||
|
mov di,[8+bp] ; majority (3) wants that (near)
|
||||||
|
|
||||||
|
jmp ax
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;***********************************************
|
||||||
|
;
|
||||||
|
; VOID memcpy(REG BYTE *s, REG BYTE *d, REG COUNT n);
|
||||||
|
;
|
||||||
|
global MEMCPY
|
||||||
|
MEMCPY:
|
||||||
|
call pascal_setup
|
||||||
|
|
||||||
|
;mov cx,[4+bp] - preset above
|
||||||
|
;mov si,[6+bp] - preset above
|
||||||
|
;mov di,[8+bp] - preset above
|
||||||
|
|
||||||
|
;mov bl,6 - preset above
|
||||||
|
|
||||||
|
|
||||||
|
domemcpy:
|
||||||
|
; And do the built-in byte copy, but do a 16-bit transfer
|
||||||
|
; whenever possible.
|
||||||
|
shr cx,1
|
||||||
|
rep movsw
|
||||||
|
jnc memcpy_return
|
||||||
|
movsb
|
||||||
|
memcpy_return:
|
||||||
|
%if 0 ; only needed for fmemcpyback
|
||||||
|
cld
|
||||||
|
%endif
|
||||||
|
|
||||||
|
;
|
||||||
|
; pascal_return - pop saved registers and do return
|
||||||
|
;
|
||||||
|
|
||||||
|
jmp short pascal_return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;************************************************************
|
||||||
|
;
|
||||||
|
; VOID fmemcpy(REG BYTE FAR *d, REG BYTE FAR *s,REG COUNT n);
|
||||||
|
; VOID fmemcpyBack(REG BYTE FAR *d, REG BYTE FAR *s,REG COUNT n);
|
||||||
|
;
|
||||||
|
global FMEMCPY
|
||||||
|
%if 0
|
||||||
|
global FMEMCPYBACK
|
||||||
|
FMEMCPYBACK:
|
||||||
|
std ; force to copy the string in reverse order
|
||||||
|
%endif
|
||||||
|
FMEMCPY:
|
||||||
|
call pascal_setup
|
||||||
|
|
||||||
|
; Get the repetition count, n preset above
|
||||||
|
; mov cx,[bp+4]
|
||||||
|
|
||||||
|
; Get the far source pointer, s
|
||||||
|
lds si,[bp+6]
|
||||||
|
|
||||||
|
; Get the far destination pointer d
|
||||||
|
les di,[bp+10]
|
||||||
|
mov bl,10
|
||||||
|
|
||||||
|
jmp short domemcpy
|
||||||
|
|
||||||
|
;***************************************************************
|
||||||
|
;
|
||||||
|
; VOID fmemset(REG VOID FAR *d, REG BYTE ch, REG COUNT n);
|
||||||
|
;
|
||||||
|
global FMEMSET
|
||||||
|
FMEMSET:
|
||||||
|
call pascal_setup
|
||||||
|
|
||||||
|
; Get the repetition count, n - preset above
|
||||||
|
; mov cx,[bp+4]
|
||||||
|
|
||||||
|
; Get the fill byte ch
|
||||||
|
mov ax,[bp+6]
|
||||||
|
|
||||||
|
; Get the far source pointer, s
|
||||||
|
les di,[bp+8]
|
||||||
|
mov bl,8
|
||||||
|
|
||||||
|
domemset:
|
||||||
|
mov ah, al
|
||||||
|
|
||||||
|
shr cx,1
|
||||||
|
rep stosw
|
||||||
|
jnc pascal_return
|
||||||
|
stosb
|
||||||
|
|
||||||
|
jmp short pascal_return
|
||||||
|
|
||||||
|
;***************************************************************
|
||||||
|
;
|
||||||
|
; VOID memset(REG VOID *d, REG BYTE ch, REG COUNT n);
|
||||||
|
;
|
||||||
|
global MEMSET
|
||||||
|
MEMSET:
|
||||||
|
call pascal_setup
|
||||||
|
|
||||||
|
; Get the repitition count, n - preset above
|
||||||
|
; mov cx,[bp+4]
|
||||||
|
|
||||||
|
; Get the char ch
|
||||||
|
mov ax, [bp+6]
|
||||||
|
|
||||||
|
; Get the far source pointer, d - preset above
|
||||||
|
; mov di,[bp+8]
|
||||||
|
|
||||||
|
;mov bl, 6 ; preset above
|
||||||
|
|
||||||
|
jmp short domemset
|
||||||
|
|
||||||
|
;*****
|
||||||
|
pascal_return:
|
||||||
|
lds di, [bp] ; return address in ds, saved bp in di
|
||||||
|
mov bh, 0
|
||||||
|
add bp, bx ; point bp to "as if there were 0 args"
|
||||||
|
mov [bp+2], ds ; put return address at first arg
|
||||||
|
mov [bp], di ; saved bp below that one
|
||||||
|
|
||||||
|
pop ds
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
%ifdef WATCOM
|
||||||
|
pop es
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
%endif
|
||||||
|
mov sp,bp
|
||||||
|
pop bp
|
||||||
|
ret
|
||||||
|
|
||||||
|
;*****************************************************************
|
||||||
|
|
||||||
|
; fstrcpy (void FAR*dest, void FAR *src);
|
||||||
|
|
||||||
|
%ifndef _INIT
|
||||||
|
global FSTRCPY
|
||||||
|
FSTRCPY:
|
||||||
|
call pascal_setup
|
||||||
|
|
||||||
|
; Get the source pointer, ss
|
||||||
|
lds si,[bp+4]
|
||||||
|
|
||||||
|
; and the destination pointer, d
|
||||||
|
les di,[bp+8]
|
||||||
|
|
||||||
|
mov bl,8
|
||||||
|
|
||||||
|
jmp short dostrcpy
|
||||||
|
%endif
|
||||||
|
|
||||||
|
;******
|
||||||
|
global STRCPY
|
||||||
|
STRCPY:
|
||||||
|
call pascal_setup
|
||||||
|
|
||||||
|
|
||||||
|
; Get the source pointer, ss
|
||||||
|
mov si,[bp+4]
|
||||||
|
|
||||||
|
; and the destination pointer, d
|
||||||
|
mov di,[bp+6]
|
||||||
|
mov bl,4
|
||||||
|
|
||||||
|
dostrcpy:
|
||||||
|
|
||||||
|
strcpy_loop:
|
||||||
|
lodsb
|
||||||
|
stosb
|
||||||
|
test al,al
|
||||||
|
jne strcpy_loop
|
||||||
|
|
||||||
|
jmp short pascal_return
|
||||||
|
|
||||||
|
;******************************************************************
|
||||||
|
%ifndef _INIT
|
||||||
|
global FSTRLEN
|
||||||
|
FSTRLEN:
|
||||||
|
call pascal_setup
|
||||||
|
|
||||||
|
; Get the source pointer, ss
|
||||||
|
les di,[bp+4]
|
||||||
|
mov bl,4
|
||||||
|
|
||||||
|
jmp short dostrlen
|
||||||
|
%endif
|
||||||
|
|
||||||
|
;**********************************************
|
||||||
|
global STRLEN
|
||||||
|
STRLEN:
|
||||||
|
call pascal_setup
|
||||||
|
; Get the source pointer, ss
|
||||||
|
mov di,[bp+4]
|
||||||
|
mov bl,2
|
||||||
|
|
||||||
|
dostrlen:
|
||||||
|
mov al,0
|
||||||
|
mov cx,0xffff
|
||||||
|
repne scasb
|
||||||
|
|
||||||
|
mov ax,cx
|
||||||
|
not ax
|
||||||
|
dec ax
|
||||||
|
|
||||||
|
jmp short pascal_return
|
||||||
|
|
||||||
|
;************************************************************
|
||||||
|
; strchr (BYTE *src , int ch);
|
||||||
|
|
||||||
|
global STRCHR
|
||||||
|
STRCHR:
|
||||||
|
call pascal_setup
|
||||||
|
|
||||||
|
; Get the source pointer, ss
|
||||||
|
; mov cx,[bp+4] - preset above
|
||||||
|
; mov si,[bp+6] - preset above
|
||||||
|
mov bl,4
|
||||||
|
|
||||||
|
strchr_loop:
|
||||||
|
lodsb
|
||||||
|
cmp al,cl
|
||||||
|
je strchr_found
|
||||||
|
test al,al
|
||||||
|
jne strchr_loop
|
||||||
|
|
||||||
|
strchr_retzero:
|
||||||
|
xor ax, ax ; return NULL if not found
|
||||||
|
mov dx, ax ; for fstrchr()
|
||||||
|
jmp short pascal_return
|
||||||
|
|
||||||
|
strchr_found:
|
||||||
|
mov ax, si
|
||||||
|
mov dx, ds ; for fstrchr()
|
||||||
|
strchr_found1:
|
||||||
|
dec ax
|
||||||
|
|
||||||
|
jmp short pascal_return
|
||||||
|
|
||||||
|
%ifndef _INIT
|
||||||
|
|
||||||
|
;*****
|
||||||
|
; fstrchr (BYTE far *src , int ch);
|
||||||
|
global FSTRCHR
|
||||||
|
FSTRCHR:
|
||||||
|
call pascal_setup
|
||||||
|
|
||||||
|
; Get ch (preset above)
|
||||||
|
;mov cx, [bp+4]
|
||||||
|
|
||||||
|
;and the source pointer, src
|
||||||
|
lds si, [bp+6]
|
||||||
|
|
||||||
|
;mov bl, 6 - preset above
|
||||||
|
|
||||||
|
jmp short strchr_loop
|
||||||
|
|
||||||
|
;******
|
||||||
|
global FMEMCHR
|
||||||
|
FMEMCHR:
|
||||||
|
call pascal_setup
|
||||||
|
|
||||||
|
; Get the length - preset above
|
||||||
|
; mov cx, [bp+4]
|
||||||
|
|
||||||
|
; and the search value
|
||||||
|
mov ax, [bp+6]
|
||||||
|
|
||||||
|
; and the source pointer, ss
|
||||||
|
les di, [bp+8]
|
||||||
|
|
||||||
|
mov bl, 8
|
||||||
|
|
||||||
|
jcxz strchr_retzero
|
||||||
|
repne scasb
|
||||||
|
jne strchr_retzero
|
||||||
|
mov dx, es
|
||||||
|
mov ax, di
|
||||||
|
jmp short strchr_found1
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
global FSTRCMP
|
||||||
|
FSTRCMP:
|
||||||
|
call pascal_setup
|
||||||
|
|
||||||
|
; Get the source pointer, ss
|
||||||
|
lds si,[bp+4]
|
||||||
|
|
||||||
|
; and the destination pointer, d
|
||||||
|
les di,[bp+8]
|
||||||
|
|
||||||
|
mov bl,8
|
||||||
|
|
||||||
|
%if 0
|
||||||
|
jmp short dostrcmp
|
||||||
|
|
||||||
|
;******
|
||||||
|
global STRCMP
|
||||||
|
STRCMP:
|
||||||
|
call pascal_setup
|
||||||
|
|
||||||
|
mov bl,4
|
||||||
|
|
||||||
|
; Get the source pointer, ss
|
||||||
|
; mov si,[bp+4]
|
||||||
|
|
||||||
|
; and the destination pointer, d
|
||||||
|
; mov di,[bp+6]
|
||||||
|
xchg si,di
|
||||||
|
|
||||||
|
dostrcmp:
|
||||||
|
%endif
|
||||||
|
; replace strncmp(s1,s2)-->
|
||||||
|
; strncmp(s1,s2,0xffff)
|
||||||
|
mov cx,0xffff
|
||||||
|
%if 0
|
||||||
|
jmp short dostrncmp
|
||||||
|
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
global FSTRNCMP
|
||||||
|
FSTRNCMP:
|
||||||
|
call pascal_setup
|
||||||
|
|
||||||
|
; Get the source pointer, ss
|
||||||
|
lds si,[bp+4]
|
||||||
|
|
||||||
|
; and the destination pointer, d
|
||||||
|
les di,[bp+8]
|
||||||
|
mov cx,[bp+12]
|
||||||
|
mov bl,10
|
||||||
|
|
||||||
|
jmp short dostrncmp
|
||||||
|
|
||||||
|
;******
|
||||||
|
global _strncmp
|
||||||
|
_strncmp:
|
||||||
|
call pascal_setup
|
||||||
|
|
||||||
|
; Get the source pointer, ss
|
||||||
|
;mov si,[bp+4]
|
||||||
|
|
||||||
|
; and the destination pointer, d
|
||||||
|
;mov di,[bp+6]
|
||||||
|
;mov cx,[bp+8]
|
||||||
|
xchg si,di
|
||||||
|
|
||||||
|
dostrncmp:
|
||||||
|
%endif
|
||||||
|
jcxz strncmp_retzero
|
||||||
|
|
||||||
|
strncmp_loop:
|
||||||
|
lodsb
|
||||||
|
scasb
|
||||||
|
jne strncmp_done
|
||||||
|
test al,al
|
||||||
|
loopne strncmp_loop
|
||||||
|
jmp short strncmp_retzero
|
||||||
|
%endif
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
; fmemcmp(BYTE FAR *s1 , BYTE FAR *s2, int count);
|
||||||
|
global FMEMCMP
|
||||||
|
FMEMCMP:
|
||||||
|
call pascal_setup
|
||||||
|
|
||||||
|
; the length - preset above
|
||||||
|
; mov cx, [bp+4]
|
||||||
|
|
||||||
|
; Get the source pointer, ss
|
||||||
|
les di,[bp+6]
|
||||||
|
|
||||||
|
; and the destination pointer, d
|
||||||
|
lds si,[bp+10]
|
||||||
|
|
||||||
|
mov bl,10
|
||||||
|
|
||||||
|
jmp short domemcmp
|
||||||
|
|
||||||
|
;******
|
||||||
|
; memcmp(BYTE *s1 , BYTE *s2, int count);
|
||||||
|
global MEMCMP
|
||||||
|
MEMCMP:
|
||||||
|
call pascal_setup
|
||||||
|
|
||||||
|
; all preset: Get the source pointer, ss
|
||||||
|
;mov si,[bp+6]
|
||||||
|
|
||||||
|
; and the destination pointer, d
|
||||||
|
;mov di,[bp+8]
|
||||||
|
;mov cx,[bp+4]
|
||||||
|
;mov bl,6
|
||||||
|
xchg si,di
|
||||||
|
|
||||||
|
domemcmp:
|
||||||
|
jcxz strncmp_retzero
|
||||||
|
repe cmpsb
|
||||||
|
jne strncmp_done
|
||||||
|
strncmp_retzero:
|
||||||
|
xor ax, ax
|
||||||
|
jmp short strncmp_done2
|
||||||
|
strncmp_done:
|
||||||
|
lahf
|
||||||
|
ror ah,1
|
||||||
|
%ifdef _INIT
|
||||||
|
strncmp_done2: jmp short pascal_return
|
||||||
|
%else
|
||||||
|
strncmp_done2: jmp pascal_return
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%endif
|
517
kernel/blockio.c
Normal file
517
kernel/blockio.c
Normal file
@ -0,0 +1,517 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* blockio.c */
|
||||||
|
/* DOS-C */
|
||||||
|
/* */
|
||||||
|
/* Block cache functions and device driver interface */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/* */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#include "portab.h"
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *blockioRcsId =
|
||||||
|
"$Id: blockio.c 1702 2012-02-04 08:46:16Z perditionc $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define b_next(bp) ((struct buffer FAR *)(MK_FP(FP_SEG(bp), bp->b_next)))
|
||||||
|
#define b_prev(bp) ((struct buffer FAR *)(MK_FP(FP_SEG(bp), bp->b_prev)))
|
||||||
|
#define bufptr(fbp) ((struct buffer FAR *)(MK_FP(FP_SEG(bp), fbp)))
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* block cache routines */
|
||||||
|
/* */
|
||||||
|
/************************************************************************/
|
||||||
|
/* #define DISPLAY_GETBLOCK */
|
||||||
|
|
||||||
|
STATIC BOOL flush1(struct buffer FAR * bp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
this searches the buffer list for the given disk/block.
|
||||||
|
|
||||||
|
returns:
|
||||||
|
a far pointer to the buffer.
|
||||||
|
|
||||||
|
If the buffer is found the UNCACHE bit is not set and else it is set.
|
||||||
|
|
||||||
|
new:
|
||||||
|
upper layer may set UNCACHE attribute
|
||||||
|
UNCACHE buffers are recycled first.
|
||||||
|
intended to be used for full sector reads into application buffer
|
||||||
|
resets UNCACHE upon a "HIT" -- so then this buffer will not be
|
||||||
|
recycled anymore.
|
||||||
|
*/
|
||||||
|
|
||||||
|
STATIC void move_buffer(struct buffer FAR *bp, size_t firstbp)
|
||||||
|
{
|
||||||
|
/* connect bp->b_prev and bp->b_next */
|
||||||
|
b_next(bp)->b_prev = bp->b_prev;
|
||||||
|
b_prev(bp)->b_next = bp->b_next;
|
||||||
|
|
||||||
|
/* insert bp between firstbp and firstbp->b_prev */
|
||||||
|
bp->b_prev = bufptr(firstbp)->b_prev;
|
||||||
|
bp->b_next = firstbp;
|
||||||
|
b_next(bp)->b_prev = FP_OFF(bp);
|
||||||
|
b_prev(bp)->b_next = FP_OFF(bp);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC struct buffer FAR *searchblock(ULONG blkno, COUNT dsk)
|
||||||
|
{
|
||||||
|
int fat_count = 0;
|
||||||
|
struct buffer FAR *bp;
|
||||||
|
size_t lastNonFat = 0;
|
||||||
|
size_t uncacheBuf = 0;
|
||||||
|
seg bufseg = FP_SEG(firstbuf);
|
||||||
|
size_t firstbp = FP_OFF(firstbuf);
|
||||||
|
|
||||||
|
#ifdef DISPLAY_GETBLOCK
|
||||||
|
printf("[searchblock %d, blk %ld, buf ", dsk, blkno);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Search through buffers to see if the required block */
|
||||||
|
/* is already in a buffer */
|
||||||
|
|
||||||
|
bp = MK_FP(bufseg, firstbp);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ((bp->b_blkno == blkno) &&
|
||||||
|
(bp->b_flag & BFR_VALID) && (bp->b_unit == dsk))
|
||||||
|
{
|
||||||
|
/* found it -- rearrange LRU links */
|
||||||
|
#ifdef DISPLAY_GETBLOCK
|
||||||
|
printf("HIT %04x:%04x]\n", FP_SEG(bp), FP_OFF(bp));
|
||||||
|
#endif
|
||||||
|
bp->b_flag &= ~BFR_UNCACHE; /* reset uncache attribute */
|
||||||
|
if (FP_OFF(bp) != firstbp)
|
||||||
|
{
|
||||||
|
*(UWORD *)&firstbuf = FP_OFF(bp);
|
||||||
|
move_buffer(bp, firstbp);
|
||||||
|
}
|
||||||
|
return bp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bp->b_flag & BFR_UNCACHE)
|
||||||
|
uncacheBuf = FP_OFF(bp);
|
||||||
|
|
||||||
|
if (bp->b_flag & BFR_FAT)
|
||||||
|
fat_count++;
|
||||||
|
else
|
||||||
|
lastNonFat = FP_OFF(bp);
|
||||||
|
bp = b_next(bp);
|
||||||
|
} while (FP_OFF(bp) != firstbp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
now take either the last buffer in chain (not used recently)
|
||||||
|
or, if we are low on FAT buffers, the last non FAT buffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (uncacheBuf)
|
||||||
|
{
|
||||||
|
bp = bufptr(uncacheBuf);
|
||||||
|
}
|
||||||
|
else if (bp->b_flag & BFR_FAT && fat_count < 3 && lastNonFat)
|
||||||
|
{
|
||||||
|
bp = bufptr(lastNonFat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bp = b_prev(bufptr(firstbp));
|
||||||
|
}
|
||||||
|
|
||||||
|
bp->b_flag |= BFR_UNCACHE; /* set uncache attribute */
|
||||||
|
|
||||||
|
#ifdef DISPLAY_GETBLOCK
|
||||||
|
printf("MISS, replace %04x:%04x]\n", FP_SEG(bp), FP_OFF(bp));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (FP_OFF(bp) != firstbp) /* move to front */
|
||||||
|
{
|
||||||
|
move_buffer(bp, firstbp);
|
||||||
|
*(UWORD *)&firstbuf = FP_OFF(bp);
|
||||||
|
}
|
||||||
|
return bp;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL DeleteBlockInBufferCache(ULONG blknolow, ULONG blknohigh, COUNT dsk, int mode)
|
||||||
|
{
|
||||||
|
struct buffer FAR *bp = firstbuf;
|
||||||
|
|
||||||
|
/* Search through buffers to see if the required block */
|
||||||
|
/* is already in a buffer */
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (blknolow <= bp->b_blkno &&
|
||||||
|
bp->b_blkno <= blknohigh &&
|
||||||
|
(bp->b_flag & BFR_VALID) && (bp->b_unit == dsk))
|
||||||
|
{
|
||||||
|
if (mode == XFR_READ)
|
||||||
|
flush1(bp);
|
||||||
|
else
|
||||||
|
bp->b_flag = 0;
|
||||||
|
}
|
||||||
|
bp = b_next(bp);
|
||||||
|
}
|
||||||
|
while (FP_OFF(bp) != FP_OFF(firstbuf));
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TOM
|
||||||
|
void dumpBufferCache(void)
|
||||||
|
{
|
||||||
|
struct buffer FAR *bp = firstbuf;
|
||||||
|
int printed = 0;
|
||||||
|
|
||||||
|
/* Search through buffers to see if the required block */
|
||||||
|
/* is already in a buffer */
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
printf("%8lx %02x ", bp->b_blkno, bp->b_flag);
|
||||||
|
if (++printed % 6 == 0)
|
||||||
|
printf("\n");
|
||||||
|
bp = b_next(bp);
|
||||||
|
}
|
||||||
|
while (FP_OFF(bp) != FP_OFF(firstbuf));
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* */
|
||||||
|
/* Return the address of a buffer structure containing the */
|
||||||
|
/* requested block. */
|
||||||
|
/* if overwrite is set, then no need to read first */
|
||||||
|
/* */
|
||||||
|
/* returns: */
|
||||||
|
/* requested block with data */
|
||||||
|
/* failure: */
|
||||||
|
/* returns NULL */
|
||||||
|
/* */
|
||||||
|
struct buffer FAR *getblk(ULONG blkno, COUNT dsk, BOOL overwrite)
|
||||||
|
{
|
||||||
|
/* Search through buffers to see if the required block */
|
||||||
|
/* is already in a buffer */
|
||||||
|
|
||||||
|
struct buffer FAR *bp = searchblock(blkno, dsk);
|
||||||
|
|
||||||
|
if (!(bp->b_flag & BFR_UNCACHE))
|
||||||
|
{
|
||||||
|
return bp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The block we need is not in a buffer, we must make a buffer */
|
||||||
|
/* available, and fill it with the desired block */
|
||||||
|
|
||||||
|
/* take the buffer that lbp points to and flush it, then read new block. */
|
||||||
|
if (!flush1(bp))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Fill the indicated disk buffer with the current track and sector */
|
||||||
|
|
||||||
|
if (!overwrite && dskxfer(dsk, blkno, bp->b_buffer, 1, DSKREAD))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bp->b_flag = BFR_VALID | BFR_DATA;
|
||||||
|
bp->b_unit = dsk;
|
||||||
|
bp->b_blkno = blkno;
|
||||||
|
|
||||||
|
return bp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* Mark all buffers for a disk as not valid */
|
||||||
|
/* */
|
||||||
|
VOID setinvld(REG COUNT dsk)
|
||||||
|
{
|
||||||
|
struct buffer FAR *bp = firstbuf;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (bp->b_unit == dsk)
|
||||||
|
bp->b_flag = 0;
|
||||||
|
bp = b_next(bp);
|
||||||
|
}
|
||||||
|
while (FP_OFF(bp) != FP_OFF(firstbuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if there is at least one dirty buffer */
|
||||||
|
/* */
|
||||||
|
BOOL dirty_buffers(REG COUNT dsk)
|
||||||
|
{
|
||||||
|
struct buffer FAR *bp = firstbuf;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (bp->b_unit == dsk &&
|
||||||
|
(bp->b_flag & (BFR_VALID | BFR_DIRTY)) == (BFR_VALID | BFR_DIRTY))
|
||||||
|
return TRUE;
|
||||||
|
bp = b_next(bp);
|
||||||
|
}
|
||||||
|
while (FP_OFF(bp) != FP_OFF(firstbuf));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* Flush all buffers for a disk */
|
||||||
|
/* */
|
||||||
|
/* returns: */
|
||||||
|
/* TRUE on success */
|
||||||
|
/* */
|
||||||
|
BOOL flush_buffers(REG COUNT dsk)
|
||||||
|
{
|
||||||
|
struct buffer FAR *bp = firstbuf;
|
||||||
|
REG BOOL ok = TRUE;
|
||||||
|
|
||||||
|
bp = firstbuf;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (bp->b_unit == dsk)
|
||||||
|
if (!flush1(bp))
|
||||||
|
ok = FALSE;
|
||||||
|
bp = b_next(bp);
|
||||||
|
}
|
||||||
|
while (FP_OFF(bp) != FP_OFF(firstbuf));
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* Write one disk buffer */
|
||||||
|
/* */
|
||||||
|
STATIC BOOL flush1(struct buffer FAR * bp)
|
||||||
|
{
|
||||||
|
BOOL ok = TRUE;
|
||||||
|
|
||||||
|
if ((bp->b_flag & (BFR_VALID | BFR_DIRTY)) == (BFR_VALID | BFR_DIRTY))
|
||||||
|
{
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
ULONG b_offset = 0;
|
||||||
|
#else
|
||||||
|
UWORD b_offset = 0;
|
||||||
|
#endif
|
||||||
|
UBYTE b_copies = 1;
|
||||||
|
ULONG blkno = bp->b_blkno;
|
||||||
|
if (bp->b_flag & BFR_FAT)
|
||||||
|
{
|
||||||
|
b_copies = bp->b_copies;
|
||||||
|
b_offset = bp->b_offset;
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
if (b_offset == 0) /* FAT32 FS */
|
||||||
|
b_offset = bp->b_dpbp->dpb_xfatsize;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
while (b_copies--)
|
||||||
|
{
|
||||||
|
if (dskxfer(bp->b_unit, blkno, bp->b_buffer, 1, DSKWRITE))
|
||||||
|
ok = FALSE;
|
||||||
|
blkno += b_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bp->b_flag &= ~BFR_DIRTY; /* even if error, mark not dirty */
|
||||||
|
if (!ok) /* otherwise system has trouble */
|
||||||
|
bp->b_flag &= ~BFR_VALID; /* continuing. */
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* Write all disk buffers */
|
||||||
|
/* */
|
||||||
|
BOOL flush(void)
|
||||||
|
{
|
||||||
|
REG struct buffer FAR *bp = firstbuf;
|
||||||
|
REG BOOL ok;
|
||||||
|
|
||||||
|
ok = TRUE;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (!flush1(bp))
|
||||||
|
ok = FALSE;
|
||||||
|
bp->b_flag &= ~BFR_VALID;
|
||||||
|
bp = b_next(bp);
|
||||||
|
}
|
||||||
|
while (FP_OFF(bp) != FP_OFF(firstbuf));
|
||||||
|
|
||||||
|
network_redirector(REM_FLUSHALL);
|
||||||
|
|
||||||
|
return (ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* Device Driver Interface Functions */
|
||||||
|
/* */
|
||||||
|
/************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* Transfer one or more blocks to/from disk */
|
||||||
|
/* */
|
||||||
|
|
||||||
|
UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks,
|
||||||
|
COUNT mode)
|
||||||
|
{
|
||||||
|
register struct dpb FAR *dpbp = get_dpb(dsk);
|
||||||
|
if (dpbp == NULL)
|
||||||
|
{
|
||||||
|
return 0x0201; /* illegal command */
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TOM
|
||||||
|
#define KeyboardShiftState() (*(BYTE FAR *)(MK_FP(0x40,0x17)))
|
||||||
|
|
||||||
|
if (KeyboardShiftState() & 0x01)
|
||||||
|
{
|
||||||
|
printf("dskxfer:%s %x - %lx %u\n", mode == DSKWRITE ? "write" : "read",
|
||||||
|
dsk, blkno, numblocks);
|
||||||
|
if ((KeyboardShiftState() & 0x03) == 3)
|
||||||
|
dumpBufferCache();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
IoReqHdr.r_length = sizeof(request);
|
||||||
|
IoReqHdr.r_unit = dpbp->dpb_subunit;
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case DSKWRITE:
|
||||||
|
if (verify_ena)
|
||||||
|
{
|
||||||
|
IoReqHdr.r_command = C_OUTVFY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* else fall through */
|
||||||
|
case DSKWRITEINT26:
|
||||||
|
IoReqHdr.r_command = C_OUTPUT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DSKREADINT25:
|
||||||
|
case DSKREAD:
|
||||||
|
IoReqHdr.r_command = C_INPUT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0x0100; /* illegal command */
|
||||||
|
}
|
||||||
|
|
||||||
|
IoReqHdr.r_status = 0;
|
||||||
|
IoReqHdr.r_meddesc = dpbp->dpb_mdb;
|
||||||
|
IoReqHdr.r_count = numblocks;
|
||||||
|
if ((dpbp->dpb_device->dh_attr & ATTR_HUGE) || blkno >= MAXSHORT)
|
||||||
|
{
|
||||||
|
IoReqHdr.r_start = HUGECOUNT;
|
||||||
|
IoReqHdr.r_huge = blkno;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
IoReqHdr.r_start = (UWORD)blkno;
|
||||||
|
/*
|
||||||
|
* Some drivers normalise transfer address so HMA transfers are disastrous!
|
||||||
|
* Then transfer block through xferbuf (DiskTransferBuffer doesn't work!)
|
||||||
|
* (But this won't work for multi-block HMA transfers... are there any?)
|
||||||
|
*/
|
||||||
|
if (FP_SEG(buf) >= 0xa000 && numblocks == 1 && bufloc != LOC_CONV)
|
||||||
|
{
|
||||||
|
IoReqHdr.r_trans = deblock_buf;
|
||||||
|
if (mode == DSKWRITE)
|
||||||
|
fmemcpy(deblock_buf, buf, dpbp->dpb_secsize);
|
||||||
|
execrh((request FAR *) & IoReqHdr, dpbp->dpb_device);
|
||||||
|
if (mode == DSKREAD)
|
||||||
|
fmemcpy(buf, deblock_buf, dpbp->dpb_secsize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IoReqHdr.r_trans = (BYTE FAR *) buf;
|
||||||
|
execrh((request FAR *) & IoReqHdr, dpbp->dpb_device);
|
||||||
|
}
|
||||||
|
if ((IoReqHdr.r_status & (S_ERROR | S_DONE)) == S_DONE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* INT25/26 (_SEEMS_ TO) return immediately with 0x8002,
|
||||||
|
if drive is not online,...
|
||||||
|
|
||||||
|
normal operations (DIR) wait for ABORT/RETRY
|
||||||
|
|
||||||
|
other condition codes not tested
|
||||||
|
*/
|
||||||
|
if (mode >= DSKWRITEINT26)
|
||||||
|
return (IoReqHdr.r_status);
|
||||||
|
|
||||||
|
loop:
|
||||||
|
switch (block_error(&IoReqHdr, dpbp->dpb_unit, dpbp->dpb_device, mode))
|
||||||
|
{
|
||||||
|
case ABORT:
|
||||||
|
case FAIL:
|
||||||
|
return (IoReqHdr.r_status);
|
||||||
|
|
||||||
|
case RETRY:
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case CONTINUE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} /* retry loop */
|
||||||
|
/* *** Changed 9/4/00 BER */
|
||||||
|
return 0; /* Success! Return 0 for a successful operation. */
|
||||||
|
/* End of change */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
this removes any (additionally allocated) buffers
|
||||||
|
from the HMA buffer chain, because they get allocated to the 'user'
|
||||||
|
*/
|
||||||
|
|
||||||
|
void AllocateHMASpace (size_t lowbuffer, size_t highbuffer)
|
||||||
|
{
|
||||||
|
REG struct buffer FAR *bp = firstbuf;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (FP_SEG(bp) != 0xffff)
|
||||||
|
return;
|
||||||
|
|
||||||
|
n = LoL_nbuffers;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* check if buffer intersects with requested area */
|
||||||
|
if (FP_OFF(bp) < highbuffer && FP_OFF(bp+1) > lowbuffer)
|
||||||
|
{
|
||||||
|
flush1(bp);
|
||||||
|
/* unlink bp from buffer chain */
|
||||||
|
|
||||||
|
b_prev(bp)->b_next = bp->b_next;
|
||||||
|
b_next(bp)->b_prev = bp->b_prev;
|
||||||
|
if (FP_OFF(bp) == FP_OFF(firstbuf))
|
||||||
|
firstbuf = b_next(bp);
|
||||||
|
LoL_nbuffers--;
|
||||||
|
}
|
||||||
|
bp = b_next(bp);
|
||||||
|
}
|
||||||
|
while (--n);
|
||||||
|
}
|
93
kernel/break.c
Normal file
93
kernel/break.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* break.c */
|
||||||
|
/* FreeDOS */
|
||||||
|
/* */
|
||||||
|
/* Control Break detection and handling */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1999 */
|
||||||
|
/* Steffen Kaiser */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#include "portab.h"
|
||||||
|
#include "globals.h"
|
||||||
|
#include "proto.h"
|
||||||
|
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *RcsId =
|
||||||
|
"$Id: break.c 885 2004-04-14 15:40:51Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CB_FLG *(UBYTE FAR*)MK_FP(0x0, 0x471)
|
||||||
|
#define CB_MSK 0x80
|
||||||
|
|
||||||
|
/* Check for ^Break/^C.
|
||||||
|
* Three sources are available:
|
||||||
|
* 1) flag at 40:71 bit 7
|
||||||
|
* 2) syscon stream (usually CON:)
|
||||||
|
* 3) i/o stream (if unequal to syscon, e.g. AUX)
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned char ctrl_break_pressed(void)
|
||||||
|
{
|
||||||
|
return CB_FLG & CB_MSK;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char check_handle_break(struct dhdr FAR **pdev)
|
||||||
|
{
|
||||||
|
unsigned char c = CTL_C;
|
||||||
|
if (!ctrl_break_pressed())
|
||||||
|
c = (unsigned char)ndread(&syscon);
|
||||||
|
if (c != CTL_C && *pdev != syscon)
|
||||||
|
c = (unsigned char)ndread(pdev);
|
||||||
|
if (c == CTL_C)
|
||||||
|
handle_break(pdev, -1);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handles a ^Break state
|
||||||
|
*
|
||||||
|
* Actions:
|
||||||
|
* 1) clear the ^Break flag
|
||||||
|
* 2) clear the STDIN stream
|
||||||
|
* 3) echo ^C to sft_out or pdev if sft_out==-1
|
||||||
|
* 4) decrease the InDOS flag as the kernel drops back to user space
|
||||||
|
* 5) invoke INT-23 and never come back
|
||||||
|
*/
|
||||||
|
|
||||||
|
void handle_break(struct dhdr FAR **pdev, int sft_out)
|
||||||
|
{
|
||||||
|
char *buf = "^C\r\n";
|
||||||
|
|
||||||
|
CB_FLG &= ~CB_MSK; /* reset the ^Break flag */
|
||||||
|
con_flush(pdev);
|
||||||
|
if (sft_out == -1)
|
||||||
|
cooked_write(pdev, 4, buf);
|
||||||
|
else
|
||||||
|
DosRWSft(sft_out, 4, buf, XFR_FORCE_WRITE);
|
||||||
|
if (!ErrorMode) /* within int21_handler, InDOS is not incremented */
|
||||||
|
if (InDOS)
|
||||||
|
--InDOS; /* fail-safe */
|
||||||
|
|
||||||
|
spawn_int23(); /* invoke user INT-23 and never come back */
|
||||||
|
}
|
||||||
|
|
548
kernel/chario.c
Normal file
548
kernel/chario.c
Normal file
@ -0,0 +1,548 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* chario.c */
|
||||||
|
/* DOS-C */
|
||||||
|
/* */
|
||||||
|
/* Character device functions and device driver interface */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1994 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/* */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#include "portab.h"
|
||||||
|
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *charioRcsId =
|
||||||
|
"$Id: chario.c 1413 2009-06-01 13:41:03Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
|
STATIC int CharRequest(struct dhdr FAR **pdev, unsigned command)
|
||||||
|
{
|
||||||
|
struct dhdr FAR *dev = *pdev;
|
||||||
|
CharReqHdr.r_command = command;
|
||||||
|
CharReqHdr.r_unit = 0;
|
||||||
|
CharReqHdr.r_status = 0;
|
||||||
|
CharReqHdr.r_length = sizeof(request);
|
||||||
|
execrh(&CharReqHdr, dev);
|
||||||
|
if (CharReqHdr.r_status & S_ERROR)
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
switch (char_error(&CharReqHdr, dev))
|
||||||
|
{
|
||||||
|
case ABORT:
|
||||||
|
case FAIL:
|
||||||
|
return DE_INVLDACC;
|
||||||
|
case CONTINUE:
|
||||||
|
CharReqHdr.r_count = 0;
|
||||||
|
return 0;
|
||||||
|
case RETRY:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
long BinaryCharIO(struct dhdr FAR **pdev, size_t n, void FAR * bp,
|
||||||
|
unsigned command)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
CharReqHdr.r_count = n;
|
||||||
|
CharReqHdr.r_trans = bp;
|
||||||
|
err = CharRequest(pdev, command);
|
||||||
|
} while (err == 1);
|
||||||
|
return err == SUCCESS ? (long)CharReqHdr.r_count : err;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC int CharIO(struct dhdr FAR **pdev, unsigned char ch, unsigned command)
|
||||||
|
{
|
||||||
|
int err = (int)BinaryCharIO(pdev, 1, &ch, command);
|
||||||
|
if (err == 0)
|
||||||
|
return 256;
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* STATE FUNCTIONS */
|
||||||
|
|
||||||
|
STATIC void CharCmd(struct dhdr FAR **pdev, unsigned command)
|
||||||
|
{
|
||||||
|
while (CharRequest(pdev, command) == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC int Busy(struct dhdr FAR **pdev)
|
||||||
|
{
|
||||||
|
CharCmd(pdev, C_ISTAT);
|
||||||
|
return CharReqHdr.r_status & S_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void con_flush(struct dhdr FAR **pdev)
|
||||||
|
{
|
||||||
|
CharCmd(pdev, C_IFLUSH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if the sft is invalid, then we just monitor syscon */
|
||||||
|
struct dhdr FAR *sft_to_dev(sft FAR *s)
|
||||||
|
{
|
||||||
|
if (FP_OFF(s) == (size_t) -1)
|
||||||
|
return syscon;
|
||||||
|
if (s->sft_flags & SFT_FDEVICE)
|
||||||
|
return s->sft_dev;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StdinBusy(void)
|
||||||
|
{
|
||||||
|
sft FAR *s = get_sft(STDIN);
|
||||||
|
struct dhdr FAR *dev = sft_to_dev(s);
|
||||||
|
|
||||||
|
if (dev)
|
||||||
|
return Busy(&dev);
|
||||||
|
|
||||||
|
return s->sft_posit >= s->sft_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get character from the console - this is how DOS gets
|
||||||
|
CTL_C/CTL_S/CTL_P when outputting */
|
||||||
|
int ndread(struct dhdr FAR **pdev)
|
||||||
|
{
|
||||||
|
CharCmd(pdev, C_NDREAD);
|
||||||
|
if (CharReqHdr.r_status & S_BUSY)
|
||||||
|
return -1;
|
||||||
|
return CharReqHdr.r_ndbyte;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OUTPUT FUNCTIONS */
|
||||||
|
|
||||||
|
#ifdef __WATCOMC__
|
||||||
|
void fast_put_char(char c);
|
||||||
|
#pragma aux fast_put_char = "int 29h" parm[al] modify exact [bx]
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* writes a character in raw mode using int29 for speed */
|
||||||
|
STATIC void fast_put_char(unsigned char chr)
|
||||||
|
{
|
||||||
|
#if defined(__TURBOC__)
|
||||||
|
_AL = chr;
|
||||||
|
__int__(0x29);
|
||||||
|
#elif defined(I86)
|
||||||
|
asm
|
||||||
|
{
|
||||||
|
mov al, byte ptr chr;
|
||||||
|
int 0x29;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void update_scr_pos(unsigned char c, unsigned char count)
|
||||||
|
{
|
||||||
|
unsigned char scrpos = scr_pos;
|
||||||
|
|
||||||
|
if (c == CR)
|
||||||
|
scrpos = 0;
|
||||||
|
else if (c == BS) {
|
||||||
|
if (scrpos > 0)
|
||||||
|
scrpos--;
|
||||||
|
} else if (c != LF && c != BELL) {
|
||||||
|
scrpos += count;
|
||||||
|
}
|
||||||
|
scr_pos = scrpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC int raw_get_char(struct dhdr FAR **pdev, BOOL check_break);
|
||||||
|
|
||||||
|
long cooked_write(struct dhdr FAR **pdev, size_t n, char FAR *bp)
|
||||||
|
{
|
||||||
|
size_t xfer;
|
||||||
|
|
||||||
|
/* bit 7 means fastcon; low 5 bits count number of characters */
|
||||||
|
unsigned char fast_counter = ((*pdev)->dh_attr & ATTR_FASTCON) << 3;
|
||||||
|
|
||||||
|
for (xfer = 0; xfer < n; xfer++)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
unsigned char count = 1, c = *bp++;
|
||||||
|
|
||||||
|
if (c == CTL_Z)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* write a character in cooked mode; maybe with printer echo;
|
||||||
|
handles TAB expansion */
|
||||||
|
if (c == HT) {
|
||||||
|
count = 8 - (scr_pos & 7);
|
||||||
|
c = ' ';
|
||||||
|
}
|
||||||
|
update_scr_pos(c, count);
|
||||||
|
do {
|
||||||
|
/* if not fast then < 0x80; always check
|
||||||
|
otherwise check every 32 characters */
|
||||||
|
if (fast_counter <= 0x80 && check_handle_break(pdev) == CTL_S)
|
||||||
|
raw_get_char(pdev, TRUE); /* Test for hold char and ctl_c */
|
||||||
|
fast_counter++;
|
||||||
|
fast_counter &= 0x9f;
|
||||||
|
if (PrinterEcho)
|
||||||
|
DosWrite(STDPRN, 1, &c);
|
||||||
|
if (fast_counter & 0x80)
|
||||||
|
fast_put_char(c);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = CharIO(pdev, c, C_OUTPUT);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
} while (--count != 0);
|
||||||
|
}
|
||||||
|
return xfer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* writes character for disk file or device */
|
||||||
|
void write_char(int c, int sft_idx)
|
||||||
|
{
|
||||||
|
unsigned char ch = (unsigned char)c;
|
||||||
|
DosRWSft(sft_idx, 1, &ch, XFR_FORCE_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_char_stdout(int c)
|
||||||
|
{
|
||||||
|
unsigned char count = 1;
|
||||||
|
unsigned flags = get_sft(STDOUT)->sft_flags;
|
||||||
|
|
||||||
|
/* ah=2, ah=9 should expand tabs even for raw devices and disk files */
|
||||||
|
if ((flags & (SFT_FDEVICE|SFT_FBINARY)) != SFT_FDEVICE)
|
||||||
|
{
|
||||||
|
if (c == HT) {
|
||||||
|
count = 8 - (scr_pos & 7);
|
||||||
|
c = ' ';
|
||||||
|
}
|
||||||
|
/* for raw CONOUT devices already updated in dosfns.c */
|
||||||
|
if ((flags & (SFT_FDEVICE|SFT_FCONOUT)) != (SFT_FDEVICE|SFT_FCONOUT))
|
||||||
|
update_scr_pos(c, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
write_char(c, get_sft_idx(STDOUT));
|
||||||
|
} while (--count != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define iscntrl(c) ((unsigned char)(c) < ' ')
|
||||||
|
|
||||||
|
/* this is for handling things like ^C, mostly used in echoed input */
|
||||||
|
STATIC int echo_char(int c, int sft_idx)
|
||||||
|
{
|
||||||
|
int out = c;
|
||||||
|
if (iscntrl(c) && c != HT && c != LF && c != CR)
|
||||||
|
{
|
||||||
|
write_char('^', sft_idx);
|
||||||
|
out += '@';
|
||||||
|
}
|
||||||
|
write_char(out, sft_idx);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC void destr_bs(int sft_idx)
|
||||||
|
{
|
||||||
|
write_char(BS, sft_idx);
|
||||||
|
write_char(' ', sft_idx);
|
||||||
|
write_char(BS, sft_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* READ FUNCTIONS */
|
||||||
|
|
||||||
|
long cooked_read(struct dhdr FAR **pdev, size_t n, char FAR *bp)
|
||||||
|
{
|
||||||
|
unsigned xfer = 0;
|
||||||
|
int c;
|
||||||
|
while(n--)
|
||||||
|
{
|
||||||
|
c = raw_get_char(pdev, TRUE);
|
||||||
|
if (c < 0)
|
||||||
|
return c;
|
||||||
|
if (c == 256)
|
||||||
|
break;
|
||||||
|
*bp++ = c;
|
||||||
|
xfer++;
|
||||||
|
if ((unsigned char)c == CTL_Z)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return xfer;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC unsigned char read_char_sft_dev(int sft_in, int sft_out,
|
||||||
|
struct dhdr FAR **pdev,
|
||||||
|
BOOL check_break)
|
||||||
|
{
|
||||||
|
unsigned char c;
|
||||||
|
|
||||||
|
if (*pdev)
|
||||||
|
{
|
||||||
|
FOREVER
|
||||||
|
{
|
||||||
|
if (ctrl_break_pressed())
|
||||||
|
{
|
||||||
|
c = CTL_C;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!Busy(pdev))
|
||||||
|
{
|
||||||
|
c = CharIO(pdev, 0, C_INPUT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (check_break && *pdev != syscon)
|
||||||
|
check_handle_break(&syscon);
|
||||||
|
/* the idle int is only safe if we're using the character stack */
|
||||||
|
if (user_r->AH < 0xd)
|
||||||
|
DosIdle_int();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DosRWSft(sft_in, 1, &c, XFR_READ);
|
||||||
|
|
||||||
|
/* check for break or stop on sft_in, echo to sft_out */
|
||||||
|
if (check_break && (c == CTL_C || c == CTL_S))
|
||||||
|
{
|
||||||
|
if (c == CTL_S)
|
||||||
|
c = read_char_sft_dev(sft_in, sft_out, pdev, FALSE);
|
||||||
|
if (c == CTL_C)
|
||||||
|
handle_break(pdev, sft_out);
|
||||||
|
/* DOS oddity: if you press ^S somekey ^C then ^C does not break */
|
||||||
|
c = read_char(sft_in, sft_out, FALSE);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC int raw_get_char(struct dhdr FAR **pdev, BOOL check_break)
|
||||||
|
{
|
||||||
|
return read_char_sft_dev(-1, -1, pdev, check_break);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char read_char(int sft_in, int sft_out, BOOL check_break)
|
||||||
|
{
|
||||||
|
struct dhdr FAR *dev = sft_to_dev(idx_to_sft(sft_in));
|
||||||
|
return read_char_sft_dev(sft_in, sft_out, &dev, check_break);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC unsigned char read_char_check_break(int sft_in, int sft_out)
|
||||||
|
{
|
||||||
|
return read_char(sft_in, sft_out, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char read_char_stdin(BOOL check_break)
|
||||||
|
{
|
||||||
|
return read_char(get_sft_idx(STDIN), get_sft_idx(STDOUT), check_break);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reads a line (buffered, called by int21/ah=0ah, 3fh) */
|
||||||
|
void read_line(int sft_in, int sft_out, keyboard FAR * kp)
|
||||||
|
{
|
||||||
|
unsigned c;
|
||||||
|
unsigned cu_pos = scr_pos;
|
||||||
|
unsigned count = 0, stored_pos = 0;
|
||||||
|
unsigned size = kp->kb_size, stored_size = kp->kb_count;
|
||||||
|
BOOL insert = FALSE, first = TRUE;
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* the stored line is invalid unless it ends with a CR */
|
||||||
|
if (kp->kb_buf[stored_size] != CR)
|
||||||
|
stored_size = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
unsigned new_pos = stored_size;
|
||||||
|
|
||||||
|
c = read_char_check_break(sft_in, sft_out);
|
||||||
|
if (c == 0)
|
||||||
|
c = (unsigned)read_char_check_break(sft_in, sft_out) << 8;
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case LF:
|
||||||
|
/* show LF if it's not the first character. Never store it */
|
||||||
|
if (!first)
|
||||||
|
{
|
||||||
|
write_char(CR, sft_out);
|
||||||
|
write_char(LF, sft_out);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CTL_F:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIGHT:
|
||||||
|
case F1:
|
||||||
|
if (stored_pos < stored_size && count < size - 1)
|
||||||
|
local_buffer[count++] = echo_char(kp->kb_buf[stored_pos++], sft_out);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case F2:
|
||||||
|
case F4:
|
||||||
|
/* insert/delete up to character c */
|
||||||
|
{
|
||||||
|
unsigned char c2 = read_char_check_break(sft_in, sft_out);
|
||||||
|
new_pos = stored_pos;
|
||||||
|
if (c2 == 0)
|
||||||
|
{
|
||||||
|
read_char_check_break(sft_in, sft_out);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char FAR *sp = fmemchr(&kp->kb_buf[stored_pos],
|
||||||
|
c2, stored_size - stored_pos);
|
||||||
|
if (sp != NULL)
|
||||||
|
new_pos = (FP_OFF(sp) - FP_OFF(&kp->kb_buf[stored_pos])) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* fall through */
|
||||||
|
case F3:
|
||||||
|
if (c != F4) /* not delete */
|
||||||
|
{
|
||||||
|
while (stored_pos < new_pos && count < size - 1)
|
||||||
|
local_buffer[count++] = echo_char(kp->kb_buf[stored_pos++], sft_out);
|
||||||
|
}
|
||||||
|
stored_pos = new_pos;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case F5:
|
||||||
|
fmemcpy(kp->kb_buf, local_buffer, count);
|
||||||
|
stored_size = count;
|
||||||
|
write_char('@', sft_out);
|
||||||
|
goto start_new_line;
|
||||||
|
|
||||||
|
case INS:
|
||||||
|
insert = !insert;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEL:
|
||||||
|
stored_pos++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LEFT:
|
||||||
|
case CTL_BS:
|
||||||
|
case BS:
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
unsigned new_pos;
|
||||||
|
char c2 = local_buffer[--count];
|
||||||
|
if (c2 == HT)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
new_pos = cu_pos;
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (local_buffer[i] == HT)
|
||||||
|
new_pos = (new_pos + 8) & ~7;
|
||||||
|
else if (iscntrl(local_buffer[i]))
|
||||||
|
new_pos += 2;
|
||||||
|
else
|
||||||
|
new_pos++;
|
||||||
|
}
|
||||||
|
do
|
||||||
|
destr_bs(sft_out);
|
||||||
|
while (scr_pos > new_pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (iscntrl(c2))
|
||||||
|
destr_bs(sft_out);
|
||||||
|
destr_bs(sft_out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stored_pos > 0)
|
||||||
|
stored_pos--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ESC:
|
||||||
|
write_char('\\', sft_out);
|
||||||
|
start_new_line:
|
||||||
|
write_char(CR, sft_out);
|
||||||
|
write_char(LF, sft_out);
|
||||||
|
for (count = 0; count < cu_pos; count++)
|
||||||
|
write_char(' ', sft_out);
|
||||||
|
count = 0;
|
||||||
|
stored_pos = 0;
|
||||||
|
insert = FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case F6:
|
||||||
|
c = CTL_Z;
|
||||||
|
/* fall through */
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (count < size - 1 || c == CR)
|
||||||
|
local_buffer[count++] = echo_char(c, sft_out);
|
||||||
|
else
|
||||||
|
write_char(BELL, sft_out);
|
||||||
|
if (stored_pos < stored_size && !insert)
|
||||||
|
stored_pos++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
first = FALSE;
|
||||||
|
} while (c != CR);
|
||||||
|
fmemcpy(kp->kb_buf, local_buffer, count);
|
||||||
|
/* if local_buffer overflows into the CON default buffer we
|
||||||
|
must invalidate it */
|
||||||
|
if (count > LINEBUFSIZECON)
|
||||||
|
kb_buf.kb_size = 0;
|
||||||
|
/* kb_count does not include the final CR */
|
||||||
|
kp->kb_count = count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called by handle func READ (int21/ah=3f) */
|
||||||
|
size_t read_line_handle(int sft_idx, size_t n, char FAR * bp)
|
||||||
|
{
|
||||||
|
size_t chars_left;
|
||||||
|
|
||||||
|
if (inputptr == NULL)
|
||||||
|
{
|
||||||
|
/* can we reuse kb_buf or was it overwritten? */
|
||||||
|
if (kb_buf.kb_size != LINEBUFSIZECON)
|
||||||
|
{
|
||||||
|
kb_buf.kb_count = 0;
|
||||||
|
kb_buf.kb_size = LINEBUFSIZECON;
|
||||||
|
}
|
||||||
|
read_line(sft_idx, sft_idx, &kb_buf);
|
||||||
|
kb_buf.kb_buf[kb_buf.kb_count + 1] = echo_char(LF, sft_idx);
|
||||||
|
inputptr = kb_buf.kb_buf;
|
||||||
|
if (*inputptr == CTL_Z)
|
||||||
|
{
|
||||||
|
inputptr = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chars_left = &kb_buf.kb_buf[kb_buf.kb_count + 2] - inputptr;
|
||||||
|
if (n > chars_left)
|
||||||
|
n = chars_left;
|
||||||
|
|
||||||
|
fmemcpy(bp, inputptr, n);
|
||||||
|
inputptr += n;
|
||||||
|
if (n == chars_left)
|
||||||
|
inputptr = NULL;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
2568
kernel/config.c
Normal file
2568
kernel/config.c
Normal file
File diff suppressed because it is too large
Load Diff
46
kernel/config.h
Normal file
46
kernel/config.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* config.h */
|
||||||
|
/* DOS-C */
|
||||||
|
/* */
|
||||||
|
/* Global data structures and declarations */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2000 */
|
||||||
|
/* Steffen Kaiser */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
struct config { /* Configuration variables */
|
||||||
|
UBYTE cfgDosDataUmb;
|
||||||
|
BYTE cfgBuffers; /* number of buffers in the system */
|
||||||
|
UBYTE cfgFiles; /* number of available files */
|
||||||
|
UBYTE cfgFilesHigh;
|
||||||
|
UBYTE cfgFcbs; /* number of available FCBs */
|
||||||
|
UBYTE cfgProtFcbs; /* number of protected FCBs */
|
||||||
|
BYTE *cfgInit; /* init of command.com */
|
||||||
|
BYTE *cfgInitTail; /* command.com's tail */
|
||||||
|
UBYTE cfgLastdrive; /* last drive */
|
||||||
|
UBYTE cfgLastdriveHigh;
|
||||||
|
BYTE cfgStacks; /* number of stacks */
|
||||||
|
BYTE cfgStacksHigh;
|
||||||
|
UWORD cfgStackSize; /* stacks size for each stack */
|
||||||
|
UBYTE cfgP_0_startmode; /* load command.com high or not */
|
||||||
|
unsigned ebda2move; /* value for switches=/E:nnnn */
|
||||||
|
};
|
254
kernel/console.asm
Normal file
254
kernel/console.asm
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
;
|
||||||
|
; File:
|
||||||
|
; console.asm
|
||||||
|
; Description:
|
||||||
|
; Console device driver
|
||||||
|
;
|
||||||
|
; Copyright (c) 1998
|
||||||
|
; Pasquale J. Villani
|
||||||
|
; All Rights Reserved
|
||||||
|
;
|
||||||
|
; This file is part of DOS-C.
|
||||||
|
;
|
||||||
|
; DOS-C is free software; you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation; either version
|
||||||
|
; 2, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; DOS-C is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||||
|
; the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public
|
||||||
|
; License along with DOS-C; see the file COPYING. If not,
|
||||||
|
; write to the Free Software Foundation, 675 Mass Ave,
|
||||||
|
; Cambridge, MA 02139, USA.
|
||||||
|
;
|
||||||
|
; $Header$
|
||||||
|
;
|
||||||
|
|
||||||
|
%include "io.inc"
|
||||||
|
|
||||||
|
|
||||||
|
segment _IO_FIXED_DATA
|
||||||
|
|
||||||
|
global ConTable
|
||||||
|
ConTable db 0Ah
|
||||||
|
dw ConInit
|
||||||
|
dw _IOExit
|
||||||
|
dw _IOExit
|
||||||
|
dw _IOCommandError
|
||||||
|
dw ConRead
|
||||||
|
dw CommonNdRdExit
|
||||||
|
dw CommonNdRdExit
|
||||||
|
dw ConInpFlush
|
||||||
|
dw ConWrite
|
||||||
|
dw ConWrite
|
||||||
|
dw _IOExit
|
||||||
|
|
||||||
|
CTL_PRT_SCREEN equ 7200h
|
||||||
|
CTL_P equ 10h
|
||||||
|
|
||||||
|
segment _LOWTEXT
|
||||||
|
|
||||||
|
uScanCode db 0 ; Scan code for con: device
|
||||||
|
|
||||||
|
global _kbdType
|
||||||
|
_kbdType db 0 ; 00 for 84key, 10h for 102key
|
||||||
|
|
||||||
|
global ConInit
|
||||||
|
ConInit:
|
||||||
|
xor ax,ax
|
||||||
|
mov ds,ax
|
||||||
|
mov al,[496h]
|
||||||
|
and al,10h
|
||||||
|
mov byte[cs:_kbdType],al ; enhanced keyboard if bit 4 set
|
||||||
|
jmp _IOExit
|
||||||
|
|
||||||
|
;
|
||||||
|
; Name:
|
||||||
|
; ConRead
|
||||||
|
;
|
||||||
|
; Function:
|
||||||
|
; Read to address in es:di characters from the keyboard. Cx contains
|
||||||
|
; a count of how many characters are to be transferred.
|
||||||
|
;
|
||||||
|
; Description:
|
||||||
|
; Calls KbdRdChar to read the characters. Destroys ax.
|
||||||
|
;
|
||||||
|
global ConRead
|
||||||
|
ConRead:
|
||||||
|
jcxz ConRead2 ; Exit if read of zero
|
||||||
|
|
||||||
|
ConRead1:
|
||||||
|
call KbdRdChar ; Get a char from kbd in al
|
||||||
|
stosb ; Store al to es:[di]
|
||||||
|
loop ConRead1 ; Loop until all are read
|
||||||
|
|
||||||
|
ConRead2:
|
||||||
|
jmp _IOExit
|
||||||
|
|
||||||
|
|
||||||
|
readkey:
|
||||||
|
mov ah,[cs:_kbdType]
|
||||||
|
int 16h
|
||||||
|
checke0: cmp al,0xe0 ; must check for 0xe0 scan code
|
||||||
|
jne .ret
|
||||||
|
or ah,ah ; check for Greek alpha
|
||||||
|
jz .ret
|
||||||
|
mov al,0 ; otherwise destroy the 0xe0
|
||||||
|
.ret: retn
|
||||||
|
|
||||||
|
;
|
||||||
|
; Name:
|
||||||
|
; KbdRdChar
|
||||||
|
;
|
||||||
|
; Function:
|
||||||
|
; Read a character from the keyboard.
|
||||||
|
;
|
||||||
|
; Description:
|
||||||
|
; This subroutine reads a character from the keyboard. It also handles
|
||||||
|
; a couple of special functions.
|
||||||
|
; It converts ctrl-printscreen to a control-P.
|
||||||
|
; It also accounts for extended scan codes by saving off
|
||||||
|
; the high byte of the return and returning it if it was non-zero on
|
||||||
|
; the previous read.
|
||||||
|
;
|
||||||
|
global KbdRdChar
|
||||||
|
KbdRdChar:
|
||||||
|
xor ax,ax ; Zero the scratch register
|
||||||
|
xchg [cs:uScanCode],al ; and swap with scan code
|
||||||
|
; now AL is set if previous key was extended,
|
||||||
|
; and previous is erased in any case
|
||||||
|
or al,al ; Test to see if it was set
|
||||||
|
jnz KbdRdRtn ; Exit if it was, returning it
|
||||||
|
call readkey ; get keybd char in al, ah=scan
|
||||||
|
or ax,ax ; Zero ?
|
||||||
|
jz KbdRdChar ; Loop if it is
|
||||||
|
cmp ax,CTL_PRT_SCREEN ; Ctrl-Print screen?
|
||||||
|
jne KbdRd1 ; Nope, keep going
|
||||||
|
mov al,CTL_P ; Yep, make it ^P
|
||||||
|
KbdRd1:
|
||||||
|
or al,al ; Extended key?
|
||||||
|
jnz KbdRdRtn ; Nope, just exit
|
||||||
|
mov [cs:uScanCode],ah ; Yep, save the scan code
|
||||||
|
KbdRdRtn:
|
||||||
|
retn
|
||||||
|
|
||||||
|
;
|
||||||
|
; Name:
|
||||||
|
; CommonNdRdExit
|
||||||
|
;
|
||||||
|
; Function:
|
||||||
|
; Checks the keyboard input buffer.
|
||||||
|
;
|
||||||
|
; Description:
|
||||||
|
; Calls int 16 (get status). Sets Busy-Flag in status field. Destroys ax.
|
||||||
|
;
|
||||||
|
global CommonNdRdExit
|
||||||
|
CommonNdRdExit: ; *** tell if key waiting and return its ASCII if yes
|
||||||
|
mov al,[cs:uScanCode] ; Test for last scan code
|
||||||
|
; now AL is set if previous key was extended,
|
||||||
|
or al,al ; Was it zero ?
|
||||||
|
jnz ConNdRd2 ; Jump if there's a char waiting
|
||||||
|
mov ah,1
|
||||||
|
add ah,[cs:_kbdType]
|
||||||
|
int 16h ; Get status, if zf=0 al=char
|
||||||
|
jz ConNdRd4 ; Jump if no char available
|
||||||
|
call checke0 ; check for e0 scancode
|
||||||
|
or ax,ax ; Zero ?
|
||||||
|
jnz ConNdRd1 ; Jump if not zero
|
||||||
|
call readkey
|
||||||
|
jmp short CommonNdRdExit
|
||||||
|
; if char was there but 0, fetch and retry...
|
||||||
|
; (why do we check uScanCode here?)
|
||||||
|
|
||||||
|
ConNdRd1:
|
||||||
|
cmp ax,CTL_PRT_SCREEN ; Was ctl+prntscrn key pressed?
|
||||||
|
jne ConNdRd2 ; Jump if not
|
||||||
|
mov al,CTL_P
|
||||||
|
|
||||||
|
ConNdRd2:
|
||||||
|
lds bx,[cs:_ReqPktPtr] ; Set the status
|
||||||
|
cmp byte[bx+2],6 ; input status call?
|
||||||
|
je ConNdRd3
|
||||||
|
mov [bx+0Dh],al ; return the ASCII of that key
|
||||||
|
|
||||||
|
ConNdRd3:
|
||||||
|
jmp _IOExit
|
||||||
|
|
||||||
|
ConNdRd4:
|
||||||
|
jmp _IODone
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
global ConInpFlush
|
||||||
|
ConInpFlush: ; *** flush that keyboard queue
|
||||||
|
call KbdInpChar ; get all available keys
|
||||||
|
jmp _IOExit ; do not even remember the last one
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
KbdInpChar: ; *** get ??00 or the last waiting key after flushing the queue
|
||||||
|
xor ax,ax
|
||||||
|
mov byte [cs:uScanCode],al
|
||||||
|
KbdInpCh1:
|
||||||
|
mov ah,1
|
||||||
|
add ah,[cs:_kbdType]
|
||||||
|
int 16h ; get status, if zf=0 al=char
|
||||||
|
jz KbdInpRtnZero ; Jump if zero
|
||||||
|
; returns 0 or the last key that was waiting in AL
|
||||||
|
call readkey
|
||||||
|
jmp short KbdInpCh1
|
||||||
|
; just read any key that is waiting, then check if
|
||||||
|
; more keys are waiting. if not, return AL of this
|
||||||
|
; key (which is its ASCII). AH (scan) discarded!
|
||||||
|
KbdInpRtnZero: mov ah,1 ; if anybody wants "1 if no key was waiting"!
|
||||||
|
KbdInpRtn:
|
||||||
|
retn
|
||||||
|
|
||||||
|
|
||||||
|
global ConWrite
|
||||||
|
ConWrite:
|
||||||
|
jcxz ConNdRd3 ; Exit if nothing to write
|
||||||
|
ConWr1:
|
||||||
|
mov al,[es:di]
|
||||||
|
inc di
|
||||||
|
int 29h ; Do fast output call
|
||||||
|
loop ConWr1 ; Loop if more to output
|
||||||
|
jmp _IOExit
|
||||||
|
|
||||||
|
CBreak:
|
||||||
|
mov byte [cs:uScanCode],3 ; Put a ^C into the buffer
|
||||||
|
IntRetn:
|
||||||
|
iret
|
||||||
|
|
||||||
|
|
||||||
|
; global _cso
|
||||||
|
;_cso
|
||||||
|
; push bp
|
||||||
|
; mov bp,sp
|
||||||
|
; push ax
|
||||||
|
; mov ax,[bp+4]
|
||||||
|
; int 29h
|
||||||
|
; pop ax
|
||||||
|
; pop bp
|
||||||
|
; retn
|
||||||
|
|
||||||
|
global _int29_handler
|
||||||
|
_int29_handler:
|
||||||
|
push ax
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push bp
|
||||||
|
push bx
|
||||||
|
mov ah,0Eh
|
||||||
|
mov bx,7
|
||||||
|
int 10h ; write char al, teletype mode
|
||||||
|
pop bx
|
||||||
|
pop bp
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop ax
|
||||||
|
iret
|
5108
kernel/country.asm
Normal file
5108
kernel/country.asm
Normal file
File diff suppressed because it is too large
Load Diff
74
kernel/cpu.asm
Normal file
74
kernel/cpu.asm
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
; File:
|
||||||
|
; cpu.asm
|
||||||
|
; Description:
|
||||||
|
; Query basic CPU running on
|
||||||
|
;
|
||||||
|
; DOS-C
|
||||||
|
; Copyright (c) 2012
|
||||||
|
; FreeDOS
|
||||||
|
; All Rights Reserved
|
||||||
|
;
|
||||||
|
; This file is part of DOS-C.
|
||||||
|
;
|
||||||
|
; DOS-C is free software; you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation; either version
|
||||||
|
; 2, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; DOS-C is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||||
|
; the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
|
||||||
|
%include "segs.inc"
|
||||||
|
segment INIT_TEXT
|
||||||
|
|
||||||
|
CPU 386
|
||||||
|
;*********************************************************************
|
||||||
|
;
|
||||||
|
; UWORD query_cpu() based on Eric Auer's public domain cpulevel.asm
|
||||||
|
; input: none
|
||||||
|
; output: ax = cpu, 0=8086/8088, 1=186/188, 2=286, 3=386+
|
||||||
|
global _query_cpu
|
||||||
|
_query_cpu:
|
||||||
|
; save registers, assumes enough space on stack & valid stack frame setup
|
||||||
|
;push ax - no need to save, return value saved here
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
pushf ; save flags
|
||||||
|
|
||||||
|
; begin check, assume x86 unless later family detected
|
||||||
|
xor bx, bx ; 808x or 186 highest detected family stored in bx
|
||||||
|
push bx
|
||||||
|
popf ; try to clear all flag bits
|
||||||
|
pushf ; copy flags to ax so we can test if clear succeeded
|
||||||
|
pop ax
|
||||||
|
and ax, 0f000h
|
||||||
|
cmp ax, 0f000h
|
||||||
|
jnz is286 ; no the 4 msb stuck set to 1, so is a 808x or 8018x
|
||||||
|
mov ax,1 ; determine if 8086 or 186
|
||||||
|
mov cl,64 ; try to shift further than size of ax
|
||||||
|
shr ax,cl
|
||||||
|
or ax,ax
|
||||||
|
jz is086 ; 186 ignores the upper bits of cl
|
||||||
|
mov bx, 1 ; 186: above 808x, below 286
|
||||||
|
is086: jmp short cleanup
|
||||||
|
is286: mov bx, 2 ; at least 286
|
||||||
|
mov ax, 0f000h
|
||||||
|
push ax
|
||||||
|
popf ; try to set 4 msb of flags
|
||||||
|
pushf ; copy flags to ax so we can test if clear succeeded
|
||||||
|
pop ax
|
||||||
|
test ax, 0f000h
|
||||||
|
jz cleanup ; 4 msb stuck to 0: 80286
|
||||||
|
mov bx, 3 ; at least 386
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
mov ax, bx ; return CPU family
|
||||||
|
popf
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
retn
|
||||||
|
|
1377
kernel/dosfns.c
Normal file
1377
kernel/dosfns.c
Normal file
File diff suppressed because it is too large
Load Diff
96
kernel/dosidle.asm
Normal file
96
kernel/dosidle.asm
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
; File:
|
||||||
|
; DosIdle.asm
|
||||||
|
; Description:
|
||||||
|
; Dos Idle Interrupt Call
|
||||||
|
;
|
||||||
|
; DOS-C
|
||||||
|
; Copyright (c) 1995, 1999
|
||||||
|
; James B. Tabor
|
||||||
|
; All Rights Reserved
|
||||||
|
;
|
||||||
|
; This file is part of DOS-C.
|
||||||
|
;
|
||||||
|
; DOS-C is free software; you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation; either version
|
||||||
|
; 2, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; DOS-C is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||||
|
; the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public
|
||||||
|
; License along with DOS-C; see the file COPYING. If not,
|
||||||
|
; write to the Free Software Foundation, 675 Mass Ave,
|
||||||
|
; Cambridge, MA 02139, USA.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
%include "segs.inc"
|
||||||
|
|
||||||
|
PSP_USERSP equ 2eh
|
||||||
|
PSP_USERSS equ 30h
|
||||||
|
|
||||||
|
segment HMA_TEXT
|
||||||
|
|
||||||
|
global _DosIdle_int
|
||||||
|
global _DosIdle_hlt
|
||||||
|
|
||||||
|
extern _InDOS:wrt DGROUP
|
||||||
|
extern _cu_psp:wrt DGROUP
|
||||||
|
extern _MachineId:wrt DGROUP
|
||||||
|
extern critical_sp:wrt DGROUP
|
||||||
|
extern _user_r:wrt DGROUP
|
||||||
|
; variables as the following are "part of" module inthndlr.c
|
||||||
|
; because of the define MAIN before include globals.h there!
|
||||||
|
extern _HaltCpuWhileIdle:wrt DGROUP
|
||||||
|
extern _DGROUP_:wrt HMA_TEXT
|
||||||
|
;
|
||||||
|
_DosIdle_hlt:
|
||||||
|
push ds
|
||||||
|
mov ds, [cs:_DGROUP_]
|
||||||
|
cmp byte [_HaltCpuWhileIdle],1
|
||||||
|
jb DosId0
|
||||||
|
pushf
|
||||||
|
sti
|
||||||
|
hlt ; save some energy :-)
|
||||||
|
popf
|
||||||
|
DosId0: pop ds
|
||||||
|
retn
|
||||||
|
;
|
||||||
|
_DosIdle_int:
|
||||||
|
call _DosIdle_hlt
|
||||||
|
push ds
|
||||||
|
mov ds, [cs:_DGROUP_]
|
||||||
|
cmp byte [_InDOS],1
|
||||||
|
ja DosId1
|
||||||
|
call Do_DosI
|
||||||
|
DosId1:
|
||||||
|
pop ds
|
||||||
|
retn
|
||||||
|
|
||||||
|
Do_DosI:
|
||||||
|
push ax
|
||||||
|
push es
|
||||||
|
push word [_MachineId]
|
||||||
|
push word [_user_r]
|
||||||
|
push word [_user_r+2]
|
||||||
|
mov es,word [_cu_psp]
|
||||||
|
push word [es:PSP_USERSS]
|
||||||
|
push word [es:PSP_USERSP]
|
||||||
|
|
||||||
|
int 28h
|
||||||
|
|
||||||
|
mov es,word [_cu_psp]
|
||||||
|
pop word [es:PSP_USERSP]
|
||||||
|
pop word [es:PSP_USERSS]
|
||||||
|
pop word [_user_r+2]
|
||||||
|
pop word [_user_r]
|
||||||
|
pop word [_MachineId]
|
||||||
|
pop es
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; segment _DATA ; belongs to DGROUP
|
||||||
|
; whatever db whatever
|
||||||
|
|
1088
kernel/dsk.c
Normal file
1088
kernel/dsk.c
Normal file
File diff suppressed because it is too large
Load Diff
19
kernel/dyndata.h
Normal file
19
kernel/dyndata.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
DynData.h
|
||||||
|
|
||||||
|
declarations for dynamic NEAR data allocations
|
||||||
|
|
||||||
|
the DynBuffer must initially be large enough to hold
|
||||||
|
the PreConfig data.
|
||||||
|
after the disksystem has been initialized, the kernel is
|
||||||
|
moveable and Dyn.Buffer resizable, but not before
|
||||||
|
*/
|
||||||
|
|
||||||
|
void far *DynAlloc(char *what, unsigned num, unsigned size);
|
||||||
|
void far *DynLast(void);
|
||||||
|
void DynFree(void *ptr);
|
||||||
|
|
||||||
|
struct DynS {
|
||||||
|
unsigned Allocated;
|
||||||
|
char Buffer[1];
|
||||||
|
};
|
98
kernel/dyninit.c
Normal file
98
kernel/dyninit.c
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
DYNINIT.C
|
||||||
|
|
||||||
|
this serves requests from the INIT modules to
|
||||||
|
allocate dynamic data.
|
||||||
|
|
||||||
|
kernel layout:
|
||||||
|
00000H 000FFH 00100H PSP PSP
|
||||||
|
00100H 004E1H 003E2H _TEXT CODE
|
||||||
|
004E2H 007A7H 002C6H _IO_TEXT CODE
|
||||||
|
007A8H 008E5H 0013EH _IO_FIXED_DATA CODE
|
||||||
|
008F0H 0139FH 00AB0H _FIXED_DATA DATA
|
||||||
|
013A0H 019F3H 00654H _DATA DATA
|
||||||
|
019F4H 0240DH 00A1AH _BSS BSS
|
||||||
|
|
||||||
|
additionally:
|
||||||
|
DYN_DATA DYN
|
||||||
|
|
||||||
|
|
||||||
|
02610H 0F40EH 0CDFFH HMA_TEXT HMA
|
||||||
|
|
||||||
|
FCBs, f_nodes, buffers,...
|
||||||
|
drivers
|
||||||
|
|
||||||
|
|
||||||
|
0F410H 122DFH 02ED0H INIT_TEXT INIT
|
||||||
|
122E0H 12AA5H 007C6H ID ID
|
||||||
|
12AA6H 12CBFH 0021AH IB IB
|
||||||
|
|
||||||
|
purpose is to move the HMA_TEXT = resident kernel
|
||||||
|
around, so that below it - after BSS, there is data
|
||||||
|
addressable near by the kernel, to hold some arrays
|
||||||
|
like f_nodes
|
||||||
|
|
||||||
|
making f_nodes near saves ~2.150 code in HMA
|
||||||
|
|
||||||
|
*/
|
||||||
|
#include "portab.h"
|
||||||
|
#include "init-mod.h"
|
||||||
|
#include "dyndata.h"
|
||||||
|
|
||||||
|
#if defined(DEBUG)
|
||||||
|
#define DebugPrintf(x) printf x
|
||||||
|
#else
|
||||||
|
#define DebugPrintf(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*extern struct DynS FAR Dyn;*/
|
||||||
|
|
||||||
|
#ifndef __TURBOC__
|
||||||
|
#include "init-dat.h"
|
||||||
|
extern struct DynS DOSFAR ASM Dyn;
|
||||||
|
#else
|
||||||
|
extern struct DynS FAR ASM Dyn;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void far *DynAlloc(char *what, unsigned num, unsigned size)
|
||||||
|
{
|
||||||
|
void far *now;
|
||||||
|
unsigned total = num * size;
|
||||||
|
struct DynS far *Dynp = MK_FP(FP_SEG(LoL), FP_OFF(&Dyn));
|
||||||
|
|
||||||
|
#ifndef DEBUG
|
||||||
|
UNREFERENCED_PARAMETER(what);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((ULONG) total + Dynp->Allocated > 0xffff)
|
||||||
|
{
|
||||||
|
printf("PANIC:Dyn %lu\n", (ULONG) total + Dynp->Allocated);
|
||||||
|
for (;;) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugPrintf(("DYNDATA:allocating %s - %u * %u bytes, total %u, %u..%u\n",
|
||||||
|
what, num, size, total, Dynp->Allocated,
|
||||||
|
Dynp->Allocated + total));
|
||||||
|
|
||||||
|
now = (void far *)&Dynp->Buffer[Dynp->Allocated];
|
||||||
|
fmemset(now, 0, total);
|
||||||
|
|
||||||
|
Dynp->Allocated += total;
|
||||||
|
|
||||||
|
return now;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynFree(void *ptr)
|
||||||
|
{
|
||||||
|
struct DynS far *Dynp = MK_FP(FP_SEG(LoL), FP_OFF(&Dyn));
|
||||||
|
Dynp->Allocated = (char *)ptr - (char *)Dynp->Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FAR * DynLast()
|
||||||
|
{
|
||||||
|
struct DynS far *Dynp = MK_FP(FP_SEG(LoL), FP_OFF(&Dyn));
|
||||||
|
DebugPrintf(("dynamic data end at %p\n",
|
||||||
|
(void FAR *)(Dynp->Buffer + Dynp->Allocated)));
|
||||||
|
|
||||||
|
return Dynp->Buffer + Dynp->Allocated;
|
||||||
|
}
|
671
kernel/entry.asm
Normal file
671
kernel/entry.asm
Normal file
@ -0,0 +1,671 @@
|
|||||||
|
;
|
||||||
|
; File:
|
||||||
|
; entry.asm
|
||||||
|
; Description:
|
||||||
|
; System call entry code
|
||||||
|
;
|
||||||
|
; Copyright (c) 1998
|
||||||
|
; Pasquale J. Villani
|
||||||
|
; All Rights Reserved
|
||||||
|
;
|
||||||
|
; This file is part of DOS-C.
|
||||||
|
;
|
||||||
|
; DOS-C is free software; you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation; either version
|
||||||
|
; 2, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; DOS-C is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||||
|
; the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public
|
||||||
|
; License along with DOS-C; see the file COPYING. If not,
|
||||||
|
; write to the Free Software Foundation, 675 Mass Ave,
|
||||||
|
; Cambridge, MA 02139, USA.
|
||||||
|
;
|
||||||
|
; $Id: entry.asm 1701 2012-01-16 22:06:21Z perditionc $
|
||||||
|
;
|
||||||
|
|
||||||
|
%include "segs.inc"
|
||||||
|
%include "stacks.inc"
|
||||||
|
|
||||||
|
segment HMA_TEXT
|
||||||
|
extern _int21_syscall
|
||||||
|
extern _int21_service
|
||||||
|
extern _int2526_handler
|
||||||
|
extern _error_tos:wrt DGROUP
|
||||||
|
extern _char_api_tos:wrt DGROUP
|
||||||
|
extern _disk_api_tos:wrt DGROUP
|
||||||
|
extern _user_r:wrt DGROUP
|
||||||
|
extern _ErrorMode:wrt DGROUP
|
||||||
|
extern _InDOS:wrt DGROUP
|
||||||
|
extern _cu_psp:wrt DGROUP
|
||||||
|
extern _MachineId:wrt DGROUP
|
||||||
|
extern critical_sp:wrt DGROUP
|
||||||
|
|
||||||
|
extern int21regs_seg:wrt DGROUP
|
||||||
|
extern int21regs_off:wrt DGROUP
|
||||||
|
|
||||||
|
extern _Int21AX:wrt DGROUP
|
||||||
|
|
||||||
|
extern _DGROUP_
|
||||||
|
|
||||||
|
global reloc_call_cpm_entry
|
||||||
|
global reloc_call_int20_handler
|
||||||
|
global reloc_call_int21_handler
|
||||||
|
global reloc_call_low_int25_handler
|
||||||
|
global reloc_call_low_int26_handler
|
||||||
|
global reloc_call_int27_handler
|
||||||
|
|
||||||
|
;
|
||||||
|
; MS-DOS CP/M style entry point
|
||||||
|
;
|
||||||
|
; VOID FAR
|
||||||
|
; cpm_entry(iregs UserRegs)
|
||||||
|
;
|
||||||
|
; For CP/M compatibility allow a program to invoke any DOS API function
|
||||||
|
; between 0 and 24h by doing a near call to psp:0005h which embeds a far call
|
||||||
|
; to absolute address 0:00C0h (int vector 30h & 31h) or FFFF:00D0 (hma).
|
||||||
|
; 0:00C0h contains the jmp instruction to reloc_call_cpm_entry which should
|
||||||
|
; be duplicated in hma to ensure correct operation with either state of A20 line.
|
||||||
|
; Note: int 31h is also used for DPMI but only in protected mode.
|
||||||
|
; Upon entry the stack has a near return offset (desired return address offset)
|
||||||
|
; and far return seg:offset (desired return segment of PSP, and useless offset
|
||||||
|
; which if used will return to the data, not code, at offset 0ah after far call
|
||||||
|
; in psp). We convert it to a normal call and correct the stack to appear same
|
||||||
|
; as if invoked via an int 21h call including proper return address.
|
||||||
|
;
|
||||||
|
reloc_call_cpm_entry:
|
||||||
|
; Stack is:
|
||||||
|
; return offset
|
||||||
|
; psp seg
|
||||||
|
; 000ah
|
||||||
|
;
|
||||||
|
add sp, byte 2 ; remove unneeded far return offset 0ah
|
||||||
|
pushf ; start setting up int 21h stack
|
||||||
|
;
|
||||||
|
; now stack is
|
||||||
|
; return offset
|
||||||
|
; psp seg
|
||||||
|
; flags
|
||||||
|
;
|
||||||
|
push bp
|
||||||
|
mov bp,sp ; set up reference frame
|
||||||
|
;
|
||||||
|
; reference frame stack is
|
||||||
|
; return offset bp + 6
|
||||||
|
; psp seg bp + 4
|
||||||
|
; flags bp + 2
|
||||||
|
; bp <--- bp
|
||||||
|
;
|
||||||
|
push ax
|
||||||
|
mov ax,[2+bp] ; get the flags
|
||||||
|
xchg ax,[6+bp] ; swap with return address
|
||||||
|
mov [2+bp],ax
|
||||||
|
pop ax ; restore working registers
|
||||||
|
pop bp
|
||||||
|
;
|
||||||
|
; Done. Stack is
|
||||||
|
; flags
|
||||||
|
; psp seg (alias .COM cs)
|
||||||
|
; return offset
|
||||||
|
;
|
||||||
|
cmp cl,024h ; restrict calls to functions 0-24h
|
||||||
|
ja cpm_error
|
||||||
|
mov ah,cl ; get the call # from cl to ah
|
||||||
|
jmp reloc_call_int21_handler ; do the system call
|
||||||
|
cpm_error: mov al,0
|
||||||
|
iret ; cleanup stack and return to caller
|
||||||
|
|
||||||
|
;
|
||||||
|
; interrupt zero divide handler:
|
||||||
|
; print a message 'Interrupt divide by zero'
|
||||||
|
; Terminate the current process
|
||||||
|
;
|
||||||
|
; VOID INRPT far
|
||||||
|
; int20_handler(iregs UserRegs)
|
||||||
|
;
|
||||||
|
|
||||||
|
print_hex: mov cl, 12
|
||||||
|
hex_loop:
|
||||||
|
mov ax, dx
|
||||||
|
shr ax, cl
|
||||||
|
and al, 0fh
|
||||||
|
cmp al, 10
|
||||||
|
sbb al, 69h
|
||||||
|
das
|
||||||
|
mov bx, 0070h
|
||||||
|
mov ah, 0eh
|
||||||
|
int 10h
|
||||||
|
sub cl, 4
|
||||||
|
jae hex_loop
|
||||||
|
ret
|
||||||
|
|
||||||
|
divide_by_zero_message db 0dh,0ah,'Interrupt divide by zero, stack:',0dh,0ah,0
|
||||||
|
|
||||||
|
global reloc_call_int0_handler
|
||||||
|
reloc_call_int0_handler:
|
||||||
|
|
||||||
|
mov si,divide_by_zero_message
|
||||||
|
|
||||||
|
zero_message_loop:
|
||||||
|
mov al, [cs:si]
|
||||||
|
test al,al
|
||||||
|
je zero_done
|
||||||
|
|
||||||
|
inc si
|
||||||
|
mov bx, 0070h
|
||||||
|
mov ah, 0eh
|
||||||
|
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
jmp short zero_message_loop
|
||||||
|
|
||||||
|
zero_done:
|
||||||
|
mov bp, sp
|
||||||
|
xor si, si ; print 13 words of stack for debugging LUDIV etc.
|
||||||
|
stack_loop:
|
||||||
|
mov dx, [bp+si]
|
||||||
|
call print_hex
|
||||||
|
mov al, ' '
|
||||||
|
int 10h
|
||||||
|
inc si
|
||||||
|
inc si
|
||||||
|
cmp si, byte 13*2
|
||||||
|
jb stack_loop
|
||||||
|
mov al, 0dh
|
||||||
|
int 10h
|
||||||
|
mov al, 0ah
|
||||||
|
int 10h
|
||||||
|
|
||||||
|
mov ax,04c7fh ; terminate with errorlevel 127
|
||||||
|
int 21h
|
||||||
|
sti
|
||||||
|
thats_it: hlt
|
||||||
|
jmp short thats_it ; it might be command.com that nukes
|
||||||
|
|
||||||
|
invalid_opcode_message db 0dh,0ah,'Invalid Opcode at ',0
|
||||||
|
|
||||||
|
global reloc_call_int6_handler
|
||||||
|
reloc_call_int6_handler:
|
||||||
|
|
||||||
|
mov si,invalid_opcode_message
|
||||||
|
jmp short zero_message_loop
|
||||||
|
|
||||||
|
global reloc_call_int19_handler
|
||||||
|
reloc_call_int19_handler:
|
||||||
|
; from Japheth's public domain code (JEMFBHLP.ASM)
|
||||||
|
; restores int 10,13,15,19,1b and then calls the original int 19.
|
||||||
|
cld
|
||||||
|
xor ax,ax
|
||||||
|
mov es,ax
|
||||||
|
mov al,70h
|
||||||
|
mov ds,ax
|
||||||
|
mov si,100h
|
||||||
|
mov cx,5
|
||||||
|
cli
|
||||||
|
nextitem: lodsb
|
||||||
|
mov di,ax
|
||||||
|
%if XCPU >= 186
|
||||||
|
shl di,2
|
||||||
|
%else
|
||||||
|
shl di,1
|
||||||
|
shl di,1
|
||||||
|
%endif
|
||||||
|
movsw
|
||||||
|
movsw
|
||||||
|
loop nextitem
|
||||||
|
int 19h
|
||||||
|
|
||||||
|
;
|
||||||
|
; Terminate the current process
|
||||||
|
;
|
||||||
|
; VOID INRPT far
|
||||||
|
; int20_handler(iregs UserRegs)
|
||||||
|
;
|
||||||
|
reloc_call_int20_handler:
|
||||||
|
mov ah,0 ; terminate through int 21h
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; MS-DOS system call entry point
|
||||||
|
;
|
||||||
|
; VOID INRPT far
|
||||||
|
; int21_handler(iregs UserRegs)
|
||||||
|
;
|
||||||
|
reloc_call_int21_handler:
|
||||||
|
;
|
||||||
|
; Create the stack frame for C call. This is done to
|
||||||
|
; preserve machine state and provide a C structure for
|
||||||
|
; access to registers.
|
||||||
|
;
|
||||||
|
; Since this is an interrupt routine, CS, IP and flags were
|
||||||
|
; pushed onto the stack by the processor, completing the
|
||||||
|
; stack frame.
|
||||||
|
;
|
||||||
|
; NB: stack frame is MS-DOS dependent and not compatible
|
||||||
|
; with compiler interrupt stack frames.
|
||||||
|
;
|
||||||
|
sti
|
||||||
|
PUSH$ALL
|
||||||
|
mov bp,sp
|
||||||
|
;
|
||||||
|
; Create kernel reference frame.
|
||||||
|
;
|
||||||
|
; NB: At this point, SS != DS and won't be set that way
|
||||||
|
; until later when which stack to run on is determined.
|
||||||
|
;
|
||||||
|
int21_reentry:
|
||||||
|
Protect386Registers
|
||||||
|
mov dx,[cs:_DGROUP_]
|
||||||
|
mov ds,dx
|
||||||
|
|
||||||
|
cmp ah,25h
|
||||||
|
je int21_user
|
||||||
|
cmp ah,33h
|
||||||
|
je int21_user
|
||||||
|
cmp ah,35h
|
||||||
|
je int21_user
|
||||||
|
cmp ah,50h
|
||||||
|
je int21_user
|
||||||
|
cmp ah,51h
|
||||||
|
je int21_user
|
||||||
|
cmp ah,62h
|
||||||
|
jne int21_1
|
||||||
|
|
||||||
|
int21_user:
|
||||||
|
call dos_crit_sect
|
||||||
|
|
||||||
|
push ss
|
||||||
|
push bp
|
||||||
|
call _int21_syscall
|
||||||
|
pop cx
|
||||||
|
pop cx
|
||||||
|
jmp short int21_ret
|
||||||
|
|
||||||
|
;
|
||||||
|
; normal entry, use one of our 4 stacks
|
||||||
|
;
|
||||||
|
; DX=DGROUP
|
||||||
|
; CX=STACK
|
||||||
|
; SI=userSS
|
||||||
|
; BX=userSP
|
||||||
|
|
||||||
|
|
||||||
|
int21_1:
|
||||||
|
mov si,ss ; save user stack, to be retored later
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; Now DS is set, let's save our stack for rentry (???TE)
|
||||||
|
;
|
||||||
|
; I don't know who needs that, but ... (TE)
|
||||||
|
;
|
||||||
|
mov word [_user_r+2],ss
|
||||||
|
mov word [_user_r],bp ; store and init
|
||||||
|
|
||||||
|
;
|
||||||
|
; Decide which stack to run on.
|
||||||
|
;
|
||||||
|
; Unlike previous versions of DOS-C, we need to do this here
|
||||||
|
; to guarantee the user stack for critical error handling.
|
||||||
|
; We need to do the int 24h from this stack location.
|
||||||
|
;
|
||||||
|
; There are actually four stacks to run on. The first is the
|
||||||
|
; user stack which is determined by system call number in
|
||||||
|
; AH. The next is the error stack determined by _ErrorMode.
|
||||||
|
; Then there's the character stack also determined by system
|
||||||
|
; call number. Finally, all others run on the disk stack.
|
||||||
|
; They are evaluated in that order.
|
||||||
|
|
||||||
|
cmp byte [_ErrorMode],0
|
||||||
|
je int21_2
|
||||||
|
|
||||||
|
int21_onerrorstack:
|
||||||
|
mov cx,_error_tos
|
||||||
|
|
||||||
|
|
||||||
|
cli
|
||||||
|
mov ss,dx
|
||||||
|
mov sp,cx
|
||||||
|
sti
|
||||||
|
|
||||||
|
push si ; user SS:SP
|
||||||
|
push bp
|
||||||
|
|
||||||
|
call _int21_service
|
||||||
|
jmp short int21_exit_nodec
|
||||||
|
|
||||||
|
|
||||||
|
int21_2: inc byte [_InDOS]
|
||||||
|
mov cx,_char_api_tos
|
||||||
|
or ah,ah
|
||||||
|
jz int21_3
|
||||||
|
cmp ah,0ch
|
||||||
|
jbe int21_normalentry
|
||||||
|
|
||||||
|
int21_3:
|
||||||
|
call dos_crit_sect
|
||||||
|
mov cx,_disk_api_tos
|
||||||
|
|
||||||
|
int21_normalentry:
|
||||||
|
|
||||||
|
cli
|
||||||
|
mov ss,dx
|
||||||
|
mov sp,cx
|
||||||
|
sti
|
||||||
|
|
||||||
|
;
|
||||||
|
; Push the far pointer to the register frame for
|
||||||
|
; int21_syscall and remainder of kernel.
|
||||||
|
;
|
||||||
|
|
||||||
|
push si ; user SS:SP
|
||||||
|
push bp
|
||||||
|
call _int21_service
|
||||||
|
|
||||||
|
int21_exit: dec byte [_InDOS]
|
||||||
|
|
||||||
|
;
|
||||||
|
; Recover registers from system call. Registers and flags
|
||||||
|
; were modified by the system call.
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
int21_exit_nodec:
|
||||||
|
pop bp ; get back user stack
|
||||||
|
pop si
|
||||||
|
|
||||||
|
global _int21_iret
|
||||||
|
_int21_iret:
|
||||||
|
cli
|
||||||
|
mov ss,si
|
||||||
|
RestoreSP
|
||||||
|
|
||||||
|
int21_ret:
|
||||||
|
Restore386Registers
|
||||||
|
POP$ALL
|
||||||
|
|
||||||
|
;
|
||||||
|
; ... and return.
|
||||||
|
;
|
||||||
|
iret
|
||||||
|
;
|
||||||
|
; end Dos Critical Section 0 thur 7
|
||||||
|
;
|
||||||
|
;
|
||||||
|
dos_crit_sect:
|
||||||
|
mov [_Int21AX],ax ; needed!
|
||||||
|
push ax ; This must be here!!!
|
||||||
|
mov ah,82h ; re-enrty sake before disk stack
|
||||||
|
int 2ah ; Calling Server Hook!
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
;
|
||||||
|
; Terminate the current process
|
||||||
|
;
|
||||||
|
; VOID INRPT far
|
||||||
|
; int27_handler(iregs UserRegs)
|
||||||
|
;
|
||||||
|
reloc_call_int27_handler:
|
||||||
|
;
|
||||||
|
; First convert the memory to paragraphs
|
||||||
|
;
|
||||||
|
add dx,byte 0fh ; round up
|
||||||
|
rcr dx,1
|
||||||
|
shr dx,1
|
||||||
|
shr dx,1
|
||||||
|
shr dx,1
|
||||||
|
;
|
||||||
|
; ... then use the standard system call
|
||||||
|
;
|
||||||
|
mov ax,3100h
|
||||||
|
jmp reloc_call_int21_handler ; terminate through int 21h
|
||||||
|
|
||||||
|
;
|
||||||
|
;
|
||||||
|
|
||||||
|
reloc_call_low_int26_handler:
|
||||||
|
sti
|
||||||
|
pushf
|
||||||
|
push ax
|
||||||
|
mov ax,026h
|
||||||
|
jmp short int2526
|
||||||
|
reloc_call_low_int25_handler:
|
||||||
|
sti
|
||||||
|
pushf
|
||||||
|
push ax
|
||||||
|
mov ax,025h
|
||||||
|
int2526:
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push bx
|
||||||
|
push sp
|
||||||
|
push bp
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
|
||||||
|
mov cx, sp ; save stack frame
|
||||||
|
mov dx, ss
|
||||||
|
|
||||||
|
cld
|
||||||
|
mov bx, [cs:_DGROUP_]
|
||||||
|
mov ds, bx
|
||||||
|
|
||||||
|
; setup our local stack
|
||||||
|
cli
|
||||||
|
mov ss,bx
|
||||||
|
mov sp,_disk_api_tos
|
||||||
|
sti
|
||||||
|
|
||||||
|
Protect386Registers
|
||||||
|
|
||||||
|
push dx
|
||||||
|
push cx ; save user stack
|
||||||
|
|
||||||
|
push dx ; SS:SP -> user stack
|
||||||
|
push cx
|
||||||
|
push ax ; was set on entry = 25,26
|
||||||
|
call _int2526_handler
|
||||||
|
add sp, byte 6
|
||||||
|
|
||||||
|
pop cx
|
||||||
|
pop dx ; restore user stack
|
||||||
|
|
||||||
|
Restore386Registers
|
||||||
|
|
||||||
|
; restore foreground stack here
|
||||||
|
cli
|
||||||
|
mov ss, dx
|
||||||
|
mov sp, cx
|
||||||
|
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop bp
|
||||||
|
pop bx ; pop off sp value
|
||||||
|
pop bx
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop ax
|
||||||
|
popf
|
||||||
|
retf ; Bug-compatiblity with MS-DOS.
|
||||||
|
; This function is supposed to leave the original
|
||||||
|
; flag image on the stack.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CONTINUE equ 00h
|
||||||
|
RETRY equ 01h
|
||||||
|
ABORT equ 02h
|
||||||
|
FAIL equ 03h
|
||||||
|
|
||||||
|
OK_IGNORE equ 20h
|
||||||
|
OK_RETRY equ 10h
|
||||||
|
OK_FAIL equ 08h
|
||||||
|
|
||||||
|
PSP_PARENT equ 16h
|
||||||
|
PSP_USERSP equ 2eh
|
||||||
|
PSP_USERSS equ 30h
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; COUNT
|
||||||
|
; CriticalError(COUNT nFlag, COUNT nDrive, COUNT nError, struct dhdr FAR *lpDevice);
|
||||||
|
;
|
||||||
|
global _CriticalError
|
||||||
|
_CriticalError:
|
||||||
|
;
|
||||||
|
; Skip critical error routine if handler is active
|
||||||
|
;
|
||||||
|
cmp byte [_ErrorMode],0
|
||||||
|
je CritErr05 ; Jump if equal
|
||||||
|
|
||||||
|
mov ax,FAIL
|
||||||
|
retn
|
||||||
|
;
|
||||||
|
; Do local error processing
|
||||||
|
;
|
||||||
|
CritErr05:
|
||||||
|
;
|
||||||
|
; C Entry
|
||||||
|
;
|
||||||
|
push bp
|
||||||
|
mov bp,sp
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
;
|
||||||
|
; Get parameters
|
||||||
|
;
|
||||||
|
mov ah,byte [bp+4] ; nFlags
|
||||||
|
mov al,byte [bp+6] ; nDrive
|
||||||
|
mov di,word [bp+8] ; nError
|
||||||
|
;
|
||||||
|
; make cx:si point to dev header
|
||||||
|
; after registers restored use bp:si
|
||||||
|
;
|
||||||
|
mov si,word [bp+10] ; lpDevice Offset
|
||||||
|
mov cx,word [bp+12] ; lpDevice segment
|
||||||
|
;
|
||||||
|
; Now save real ss:sp and retry info in internal stack
|
||||||
|
;
|
||||||
|
cli
|
||||||
|
mov es,[_cu_psp]
|
||||||
|
push word [es:PSP_USERSS]
|
||||||
|
push word [es:PSP_USERSP]
|
||||||
|
push word [_MachineId]
|
||||||
|
push word [int21regs_seg]
|
||||||
|
push word [int21regs_off]
|
||||||
|
push word [_user_r+2]
|
||||||
|
push word [_user_r]
|
||||||
|
mov [critical_sp],sp
|
||||||
|
;
|
||||||
|
; do some clean up because user may never return
|
||||||
|
;
|
||||||
|
inc byte [_ErrorMode]
|
||||||
|
dec byte [_InDOS]
|
||||||
|
;
|
||||||
|
; switch to user's stack
|
||||||
|
;
|
||||||
|
mov ss,[es:PSP_USERSS]
|
||||||
|
mov bp,[es:PSP_USERSP]
|
||||||
|
RestoreSP
|
||||||
|
Restore386Registers
|
||||||
|
mov bp,cx
|
||||||
|
;
|
||||||
|
; and call critical error handler
|
||||||
|
;
|
||||||
|
int 24h ; DOS Critical error handler
|
||||||
|
|
||||||
|
;
|
||||||
|
; recover context
|
||||||
|
;
|
||||||
|
cld
|
||||||
|
cli
|
||||||
|
mov bp, [cs:_DGROUP_]
|
||||||
|
mov ds,bp
|
||||||
|
mov ss,bp
|
||||||
|
mov sp,[critical_sp]
|
||||||
|
pop word [_user_r]
|
||||||
|
pop word [_user_r+2]
|
||||||
|
pop word [int21regs_off]
|
||||||
|
pop word [int21regs_seg]
|
||||||
|
pop word [_MachineId]
|
||||||
|
mov es,[_cu_psp]
|
||||||
|
pop word [es:PSP_USERSP]
|
||||||
|
pop word [es:PSP_USERSS]
|
||||||
|
mov bp, sp
|
||||||
|
mov ah, byte [bp+4+4] ; restore old AH from nFlags
|
||||||
|
sti ; Enable interrupts
|
||||||
|
;
|
||||||
|
; clear flags
|
||||||
|
;
|
||||||
|
mov byte [_ErrorMode],0
|
||||||
|
inc byte [_InDOS]
|
||||||
|
;
|
||||||
|
; Check for ignore and force fail if not ok
|
||||||
|
cmp al,CONTINUE
|
||||||
|
jne CritErr10 ; not ignore, keep testing
|
||||||
|
test ah,OK_IGNORE
|
||||||
|
jnz CritErr10
|
||||||
|
mov al,FAIL
|
||||||
|
;
|
||||||
|
; Check for retry and force fail if not ok
|
||||||
|
;
|
||||||
|
CritErr10:
|
||||||
|
cmp al,RETRY
|
||||||
|
jne CritErr20 ; not retry, keep testing
|
||||||
|
test ah,OK_RETRY
|
||||||
|
jnz CritErr20
|
||||||
|
mov al,FAIL
|
||||||
|
;
|
||||||
|
; You know the drill, but now it's different.
|
||||||
|
; check for fail and force abort if not ok
|
||||||
|
;
|
||||||
|
CritErr20:
|
||||||
|
cmp al,FAIL
|
||||||
|
jne CritErr30 ; not fail, do exit processing
|
||||||
|
test ah,OK_FAIL
|
||||||
|
jnz CritErr30
|
||||||
|
mov al,ABORT
|
||||||
|
;
|
||||||
|
; OK, if it's abort we do extra processing. Otherwise just
|
||||||
|
; exit.
|
||||||
|
;
|
||||||
|
CritErr30:
|
||||||
|
cmp al,ABORT
|
||||||
|
je CritErrAbort ; process abort
|
||||||
|
|
||||||
|
CritErrExit:
|
||||||
|
xor ah,ah ; clear out top for return
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop bp
|
||||||
|
ret
|
||||||
|
|
||||||
|
;
|
||||||
|
; Abort processing.
|
||||||
|
;
|
||||||
|
CritErrAbort:
|
||||||
|
mov ax,[_cu_psp]
|
||||||
|
mov es,ax
|
||||||
|
cmp ax,[es:PSP_PARENT]
|
||||||
|
mov al,FAIL
|
||||||
|
jz CritErrExit
|
||||||
|
cli
|
||||||
|
mov bp,word [_user_r+2] ;Get frame
|
||||||
|
mov ss,bp
|
||||||
|
mov bp,word [_user_r]
|
||||||
|
mov sp,bp
|
||||||
|
mov byte [_ErrorMode],1 ; flag abort
|
||||||
|
mov ax,4C00h
|
||||||
|
mov [bp+reg_ax],ax
|
||||||
|
sti
|
||||||
|
jmp int21_reentry ; restart the system call
|
95
kernel/error.c
Normal file
95
kernel/error.c
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* error.c */
|
||||||
|
/* */
|
||||||
|
/* Main Kernel Error Handler Functions */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#include "portab.h"
|
||||||
|
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *errorRcsId =
|
||||||
|
"$Id: error.c 709 2003-09-24 19:34:11Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
/* error registers */
|
||||||
|
VOID dump(void)
|
||||||
|
{
|
||||||
|
printf("Register Dump [AH = %02x CS:IP = %04x:%04x FLAGS = %04x]\n",
|
||||||
|
error_regs.AH, error_regs.CS, error_regs.IP, error_regs.FLAGS);
|
||||||
|
printf("AX:%04x BX:%04x CX:%04x DX:%04x\n",
|
||||||
|
error_regs.AX, error_regs.BX, error_regs.CX, error_regs.DX);
|
||||||
|
printf("SI:%04x DI:%04x DS:%04x ES:%04x\n",
|
||||||
|
error_regs.SI, error_regs.DI, error_regs.DS, error_regs.ES);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* issue a panic message for corrupted data structures */
|
||||||
|
VOID panic(BYTE * s)
|
||||||
|
{
|
||||||
|
put_string("\nPANIC: ");
|
||||||
|
put_string(s);
|
||||||
|
put_string("\nSystem halted");
|
||||||
|
for (;;) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef IPL
|
||||||
|
/* issue an internal error message */
|
||||||
|
VOID fatal(BYTE * err_msg)
|
||||||
|
{
|
||||||
|
printf("\nInternal IPL error - %s\nSystem halted\n", err_msg);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* issue an internal error message */
|
||||||
|
#if 0
|
||||||
|
VOID fatal(BYTE * err_msg)
|
||||||
|
{
|
||||||
|
printf("\nInternal kernel error - \n");
|
||||||
|
panic(err_msg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Abort, retry or fail for character devices */
|
||||||
|
COUNT char_error(request * rq, struct dhdr FAR * lpDevice)
|
||||||
|
{
|
||||||
|
CritErrCode = (rq->r_status & S_MASK) + 0x13;
|
||||||
|
return CriticalError(EFLG_CHAR | EFLG_ABORT | EFLG_RETRY | EFLG_IGNORE,
|
||||||
|
0, rq->r_status & S_MASK, lpDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Abort, retry or fail for block devices */
|
||||||
|
COUNT block_error(request * rq, COUNT nDrive, struct dhdr FAR * lpDevice,
|
||||||
|
int mode)
|
||||||
|
{
|
||||||
|
CritErrCode = (rq->r_status & S_MASK) + 0x13;
|
||||||
|
return CriticalError(EFLG_ABORT | EFLG_RETRY | EFLG_IGNORE |
|
||||||
|
(mode == DSKWRITE ? EFLG_WRITE : 0),
|
||||||
|
nDrive, rq->r_status & S_MASK, lpDevice);
|
||||||
|
}
|
||||||
|
|
95
kernel/execrh.asm
Normal file
95
kernel/execrh.asm
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
;
|
||||||
|
; File:
|
||||||
|
; execrh.asm
|
||||||
|
; Description:
|
||||||
|
; request handler for calling device drivers
|
||||||
|
;
|
||||||
|
; Copyright (c) 1995, 1998
|
||||||
|
; Pasquale J. Villani
|
||||||
|
; All Rights Reserved
|
||||||
|
;
|
||||||
|
; This file is part of DOS-C.
|
||||||
|
;
|
||||||
|
; DOS-C is free software; you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation; either version
|
||||||
|
; 2, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; DOS-C is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||||
|
; the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public
|
||||||
|
; License along with DOS-C; see the file COPYING. If not,
|
||||||
|
; write to the Free Software Foundation, 675 Mass Ave,
|
||||||
|
; Cambridge, MA 02139, USA.
|
||||||
|
;
|
||||||
|
; $Id: execrh.asm 1184 2006-05-20 20:49:59Z mceric $
|
||||||
|
;
|
||||||
|
|
||||||
|
%include "segs.inc"
|
||||||
|
%include "stacks.inc"
|
||||||
|
|
||||||
|
segment HMA_TEXT
|
||||||
|
; EXECRH
|
||||||
|
; Execute Device Request
|
||||||
|
;
|
||||||
|
; execrh(rhp, dhp)
|
||||||
|
; request far *rhp;
|
||||||
|
; struct dhdr far *dhp;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; The stack is very critical in here.
|
||||||
|
;
|
||||||
|
global EXECRH
|
||||||
|
global INIT_EXECRH
|
||||||
|
|
||||||
|
%macro EXECRHM 0
|
||||||
|
push bp ; perform c entry
|
||||||
|
mov bp,sp
|
||||||
|
push si
|
||||||
|
push ds ; sp=bp-8
|
||||||
|
|
||||||
|
lds si,[bp+4] ; ds:si = device header
|
||||||
|
les bx,[bp+8] ; es:bx = request header
|
||||||
|
|
||||||
|
|
||||||
|
mov ax, [si+6] ; construct strategy address
|
||||||
|
mov [bp+4], ax
|
||||||
|
|
||||||
|
push si ; the bloody fucking RTSND.DOS
|
||||||
|
push di ; driver destroys SI,DI (tom 14.2.03)
|
||||||
|
|
||||||
|
call far[bp+4] ; call far the strategy
|
||||||
|
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
|
||||||
|
; Protect386Registers ; old free-EMM386 versions destroy regs in their INIT method
|
||||||
|
|
||||||
|
mov ax,[si+8] ; construct 'interrupt' address
|
||||||
|
mov [bp+4],ax ; construct interrupt address
|
||||||
|
call far[bp+4] ; call far the interrupt
|
||||||
|
|
||||||
|
; Restore386Registers ; less stack load and better performance...
|
||||||
|
|
||||||
|
sti ; damm driver turn off ints
|
||||||
|
cld ; has gone backwards
|
||||||
|
pop ds
|
||||||
|
pop si
|
||||||
|
pop bp
|
||||||
|
ret 8
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
EXECRH:
|
||||||
|
EXECRHM
|
||||||
|
|
||||||
|
%ifndef WATCOM
|
||||||
|
|
||||||
|
segment INIT_TEXT
|
||||||
|
|
||||||
|
INIT_EXECRH:
|
||||||
|
EXECRHM
|
||||||
|
|
||||||
|
%endif
|
482
kernel/fatdir.c
Normal file
482
kernel/fatdir.c
Normal file
@ -0,0 +1,482 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* fatdir.c */
|
||||||
|
/* DOS-C */
|
||||||
|
/* */
|
||||||
|
/* FAT File System dir Functions */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#include "portab.h"
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *fatdirRcsId =
|
||||||
|
"$Id: fatdir.c 1561 2011-04-08 15:35:23Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Description.
|
||||||
|
* Initialize a fnode so that it will point to the directory with
|
||||||
|
* dirstart starting cluster; in case of passing dirstart == 0
|
||||||
|
* fnode will point to the start of a root directory */
|
||||||
|
VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart)
|
||||||
|
{
|
||||||
|
/* reset the directory flags */
|
||||||
|
fnp->f_sft_idx = 0xff;
|
||||||
|
fnp->f_dmp = &sda_tmp_dm;
|
||||||
|
if (fnp == &fnode[1])
|
||||||
|
fnp->f_dmp = &sda_tmp_dm_ren;
|
||||||
|
fnp->f_offset = 0l;
|
||||||
|
fnp->f_cluster_offset = 0;
|
||||||
|
|
||||||
|
/* root directory */
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
if (dirstart == 0)
|
||||||
|
if (ISFAT32(fnp->f_dpb))
|
||||||
|
dirstart = fnp->f_dpb->dpb_xrootclst;
|
||||||
|
#endif
|
||||||
|
fnp->f_cluster = fnp->f_dmp->dm_dircluster = dirstart;
|
||||||
|
}
|
||||||
|
|
||||||
|
f_node_ptr dir_open(register const char *dirname, BOOL split, f_node_ptr fnp)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *fcbname;
|
||||||
|
|
||||||
|
/* determine what drive and dpb we are using... */
|
||||||
|
fnp->f_dpb = get_dpb(dirname[0]-'A');
|
||||||
|
/* Perform all directory common handling after all special */
|
||||||
|
/* handling has been performed. */
|
||||||
|
|
||||||
|
/* truename() already did a media check() */
|
||||||
|
|
||||||
|
/* Walk the directory tree to find the starting cluster */
|
||||||
|
/* */
|
||||||
|
/* Start from the root directory (dirstart = 0) */
|
||||||
|
|
||||||
|
/* The CDS's cdsStartCls may be used to shorten the search
|
||||||
|
beginning at the CWD, see mapPath() and CDS.H in order
|
||||||
|
to enable this behaviour there.
|
||||||
|
-- 2001/09/04 ska*/
|
||||||
|
|
||||||
|
dir_init_fnode(fnp, 0);
|
||||||
|
fnp->f_dmp->dm_entry = 0;
|
||||||
|
|
||||||
|
dirname += 2; /* Assume FAT style drive */
|
||||||
|
fcbname = fnp->f_dmp->dm_name_pat;
|
||||||
|
while(*dirname != '\0')
|
||||||
|
{
|
||||||
|
/* skip the path seperator */
|
||||||
|
++dirname;
|
||||||
|
|
||||||
|
/* don't continue if we're at the end: this check is */
|
||||||
|
/* for root directories, the only fully-qualified path */
|
||||||
|
/* names that end in a \ */
|
||||||
|
if (*dirname == '\0')
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Convert the name into an absolute name for */
|
||||||
|
/* comparison... */
|
||||||
|
|
||||||
|
dirname = ConvertNameSZToName83(fcbname, dirname);
|
||||||
|
|
||||||
|
/* do not continue if we split the filename off and are */
|
||||||
|
/* at the end */
|
||||||
|
if (split && *dirname == '\0')
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Now search through the directory to */
|
||||||
|
/* find the entry... */
|
||||||
|
i = FALSE;
|
||||||
|
|
||||||
|
while (dir_read(fnp) == 1)
|
||||||
|
{
|
||||||
|
if (!(fnp->f_dir.dir_attrib & D_VOLID) &&
|
||||||
|
fcbmatch(fcbname, fnp->f_dir.dir_name))
|
||||||
|
{
|
||||||
|
i = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fnp->f_dmp->dm_entry++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!i || !(fnp->f_dir.dir_attrib & D_DIR))
|
||||||
|
{
|
||||||
|
return (f_node_ptr) 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* make certain we've moved off */
|
||||||
|
/* root */
|
||||||
|
dir_init_fnode(fnp, getdstart(fnp->f_dpb, &fnp->f_dir));
|
||||||
|
fnp->f_dmp->dm_entry = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fnp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* swap internal and external delete flags */
|
||||||
|
STATIC void swap_deleted(char *name)
|
||||||
|
{
|
||||||
|
if (name[0] == DELETED || name[0] == EXT_DELETED)
|
||||||
|
name[0] ^= EXT_DELETED - DELETED; /* 0xe0 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Description.
|
||||||
|
* Read next consequitive directory entry, pointed by fnp.
|
||||||
|
* If some error occures the other critical
|
||||||
|
* fields aren't changed, except those used for caching.
|
||||||
|
* The fnp->f_dmp->dm_entry always corresponds to the directory entry
|
||||||
|
* which has been read.
|
||||||
|
* Return value.
|
||||||
|
* 1 - all OK, directory entry having been read is not empty.
|
||||||
|
* 0 - Directory entry is empty.
|
||||||
|
* DE_SEEK - Attempt to read beyound the end of the directory.
|
||||||
|
* DE_BLKINVLD - Invalid block.
|
||||||
|
* Note. Empty directory entries always resides at the end of the directory. */
|
||||||
|
COUNT dir_read(REG f_node_ptr fnp)
|
||||||
|
{
|
||||||
|
struct buffer FAR *bp;
|
||||||
|
REG UWORD secsize = fnp->f_dpb->dpb_secsize;
|
||||||
|
unsigned sector;
|
||||||
|
unsigned entry = fnp->f_dmp->dm_entry;
|
||||||
|
|
||||||
|
/* can't have more than 65535 directory entries */
|
||||||
|
if (entry >= 65535U)
|
||||||
|
return DE_SEEK;
|
||||||
|
|
||||||
|
/* Determine if we hit the end of the directory. If we have, */
|
||||||
|
/* bump the offset back to the end and exit. If not, fill the */
|
||||||
|
/* dirent portion of the fnode, set the SFT_FCLEAN bit and leave,*/
|
||||||
|
/* but only for root directories */
|
||||||
|
|
||||||
|
if (fnp->f_dmp->dm_dircluster == 0)
|
||||||
|
{
|
||||||
|
if (entry >= fnp->f_dpb->dpb_dirents)
|
||||||
|
return DE_SEEK;
|
||||||
|
|
||||||
|
fnp->f_dirsector = entry / (secsize / DIRENT_SIZE) +
|
||||||
|
fnp->f_dpb->dpb_dirstrt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Do a "seek" to the directory position */
|
||||||
|
fnp->f_offset = entry * (ULONG)DIRENT_SIZE;
|
||||||
|
|
||||||
|
/* Search through the FAT to find the block */
|
||||||
|
/* that this entry is in. */
|
||||||
|
if (map_cluster(fnp, XFR_READ) != SUCCESS)
|
||||||
|
return DE_SEEK;
|
||||||
|
|
||||||
|
/* Compute the block within the cluster and the */
|
||||||
|
/* offset within the block. */
|
||||||
|
sector = (UBYTE)(fnp->f_offset / secsize) & fnp->f_dpb->dpb_clsmask;
|
||||||
|
|
||||||
|
fnp->f_dirsector = clus2phys(fnp->f_cluster, fnp->f_dpb) + sector;
|
||||||
|
/* Get the block we need from cache */
|
||||||
|
}
|
||||||
|
|
||||||
|
bp = getblock(fnp->f_dirsector, fnp->f_dpb->dpb_unit);
|
||||||
|
|
||||||
|
#ifdef DISPLAY_GETBLOCK
|
||||||
|
printf("DIR (dir_read)\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Now that we have the block for our entry, get the */
|
||||||
|
/* directory entry. */
|
||||||
|
if (bp == NULL)
|
||||||
|
return DE_BLKINVLD;
|
||||||
|
|
||||||
|
bp->b_flag &= ~(BFR_DATA | BFR_FAT);
|
||||||
|
bp->b_flag |= BFR_DIR | BFR_VALID;
|
||||||
|
|
||||||
|
fnp->f_diridx = entry % (secsize / DIRENT_SIZE);
|
||||||
|
getdirent(&bp->b_buffer[fnp->f_diridx * DIRENT_SIZE], &fnp->f_dir);
|
||||||
|
|
||||||
|
swap_deleted(fnp->f_dir.dir_name);
|
||||||
|
|
||||||
|
/* and for efficiency, stop when we hit the first */
|
||||||
|
/* unused entry. */
|
||||||
|
/* either returns 1 or 0 */
|
||||||
|
return (fnp->f_dir.dir_name[0] != '\0');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Description.
|
||||||
|
* Writes directory entry pointed by fnp to disk. In case of erroneous
|
||||||
|
* situation fnode is released.
|
||||||
|
* The caller should set
|
||||||
|
* 1. F_DMOD flag if original directory entry was modified.
|
||||||
|
* Return value.
|
||||||
|
* TRUE - all OK.
|
||||||
|
* FALSE - error occured (fnode is released).
|
||||||
|
*/
|
||||||
|
BOOL dir_write_update(REG f_node_ptr fnp, BOOL update)
|
||||||
|
{
|
||||||
|
struct buffer FAR *bp;
|
||||||
|
UBYTE FAR *vp;
|
||||||
|
|
||||||
|
/* Update the entry if it was modified by a write or create... */
|
||||||
|
if (!update || (fnp->f_flags & (SFT_FCLEAN|SFT_FDATE)) != SFT_FCLEAN)
|
||||||
|
{
|
||||||
|
bp = getblock(fnp->f_dirsector, fnp->f_dpb->dpb_unit);
|
||||||
|
|
||||||
|
/* Now that we have a block, transfer the directory */
|
||||||
|
/* entry into the block. */
|
||||||
|
if (bp == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
#ifdef DISPLAY_GETBLOCK
|
||||||
|
printf("DIR (dir_write)\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
swap_deleted(fnp->f_dir.dir_name);
|
||||||
|
|
||||||
|
vp = &bp->b_buffer[fnp->f_diridx * DIRENT_SIZE];
|
||||||
|
|
||||||
|
if (update)
|
||||||
|
{
|
||||||
|
/* only update fields that are also in the SFT, for dos_close/commit */
|
||||||
|
fmemcpy(&vp[DIR_NAME], fnp->f_dir.dir_name, FNAME_SIZE + FEXT_SIZE);
|
||||||
|
fputbyte(&vp[DIR_ATTRIB], fnp->f_dir.dir_attrib);
|
||||||
|
fputword(&vp[DIR_TIME], fnp->f_dir.dir_time);
|
||||||
|
fputword(&vp[DIR_DATE], fnp->f_dir.dir_date);
|
||||||
|
fputword(&vp[DIR_START], fnp->f_dir.dir_start);
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
if (ISFAT32(fnp->f_dpb))
|
||||||
|
fputword(&vp[DIR_START_HIGH], fnp->f_dir.dir_start_high);
|
||||||
|
#endif
|
||||||
|
fputlong(&vp[DIR_SIZE], fnp->f_dir.dir_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
putdirent(&fnp->f_dir, vp);
|
||||||
|
}
|
||||||
|
|
||||||
|
swap_deleted(fnp->f_dir.dir_name);
|
||||||
|
|
||||||
|
bp->b_flag &= ~(BFR_DATA | BFR_FAT);
|
||||||
|
bp->b_flag |= BFR_DIR | BFR_DIRTY | BFR_VALID;
|
||||||
|
}
|
||||||
|
/* Clear buffers after directory write or DOS close */
|
||||||
|
return flush_buffers(fnp->f_dpb->dpb_unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef IPL
|
||||||
|
COUNT dos_findfirst(UCOUNT attr, BYTE * name)
|
||||||
|
{
|
||||||
|
REG f_node_ptr fnp;
|
||||||
|
REG dmatch *dmp = &sda_tmp_dm;
|
||||||
|
|
||||||
|
/* printf("ff %Fs\n", name);*/
|
||||||
|
|
||||||
|
/* The findfirst/findnext calls are probably the worst of the */
|
||||||
|
/* DOS calls. They must work somewhat on the fly (i.e. - open */
|
||||||
|
/* but never close). The near fnodes now work this way. Every */
|
||||||
|
/* time a directory is searched, we will initialize the DOS */
|
||||||
|
/* dirmatch structure and then for every find, we will open the */
|
||||||
|
/* current directory, do a seek and read. */
|
||||||
|
|
||||||
|
/* first: findfirst("D:\\") returns DE_NFILES */
|
||||||
|
if (name[3] == '\0')
|
||||||
|
return DE_NFILES;
|
||||||
|
|
||||||
|
/* Now open this directory so that we can read the */
|
||||||
|
/* fnode entry and do a match on it. */
|
||||||
|
if ((fnp = split_path(name, &fnode[0])) == NULL)
|
||||||
|
return DE_PATHNOTFND;
|
||||||
|
|
||||||
|
/* Now search through the directory to find the entry... */
|
||||||
|
|
||||||
|
/* Special handling - the volume id is only in the root */
|
||||||
|
/* directory and only searched for once. So we need to open */
|
||||||
|
/* the root and return only the first entry that contains the */
|
||||||
|
/* volume id bit set (while ignoring LFN entries). */
|
||||||
|
/* RBIL: ignore ReaDONLY and ARCHIVE bits but DEVICE ignored too*/
|
||||||
|
/* For compatibility with bad search requests, only treat as */
|
||||||
|
/* volume search if only volume bit set, else ignore it. */
|
||||||
|
if ((attr & ~(D_RDONLY | D_ARCHIVE | D_DEVICE)) == D_VOLID)
|
||||||
|
/* if ONLY label wanted redirect search to root dir */
|
||||||
|
dir_init_fnode(fnp, 0);
|
||||||
|
|
||||||
|
/* Now further initialize the dirmatch structure. */
|
||||||
|
dmp->dm_drive = name[0] - 'A';
|
||||||
|
dmp->dm_attr_srch = attr;
|
||||||
|
|
||||||
|
return dos_findnext();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
BUGFIX TE 06/28/01
|
||||||
|
|
||||||
|
when using FcbFindXxx, the only information available is
|
||||||
|
the cluster number + entrycount. everything else MUST\
|
||||||
|
be recalculated.
|
||||||
|
a good test for this is MSDOS CHKDSK, which now (seems too) work
|
||||||
|
*/
|
||||||
|
|
||||||
|
COUNT dos_findnext(void)
|
||||||
|
{
|
||||||
|
REG f_node_ptr fnp;
|
||||||
|
REG dmatch *dmp;
|
||||||
|
|
||||||
|
/* Select the default to help non-drive specified path */
|
||||||
|
/* searches... */
|
||||||
|
fnp = &fnode[0];
|
||||||
|
dmp = &sda_tmp_dm;
|
||||||
|
fnp->f_dpb = get_dpb(dmp->dm_drive);
|
||||||
|
if (media_check(fnp->f_dpb) < 0)
|
||||||
|
return DE_NFILES;
|
||||||
|
|
||||||
|
dir_init_fnode(fnp, dmp->dm_dircluster);
|
||||||
|
|
||||||
|
/* Search through the directory to find the entry, but do a */
|
||||||
|
/* seek first. */
|
||||||
|
/* Loop through the directory */
|
||||||
|
while (dir_read(fnp) == 1)
|
||||||
|
{
|
||||||
|
++dmp->dm_entry;
|
||||||
|
if (fnp->f_dir.dir_name[0] != DELETED
|
||||||
|
&& (fnp->f_dir.dir_attrib & D_LFN) != D_LFN)
|
||||||
|
{
|
||||||
|
if (fcmp_wild(dmp->dm_name_pat, fnp->f_dir.dir_name, FNAME_SIZE + FEXT_SIZE))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
MSD Command.com uses FCB FN 11 & 12 with attrib set to 0x16.
|
||||||
|
Bits 0x21 seem to get set some where in MSD so Rd and Arc
|
||||||
|
files are returned.
|
||||||
|
RdOnly + Archive bits are ignored
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Test the attribute as the final step */
|
||||||
|
/* It's either a special volume label search or an */
|
||||||
|
/* attribute inclusive search. The attribute inclusive search */
|
||||||
|
/* can also find volume labels if you set e.g. D_DIR|D_VOLUME */
|
||||||
|
UBYTE attr_srch;
|
||||||
|
attr_srch = dmp->dm_attr_srch & ~(D_RDONLY | D_ARCHIVE | D_DEVICE);
|
||||||
|
if (attr_srch == D_VOLID)
|
||||||
|
{
|
||||||
|
if (!(fnp->f_dir.dir_attrib & D_VOLID))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (~attr_srch & (D_DIR | D_SYSTEM | D_HIDDEN | D_VOLID) &
|
||||||
|
fnp->f_dir.dir_attrib)
|
||||||
|
continue;
|
||||||
|
/* If found, transfer it to the dmatch structure */
|
||||||
|
memcpy(&SearchDir, &fnp->f_dir, sizeof(struct dirent));
|
||||||
|
/* return the result */
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("dos_findnext: %11s\n", fnp->f_dir.dir_name);
|
||||||
|
#endif
|
||||||
|
/* return the result */
|
||||||
|
return DE_NFILES;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
this receives a name in 11 char field NAME+EXT and builds
|
||||||
|
a zeroterminated string
|
||||||
|
|
||||||
|
unfortunately, blanks are allowed in filenames. like
|
||||||
|
"test e", " test .y z",...
|
||||||
|
|
||||||
|
so we have to work from the last blank backward
|
||||||
|
*/
|
||||||
|
void ConvertName83ToNameSZ(BYTE FAR * destSZ, BYTE FAR * srcFCBName)
|
||||||
|
{
|
||||||
|
int loop;
|
||||||
|
int noExtension = FALSE;
|
||||||
|
|
||||||
|
if (*srcFCBName == '.')
|
||||||
|
{
|
||||||
|
noExtension = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fmemcpy(destSZ, srcFCBName, FNAME_SIZE);
|
||||||
|
|
||||||
|
srcFCBName += FNAME_SIZE;
|
||||||
|
|
||||||
|
for (loop = FNAME_SIZE; --loop >= 0;)
|
||||||
|
{
|
||||||
|
if (destSZ[loop] != ' ')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
destSZ += loop + 1;
|
||||||
|
|
||||||
|
if (!noExtension) /* not for ".", ".." */
|
||||||
|
{
|
||||||
|
|
||||||
|
for (loop = FEXT_SIZE; --loop >= 0;)
|
||||||
|
{
|
||||||
|
if (srcFCBName[loop] != ' ')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (loop >= 0)
|
||||||
|
{
|
||||||
|
*destSZ++ = '.';
|
||||||
|
fmemcpy(destSZ, srcFCBName, loop + 1);
|
||||||
|
destSZ += loop + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*destSZ = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/*
|
||||||
|
returns the asciiSZ length of a 8.3 filename
|
||||||
|
*/
|
||||||
|
|
||||||
|
int FileName83Length(BYTE * filename83)
|
||||||
|
{
|
||||||
|
BYTE buff[13];
|
||||||
|
|
||||||
|
ConvertName83ToNameSZ(buff, filename83);
|
||||||
|
|
||||||
|
return strlen(buff);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* this routine converts a name portion of a fully qualified path */
|
||||||
|
/* name, so . and .. are not allowed, only straightforward 8+3 names */
|
||||||
|
const char *ConvertNameSZToName83(char *fcbname, const char *dirname)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
memset(fcbname, ' ', FNAME_SIZE + FEXT_SIZE);
|
||||||
|
|
||||||
|
for (i = 0; i < FNAME_SIZE + FEXT_SIZE; i++, dirname++)
|
||||||
|
{
|
||||||
|
char c = *dirname;
|
||||||
|
if (c == '.')
|
||||||
|
i = FNAME_SIZE - 1;
|
||||||
|
else if (c != '\0' && c != '\\')
|
||||||
|
fcbname[i] = c;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return dirname;
|
||||||
|
}
|
||||||
|
|
1870
kernel/fatfs.c
Normal file
1870
kernel/fatfs.c
Normal file
File diff suppressed because it is too large
Load Diff
413
kernel/fattab.c
Normal file
413
kernel/fattab.c
Normal file
@ -0,0 +1,413 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* fattab.c */
|
||||||
|
/* */
|
||||||
|
/* FAT File System Table Functions */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#include "portab.h"
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *RcsId =
|
||||||
|
"$Id: fattab.c 1631 2011-06-13 16:27:34Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* cluster/sector routines */
|
||||||
|
/* */
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
/* special "impossible" "Cluster2" value of 1 denotes reading the
|
||||||
|
cluster number rather than overwriting it */
|
||||||
|
#define READ_CLUSTER 1
|
||||||
|
|
||||||
|
#ifndef ISFAT32
|
||||||
|
int ISFAT32(struct dpb FAR * dpbp)
|
||||||
|
{
|
||||||
|
return _ISFAT32(dpbp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void clusterMessage(const char * msg, CLUSTER clussec)
|
||||||
|
{
|
||||||
|
put_string("Run chkdsk: Bad FAT ");
|
||||||
|
put_string(msg);
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
put_unsigned((unsigned)(clussec >> 16), 16, 4);
|
||||||
|
#endif
|
||||||
|
put_unsigned((unsigned)(clussec & 0xffffu), 16, 4);
|
||||||
|
put_console('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
struct buffer FAR *getFATblock(struct dpb FAR * dpbp, CLUSTER clussec)
|
||||||
|
{
|
||||||
|
/* *** why dpbp->dpb_unit? only useful to know in context of the dpbp...? *** */
|
||||||
|
struct buffer FAR *bp = getblock(clussec, dpbp->dpb_unit);
|
||||||
|
|
||||||
|
if (bp)
|
||||||
|
{
|
||||||
|
bp->b_flag &= ~(BFR_DATA | BFR_DIR);
|
||||||
|
bp->b_flag |= BFR_FAT | BFR_VALID;
|
||||||
|
bp->b_dpbp = dpbp;
|
||||||
|
bp->b_copies = dpbp->dpb_fats;
|
||||||
|
bp->b_offset = dpbp->dpb_fatsize; /* 0 for FAT32 but blockio.c knows that */
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
if (ISFAT32(dpbp))
|
||||||
|
{
|
||||||
|
if (dpbp->dpb_xflags & FAT_NO_MIRRORING)
|
||||||
|
bp->b_copies = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
clusterMessage("I/O: 0x",clussec);
|
||||||
|
}
|
||||||
|
return bp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
void read_fsinfo(struct dpb FAR * dpbp)
|
||||||
|
{
|
||||||
|
struct buffer FAR *bp;
|
||||||
|
struct fsinfo FAR *fip;
|
||||||
|
CLUSTER cluster;
|
||||||
|
|
||||||
|
if (dpbp->dpb_xfsinfosec == 0xffff)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bp = getblock(dpbp->dpb_xfsinfosec, dpbp->dpb_unit);
|
||||||
|
bp->b_flag &= ~(BFR_DATA | BFR_DIR | BFR_FAT | BFR_DIRTY);
|
||||||
|
bp->b_flag |= BFR_VALID;
|
||||||
|
|
||||||
|
fip = (struct fsinfo FAR *)&bp->b_buffer[0x1e4];
|
||||||
|
/* need to range check values because they may not be correct */
|
||||||
|
cluster = fip->fi_nfreeclst;
|
||||||
|
if (cluster >= dpbp->dpb_xsize)
|
||||||
|
cluster = XUNKNCLSTFREE;
|
||||||
|
dpbp->dpb_xnfreeclst = cluster;
|
||||||
|
cluster = fip->fi_cluster;
|
||||||
|
if (cluster < 2 || cluster > dpbp->dpb_xsize)
|
||||||
|
cluster = UNKNCLUSTER;
|
||||||
|
dpbp->dpb_xcluster = cluster;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_fsinfo(struct dpb FAR * dpbp)
|
||||||
|
{
|
||||||
|
struct buffer FAR *bp;
|
||||||
|
struct fsinfo FAR *fip;
|
||||||
|
|
||||||
|
if (dpbp->dpb_xfsinfosec == 0xffff)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bp = getblock(dpbp->dpb_xfsinfosec, dpbp->dpb_unit);
|
||||||
|
bp->b_flag &= ~(BFR_DATA | BFR_DIR | BFR_FAT);
|
||||||
|
bp->b_flag |= BFR_VALID;
|
||||||
|
|
||||||
|
fip = (struct fsinfo FAR *)&bp->b_buffer[0x1e4];
|
||||||
|
|
||||||
|
if (fip->fi_nfreeclst != dpbp->dpb_xnfreeclst ||
|
||||||
|
fip->fi_cluster != dpbp->dpb_xcluster)
|
||||||
|
bp->b_flag |= BFR_DIRTY; /* only flag for update if we had real news */
|
||||||
|
|
||||||
|
fip->fi_nfreeclst = dpbp->dpb_xnfreeclst;
|
||||||
|
fip->fi_cluster = dpbp->dpb_xcluster;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* The FAT file system is difficult to trace through FAT table. */
|
||||||
|
/* There are two kinds of FATs, 12 bit and 16 bit. The 16 bit */
|
||||||
|
/* FAT is the easiest, since it is nothing more than a series */
|
||||||
|
/* of UWORDs. The 12 bit FAT is difficult, because it packs 3 */
|
||||||
|
/* FAT entries into two BYTEs. These are packed as follows: */
|
||||||
|
/* */
|
||||||
|
/* 0x0003 0x0004 0x0005 0x0006 0x0007 0x0008 0x0009 ... */
|
||||||
|
/* */
|
||||||
|
/* are packed as */
|
||||||
|
/* */
|
||||||
|
/* 0x03 0x40 0x00 0x05 0x60 0x00 0x07 0x80 0x00 0x09 ... */
|
||||||
|
/* */
|
||||||
|
/* 12 bytes are compressed to 9 bytes */
|
||||||
|
/* */
|
||||||
|
|
||||||
|
/* either read the value at Cluster1 (if Cluster2 is READ_CLUSTER) */
|
||||||
|
/* or write the Cluster2 value to the FAT entry at Cluster1 */
|
||||||
|
/* Read is always via next_cluster wrapper which has extra checks */
|
||||||
|
/* It might make sense to manually check old values before a write */
|
||||||
|
/* returns: the cluster number (or 1 on error) for read mode */
|
||||||
|
/* returns: SUCCESS (or 1 on error) for write mode */
|
||||||
|
CLUSTER link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||||
|
REG CLUSTER Cluster2)
|
||||||
|
{
|
||||||
|
struct buffer FAR *bp;
|
||||||
|
unsigned idx;
|
||||||
|
unsigned secdiv; /* FAT entries per sector; nibbles for FAT12! */
|
||||||
|
unsigned char wasfree;
|
||||||
|
CLUSTER clussec = Cluster1;
|
||||||
|
CLUSTER max_cluster = dpbp->dpb_size;
|
||||||
|
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
if (ISFAT32(dpbp))
|
||||||
|
max_cluster = dpbp->dpb_xsize;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (clussec <= 1 || clussec > max_cluster) /* try to read out of range? */
|
||||||
|
{
|
||||||
|
clusterMessage("index: 0x",clussec); /* bad array offset */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cluster2 can 0 (FREE) or 1 (READ_CLUSTER), a cluster nr. >= 2, */
|
||||||
|
/* (range check this case!) LONG_LAST_CLUSTER or LONG_BAD here... */
|
||||||
|
if (Cluster2 < LONG_BAD && Cluster2 > max_cluster) /* writing bad value? */
|
||||||
|
{
|
||||||
|
clusterMessage("write: 0x",Cluster2); /* refuse to write bad value */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
secdiv = dpbp->dpb_secsize;
|
||||||
|
if (ISFAT12(dpbp))
|
||||||
|
{
|
||||||
|
clussec = (unsigned)clussec * 3;
|
||||||
|
secdiv *= 2;
|
||||||
|
}
|
||||||
|
else /* FAT16 or FAT32 */
|
||||||
|
{
|
||||||
|
secdiv /= 2;
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
if (ISFAT32(dpbp))
|
||||||
|
secdiv /= 2;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* idx is a pointer to an index which is the nibble offset of the FAT
|
||||||
|
entry within the sector for FAT12, or word offset for FAT16, or
|
||||||
|
dword offset for FAT32 */
|
||||||
|
idx = (unsigned)(clussec % secdiv);
|
||||||
|
clussec /= secdiv;
|
||||||
|
clussec += dpbp->dpb_fatstrt;
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
if (ISFAT32(dpbp) && (dpbp->dpb_xflags & FAT_NO_MIRRORING))
|
||||||
|
{
|
||||||
|
/* we must modify the active fat,
|
||||||
|
it's number is in the 0-3 bits of dpb_xflags */
|
||||||
|
clussec += (dpbp->dpb_xflags & 0xf) * dpbp->dpb_xfatsize;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get the block that this cluster is in */
|
||||||
|
bp = getFATblock(dpbp, clussec);
|
||||||
|
|
||||||
|
if (bp == NULL) {
|
||||||
|
return 1; /* the only error code possible here */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ISFAT12(dpbp))
|
||||||
|
{
|
||||||
|
REG UBYTE FAR *fbp0, FAR * fbp1;
|
||||||
|
struct buffer FAR * bp1;
|
||||||
|
unsigned cluster, cluster2;
|
||||||
|
|
||||||
|
/* form an index so that we can read the block as a */
|
||||||
|
/* byte array */
|
||||||
|
idx /= 2;
|
||||||
|
|
||||||
|
/* Test to see if the cluster straddles the block. If */
|
||||||
|
/* it does, get the next block and use both to form the */
|
||||||
|
/* the FAT word. Otherwise, just point to the next */
|
||||||
|
/* block. */
|
||||||
|
fbp0 = &bp->b_buffer[idx];
|
||||||
|
|
||||||
|
/* pointer to next byte, will be overwritten, if not valid */
|
||||||
|
fbp1 = fbp0 + 1;
|
||||||
|
|
||||||
|
if (idx >= (unsigned)dpbp->dpb_secsize - 1)
|
||||||
|
{
|
||||||
|
/* blockio.c LRU logic ensures that bp != bp1 */
|
||||||
|
bp1 = getFATblock(dpbp, (unsigned)clussec + 1);
|
||||||
|
if (bp1 == 0)
|
||||||
|
return 1; /* the only error code possible here */
|
||||||
|
|
||||||
|
if (Cluster2 != READ_CLUSTER)
|
||||||
|
bp1->b_flag |= BFR_DIRTY | BFR_VALID;
|
||||||
|
|
||||||
|
fbp1 = &bp1->b_buffer[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
cluster = *fbp0 | (*fbp1 << 8);
|
||||||
|
{
|
||||||
|
unsigned res = cluster;
|
||||||
|
|
||||||
|
/* Now to unpack the contents of the FAT entry. Odd and */
|
||||||
|
/* even bytes are packed differently. */
|
||||||
|
|
||||||
|
if (Cluster1 & 0x01)
|
||||||
|
cluster >>= 4;
|
||||||
|
cluster &= 0x0fff;
|
||||||
|
|
||||||
|
if ((unsigned)Cluster2 == READ_CLUSTER)
|
||||||
|
{
|
||||||
|
if (cluster >= MASK12)
|
||||||
|
return LONG_LAST_CLUSTER;
|
||||||
|
if (cluster == BAD12)
|
||||||
|
return LONG_BAD;
|
||||||
|
return cluster;
|
||||||
|
}
|
||||||
|
|
||||||
|
wasfree = 0;
|
||||||
|
if (cluster == FREE)
|
||||||
|
wasfree = 1;
|
||||||
|
|
||||||
|
cluster = res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cluster2 may be set to LONG_LAST_CLUSTER == 0x0FFFFFFFUL or 0xFFFF */
|
||||||
|
/* -- please don't remove this mask! */
|
||||||
|
cluster2 = (unsigned)Cluster2 & 0x0fff;
|
||||||
|
|
||||||
|
/* Now pack the value in */
|
||||||
|
if ((unsigned)Cluster1 & 0x01)
|
||||||
|
{
|
||||||
|
cluster &= 0x000f;
|
||||||
|
cluster2 <<= 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cluster &= 0xf000;
|
||||||
|
}
|
||||||
|
cluster |= cluster2;
|
||||||
|
*fbp0 = (UBYTE)cluster;
|
||||||
|
*fbp1 = (UBYTE)(cluster >> 8);
|
||||||
|
}
|
||||||
|
else if (ISFAT16(dpbp))
|
||||||
|
{
|
||||||
|
/* form an index so that we can read the block as a */
|
||||||
|
/* byte array */
|
||||||
|
/* and get the cluster number */
|
||||||
|
UWORD res = fgetword(&bp->b_buffer[idx * 2]);
|
||||||
|
if ((unsigned)Cluster2 == READ_CLUSTER)
|
||||||
|
{
|
||||||
|
if (res >= MASK16)
|
||||||
|
return LONG_LAST_CLUSTER;
|
||||||
|
if (res == BAD16)
|
||||||
|
return LONG_BAD;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
/* Finally, put the word into the buffer and mark the */
|
||||||
|
/* buffer as dirty. */
|
||||||
|
fputword(&bp->b_buffer[idx * 2], (UWORD)Cluster2);
|
||||||
|
wasfree = 0;
|
||||||
|
if (res == FREE)
|
||||||
|
wasfree = 1;
|
||||||
|
}
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
else if (ISFAT32(dpbp))
|
||||||
|
{
|
||||||
|
/* form an index so that we can read the block as a */
|
||||||
|
/* byte array */
|
||||||
|
UDWORD res = fgetlong(&bp->b_buffer[idx * 4]) & LONG_LAST_CLUSTER;
|
||||||
|
if (Cluster2 == READ_CLUSTER)
|
||||||
|
{
|
||||||
|
if (res > LONG_BAD)
|
||||||
|
return LONG_LAST_CLUSTER;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
/* Finally, put the word into the buffer and mark the */
|
||||||
|
/* buffer as dirty. */
|
||||||
|
fputlong(&bp->b_buffer[idx * 4], Cluster2 & LONG_LAST_CLUSTER);
|
||||||
|
wasfree = 0;
|
||||||
|
if (res == FREE)
|
||||||
|
wasfree = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
put_string("Bad DPB!\n"); /* FAT1x size field > 65525U (see fat.h) */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update the free space count */
|
||||||
|
bp->b_flag |= BFR_DIRTY | BFR_VALID;
|
||||||
|
if (Cluster2 == FREE || wasfree)
|
||||||
|
{
|
||||||
|
int adjust = 0;
|
||||||
|
if (!wasfree)
|
||||||
|
adjust = 1;
|
||||||
|
else if (Cluster2 != FREE)
|
||||||
|
adjust = -1;
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
if (ISFAT32(dpbp) && dpbp->dpb_xnfreeclst != XUNKNCLSTFREE)
|
||||||
|
{
|
||||||
|
/* update the free space count for returned */
|
||||||
|
/* cluster */
|
||||||
|
dpbp->dpb_xnfreeclst += adjust;
|
||||||
|
write_fsinfo(dpbp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (dpbp->dpb_nfreeclst != UNKNCLSTFREE)
|
||||||
|
dpbp->dpb_nfreeclst += adjust;
|
||||||
|
}
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given the disk parameters, and a cluster number, this function */
|
||||||
|
/* looks at the FAT, and returns the next cluster in the clain or */
|
||||||
|
/* 0 if there is no chain, 1 on error, LONG_LAST_CLUSTER at end. */
|
||||||
|
CLUSTER next_cluster(struct dpb FAR * dpbp, CLUSTER ClusterNum)
|
||||||
|
{
|
||||||
|
CLUSTER candidate, following, max_cluster;
|
||||||
|
candidate = link_fat(dpbp, ClusterNum, READ_CLUSTER);
|
||||||
|
/* empty (0) error (1) bad (LONG_BAD) last (>LONG_BAD) need no checks */
|
||||||
|
#if 0
|
||||||
|
if (candidate == ClusterNum)
|
||||||
|
return 1; /* chain has a tiny loop - easy but boring error check */
|
||||||
|
#endif
|
||||||
|
if (candidate < 2 || candidate >= LONG_BAD)
|
||||||
|
return candidate;
|
||||||
|
max_cluster = dpbp->dpb_size;
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
if (ISFAT32(dpbp))
|
||||||
|
max_cluster = dpbp->dpb_xsize;
|
||||||
|
#endif
|
||||||
|
/* FAT entry points to a possibly invalid next cluster */
|
||||||
|
following = link_fat(dpbp, candidate, READ_CLUSTER);
|
||||||
|
if (following<2 || (following < LONG_BAD && following > max_cluster))
|
||||||
|
{
|
||||||
|
/* chain must not contain free or out of range clusters */
|
||||||
|
clusterMessage("value: 0x",following); /* read returned bad value */
|
||||||
|
return 1; /* only possible error code here */
|
||||||
|
}
|
||||||
|
/* without checking "following", a chain can dangle to a free cluster: */
|
||||||
|
/* if that cluster is later used by another chain, you get cross links */
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if the selected cluster is free (faster than next_cluster) */
|
||||||
|
BOOL is_free_cluster(struct dpb FAR * dpbp, CLUSTER ClusterNum)
|
||||||
|
{
|
||||||
|
return (link_fat(dpbp, ClusterNum, READ_CLUSTER) == FREE);
|
||||||
|
}
|
713
kernel/fcbfns.c
Normal file
713
kernel/fcbfns.c
Normal file
@ -0,0 +1,713 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* fcbfns.c */
|
||||||
|
/* */
|
||||||
|
/* Old CP/M Style Function Handlers for Kernel */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#include "portab.h"
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *RcsId =
|
||||||
|
"$Id: fcbfns.c 1405 2009-05-26 20:44:44Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FCB_SUCCESS 0
|
||||||
|
#define FCB_ERR_NODATA 1
|
||||||
|
#define FCB_ERR_SEGMENT_WRAP 2
|
||||||
|
#define FCB_ERR_EOF 3
|
||||||
|
#define FCB_ERROR 0xff
|
||||||
|
|
||||||
|
STATIC fcb FAR *ExtFcbToFcb(xfcb FAR * lpExtFcb);
|
||||||
|
STATIC fcb FAR *CommonFcbInit(xfcb FAR * lpExtFcb, BYTE * pszBuffer,
|
||||||
|
COUNT * pCurDrive);
|
||||||
|
STATIC void FcbNameInit(fcb FAR * lpFcb, BYTE * pszBuffer, COUNT * pCurDrive);
|
||||||
|
STATIC void FcbNextRecord(fcb FAR * lpFcb);
|
||||||
|
STATIC void FcbCalcRec(xfcb FAR * lpXfcb);
|
||||||
|
|
||||||
|
#define TestCmnSeps(lpFileName) (*lpFileName && strchr(":<|>+=,", *lpFileName) != NULL)
|
||||||
|
#define TestFieldSeps(lpFileName) ((unsigned char)*lpFileName <= ' ' || strchr("/\"[]<>|.", *lpFileName) != NULL)
|
||||||
|
|
||||||
|
static dmatch Dmatch;
|
||||||
|
|
||||||
|
BYTE FAR *FatGetDrvData(UBYTE drive, UBYTE * pspc, UWORD * bps, UWORD * nc)
|
||||||
|
{
|
||||||
|
static BYTE mdb;
|
||||||
|
UWORD spc;
|
||||||
|
|
||||||
|
/* get the data available from dpb */
|
||||||
|
spc = DosGetFree(drive, NULL, bps, nc);
|
||||||
|
if (spc != 0xffff)
|
||||||
|
{
|
||||||
|
struct dpb FAR *dpbp = get_dpb(drive == 0 ? default_drive : drive - 1);
|
||||||
|
/* Point to the media desctriptor for this drive */
|
||||||
|
*pspc = (UBYTE)spc;
|
||||||
|
if (dpbp == NULL)
|
||||||
|
{
|
||||||
|
mdb = spc >> 8;
|
||||||
|
spc &= 0xff;
|
||||||
|
return &mdb;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (BYTE FAR *) & (dpbp->dpb_mdb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PARSE_SEP_STOP 0x01
|
||||||
|
#define PARSE_DFLT_DRIVE 0x02
|
||||||
|
#define PARSE_BLNK_FNAME 0x04
|
||||||
|
#define PARSE_BLNK_FEXT 0x08
|
||||||
|
|
||||||
|
#define PARSE_RET_NOWILD 0
|
||||||
|
#define PARSE_RET_WILD 1
|
||||||
|
#define PARSE_RET_BADDRIVE 0xff
|
||||||
|
|
||||||
|
#ifndef IPL
|
||||||
|
UWORD FcbParseFname(UBYTE *wTestMode, const BYTE FAR * lpFileName, fcb FAR * lpFcb)
|
||||||
|
{
|
||||||
|
WORD wRetCodeName = FALSE, wRetCodeExt = FALSE;
|
||||||
|
|
||||||
|
/* pjv -- ExtFcbToFcb? */
|
||||||
|
if (!(*wTestMode & PARSE_SEP_STOP))
|
||||||
|
{
|
||||||
|
lpFileName = ParseSkipWh(lpFileName);
|
||||||
|
if (TestCmnSeps(lpFileName))
|
||||||
|
++lpFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Undocumented "feature," we skip white space anyway */
|
||||||
|
lpFileName = ParseSkipWh(lpFileName);
|
||||||
|
|
||||||
|
/* Now check for drive specification */
|
||||||
|
if (*(lpFileName + 1) == ':')
|
||||||
|
{
|
||||||
|
/* non-portable construct to be changed */
|
||||||
|
REG UBYTE Drive = DosUpFChar(*lpFileName) - 'A';
|
||||||
|
|
||||||
|
if (get_cds(Drive) == NULL)
|
||||||
|
{
|
||||||
|
*wTestMode = PARSE_RET_BADDRIVE;
|
||||||
|
return FP_OFF(lpFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
lpFcb->fcb_drive = Drive + 1;
|
||||||
|
lpFileName += 2;
|
||||||
|
} else if (!(*wTestMode & PARSE_DFLT_DRIVE)) {
|
||||||
|
lpFcb->fcb_drive = FDFLT_DRIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Undocumented behavior, set record number & record size to 0 */
|
||||||
|
lpFcb->fcb_cublock = lpFcb->fcb_recsiz = 0;
|
||||||
|
|
||||||
|
if (!(*wTestMode & PARSE_BLNK_FNAME))
|
||||||
|
{
|
||||||
|
fmemset(lpFcb->fcb_fname, ' ', FNAME_SIZE);
|
||||||
|
}
|
||||||
|
if (!(*wTestMode & PARSE_BLNK_FEXT))
|
||||||
|
{
|
||||||
|
fmemset(lpFcb->fcb_fext, ' ', FEXT_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* special cases: '.' and '..' */
|
||||||
|
if (*lpFileName == '.')
|
||||||
|
{
|
||||||
|
lpFcb->fcb_fname[0] = '.';
|
||||||
|
++lpFileName;
|
||||||
|
if (*lpFileName == '.')
|
||||||
|
{
|
||||||
|
lpFcb->fcb_fname[1] = '.';
|
||||||
|
++lpFileName;
|
||||||
|
}
|
||||||
|
*wTestMode = PARSE_RET_NOWILD;
|
||||||
|
return FP_OFF(lpFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now to format the file name into the string */
|
||||||
|
lpFileName =
|
||||||
|
GetNameField(lpFileName, (BYTE FAR *) lpFcb->fcb_fname, FNAME_SIZE,
|
||||||
|
(BOOL *) & wRetCodeName);
|
||||||
|
|
||||||
|
/* Do we have an extension? If do, format it else return */
|
||||||
|
if (*lpFileName == '.')
|
||||||
|
lpFileName =
|
||||||
|
GetNameField(++lpFileName, (BYTE FAR *) lpFcb->fcb_fext,
|
||||||
|
FEXT_SIZE, (BOOL *) & wRetCodeExt);
|
||||||
|
|
||||||
|
*wTestMode = (wRetCodeName | wRetCodeExt) ? PARSE_RET_WILD : PARSE_RET_NOWILD;
|
||||||
|
return FP_OFF(lpFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
const BYTE FAR * ParseSkipWh(const BYTE FAR * lpFileName)
|
||||||
|
{
|
||||||
|
while (*lpFileName == ' ' || *lpFileName == '\t')
|
||||||
|
++lpFileName;
|
||||||
|
return lpFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 /* defined above */
|
||||||
|
BOOL TestCmnSeps(BYTE FAR * lpFileName)
|
||||||
|
{
|
||||||
|
BYTE *pszTest, *pszCmnSeps = ":<|>+=,";
|
||||||
|
|
||||||
|
for (pszTest = pszCmnSeps; *pszTest != '\0'; ++pszTest)
|
||||||
|
if (*lpFileName == *pszTest)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
BOOL TestFieldSeps(BYTE FAR * lpFileName)
|
||||||
|
{
|
||||||
|
BYTE *pszTest, *pszCmnSeps = "/\"[]<>|.";
|
||||||
|
|
||||||
|
/* Another non-portable construct */
|
||||||
|
if (*lpFileName <= ' ')
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
for (pszTest = pszCmnSeps; *pszTest != '\0'; ++pszTest)
|
||||||
|
if (*lpFileName == *pszTest)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const BYTE FAR * GetNameField(const BYTE FAR * lpFileName, BYTE FAR * lpDestField,
|
||||||
|
COUNT nFieldSize, BOOL * pbWildCard)
|
||||||
|
{
|
||||||
|
COUNT nIndex = 0;
|
||||||
|
BYTE cFill = ' ';
|
||||||
|
|
||||||
|
while (*lpFileName != '\0' && !TestFieldSeps(lpFileName)
|
||||||
|
&& nIndex < nFieldSize)
|
||||||
|
{
|
||||||
|
if (*lpFileName == ' ')
|
||||||
|
break;
|
||||||
|
if (*lpFileName == '*')
|
||||||
|
{
|
||||||
|
*pbWildCard = TRUE;
|
||||||
|
cFill = '?';
|
||||||
|
++lpFileName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (*lpFileName == '?')
|
||||||
|
*pbWildCard = TRUE;
|
||||||
|
*lpDestField++ = DosUpFChar(*lpFileName++);
|
||||||
|
++nIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blank out remainder of field on exit */
|
||||||
|
fmemset(lpDestField, cFill, nFieldSize - nIndex);
|
||||||
|
return lpFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC VOID FcbNextRecord(fcb FAR * lpFcb)
|
||||||
|
{
|
||||||
|
if (++lpFcb->fcb_curec >= 128)
|
||||||
|
{
|
||||||
|
lpFcb->fcb_curec = 0;
|
||||||
|
++lpFcb->fcb_cublock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC ULONG FcbRec(fcb FAR *lpFcb)
|
||||||
|
{
|
||||||
|
return ((ULONG) lpFcb->fcb_cublock * 128) + lpFcb->fcb_curec;
|
||||||
|
}
|
||||||
|
|
||||||
|
UBYTE FcbReadWrite(xfcb FAR * lpXfcb, UCOUNT recno, int mode)
|
||||||
|
{
|
||||||
|
ULONG lPosit;
|
||||||
|
long nTransfer;
|
||||||
|
fcb FAR *lpFcb;
|
||||||
|
unsigned size;
|
||||||
|
unsigned long bigsize;
|
||||||
|
unsigned recsiz;
|
||||||
|
|
||||||
|
/* Convert to fcb if necessary */
|
||||||
|
lpFcb = ExtFcbToFcb(lpXfcb);
|
||||||
|
|
||||||
|
recsiz = lpFcb->fcb_recsiz;
|
||||||
|
bigsize = (ULONG)recsiz * recno;
|
||||||
|
if (bigsize > 0xffff)
|
||||||
|
return FCB_ERR_SEGMENT_WRAP;
|
||||||
|
size = (unsigned)bigsize;
|
||||||
|
|
||||||
|
if (FP_OFF(dta) + size < FP_OFF(dta))
|
||||||
|
return FCB_ERR_SEGMENT_WRAP;
|
||||||
|
|
||||||
|
/* Now update the fcb and compute where we need to position */
|
||||||
|
/* to. */
|
||||||
|
lPosit = FcbRec(lpFcb) * recsiz;
|
||||||
|
if ((CritErrCode = -SftSeek(lpFcb->fcb_sftno, lPosit, 0)) != SUCCESS)
|
||||||
|
return FCB_ERR_NODATA;
|
||||||
|
|
||||||
|
/* Do the read */
|
||||||
|
nTransfer = DosRWSft(lpFcb->fcb_sftno, size, dta, mode & ~XFR_FCB_RANDOM);
|
||||||
|
if (nTransfer < 0)
|
||||||
|
CritErrCode = -(int)nTransfer;
|
||||||
|
|
||||||
|
/* Now find out how we will return and do it. */
|
||||||
|
if (mode & XFR_WRITE)
|
||||||
|
lpFcb->fcb_fsize = SftGetFsize(lpFcb->fcb_sftno);
|
||||||
|
|
||||||
|
/* if end-of-file, then partial read should count last record */
|
||||||
|
if (mode & XFR_FCB_RANDOM && recsiz > 0)
|
||||||
|
lpFcb->fcb_rndm += ((unsigned)nTransfer + recsiz - 1) / recsiz;
|
||||||
|
size -= (unsigned)nTransfer;
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
FcbNextRecord(lpFcb);
|
||||||
|
return FCB_SUCCESS;
|
||||||
|
}
|
||||||
|
size %= lpFcb->fcb_recsiz;
|
||||||
|
if (mode & XFR_READ && size > 0)
|
||||||
|
{
|
||||||
|
fmemset((char FAR *)dta + (unsigned)nTransfer, 0, size);
|
||||||
|
FcbNextRecord(lpFcb);
|
||||||
|
return FCB_ERR_EOF;
|
||||||
|
}
|
||||||
|
return FCB_ERR_NODATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
UBYTE FcbGetFileSize(xfcb FAR * lpXfcb)
|
||||||
|
{
|
||||||
|
int FcbDrive, sft_idx;
|
||||||
|
unsigned recsiz;
|
||||||
|
|
||||||
|
/* Build a traditional DOS file name */
|
||||||
|
fcb FAR *lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
||||||
|
recsiz = lpFcb->fcb_recsiz;
|
||||||
|
|
||||||
|
/* check for a device */
|
||||||
|
if (!lpFcb || IsDevice(SecPathName) || (recsiz == 0))
|
||||||
|
return FCB_ERROR;
|
||||||
|
|
||||||
|
sft_idx = (short)DosOpenSft(SecPathName, O_LEGACY | O_RDONLY | O_OPEN, 0);
|
||||||
|
if (sft_idx >= 0)
|
||||||
|
{
|
||||||
|
ULONG fsize;
|
||||||
|
|
||||||
|
/* Get the size */
|
||||||
|
fsize = SftGetFsize(sft_idx);
|
||||||
|
|
||||||
|
/* compute the size and update the fcb */
|
||||||
|
lpFcb->fcb_rndm = (fsize + (recsiz - 1)) / recsiz;
|
||||||
|
|
||||||
|
/* close the file and leave */
|
||||||
|
if ((CritErrCode = -DosCloseSft(sft_idx, FALSE)) == SUCCESS)
|
||||||
|
return FCB_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CritErrCode = -sft_idx;
|
||||||
|
return FCB_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FcbSetRandom(xfcb FAR * lpXfcb)
|
||||||
|
{
|
||||||
|
/* Convert to fcb if necessary */
|
||||||
|
fcb FAR *lpFcb = ExtFcbToFcb(lpXfcb);
|
||||||
|
|
||||||
|
/* Now update the fcb and compute where we need to position */
|
||||||
|
/* to. */
|
||||||
|
lpFcb->fcb_rndm = FcbRec(lpFcb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FcbCalcRec(xfcb FAR * lpXfcb)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Convert to fcb if necessary */
|
||||||
|
fcb FAR *lpFcb = ExtFcbToFcb(lpXfcb);
|
||||||
|
|
||||||
|
/* Now update the fcb and compute where we need to position */
|
||||||
|
/* to. */
|
||||||
|
lpFcb->fcb_cublock = (UWORD)(lpFcb->fcb_rndm / 128);
|
||||||
|
lpFcb->fcb_curec = (UBYTE)lpFcb->fcb_rndm & 127;
|
||||||
|
}
|
||||||
|
|
||||||
|
UBYTE FcbRandomBlockIO(xfcb FAR * lpXfcb, UWORD *nRecords, int mode)
|
||||||
|
{
|
||||||
|
UBYTE nErrorCode;
|
||||||
|
fcb FAR *lpFcb;
|
||||||
|
unsigned long old;
|
||||||
|
|
||||||
|
FcbCalcRec(lpXfcb);
|
||||||
|
|
||||||
|
/* Convert to fcb if necessary */
|
||||||
|
lpFcb = ExtFcbToFcb(lpXfcb);
|
||||||
|
|
||||||
|
old = lpFcb->fcb_rndm;
|
||||||
|
nErrorCode = FcbReadWrite(lpXfcb, *nRecords, mode);
|
||||||
|
*nRecords = (UWORD)(lpFcb->fcb_rndm - old);
|
||||||
|
|
||||||
|
/* Now update the fcb */
|
||||||
|
FcbCalcRec(lpXfcb);
|
||||||
|
|
||||||
|
return nErrorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
UBYTE FcbRandomIO(xfcb FAR * lpXfcb, int mode)
|
||||||
|
{
|
||||||
|
UWORD uwCurrentBlock;
|
||||||
|
UBYTE ucCurrentRecord;
|
||||||
|
UBYTE nErrorCode;
|
||||||
|
fcb FAR *lpFcb;
|
||||||
|
|
||||||
|
FcbCalcRec(lpXfcb);
|
||||||
|
|
||||||
|
/* Convert to fcb if necessary */
|
||||||
|
lpFcb = ExtFcbToFcb(lpXfcb);
|
||||||
|
|
||||||
|
uwCurrentBlock = lpFcb->fcb_cublock;
|
||||||
|
ucCurrentRecord = lpFcb->fcb_curec;
|
||||||
|
|
||||||
|
nErrorCode = FcbReadWrite(lpXfcb, 1, mode);
|
||||||
|
|
||||||
|
lpFcb->fcb_cublock = uwCurrentBlock;
|
||||||
|
lpFcb->fcb_curec = ucCurrentRecord;
|
||||||
|
return nErrorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FcbOpen and FcbCreate
|
||||||
|
Expects lpXfcb to point to a valid, unopened FCB, containing file name to open (create)
|
||||||
|
Create will attempt to find the file name in the current directory, if found truncates
|
||||||
|
setting file size to 0, otherwise if does not exist will create the new file; the
|
||||||
|
FCB is filled in same as the open call.
|
||||||
|
On any error returns FCB_ERROR
|
||||||
|
On success returns FCB_SUCCESS, and sets the following fields (other non-system reserved ones left unchanged)
|
||||||
|
drive identifier (fcb_drive) set to actual drive (1=A, 2=B, ...; always >0 if not device)
|
||||||
|
current block number (fcb_cublock) to 0
|
||||||
|
file size (fcb_fsize) value from directory entry (0 if create)
|
||||||
|
record size (fcb_recsiz) to 128; set to 0 for devices
|
||||||
|
time & date (fcb_time & fcb_date) values from directory entry
|
||||||
|
fcb_sftno, fcb_attrib_hi/_lo, fcb_strtclst, fcb_dirclst/off_unused are for internal use (system reserved)
|
||||||
|
*/
|
||||||
|
UBYTE FcbOpen(xfcb FAR * lpXfcb, unsigned flags)
|
||||||
|
{
|
||||||
|
sft FAR *sftp;
|
||||||
|
COUNT sft_idx, FcbDrive;
|
||||||
|
unsigned attr = 0;
|
||||||
|
|
||||||
|
/* Build a traditional DOS file name */
|
||||||
|
fcb FAR *lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
||||||
|
if ((flags & O_CREAT) && lpXfcb->xfcb_flag == 0xff)
|
||||||
|
/* pass attribute without constraints (dangerous for directories) */
|
||||||
|
attr = lpXfcb->xfcb_attrib;
|
||||||
|
|
||||||
|
sft_idx = (short)DosOpenSft(SecPathName, flags, attr);
|
||||||
|
if (sft_idx < 0)
|
||||||
|
{
|
||||||
|
CritErrCode = -sft_idx;
|
||||||
|
return FCB_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
sftp = idx_to_sft(sft_idx);
|
||||||
|
sftp->sft_mode |= O_FCB;
|
||||||
|
|
||||||
|
lpFcb->fcb_sftno = sft_idx;
|
||||||
|
lpFcb->fcb_cublock = 0;
|
||||||
|
/* should not be cleared, programs e.g. GEM depend on these values remaining unchanged
|
||||||
|
lpFcb->fcb_curec = 0;
|
||||||
|
lpFcb->fcb_rndm = 0;
|
||||||
|
*/
|
||||||
|
|
||||||
|
lpFcb->fcb_recsiz = 0; /* true for devices */
|
||||||
|
if (!(sftp->sft_flags & SFT_FDEVICE)) /* check for a device */
|
||||||
|
{
|
||||||
|
lpFcb->fcb_drive = FcbDrive;
|
||||||
|
lpFcb->fcb_recsiz = 128;
|
||||||
|
}
|
||||||
|
lpFcb->fcb_fsize = sftp->sft_size;
|
||||||
|
lpFcb->fcb_date = sftp->sft_date;
|
||||||
|
lpFcb->fcb_time = sftp->sft_time;
|
||||||
|
return FCB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STATIC fcb FAR *ExtFcbToFcb(xfcb FAR * lpExtFcb)
|
||||||
|
{
|
||||||
|
if (*((UBYTE FAR *) lpExtFcb) == 0xff)
|
||||||
|
sda_lpFcb = &lpExtFcb->xfcb_fcb;
|
||||||
|
else
|
||||||
|
sda_lpFcb = (fcb FAR *) lpExtFcb;
|
||||||
|
return sda_lpFcb;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC fcb FAR *CommonFcbInit(xfcb FAR * lpExtFcb, BYTE * pszBuffer,
|
||||||
|
COUNT * pCurDrive)
|
||||||
|
{
|
||||||
|
fcb FAR *lpFcb;
|
||||||
|
|
||||||
|
/* convert to fcb if needed first */
|
||||||
|
sda_lpFcb = lpFcb = ExtFcbToFcb(lpExtFcb);
|
||||||
|
|
||||||
|
/* Build a traditional DOS file name */
|
||||||
|
FcbNameInit(lpFcb, pszBuffer, pCurDrive);
|
||||||
|
/* and return the fcb pointer */
|
||||||
|
return lpFcb;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC void FcbNameInit(fcb FAR * lpFcb, BYTE * szBuffer, COUNT * pCurDrive)
|
||||||
|
{
|
||||||
|
BYTE *pszBuffer = szBuffer;
|
||||||
|
|
||||||
|
/* Build a traditional DOS file name */
|
||||||
|
*pCurDrive = default_drive + 1;
|
||||||
|
if (lpFcb->fcb_drive != 0)
|
||||||
|
{
|
||||||
|
*pCurDrive = lpFcb->fcb_drive;
|
||||||
|
pszBuffer[0] = 'A' + lpFcb->fcb_drive - 1;
|
||||||
|
pszBuffer[1] = ':';
|
||||||
|
pszBuffer += 2;
|
||||||
|
}
|
||||||
|
ConvertName83ToNameSZ(pszBuffer, lpFcb->fcb_fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
UBYTE FcbDelete(xfcb FAR * lpXfcb)
|
||||||
|
{
|
||||||
|
COUNT FcbDrive;
|
||||||
|
UBYTE result = FCB_SUCCESS;
|
||||||
|
void FAR *lpOldDta = dta;
|
||||||
|
|
||||||
|
/* Build a traditional DOS file name */
|
||||||
|
CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
||||||
|
/* check for a device */
|
||||||
|
if (IsDevice(SecPathName))
|
||||||
|
{
|
||||||
|
result = FCB_ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int attr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL);
|
||||||
|
dmatch Dmatch;
|
||||||
|
|
||||||
|
dta = &Dmatch;
|
||||||
|
if ((CritErrCode = -DosFindFirst(attr, SecPathName)) != SUCCESS)
|
||||||
|
{
|
||||||
|
result = FCB_ERROR;
|
||||||
|
}
|
||||||
|
else do
|
||||||
|
{
|
||||||
|
SecPathName[0] = 'A' + FcbDrive - 1;
|
||||||
|
SecPathName[1] = ':';
|
||||||
|
strcpy(&SecPathName[2], Dmatch.dm_name);
|
||||||
|
if (DosDelete(SecPathName, attr) != SUCCESS)
|
||||||
|
{
|
||||||
|
result = FCB_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ((CritErrCode = -DosFindNext()) == SUCCESS);
|
||||||
|
}
|
||||||
|
dta = lpOldDta;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
UBYTE FcbRename(xfcb FAR * lpXfcb)
|
||||||
|
{
|
||||||
|
rfcb FAR *lpRenameFcb;
|
||||||
|
COUNT FcbDrive;
|
||||||
|
UBYTE result = FCB_SUCCESS;
|
||||||
|
void FAR *lpOldDta = dta;
|
||||||
|
|
||||||
|
/* Build a traditional DOS file name */
|
||||||
|
lpRenameFcb = (rfcb FAR *) CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
||||||
|
|
||||||
|
/* check for a device */
|
||||||
|
if (IsDevice(SecPathName))
|
||||||
|
{
|
||||||
|
result = FCB_ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dmatch Dmatch;
|
||||||
|
COUNT result;
|
||||||
|
|
||||||
|
wAttr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL);
|
||||||
|
dta = &Dmatch;
|
||||||
|
if ((CritErrCode = -DosFindFirst(wAttr, SecPathName)) != SUCCESS)
|
||||||
|
{
|
||||||
|
result = FCB_ERROR;
|
||||||
|
}
|
||||||
|
else do
|
||||||
|
{
|
||||||
|
/* 'A:' + '.' + '\0' */
|
||||||
|
BYTE loc_szBuffer[2 + FNAME_SIZE + 1 + FEXT_SIZE + 1];
|
||||||
|
fcb LocalFcb;
|
||||||
|
BYTE *pToName;
|
||||||
|
const BYTE FAR *pFromPattern = Dmatch.dm_name;
|
||||||
|
int i;
|
||||||
|
UBYTE mode = 0;
|
||||||
|
|
||||||
|
FcbParseFname(&mode, pFromPattern, &LocalFcb);
|
||||||
|
/* Overlay the pattern, skipping '?' */
|
||||||
|
/* I'm cheating because this assumes that the */
|
||||||
|
/* struct alignments are on byte boundaries */
|
||||||
|
pToName = LocalFcb.fcb_fname;
|
||||||
|
pFromPattern = lpRenameFcb->renNewName;
|
||||||
|
for (i = 0; i < FNAME_SIZE + FEXT_SIZE; i++)
|
||||||
|
{
|
||||||
|
if (*pFromPattern != '?')
|
||||||
|
*pToName = *pFromPattern;
|
||||||
|
pToName++;
|
||||||
|
pFromPattern++;
|
||||||
|
}
|
||||||
|
|
||||||
|
SecPathName[0] = 'A' + FcbDrive - 1;
|
||||||
|
SecPathName[1] = ':';
|
||||||
|
strcpy(&SecPathName[2], Dmatch.dm_name);
|
||||||
|
result = truename(SecPathName, PriPathName, 0);
|
||||||
|
|
||||||
|
if (result < SUCCESS || (result & IS_DEVICE))
|
||||||
|
{
|
||||||
|
result = FCB_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* now to build a dos name again */
|
||||||
|
LocalFcb.fcb_drive = FcbDrive;
|
||||||
|
FcbNameInit(&LocalFcb, loc_szBuffer, &FcbDrive);
|
||||||
|
result = truename(loc_szBuffer, SecPathName, 0);
|
||||||
|
if (result < SUCCESS || (result & (IS_NETWORK|IS_DEVICE)) == IS_DEVICE
|
||||||
|
|| DosRenameTrue(PriPathName, SecPathName, wAttr) != SUCCESS)
|
||||||
|
{
|
||||||
|
result = FCB_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ((CritErrCode = -DosFindNext()) == SUCCESS);
|
||||||
|
}
|
||||||
|
dta = lpOldDta;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TE:the MoveDirInfo() is now done by simply copying the dirEntry into the FCB
|
||||||
|
this prevents problems with ".", ".." and saves code
|
||||||
|
BO:use global SearchDir, as produced by FindFirst/Next
|
||||||
|
*/
|
||||||
|
|
||||||
|
UBYTE FcbClose(xfcb FAR * lpXfcb)
|
||||||
|
{
|
||||||
|
sft FAR *s;
|
||||||
|
|
||||||
|
/* Convert to fcb if necessary */
|
||||||
|
fcb FAR *lpFcb = ExtFcbToFcb(lpXfcb);
|
||||||
|
|
||||||
|
/* An already closed FCB can be closed again without error */
|
||||||
|
if (lpFcb->fcb_sftno == (BYTE) 0xff)
|
||||||
|
return FCB_SUCCESS;
|
||||||
|
|
||||||
|
/* Get the SFT block that contains the SFT */
|
||||||
|
if ((s = idx_to_sft(lpFcb->fcb_sftno)) == (sft FAR *) - 1)
|
||||||
|
return FCB_ERROR;
|
||||||
|
|
||||||
|
/* change time and set file size */
|
||||||
|
s->sft_size = lpFcb->fcb_fsize;
|
||||||
|
if (!(s->sft_flags & SFT_FSHARED))
|
||||||
|
dos_merge_file_changes(lpFcb->fcb_sftno);
|
||||||
|
DosSetFtimeSft(lpFcb->fcb_sftno, lpFcb->fcb_date, lpFcb->fcb_time);
|
||||||
|
if ((CritErrCode = -DosCloseSft(lpFcb->fcb_sftno, FALSE)) == SUCCESS)
|
||||||
|
{
|
||||||
|
lpFcb->fcb_sftno = (BYTE) 0xff;
|
||||||
|
return FCB_SUCCESS;
|
||||||
|
}
|
||||||
|
return FCB_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close all files the current process opened by FCBs */
|
||||||
|
VOID FcbCloseAll()
|
||||||
|
{
|
||||||
|
COUNT idx = 0;
|
||||||
|
sft FAR *sftp;
|
||||||
|
|
||||||
|
for (idx = 0; (sftp = idx_to_sft(idx)) != (sft FAR *) - 1; idx++)
|
||||||
|
if ((sftp->sft_mode & O_FCB) && sftp->sft_psp == cu_psp)
|
||||||
|
DosCloseSft(idx, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First)
|
||||||
|
{
|
||||||
|
void FAR *orig_dta = dta;
|
||||||
|
BYTE FAR *lpDir;
|
||||||
|
COUNT FcbDrive;
|
||||||
|
fcb FAR *lpFcb;
|
||||||
|
|
||||||
|
/* First, move the dta to a local and change it around to match */
|
||||||
|
/* our functions. */
|
||||||
|
lpDir = dta;
|
||||||
|
dta = &Dmatch;
|
||||||
|
|
||||||
|
/* Next initialze local variables by moving them from the fcb */
|
||||||
|
lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
||||||
|
/* Reconstrct the dirmatch structure from the fcb - doesn't hurt for first */
|
||||||
|
Dmatch.dm_drive = lpFcb->fcb_sftno;
|
||||||
|
|
||||||
|
fmemcpy(Dmatch.dm_name_pat, lpFcb->fcb_fname, FNAME_SIZE + FEXT_SIZE);
|
||||||
|
DosUpFMem((BYTE FAR *) Dmatch.dm_name_pat, FNAME_SIZE + FEXT_SIZE);
|
||||||
|
|
||||||
|
Dmatch.dm_attr_srch = wAttr;
|
||||||
|
Dmatch.dm_entry = lpFcb->fcb_strtclst;
|
||||||
|
Dmatch.dm_dircluster = lpFcb->fcb_dirclst;
|
||||||
|
|
||||||
|
wAttr = D_ALL;
|
||||||
|
|
||||||
|
if ((xfcb FAR *) lpFcb != lpXfcb)
|
||||||
|
{
|
||||||
|
wAttr = lpXfcb->xfcb_attrib;
|
||||||
|
fmemcpy(lpDir, lpXfcb, 7);
|
||||||
|
lpDir += 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
CritErrCode = -(First ? DosFindFirst(wAttr, SecPathName) : DosFindNext());
|
||||||
|
if (CritErrCode != SUCCESS)
|
||||||
|
{
|
||||||
|
dta = orig_dta;
|
||||||
|
return FCB_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
*lpDir++ = FcbDrive;
|
||||||
|
fmemcpy(lpDir, &SearchDir, sizeof(struct dirent));
|
||||||
|
|
||||||
|
lpFcb->fcb_dirclst = (UWORD) Dmatch.dm_dircluster;
|
||||||
|
lpFcb->fcb_strtclst = Dmatch.dm_entry;
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is undocumented and seen using Pcwatch and Ramview.
|
||||||
|
The First byte is the current directory count and the second seems
|
||||||
|
to be the attribute byte.
|
||||||
|
*/
|
||||||
|
lpFcb->fcb_sftno = Dmatch.dm_drive; /* MSD seems to save this @ fcb_date. */
|
||||||
|
#if 0
|
||||||
|
lpFcb->fcb_cublock = Dmatch.dm_entry;
|
||||||
|
lpFcb->fcb_cublock *= 0x100;
|
||||||
|
lpFcb->fcb_cublock += wAttr;
|
||||||
|
#endif
|
||||||
|
dta = orig_dta;
|
||||||
|
return FCB_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
429
kernel/globals.h
Normal file
429
kernel/globals.h
Normal file
@ -0,0 +1,429 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* globals.h */
|
||||||
|
/* DOS-C */
|
||||||
|
/* */
|
||||||
|
/* Global data structures and declarations */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995, 1996 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
#ifdef MAIN
|
||||||
|
static BYTE *Globals_hRcsId =
|
||||||
|
"$Id: globals.h 1705 2012-02-07 08:10:33Z perditionc $";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "device.h"
|
||||||
|
#include "mcb.h"
|
||||||
|
#include "pcb.h"
|
||||||
|
#include "date.h"
|
||||||
|
#include "time.h"
|
||||||
|
#include "fat.h"
|
||||||
|
#include "fcb.h"
|
||||||
|
#include "tail.h"
|
||||||
|
#include "process.h"
|
||||||
|
#include "sft.h"
|
||||||
|
#include "cds.h"
|
||||||
|
#include "exe.h"
|
||||||
|
#include "dirmatch.h"
|
||||||
|
#include "fnode.h"
|
||||||
|
#include "file.h"
|
||||||
|
#include "clock.h"
|
||||||
|
#include "kbd.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "version.h"
|
||||||
|
#include "network.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
#include "dcb.h"
|
||||||
|
#include "xstructs.h"
|
||||||
|
|
||||||
|
/* fatfs.c */
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
VOID bpb_to_dpb(bpb FAR * bpbp, REG struct dpb FAR * dpbp, BOOL extended);
|
||||||
|
#else
|
||||||
|
VOID bpb_to_dpb(bpb FAR * bpbp, REG struct dpb FAR * dpbp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
struct dpb FAR *GetDriveDPB(UBYTE drive, COUNT * rc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern struct dpb
|
||||||
|
FAR * ASM DPBp; /* First drive Parameter Block */
|
||||||
|
|
||||||
|
|
||||||
|
/* JPP: for testing/debuging disk IO */
|
||||||
|
/*#define DISPLAY_GETBLOCK */
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* Convience switch for maintaining variables in a single location */
|
||||||
|
/* */
|
||||||
|
#ifdef MAIN
|
||||||
|
#define GLOBAL
|
||||||
|
#else
|
||||||
|
#define GLOBAL extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* Convience definitions of TRUE and FALSE */
|
||||||
|
/* */
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE (1)
|
||||||
|
#endif
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* Constants and macros */
|
||||||
|
/* */
|
||||||
|
/* Defaults and limits - System wide */
|
||||||
|
#define NAMEMAX MAX_CDSPATH /* Maximum path for CDS */
|
||||||
|
|
||||||
|
/* internal error from failure or aborted operation */
|
||||||
|
#define ERROR -1
|
||||||
|
#define OK 0
|
||||||
|
|
||||||
|
/* internal transfer direction flags */
|
||||||
|
#define XFR_READ 1
|
||||||
|
#define XFR_WRITE 2
|
||||||
|
#define XFR_FORCE_WRITE 3
|
||||||
|
/* flag to update fcb_rndm field */
|
||||||
|
#define XFR_FCB_RANDOM 4
|
||||||
|
|
||||||
|
#define RDONLY 0
|
||||||
|
#define WRONLY 1
|
||||||
|
#define RDWR 2
|
||||||
|
|
||||||
|
/* special ascii code equates */
|
||||||
|
#define SPCL 0x00
|
||||||
|
#define CTL_C 0x03
|
||||||
|
#define CTL_F 0x06
|
||||||
|
#define BELL 0x07
|
||||||
|
#define BS 0x08
|
||||||
|
#define HT 0x09
|
||||||
|
#define LF 0x0a
|
||||||
|
#define CR 0x0d
|
||||||
|
#define CTL_P 0x10
|
||||||
|
#define CTL_Q 0x11
|
||||||
|
#define CTL_S 0x13
|
||||||
|
#define CTL_Z 0x1a
|
||||||
|
#define ESC 0x1b
|
||||||
|
#define CTL_BS 0x7f
|
||||||
|
|
||||||
|
#define INS 0x5200
|
||||||
|
#define DEL 0x5300
|
||||||
|
|
||||||
|
#define F1 0x3b00
|
||||||
|
#define F2 0x3c00
|
||||||
|
#define F3 0x3d00
|
||||||
|
#define F4 0x3e00
|
||||||
|
#define F5 0x3f00
|
||||||
|
#define F6 0x4000
|
||||||
|
#define LEFT 0x4b00
|
||||||
|
#define RIGHT 0x4d00
|
||||||
|
|
||||||
|
/* Blockio constants */
|
||||||
|
#define DSKWRITE 1 /* dskxfr function parameters */
|
||||||
|
#define DSKREAD 2
|
||||||
|
#define DSKWRITEINT26 3
|
||||||
|
#define DSKREADINT25 4
|
||||||
|
|
||||||
|
/* NLS character table type */
|
||||||
|
typedef BYTE *UPMAP;
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* External Assembly variables */
|
||||||
|
/* */
|
||||||
|
extern struct dhdr
|
||||||
|
FAR ASM clk_dev, /* Clock device driver */
|
||||||
|
FAR ASM con_dev, /* Console device driver */
|
||||||
|
FAR ASM prn_dev, /* Generic printer device driver */
|
||||||
|
FAR ASM aux_dev, /* Generic aux device driver */
|
||||||
|
FAR ASM blk_dev; /* Block device (Disk) driver */
|
||||||
|
extern COUNT *error_tos, /* error stack */
|
||||||
|
disk_api_tos, /* API handler stack - disk fns */
|
||||||
|
char_api_tos; /* API handler stack - char fns */
|
||||||
|
extern BYTE FAR _HMATextAvailable, /* first byte of available CODE area */
|
||||||
|
FAR _HMATextStart[], /* first byte of HMAable CODE area */
|
||||||
|
FAR _HMATextEnd[]; /* and the last byte of it */
|
||||||
|
extern
|
||||||
|
BYTE DosLoadedInHMA; /* if InitHMA has moved DOS up */
|
||||||
|
|
||||||
|
extern struct ClockRecord
|
||||||
|
ASM ClkRecord;
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* Global variables */
|
||||||
|
/* */
|
||||||
|
extern BYTE ASM os_setver_major,/* editable major version number */
|
||||||
|
ASM os_setver_minor, /* editable minor version number */
|
||||||
|
ASM os_major, /* major version number */
|
||||||
|
ASM os_minor, /* minor version number */
|
||||||
|
ASM rev_number, /* minor version number */
|
||||||
|
ASM version_flags; /* minor version number */
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
GLOBAL WORD bDumpRegs
|
||||||
|
#ifdef MAIN
|
||||||
|
= FALSE;
|
||||||
|
#else
|
||||||
|
;
|
||||||
|
#endif
|
||||||
|
GLOBAL WORD bDumpRdWrParms
|
||||||
|
#ifdef MAIN
|
||||||
|
= FALSE;
|
||||||
|
#else
|
||||||
|
;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0 /* defined in MAIN.C now to save low memory */
|
||||||
|
|
||||||
|
GLOBAL BYTE copyright[] =
|
||||||
|
"(C) Copyright 1995-2006 Pasquale J. Villani and The FreeDOS Project.\n"
|
||||||
|
"All Rights Reserved. This is free software and comes with ABSOLUTELY NO\n"
|
||||||
|
"WARRANTY; you can redistribute it and/or modify it under the terms of the\n"
|
||||||
|
"GNU General Public License as published by the Free Software Foundation;\n"
|
||||||
|
"either version 2, or (at your option) any later version.\n";
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GLOBAL const BYTE ASM os_release[]
|
||||||
|
#ifdef MAIN
|
||||||
|
= KERNEL_VERSION_STRING
|
||||||
|
#if 0
|
||||||
|
"For technical information and description of the DOS-C operating system\n\
|
||||||
|
consult \"FreeDOS Kernel\" by Pat Villani, published by Miller\n\
|
||||||
|
Freeman Publishing, Lawrence KS, USA (ISBN 0-87930-436-7).\n\
|
||||||
|
\n"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
/* Globally referenced variables - WARNING: ORDER IS DEFINED IN */
|
||||||
|
/* KERNEL.ASM AND MUST NOT BE CHANGED. DO NOT CHANGE ORDER BECAUSE THEY */
|
||||||
|
/* ARE DOCUMENTED AS UNDOCUMENTED (?) AND HAVE MANY PROGRAMS AND TSRs */
|
||||||
|
/* ACCESSING THEM */
|
||||||
|
|
||||||
|
extern UWORD ASM NetBios;
|
||||||
|
extern BYTE * ASM net_name;
|
||||||
|
extern BYTE ASM net_set_count;
|
||||||
|
extern BYTE ASM NetDelay, ASM NetRetry;
|
||||||
|
|
||||||
|
extern UWORD ASM first_mcb, /* Start of user memory */
|
||||||
|
ASM uppermem_root; /* Start of umb chain (usually 9fff) */
|
||||||
|
extern char * ASM inputptr; /* pointer to unread CON input */
|
||||||
|
extern sfttbl FAR * ASM sfthead; /* System File Table head */
|
||||||
|
extern struct dhdr
|
||||||
|
FAR * ASM clock, /* CLOCK$ device */
|
||||||
|
FAR * ASM syscon; /* console device */
|
||||||
|
extern WORD ASM maxsecsize; /* largest sector size in use (can use) */
|
||||||
|
extern struct buffer
|
||||||
|
FAR *ASM firstbuf; /* head of buffers linked list */
|
||||||
|
enum {LOC_CONV=0, LOC_HMA=1};
|
||||||
|
extern unsigned char ASM bufloc; /* 0=conv, 1=HMA */
|
||||||
|
extern void far * ASM deblock_buf; /* pointer to workspace buffer */
|
||||||
|
GLOBAL char FAR *firstAvailableBuf;
|
||||||
|
extern struct cds FAR * ASM CDSp; /* Current Directory Structure */
|
||||||
|
extern
|
||||||
|
struct cds FAR * ASM current_ldt;
|
||||||
|
extern LONG ASM current_filepos; /* current file position */
|
||||||
|
extern sfttbl FAR * ASM FCBp; /* FCB table pointer */
|
||||||
|
extern WORD ASM nprotfcb; /* number of protected fcbs */
|
||||||
|
extern UBYTE ASM nblkdev, /* number of block devices */
|
||||||
|
ASM lastdrive, /* value of last drive */
|
||||||
|
ASM uppermem_link, /* UMB Link flag */
|
||||||
|
ASM PrinterEcho; /* Printer Echo Flag */
|
||||||
|
|
||||||
|
extern UWORD ASM LoL_nbuffers; /* Number of buffers */
|
||||||
|
|
||||||
|
extern struct dhdr
|
||||||
|
ASM nul_dev;
|
||||||
|
extern UBYTE ASM mem_access_mode; /* memory allocation scheme */
|
||||||
|
extern BYTE ASM ErrorMode, /* Critical error flag */
|
||||||
|
ASM InDOS, /* In DOS critical section */
|
||||||
|
ASM OpenMode, /* File Open Attributes */
|
||||||
|
ASM SAttr, /* Attrib Mask for Dir Search */
|
||||||
|
ASM dosidle_flag, ASM Server_Call, ASM CritErrLocus, ASM CritErrAction,
|
||||||
|
ASM CritErrClass, ASM VgaSet,
|
||||||
|
ASM njoined; /* number of joined devices */
|
||||||
|
|
||||||
|
extern UWORD ASM Int21AX;
|
||||||
|
extern COUNT ASM CritErrCode;
|
||||||
|
extern BYTE FAR * ASM CritErrDev;
|
||||||
|
|
||||||
|
extern struct dirent
|
||||||
|
ASM SearchDir;
|
||||||
|
|
||||||
|
extern struct {
|
||||||
|
COUNT nDrive;
|
||||||
|
BYTE szName[FNAME_SIZE + 1];
|
||||||
|
BYTE szExt[FEXT_SIZE + 1];
|
||||||
|
} ASM FcbSearchBuffer;
|
||||||
|
|
||||||
|
extern struct /* Path name parsing buffer */
|
||||||
|
{
|
||||||
|
BYTE _PriPathName[128];
|
||||||
|
} ASM _PriPathBuffer;
|
||||||
|
|
||||||
|
#define PriPathName _PriPathBuffer._PriPathName
|
||||||
|
|
||||||
|
extern struct /* Alternate path name parsing buffer */
|
||||||
|
{
|
||||||
|
BYTE _SecPathName[128];
|
||||||
|
} ASM _SecPathBuffer;
|
||||||
|
|
||||||
|
#define SecPathName _SecPathBuffer._SecPathName
|
||||||
|
|
||||||
|
extern UWORD ASM wAttr;
|
||||||
|
|
||||||
|
extern BYTE ASM default_drive; /* default drive for dos */
|
||||||
|
|
||||||
|
extern dmatch ASM sda_tmp_dm; /* Temporary directory match buffer */
|
||||||
|
extern dmatch ASM sda_tmp_dm_ren; /* 2nd Temporary directory match buffer */
|
||||||
|
extern BYTE
|
||||||
|
ASM internal_data[], /* sda areas */
|
||||||
|
ASM swap_always[], /* " " */
|
||||||
|
ASM swap_indos[], /* " " */
|
||||||
|
ASM tsr, /* true if program is TSR */
|
||||||
|
ASM break_flg, /* true if break was detected */
|
||||||
|
ASM break_ena; /* break enabled flag */
|
||||||
|
extern void FAR * ASM dta; /* Disk transfer area (kludge) */
|
||||||
|
extern seg ASM cu_psp; /* current psp segment */
|
||||||
|
extern iregs FAR * ASM user_r; /* User registers for int 21h call */
|
||||||
|
|
||||||
|
extern struct dirent /* Temporary directory entry */
|
||||||
|
ASM DirEntBuffer;
|
||||||
|
|
||||||
|
extern fcb FAR * ASM sda_lpFcb; /* Pointer to users fcb */
|
||||||
|
|
||||||
|
extern sft FAR * ASM lpCurSft;
|
||||||
|
|
||||||
|
extern BYTE ASM verify_ena, /* verify enabled flag */
|
||||||
|
ASM switchar; /* switch char */
|
||||||
|
extern UWORD ASM return_code; /* Process termination rets */
|
||||||
|
|
||||||
|
extern UBYTE ASM BootDrive, /* Drive we came up from */
|
||||||
|
ASM CPULevel, /* CPU family, 0=8086, 1=186, ... */
|
||||||
|
ASM scr_pos; /* screen position for bs, ht, etc */
|
||||||
|
/*extern WORD
|
||||||
|
NumFloppies; !!*//* How many floppies we have */
|
||||||
|
|
||||||
|
extern keyboard ASM kb_buf;
|
||||||
|
extern char ASM local_buffer[LINEBUFSIZE0A];
|
||||||
|
extern UBYTE DiskTransferBuffer[/*SEC_SIZE*/];
|
||||||
|
|
||||||
|
extern struct cds
|
||||||
|
ASM TempCDS;
|
||||||
|
|
||||||
|
/* start of uncontrolled variables */
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
GLOBAL iregs error_regs; /* registers for dump */
|
||||||
|
|
||||||
|
GLOBAL WORD dump_regs; /* dump registers of bad call */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* Function prototypes - automatically generated */
|
||||||
|
/* */
|
||||||
|
#include "proto.h"
|
||||||
|
|
||||||
|
/* Process related functions - not under automatic generation. */
|
||||||
|
/* Typically, these are in ".asm" files. */
|
||||||
|
VOID ASMCFUNC FAR cpm_entry(VOID)
|
||||||
|
/*INRPT FAR handle_break(VOID) */ ;
|
||||||
|
COUNT ASMCFUNC
|
||||||
|
CriticalError(COUNT nFlag, COUNT nDrive, COUNT nError,
|
||||||
|
struct dhdr FAR * lpDevice);
|
||||||
|
|
||||||
|
VOID ASMCFUNC FAR CharMapSrvc(VOID);
|
||||||
|
#if 0
|
||||||
|
VOID ASMCFUNC FAR set_stack(VOID);
|
||||||
|
VOID ASMCFUNC FAR restore_stack(VOID);
|
||||||
|
#endif
|
||||||
|
/*VOID INRPT FAR handle_break(VOID); */
|
||||||
|
|
||||||
|
ULONG ASMPASCAL ReadPCClock(VOID);
|
||||||
|
VOID ASMPASCAL WriteATClock(BYTE *, BYTE, BYTE, BYTE);
|
||||||
|
VOID ASMPASCAL WritePCClock(ULONG);
|
||||||
|
intvec getvec(unsigned char);
|
||||||
|
#ifdef __WATCOMC__
|
||||||
|
#pragma aux (pascal) ReadPCClock modify exact [ax cx dx]
|
||||||
|
#pragma aux (pascal) WriteATClock modify exact [ax bx cx dx]
|
||||||
|
#pragma aux (pascal) WritePCClock modify exact [ax cx dx]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* special word packing prototypes */
|
||||||
|
/* */
|
||||||
|
#ifdef NATIVE
|
||||||
|
#define getlong(vp) (*(UDWORD *)(vp))
|
||||||
|
#define getword(vp) (*(UWORD *)(vp))
|
||||||
|
#define getbyte(vp) (*(UBYTE *)(vp))
|
||||||
|
#define fgetlong(vp) (*(UDWORD FAR *)(vp))
|
||||||
|
#define fgetword(vp) (*(UWORD FAR *)(vp))
|
||||||
|
#define fgetbyte(vp) (*(UBYTE FAR *)(vp))
|
||||||
|
#define fputlong(vp, l) (*(UDWORD FAR *)(vp)=l)
|
||||||
|
#define fputword(vp, w) (*(UWORD FAR *)(vp)=w)
|
||||||
|
#define fputbyte(vp, b) (*(UBYTE FAR *)(vp)=b)
|
||||||
|
#else
|
||||||
|
UDWORD getlong(VOID *);
|
||||||
|
UWORD getword(VOID *);
|
||||||
|
UBYTE getbyte(VOID *);
|
||||||
|
UDWORD fgetlong(VOID FAR *);
|
||||||
|
UWORD fgetword(VOID FAR *);
|
||||||
|
UBYTE fgetbyte(VOID FAR *);
|
||||||
|
VOID fputlong(VOID FAR *, UDWORD);
|
||||||
|
VOID fputword(VOID FAR *, UWORD);
|
||||||
|
VOID fputbyte(VOID FAR *, UBYTE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __WATCOMC__
|
||||||
|
#define setvec setvec_resident
|
||||||
|
#endif
|
||||||
|
void setvec(unsigned char intno, intvec vector);
|
||||||
|
/*#define is_leap_year(y) ((y) & 3 ? 0 : (y) % 100 ? 1 : (y) % 400 ? 0 : 1) */
|
||||||
|
|
||||||
|
/* ^Break handling */
|
||||||
|
#ifdef __WATCOMC__
|
||||||
|
#pragma aux (cdecl) spawn_int23 aborts;
|
||||||
|
#endif
|
||||||
|
void ASMCFUNC spawn_int23(void); /* procsupt.asm */
|
||||||
|
void ASMCFUNC DosIdle_hlt(void); /* dosidle.asm */
|
||||||
|
|
||||||
|
GLOBAL BYTE ReturnAnyDosVersionExpected;
|
||||||
|
GLOBAL BYTE ASM HaltCpuWhileIdle;
|
||||||
|
|
||||||
|
/* near fnodes:
|
||||||
|
* fnode[0] is used internally for almost all cases.
|
||||||
|
* fnode[1] is only used for:
|
||||||
|
* 1) rename (target)
|
||||||
|
* 2) rmdir (checks if the directory to remove is empty)
|
||||||
|
* 3) commit (copies, than closes fnode[0])
|
||||||
|
* 3) merge_file_changes (for SHARE)
|
||||||
|
*/
|
||||||
|
GLOBAL struct f_node fnode[2];
|
32
kernel/init-dat.h
Normal file
32
kernel/init-dat.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* Included by initialisation functions */
|
||||||
|
|
||||||
|
#if _MSC_VER != 0
|
||||||
|
extern __segment DosDataSeg; /* serves for all references to the DOS DATA segment
|
||||||
|
necessary for MSC+our funny linking model
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern __segment DosTextSeg;
|
||||||
|
|
||||||
|
#define DOSFAR __based(DosDataSeg)
|
||||||
|
#define DOSTEXTFAR __based(DosTextSeg)
|
||||||
|
|
||||||
|
#elif defined(__TURBOC__)
|
||||||
|
|
||||||
|
#define DOSFAR FAR
|
||||||
|
#define DOSTEXTFAR FAR
|
||||||
|
|
||||||
|
#elif defined(__WATCOMC__)
|
||||||
|
|
||||||
|
#define DOSFAR FAR
|
||||||
|
#define DOSTEXTFAR FAR
|
||||||
|
|
||||||
|
#elif !defined(I86)
|
||||||
|
|
||||||
|
#define DOSFAR
|
||||||
|
#define DOSTEXTFAR
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#error unknown compiler - please adjust
|
||||||
|
We might even deal with a pre-ANSI compiler. This will certainly not compile.
|
||||||
|
#endif
|
336
kernel/init-mod.h
Normal file
336
kernel/init-mod.h
Normal file
@ -0,0 +1,336 @@
|
|||||||
|
/* Included by initialisation functions */
|
||||||
|
#define IN_INIT_MOD
|
||||||
|
|
||||||
|
#include "version.h"
|
||||||
|
#include "date.h"
|
||||||
|
#include "time.h"
|
||||||
|
#include "mcb.h"
|
||||||
|
#include "sft.h"
|
||||||
|
#include "fat.h"
|
||||||
|
#include "file.h"
|
||||||
|
#include "cds.h"
|
||||||
|
#include "device.h"
|
||||||
|
#include "kbd.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "fcb.h"
|
||||||
|
#include "tail.h"
|
||||||
|
#include "process.h"
|
||||||
|
#include "pcb.h"
|
||||||
|
#include "nls.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
#include "dcb.h"
|
||||||
|
#include "lol.h"
|
||||||
|
|
||||||
|
#include "init-dat.h"
|
||||||
|
|
||||||
|
#include "kconfig.h"
|
||||||
|
|
||||||
|
/* MSC places uninitialized data into COMDEF records,
|
||||||
|
that end up in DATA segment. this can't be tolerated in INIT code.
|
||||||
|
please make sure, that ALL data in INIT is initialized !!
|
||||||
|
|
||||||
|
These guys are marked BSS_INIT to mark that they really should be BSS
|
||||||
|
but can't be because of MS
|
||||||
|
*/
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define BSS_INIT(x) = x
|
||||||
|
#else
|
||||||
|
#define BSS_INIT(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern struct _KernelConfig InitKernelConfig;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Functions in `INIT_TEXT' may need to call functions in `_TEXT'. The entry
|
||||||
|
* calls for the latter functions therefore need to be wrapped up with far
|
||||||
|
* entry points.
|
||||||
|
*/
|
||||||
|
#define printf init_printf
|
||||||
|
#define sprintf init_sprintf
|
||||||
|
#ifndef __WATCOMC__
|
||||||
|
#define execrh init_execrh
|
||||||
|
#define memcpy init_memcpy
|
||||||
|
#define fmemcpy init_fmemcpy
|
||||||
|
#define fmemset init_fmemset
|
||||||
|
#define fmemcmp init_fmemcmp
|
||||||
|
#define memcmp init_memcmp
|
||||||
|
#define memset init_memset
|
||||||
|
#define strchr init_strchr
|
||||||
|
#define strcpy init_strcpy
|
||||||
|
#define strlen init_strlen
|
||||||
|
#define fstrlen init_fstrlen
|
||||||
|
#endif
|
||||||
|
#define open init_DosOpen
|
||||||
|
|
||||||
|
/* execrh.asm */
|
||||||
|
#ifndef __WATCOMC__
|
||||||
|
WORD ASMPASCAL execrh(request FAR *, struct dhdr FAR *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* asmsupt.asm */
|
||||||
|
VOID ASMPASCAL memset( void *s, int ch, size_t n);
|
||||||
|
VOID ASMPASCAL fmemset( void FAR *s, int ch, size_t n);
|
||||||
|
int ASMPASCAL memcmp(const void *m1, const void *m2, size_t n);
|
||||||
|
int ASMPASCAL fmemcmp(const void FAR *m1, const void FAR *m2, size_t n);
|
||||||
|
VOID ASMPASCAL memcpy( void *d, const void *s, size_t n);
|
||||||
|
VOID ASMPASCAL fmemcpy( void FAR *d, const void FAR *s, size_t n);
|
||||||
|
VOID ASMPASCAL strcpy(char *d, const char *s);
|
||||||
|
size_t ASMPASCAL strlen(const char *s);
|
||||||
|
size_t ASMPASCAL fstrlen(const char FAR *s);
|
||||||
|
char * ASMPASCAL strchr(const char *s, int ch);
|
||||||
|
|
||||||
|
#ifdef __WATCOMC__
|
||||||
|
/* bx, cx, dx and es not used or clobbered for all asmsupt.asm functions except
|
||||||
|
(f)memchr/(f)strchr (which clobber dx) */
|
||||||
|
#pragma aux (pascal) pascal_ax modify exact [ax]
|
||||||
|
#pragma aux (pascal_ax) memset
|
||||||
|
#pragma aux (pascal_ax) fmemset
|
||||||
|
#pragma aux (pascal_ax) memcpy
|
||||||
|
#pragma aux (pascal_ax) fmemcpy
|
||||||
|
#pragma aux (pascal_ax) memcmp modify nomemory
|
||||||
|
#pragma aux (pascal_ax) fmemcmp modify nomemory
|
||||||
|
#pragma aux (pascal_ax) strcpy
|
||||||
|
#pragma aux (pascal_ax) strlen modify nomemory
|
||||||
|
#pragma aux (pascal_ax) fstrlen modify nomemory
|
||||||
|
#pragma aux (pascal) strchr modify exact [ax dx] nomemory
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef LINESIZE
|
||||||
|
#define LINESIZE KBD_MAXLENGTH
|
||||||
|
|
||||||
|
/*inithma.c*/
|
||||||
|
extern BYTE DosLoadedInHMA;
|
||||||
|
void MoveKernel(unsigned NewKernelSegment);
|
||||||
|
|
||||||
|
void setvec(unsigned char intno, intvec vector);
|
||||||
|
#ifndef __WATCOMC__
|
||||||
|
#define getvec init_getvec
|
||||||
|
#endif
|
||||||
|
intvec getvec(unsigned char intno);
|
||||||
|
|
||||||
|
#define GLOBAL extern
|
||||||
|
#define NAMEMAX MAX_CDSPATH /* Maximum path for CDS */
|
||||||
|
#define NFILES 16 /* number of files in table */
|
||||||
|
#define NFCBS 16 /* number of fcbs */
|
||||||
|
#define NSTACKS 8 /* number of stacks */
|
||||||
|
#define STACKSIZE 256 /* default stacksize */
|
||||||
|
#define NLAST 5 /* last drive */
|
||||||
|
#define NUMBUFF 20 /* Number of track buffers at INIT time */
|
||||||
|
/* -- must be at least 3 */
|
||||||
|
#define MAX_HARD_DRIVE 8
|
||||||
|
#define NDEV 26 /* up to Z: */
|
||||||
|
|
||||||
|
#include "config.h" /* config structure */
|
||||||
|
|
||||||
|
/* config.c */
|
||||||
|
extern struct config Config;
|
||||||
|
VOID PreConfig(VOID);
|
||||||
|
VOID PreConfig2(VOID);
|
||||||
|
VOID DoConfig(int pass);
|
||||||
|
VOID PostConfig(VOID);
|
||||||
|
VOID configDone(VOID);
|
||||||
|
VOID FAR * KernelAlloc(size_t nBytes, char type, int mode);
|
||||||
|
void FAR * KernelAllocPara(size_t nPara, char type, char *name, int mode);
|
||||||
|
char *strcat(char * d, const char * s);
|
||||||
|
BYTE * GetStringArg(BYTE * pLine, BYTE * pszString);
|
||||||
|
void DoInstall(void);
|
||||||
|
UWORD GetBiosKey(int timeout);
|
||||||
|
|
||||||
|
/* diskinit.c */
|
||||||
|
COUNT dsk_init(VOID);
|
||||||
|
|
||||||
|
/* int2f.asm */
|
||||||
|
COUNT ASMPASCAL Umb_Test(void);
|
||||||
|
COUNT ASMPASCAL UMB_get_largest(void FAR * driverAddress,
|
||||||
|
UCOUNT * seg, UCOUNT * size);
|
||||||
|
#ifdef __WATCOMC__
|
||||||
|
#pragma aux (pascal) UMB_get_largest modify exact [ax bx cx dx]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* inithma.c */
|
||||||
|
int MoveKernelToHMA(void);
|
||||||
|
VOID FAR * HMAalloc(COUNT bytesToAllocate);
|
||||||
|
|
||||||
|
/* initoem.c */
|
||||||
|
unsigned init_oem(void);
|
||||||
|
void movebda(size_t bytes, unsigned new_seg);
|
||||||
|
unsigned ebdasize(void);
|
||||||
|
|
||||||
|
/* dosidle.asm */
|
||||||
|
extern void ASM DosIdle_hlt(VOID);
|
||||||
|
|
||||||
|
/* intr.asm */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Invoke interrupt "nr" with all registers from *rp loaded
|
||||||
|
* into the processor registers (except: SS, SP,& flags)
|
||||||
|
* On return, all processor registers are stored into *rp (including
|
||||||
|
* flags).
|
||||||
|
*/
|
||||||
|
unsigned ASMPASCAL init_call_intr(int nr, iregs * rp);
|
||||||
|
|
||||||
|
unsigned ASMPASCAL read(int fd, void *buf, unsigned count);
|
||||||
|
int ASMPASCAL open(const char *pathname, int flags);
|
||||||
|
int ASMPASCAL close(int fd);
|
||||||
|
int ASMPASCAL dup2(int oldfd, int newfd);
|
||||||
|
ULONG ASMPASCAL lseek(int fd, long position);
|
||||||
|
seg ASMPASCAL allocmem(UWORD size);
|
||||||
|
void ASMPASCAL init_PSPSet(seg psp_seg);
|
||||||
|
int ASMPASCAL init_DosExec(int mode, exec_blk * ep, char * lp);
|
||||||
|
int ASMPASCAL init_setdrive(int drive);
|
||||||
|
int ASMPASCAL init_switchar(int chr);
|
||||||
|
void ASMPASCAL keycheck(void);
|
||||||
|
void ASMPASCAL set_DTA(void far *dta);
|
||||||
|
#ifdef __WATCOMC__
|
||||||
|
#pragma aux (pascal) init_call_intr modify exact [ax]
|
||||||
|
#pragma aux (pascal) read modify exact [ax bx cx dx]
|
||||||
|
#pragma aux (pascal) init_DosOpen modify exact [ax bx dx]
|
||||||
|
#pragma aux (pascal) close modify exact [ax bx]
|
||||||
|
#pragma aux (pascal) dup2 modify exact [ax bx cx]
|
||||||
|
#pragma aux (pascal) allocmem modify exact [ax bx]
|
||||||
|
#pragma aux (pascal) init_PSPSet modify exact [ax bx]
|
||||||
|
#pragma aux (pascal) init_DosExec modify exact [ax bx dx es]
|
||||||
|
#pragma aux (pascal) init_setdrive modify exact [ax bx dx]
|
||||||
|
#pragma aux (pascal) init_switchar modify exact [ax bx dx]
|
||||||
|
#pragma aux (pascal) keycheck modify exact [ax]
|
||||||
|
#pragma aux (pascal) set_DTA modify exact [ax bx dx]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* irqstack.asm */
|
||||||
|
VOID ASMCFUNC init_stacks(VOID FAR * stack_base, COUNT nStacks,
|
||||||
|
WORD stackSize);
|
||||||
|
|
||||||
|
/* inthndlr.c */
|
||||||
|
VOID ASMCFUNC FAR int21_entry(iregs UserRegs);
|
||||||
|
VOID ASMCFUNC int21_service(iregs far * r);
|
||||||
|
VOID ASMCFUNC FAR int0_handler(void);
|
||||||
|
VOID ASMCFUNC FAR int6_handler(void);
|
||||||
|
VOID ASMCFUNC FAR int19_handler(void);
|
||||||
|
VOID ASMCFUNC FAR empty_handler(void);
|
||||||
|
VOID ASMCFUNC FAR int20_handler(void);
|
||||||
|
VOID ASMCFUNC FAR int21_handler(void);
|
||||||
|
VOID ASMCFUNC FAR int22_handler(void);
|
||||||
|
VOID ASMCFUNC FAR int24_handler(void);
|
||||||
|
VOID ASMCFUNC FAR low_int25_handler(void);
|
||||||
|
VOID ASMCFUNC FAR low_int26_handler(void);
|
||||||
|
VOID ASMCFUNC FAR int27_handler(void);
|
||||||
|
VOID ASMCFUNC FAR int28_handler(void);
|
||||||
|
VOID ASMCFUNC FAR int29_handler(void);
|
||||||
|
VOID ASMCFUNC FAR int2a_handler(void);
|
||||||
|
VOID ASMCFUNC FAR int2f_handler(void);
|
||||||
|
VOID ASMCFUNC FAR cpm_entry(void);
|
||||||
|
|
||||||
|
/* kernel.asm */
|
||||||
|
VOID ASMCFUNC FAR init_call_p_0(struct config FAR *Config); /* P_0, actually */
|
||||||
|
|
||||||
|
/* main.c */
|
||||||
|
VOID ASMCFUNC FreeDOSmain(void);
|
||||||
|
BOOL init_device(struct dhdr FAR * dhp, char * cmdLine,
|
||||||
|
COUNT mode, char FAR **top);
|
||||||
|
VOID init_fatal(BYTE * err_msg);
|
||||||
|
|
||||||
|
/* prf.c */
|
||||||
|
int VA_CDECL init_printf(CONST char * fmt, ...);
|
||||||
|
int VA_CDECL init_sprintf(char * buff, CONST char * fmt, ...);
|
||||||
|
|
||||||
|
/* procsupt.asm */
|
||||||
|
VOID ASMCFUNC FAR got_cbreak(void);
|
||||||
|
|
||||||
|
/* initclk.c */
|
||||||
|
extern void Init_clk_driver(void);
|
||||||
|
|
||||||
|
extern UWORD HMAFree; /* first byte in HMA not yet used */
|
||||||
|
|
||||||
|
extern unsigned CurrentKernelSegment;
|
||||||
|
extern struct _KernelConfig FAR ASM LowKernelConfig;
|
||||||
|
extern WORD days[2][13];
|
||||||
|
extern BYTE FAR *lpTop;
|
||||||
|
extern BYTE ASM _ib_start[], ASM _ib_end[], ASM _init_end[];
|
||||||
|
extern UWORD ram_top; /* How much ram in Kbytes */
|
||||||
|
extern char singleStep;
|
||||||
|
extern char SkipAllConfig;
|
||||||
|
extern char master_env[128];
|
||||||
|
|
||||||
|
extern struct lol FAR *LoL;
|
||||||
|
|
||||||
|
extern struct dhdr DOSTEXTFAR ASM blk_dev; /* Block device (Disk) driver */
|
||||||
|
|
||||||
|
extern struct buffer FAR *DOSFAR firstAvailableBuf; /* first 'available' buffer */
|
||||||
|
extern struct lol ASM FAR DATASTART;
|
||||||
|
|
||||||
|
extern BYTE DOSFAR ASM _HMATextAvailable, /* first byte of available CODE area */
|
||||||
|
FAR ASM _HMATextStart[], /* first byte of HMAable CODE area */
|
||||||
|
FAR ASM _HMATextEnd[], DOSFAR ASM break_ena; /* break enabled flag */
|
||||||
|
extern BYTE DOSFAR ASM _InitTextStart[], /* first available byte of ram */
|
||||||
|
DOSFAR ASM _InitTextEnd[],
|
||||||
|
DOSFAR ReturnAnyDosVersionExpected,
|
||||||
|
DOSFAR ASM HaltCpuWhileIdle;
|
||||||
|
|
||||||
|
extern BYTE FAR ASM internal_data[];
|
||||||
|
extern unsigned char FAR ASM kbdType;
|
||||||
|
|
||||||
|
extern struct {
|
||||||
|
char ThisIsAConstantOne;
|
||||||
|
short TableSize;
|
||||||
|
|
||||||
|
struct CountrySpecificInfo C;
|
||||||
|
|
||||||
|
} FAR ASM nlsCountryInfoHardcoded;
|
||||||
|
|
||||||
|
/*
|
||||||
|
data shared between DSK.C and INITDISK.C
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern UWORD DOSFAR LBA_WRITE_VERIFY;
|
||||||
|
|
||||||
|
/* original interrupt vectors, at 70:xxxx */
|
||||||
|
extern struct lowvec {
|
||||||
|
unsigned char intno;
|
||||||
|
intvec isv;
|
||||||
|
} DOSTEXTFAR ASM intvec_table[5];
|
||||||
|
|
||||||
|
/* floppy parameter table, at 70:xxxx */
|
||||||
|
extern unsigned char DOSTEXTFAR ASM int1e_table[0xe];
|
||||||
|
|
||||||
|
extern char DOSFAR DiskTransferBuffer[/*MAX_SEC_SIZE*/]; /* in dsk.c */
|
||||||
|
|
||||||
|
struct RelocationTable {
|
||||||
|
UBYTE jmpFar;
|
||||||
|
UWORD jmpOffset;
|
||||||
|
UWORD jmpSegment;
|
||||||
|
UBYTE callNear;
|
||||||
|
UWORD callOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RelocatedEntry {
|
||||||
|
UBYTE callNear;
|
||||||
|
UWORD callOffset;
|
||||||
|
UBYTE jmpFar;
|
||||||
|
UWORD jmpOffset;
|
||||||
|
UWORD jmpSegment;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct RelocationTable
|
||||||
|
DOSFAR ASM _HMARelocationTableStart[],
|
||||||
|
DOSFAR ASM _HMARelocationTableEnd[];
|
||||||
|
|
||||||
|
extern void FAR *DOSFAR ASM XMSDriverAddress;
|
||||||
|
extern VOID ASMPASCAL FAR _EnableA20(VOID);
|
||||||
|
extern VOID ASMPASCAL FAR _DisableA20(VOID);
|
||||||
|
|
||||||
|
extern void FAR * ASMPASCAL DetectXMSDriver(VOID);
|
||||||
|
extern int ASMPASCAL init_call_XMScall(void FAR * driverAddress, UWORD ax,
|
||||||
|
UWORD dx);
|
||||||
|
#ifdef __WATCOMC__
|
||||||
|
#pragma aux (pascal) DetectXMSDriver modify exact [ax dx]
|
||||||
|
#pragma aux (pascal) _EnableA20 modify exact [ax]
|
||||||
|
#pragma aux (pascal) _DisableA20 modify exact [ax]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WATCOM) && 0
|
||||||
|
ULONG ASMCFUNC FAR MULULUS(ULONG mul1, UWORD mul2); /* MULtiply ULong by UShort */
|
||||||
|
ULONG ASMCFUNC FAR MULULUL(ULONG mul1, ULONG mul2); /* MULtiply ULong by ULong */
|
||||||
|
ULONG ASMCFUNC FAR DIVULUS(ULONG mul1, UWORD mul2); /* DIVide ULong by UShort */
|
||||||
|
ULONG ASMCFUNC FAR DIVMODULUS(ULONG mul1, UWORD mul2, UWORD * rem); /* DIVide ULong by UShort */
|
||||||
|
#endif
|
||||||
|
|
74
kernel/initclk.c
Normal file
74
kernel/initclk.c
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* initclk.c */
|
||||||
|
/* */
|
||||||
|
/* System Clock Driver - initialization */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#include "portab.h"
|
||||||
|
#include "init-mod.h"
|
||||||
|
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static char *RcsId =
|
||||||
|
"$Id: initclk.c 1359 2008-03-09 16:11:10Z mceric $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* WARNING - THIS DRIVER IS NON-PORTABLE!!!! */
|
||||||
|
/* */
|
||||||
|
|
||||||
|
STATIC int InitBcdToByte(int x)
|
||||||
|
{
|
||||||
|
return ((x >> 4) & 0xf) * 10 + (x & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init_clk_driver(void)
|
||||||
|
{
|
||||||
|
static iregs regsT = {0x200}; /* ah=0x02 */
|
||||||
|
static iregs regsD = {0x400, 0, 0x1400, 0x101};
|
||||||
|
/* ah=4, ch=20^ ^cl=0, ^dh=dl=1 (2000/1/1)
|
||||||
|
* (above date will be set on error) */
|
||||||
|
iregs dosregs;
|
||||||
|
|
||||||
|
init_call_intr(0x1a, ®sT); /* get BIOS time */
|
||||||
|
init_call_intr(0x1a, ®sD); /* get BIOS date */
|
||||||
|
|
||||||
|
/* DosSetDate */
|
||||||
|
dosregs.a.b.h = 0x2b;
|
||||||
|
dosregs.c.x = 100 * InitBcdToByte(regsD.c.b.h) /* century */
|
||||||
|
+ InitBcdToByte(regsD.c.b.l);/* year */
|
||||||
|
/* A BIOS with y2k (year 2000) bug will always report year 19nn */
|
||||||
|
if ((dosregs.c.x >= 1900) && (dosregs.c.x < 1980)) dosregs.c.x += 100;
|
||||||
|
dosregs.d.b.h = InitBcdToByte(regsD.d.b.h); /* month */
|
||||||
|
dosregs.d.b.l = InitBcdToByte(regsD.d.b.l); /* day */
|
||||||
|
init_call_intr(0x21, &dosregs);
|
||||||
|
|
||||||
|
/* DosSetTime */
|
||||||
|
dosregs.a.b.h = 0x2d;
|
||||||
|
dosregs.c.b.l = InitBcdToByte(regsT.c.b.l); /* minutes */
|
||||||
|
dosregs.c.b.h = InitBcdToByte(regsT.c.b.h); /* hours */
|
||||||
|
dosregs.d.b.h = InitBcdToByte(regsT.d.b.h); /*seconds */
|
||||||
|
dosregs.d.b.l = 0;
|
||||||
|
init_call_intr(0x21, &dosregs);
|
||||||
|
}
|
1401
kernel/initdisk.c
Normal file
1401
kernel/initdisk.c
Normal file
File diff suppressed because it is too large
Load Diff
410
kernel/inithma.c
Normal file
410
kernel/inithma.c
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* initHMA.c */
|
||||||
|
/* DOS-C */
|
||||||
|
/* */
|
||||||
|
/* move kernel to HMA area */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2001 */
|
||||||
|
/* tom ehlert */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
current status:
|
||||||
|
|
||||||
|
load FreeDOS high, if DOS=HIGH detected
|
||||||
|
|
||||||
|
suppress High Loading, if any SHIFT status detected (for debugging)
|
||||||
|
|
||||||
|
if no XMS driver (HIMEM,FDXMS,...) loaded, should work
|
||||||
|
|
||||||
|
cooperation with XMS drivers as follows:
|
||||||
|
|
||||||
|
copy HMA_TEXT segment up.
|
||||||
|
|
||||||
|
after each loaded DEVICE=SOMETHING.SYS, try to request the HMA
|
||||||
|
(XMS function 0x01).
|
||||||
|
if no XMS driver detected, during ONFIG.SYS processing,
|
||||||
|
create a dummy VDISK entry in high memory
|
||||||
|
|
||||||
|
this works with
|
||||||
|
|
||||||
|
FD FDXMS - no problems detected
|
||||||
|
|
||||||
|
|
||||||
|
MS HIMEM.SYS (from DOS 6.2, 9-30-93)
|
||||||
|
|
||||||
|
works if and only if
|
||||||
|
|
||||||
|
/TESTMEM:OFF
|
||||||
|
|
||||||
|
is given
|
||||||
|
|
||||||
|
otherwise HIMEM will TEST AND ZERO THE HIGH MEMORY+HMA.
|
||||||
|
so, in CONFIG.C, if "HIMEM.SYS" is detected, a "/TESTMEM:OFF"
|
||||||
|
parameter is forced.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "portab.h"
|
||||||
|
#include "init-mod.h"
|
||||||
|
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *RcsId =
|
||||||
|
"$Id: inithma.c 956 2004-05-24 17:07:04Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BYTE DosLoadedInHMA BSS_INIT(FALSE); /* set to TRUE if loaded HIGH */
|
||||||
|
BYTE HMAclaimed BSS_INIT(0); /* set to TRUE if claimed from HIMEM */
|
||||||
|
UWORD HMAFree BSS_INIT(0); /* first byte in HMA not yet used */
|
||||||
|
|
||||||
|
STATIC void InstallVDISK(void);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#ifdef __TURBOC__
|
||||||
|
#define int3() __int__(3);
|
||||||
|
#else
|
||||||
|
void int3()
|
||||||
|
{
|
||||||
|
__asm int 3;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define int3()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define HMAInitPrintf(x) printf x
|
||||||
|
#else
|
||||||
|
#define HMAInitPrintf(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
VOID hdump(BYTE FAR * p)
|
||||||
|
{
|
||||||
|
int loop;
|
||||||
|
HMAInitPrintf(("%p", p));
|
||||||
|
|
||||||
|
for (loop = 0; loop < 16; loop++)
|
||||||
|
HMAInitPrintf(("%02x ", p[loop]));
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define hdump(ptr)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define KeyboardShiftState() (*(BYTE FAR *)(MK_FP(0x40,0x17)))
|
||||||
|
|
||||||
|
/*
|
||||||
|
this tests, if the HMA area can be enabled.
|
||||||
|
if so, it simply leaves it on
|
||||||
|
*/
|
||||||
|
|
||||||
|
STATIC int EnabledA20(void)
|
||||||
|
{
|
||||||
|
return fmemcmp(MK_FP(0, 0), MK_FP(0xffff, 0x0010), 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
int EnableHMA(VOID)
|
||||||
|
{
|
||||||
|
|
||||||
|
_EnableA20();
|
||||||
|
|
||||||
|
if (!EnabledA20())
|
||||||
|
{
|
||||||
|
printf("HMA can't be enabled\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_DisableA20();
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (EnabledA20())
|
||||||
|
{
|
||||||
|
printf("HMA can't be disabled - no problem for us\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_EnableA20();
|
||||||
|
if (!EnabledA20())
|
||||||
|
{
|
||||||
|
printf("HMA can't be enabled second time\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HMAInitPrintf(("HMA success - leaving enabled\n"));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
move the kernel up to high memory
|
||||||
|
this is very unportable
|
||||||
|
|
||||||
|
if we thin we succeeded, we return TRUE, else FALSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define HMAOFFSET 0x20
|
||||||
|
#define HMASEGMENT 0xffff
|
||||||
|
|
||||||
|
int MoveKernelToHMA()
|
||||||
|
{
|
||||||
|
void far *xms_addr;
|
||||||
|
|
||||||
|
if (DosLoadedInHMA)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((xms_addr = DetectXMSDriver()) == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
XMSDriverAddress = xms_addr;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
/* A) for debugging purpose, suppress this,
|
||||||
|
if any shift key is pressed
|
||||||
|
*/
|
||||||
|
if (KeyboardShiftState() & 0x0f)
|
||||||
|
{
|
||||||
|
printf("Keyboard state is %0x, NOT moving to HMA\n",
|
||||||
|
KeyboardShiftState());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* B) check out, if we can have HMA */
|
||||||
|
|
||||||
|
if (!EnableHMA())
|
||||||
|
{
|
||||||
|
printf("Can't enable HMA area (the famous A20), NOT moving to HMA\n");
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate HMA through XMS driver */
|
||||||
|
|
||||||
|
if (HMAclaimed == 0 &&
|
||||||
|
(HMAclaimed =
|
||||||
|
init_call_XMScall(xms_addr, 0x0100, 0xffff)) == 0)
|
||||||
|
{
|
||||||
|
printf("Can't reserve HMA area ??\n");
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MoveKernel(0xffff);
|
||||||
|
|
||||||
|
{
|
||||||
|
/* E) up to now, nothing really bad was done.
|
||||||
|
but now, we reuse the HMA area. bad things will happen
|
||||||
|
|
||||||
|
to find bugs early,
|
||||||
|
cause INT 3 on all accesses to this area
|
||||||
|
*/
|
||||||
|
|
||||||
|
DosLoadedInHMA = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
on finalize, will install a VDISK
|
||||||
|
*/
|
||||||
|
|
||||||
|
InstallVDISK();
|
||||||
|
|
||||||
|
/* report the fact we are running high through int 21, ax=3306 */
|
||||||
|
LoL->version_flags |= 0x10;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
now protect against HIMEM/FDXMS/... by simulating a VDISK
|
||||||
|
FDXMS should detect us and not give HMA access to ohers
|
||||||
|
unfortunately this also disables HIMEM completely
|
||||||
|
|
||||||
|
so: we install this after all drivers have been loaded
|
||||||
|
*/
|
||||||
|
STATIC void InstallVDISK(void)
|
||||||
|
{
|
||||||
|
static struct { /* Boot-Sektor of a RAM-Disk */
|
||||||
|
UBYTE dummy1[3]; /* HIMEM.SYS uses 3, but FDXMS uses 2 */
|
||||||
|
char Name[5];
|
||||||
|
BYTE dummy2[3];
|
||||||
|
WORD BpS;
|
||||||
|
BYTE dummy3[6];
|
||||||
|
WORD Sektoren;
|
||||||
|
BYTE dummy4;
|
||||||
|
} VDISK_BOOT_SEKTOR = {
|
||||||
|
{
|
||||||
|
0xcf, ' ', ' '},
|
||||||
|
{
|
||||||
|
'V', 'D', 'I', 'S', 'K'},
|
||||||
|
{
|
||||||
|
' ', ' ', ' '}, 512,
|
||||||
|
{
|
||||||
|
'F', 'D', 'O', 'S', ' ', ' '}, 128, /* 128*512 = 64K */
|
||||||
|
' '};
|
||||||
|
|
||||||
|
if (!DosLoadedInHMA)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fmemcpy(MK_FP(0xffff, 0x0010), &VDISK_BOOT_SEKTOR,
|
||||||
|
sizeof(VDISK_BOOT_SEKTOR));
|
||||||
|
|
||||||
|
*(WORD FAR *) MK_FP(0xffff, 0x002e) = 1024 + 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
this allocates some bytes from the HMA area
|
||||||
|
only available if DOS=HIGH was successful
|
||||||
|
*/
|
||||||
|
|
||||||
|
VOID FAR * HMAalloc(COUNT bytesToAllocate)
|
||||||
|
{
|
||||||
|
VOID FAR *HMAptr;
|
||||||
|
|
||||||
|
if (!DosLoadedInHMA)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (HMAFree > 0xfff0 - bytesToAllocate)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
HMAptr = MK_FP(0xffff, HMAFree);
|
||||||
|
|
||||||
|
/* align on 16 byte boundary */
|
||||||
|
HMAFree = (HMAFree + bytesToAllocate + 0xf) & 0xfff0;
|
||||||
|
|
||||||
|
/*printf("HMA allocated %d byte at %x\n", bytesToAllocate, HMAptr); */
|
||||||
|
|
||||||
|
fmemset(HMAptr, 0, bytesToAllocate);
|
||||||
|
|
||||||
|
return HMAptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned CurrentKernelSegment = 0;
|
||||||
|
|
||||||
|
void MoveKernel(unsigned NewKernelSegment)
|
||||||
|
{
|
||||||
|
UBYTE FAR *HMADest;
|
||||||
|
UBYTE FAR *HMASource;
|
||||||
|
unsigned len;
|
||||||
|
unsigned jmpseg = CurrentKernelSegment;
|
||||||
|
|
||||||
|
if (CurrentKernelSegment == 0)
|
||||||
|
CurrentKernelSegment = FP_SEG(_HMATextEnd);
|
||||||
|
|
||||||
|
if (CurrentKernelSegment == 0xffff)
|
||||||
|
return;
|
||||||
|
|
||||||
|
HMASource =
|
||||||
|
MK_FP(CurrentKernelSegment, (FP_OFF(_HMATextStart) & 0xfff0));
|
||||||
|
HMADest = MK_FP(NewKernelSegment, 0x0000);
|
||||||
|
|
||||||
|
len = (FP_OFF(_HMATextEnd) | 0x000f) - (FP_OFF(_HMATextStart) & 0xfff0);
|
||||||
|
|
||||||
|
if (NewKernelSegment == 0xffff)
|
||||||
|
{
|
||||||
|
HMASource += HMAOFFSET;
|
||||||
|
HMADest += HMAOFFSET;
|
||||||
|
len -= HMAOFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
HMAInitPrintf(("HMA moving %p up to %p for %04x bytes\n",
|
||||||
|
HMASource, HMADest, len));
|
||||||
|
|
||||||
|
if (NewKernelSegment < CurrentKernelSegment ||
|
||||||
|
NewKernelSegment == 0xffff)
|
||||||
|
fmemcpy(HMADest, HMASource, len);
|
||||||
|
/* else it's the very first relocation: handled by kernel.asm */
|
||||||
|
|
||||||
|
HMAFree = (FP_OFF(HMADest) + len + 0xf) & 0xfff0;
|
||||||
|
/* first free byte after HMA_TEXT on 16 byte boundary */
|
||||||
|
|
||||||
|
{
|
||||||
|
/* D) but it only makes sense, if we can relocate
|
||||||
|
all our entries to make use of HMA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* this is for a
|
||||||
|
call near enableA20
|
||||||
|
jmp far kernelentry
|
||||||
|
style table
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct RelocationTable FAR *rp, rtemp;
|
||||||
|
|
||||||
|
/* verify, that all entries are valid */
|
||||||
|
|
||||||
|
for (rp = _HMARelocationTableStart; rp < _HMARelocationTableEnd; rp++)
|
||||||
|
{
|
||||||
|
if (rp->jmpFar != 0xea || /* jmp FAR */
|
||||||
|
rp->jmpSegment != jmpseg || /* will only relocate HMA_TEXT */
|
||||||
|
rp->callNear != 0xe8 || /* call NEAR */
|
||||||
|
0)
|
||||||
|
{
|
||||||
|
printf("illegal relocation entry # %d\n",
|
||||||
|
(FP_OFF(rp) -
|
||||||
|
FP_OFF(_HMARelocationTableStart)) /
|
||||||
|
sizeof(struct RelocationTable));
|
||||||
|
int3();
|
||||||
|
goto errorReturn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OK, all valid, go to relocate */
|
||||||
|
|
||||||
|
for (rp = _HMARelocationTableStart; rp < _HMARelocationTableEnd; rp++)
|
||||||
|
{
|
||||||
|
if (NewKernelSegment == 0xffff)
|
||||||
|
{
|
||||||
|
struct RelocatedEntry FAR *rel = (struct RelocatedEntry FAR *)rp;
|
||||||
|
|
||||||
|
fmemcpy(&rtemp, rp, sizeof(rtemp));
|
||||||
|
|
||||||
|
rel->jmpFar = rtemp.jmpFar;
|
||||||
|
rel->jmpSegment = NewKernelSegment;
|
||||||
|
rel->jmpOffset = rtemp.jmpOffset;
|
||||||
|
rel->callNear = rtemp.callNear;
|
||||||
|
rel->callOffset = rtemp.callOffset + 5; /* near calls are relative */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rp->jmpSegment = NewKernelSegment;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NewKernelSegment == 0xffff)
|
||||||
|
{
|
||||||
|
/* jmp far cpm_entry (copy from 0:c0) */
|
||||||
|
pokeb(0xffff, 0x30 * 4 + 0x10, 0xea);
|
||||||
|
pokel(0xffff, 0x30 * 4 + 0x11, (ULONG)cpm_entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentKernelSegment = NewKernelSegment;
|
||||||
|
return;
|
||||||
|
|
||||||
|
errorReturn:
|
||||||
|
for (;;) ;
|
||||||
|
}
|
||||||
|
|
73
kernel/initoem.c
Normal file
73
kernel/initoem.c
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* initoem.c */
|
||||||
|
/* */
|
||||||
|
/* OEM Initializattion Functions */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 1995 */
|
||||||
|
/* Pasquale J. Villani */
|
||||||
|
/* All Rights Reserved */
|
||||||
|
/* */
|
||||||
|
/* This file is part of DOS-C. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is free software; you can redistribute it and/or */
|
||||||
|
/* modify it under the terms of the GNU General Public License */
|
||||||
|
/* as published by the Free Software Foundation; either version */
|
||||||
|
/* 2, or (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
||||||
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
||||||
|
/* the GNU General Public License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General Public */
|
||||||
|
/* License along with DOS-C; see the file COPYING. If not, */
|
||||||
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
||||||
|
/* Cambridge, MA 02139, USA. */
|
||||||
|
/* */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#include "portab.h"
|
||||||
|
#include "init-mod.h"
|
||||||
|
|
||||||
|
#ifdef VERSION_STRINGS
|
||||||
|
static BYTE *RcsId =
|
||||||
|
"$Id: initoem.c 1321 2007-05-21 02:16:36Z bartoldeman $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EBDASEG 0x40e
|
||||||
|
#define RAMSIZE 0x413
|
||||||
|
|
||||||
|
unsigned init_oem(void)
|
||||||
|
{
|
||||||
|
iregs r;
|
||||||
|
init_call_intr(0x12, &r);
|
||||||
|
return r.a.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void movebda(size_t bytes, unsigned new_seg)
|
||||||
|
{
|
||||||
|
unsigned old_seg = peek(0, EBDASEG);
|
||||||
|
fmemcpy(MK_FP(new_seg, 0), MK_FP(old_seg, 0), bytes);
|
||||||
|
poke(0, EBDASEG, new_seg);
|
||||||
|
poke(0, RAMSIZE, ram_top);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned ebdasize(void)
|
||||||
|
{
|
||||||
|
unsigned ebdaseg = peek(0, EBDASEG);
|
||||||
|
unsigned ramsize = ram_top;
|
||||||
|
|
||||||
|
if (ramsize == peek(0, RAMSIZE))
|
||||||
|
if (ramsize * 64 == ebdaseg && ramsize < 640 && peek(0, RAMSIZE) == ramsize)
|
||||||
|
{
|
||||||
|
unsigned ebdasz = peekb(ebdaseg, 0);
|
||||||
|
|
||||||
|
/* sanity check: is there really no more than 63 KB?
|
||||||
|
* must be at 640k (all other values never seen and are untested)
|
||||||
|
*/
|
||||||
|
if (ebdasz <= 63 && ramsize + ebdasz == 640)
|
||||||
|
return ebdasz * 1024U;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
539
kernel/int2f.asm
Normal file
539
kernel/int2f.asm
Normal file
@ -0,0 +1,539 @@
|
|||||||
|
;
|
||||||
|
; File:
|
||||||
|
; int2f.asm
|
||||||
|
; Description:
|
||||||
|
; multiplex interrupt support code
|
||||||
|
;
|
||||||
|
; Copyright (c) 1996, 1998
|
||||||
|
; Pasquale J. Villani
|
||||||
|
; All Rights Reserved
|
||||||
|
;
|
||||||
|
; This file is part of DOS-C.
|
||||||
|
;
|
||||||
|
; DOS-C is free software; you can redistribute it and/or
|
||||||
|
; modify it under the terms of the GNU General Public License
|
||||||
|
; as published by the Free Software Foundation; either version
|
||||||
|
; 2, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; DOS-C is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||||
|
; the GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public
|
||||||
|
; License along with DOS-C; see the file COPYING. If not,
|
||||||
|
; write to the Free Software Foundation, 675 Mass Ave,
|
||||||
|
; Cambridge, MA 02139, USA.
|
||||||
|
;
|
||||||
|
; $Id: int2f.asm 1591 2011-05-06 01:46:55Z bartoldeman $
|
||||||
|
;
|
||||||
|
|
||||||
|
%include "segs.inc"
|
||||||
|
%include "stacks.inc"
|
||||||
|
|
||||||
|
segment HMA_TEXT
|
||||||
|
extern _cu_psp:wrt DGROUP
|
||||||
|
extern _HaltCpuWhileIdle:wrt DGROUP
|
||||||
|
extern _syscall_MUX14
|
||||||
|
|
||||||
|
extern _DGROUP_
|
||||||
|
|
||||||
|
global reloc_call_int2f_handler
|
||||||
|
reloc_call_int2f_handler:
|
||||||
|
sti ; Enable interrupts
|
||||||
|
cmp ah,11h ; Network interrupt?
|
||||||
|
jne Int2f3 ; No, continue
|
||||||
|
Int2f1:
|
||||||
|
or al,al ; Installation check?
|
||||||
|
jz FarTabRetn ; yes, just return
|
||||||
|
Int2f2:
|
||||||
|
mov ax,1 ; TE 07/13/01
|
||||||
|
; at least for redirected INT21/5F44
|
||||||
|
; --> 2f/111e
|
||||||
|
; the error code is AX=0001 = unknown function
|
||||||
|
stc
|
||||||
|
FarTabRetn:
|
||||||
|
retf 2 ; Return far
|
||||||
|
|
||||||
|
WinIdle: ; only HLT if at haltlevel 2+
|
||||||
|
push ds
|
||||||
|
mov ds, [cs:_DGROUP_]
|
||||||
|
cmp byte [_HaltCpuWhileIdle],2
|
||||||
|
pop ds
|
||||||
|
jb FarTabRetn
|
||||||
|
pushf
|
||||||
|
sti
|
||||||
|
hlt ; save some energy :-)
|
||||||
|
popf
|
||||||
|
push ds
|
||||||
|
mov ds, [cs:_DGROUP_]
|
||||||
|
cmp byte [_HaltCpuWhileIdle],3
|
||||||
|
pop ds
|
||||||
|
jb FarTabRetn
|
||||||
|
mov al,0 ; even admit we HLTed ;-)
|
||||||
|
jmp short FarTabRetn
|
||||||
|
|
||||||
|
Int2f3: cmp ax,1680h ; Win "release time slice"
|
||||||
|
je WinIdle
|
||||||
|
cmp ah,16h
|
||||||
|
je FarTabRetn ; other Win Hook return fast
|
||||||
|
cmp ah,12h
|
||||||
|
je IntDosCal ; Dos Internal calls
|
||||||
|
|
||||||
|
cmp ax,4a01h
|
||||||
|
je IntDosCal ; Dos Internal calls
|
||||||
|
cmp ax,4a02h
|
||||||
|
je IntDosCal ; Dos Internal calls
|
||||||
|
%ifdef WITHFAT32
|
||||||
|
cmp ax,4a33h ; Check DOS version 7
|
||||||
|
jne Check4Share
|
||||||
|
xor ax,ax ; no undocumented shell strings
|
||||||
|
iret
|
||||||
|
Check4Share:
|
||||||
|
%endif
|
||||||
|
cmp ah,10h ; SHARE.EXE interrupt?
|
||||||
|
je Int2f1 ; yes, do installation check
|
||||||
|
cmp ah,08h
|
||||||
|
je DriverSysCal ; DRIVER.SYS calls
|
||||||
|
cmp ah,14h ; NLSFUNC.EXE interrupt?
|
||||||
|
jne Int2f?iret ; yes, do installation check
|
||||||
|
Int2f?14: ;; MUX-14 -- NLSFUNC API
|
||||||
|
;; all functions are passed to syscall_MUX14
|
||||||
|
push bp ; Preserve BP later on
|
||||||
|
Protect386Registers
|
||||||
|
PUSH$ALL
|
||||||
|
mov ds, [cs:_DGROUP_]
|
||||||
|
call _syscall_MUX14
|
||||||
|
pop bp ; Discard incoming AX
|
||||||
|
push ax ; Correct stack for POP$ALL
|
||||||
|
POP$ALL
|
||||||
|
Restore386Registers
|
||||||
|
mov bp, sp
|
||||||
|
or ax, ax
|
||||||
|
jnz Int2f?14?1 ; must return set carry
|
||||||
|
;; -6 == -2 (CS), -2 (IP), -2 (flags)
|
||||||
|
;; current SP = on old_BP
|
||||||
|
and BYTE [bp-6], 0feh ; clear carry as no error condition
|
||||||
|
pop bp
|
||||||
|
iret
|
||||||
|
Int2f?14?1: or BYTE [bp-6], 1
|
||||||
|
pop bp
|
||||||
|
Int2f?iret:
|
||||||
|
iret
|
||||||
|
|
||||||
|
; DRIVER.SYS calls - now only 0803.
|
||||||
|
DriverSysCal:
|
||||||
|
extern _Dyn:wrt DGROUP
|
||||||
|
cmp al, 3
|
||||||
|
jne Int2f?iret
|
||||||
|
mov ds, [cs:_DGROUP_]
|
||||||
|
mov di, _Dyn+2
|
||||||
|
jmp short Int2f?iret
|
||||||
|
|
||||||
|
|
||||||
|
;**********************************************************************
|
||||||
|
; internal dos calls INT2F/12xx and INT2F/4A01,4A02 - handled through C
|
||||||
|
;**********************************************************************
|
||||||
|
IntDosCal:
|
||||||
|
; set up register frame
|
||||||
|
;struct int2f12regs
|
||||||
|
;{
|
||||||
|
; [space for 386 regs]
|
||||||
|
; UWORD es,ds;
|
||||||
|
; UWORD di,si,bp,bx,dx,cx,ax;
|
||||||
|
; UWORD ip,cs,flags;
|
||||||
|
; UWORD callerARG1;
|
||||||
|
;}
|
||||||
|
push ax
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push bx
|
||||||
|
push bp
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
|
||||||
|
cld
|
||||||
|
|
||||||
|
%if XCPU >= 386
|
||||||
|
%ifdef WATCOM
|
||||||
|
mov si,fs
|
||||||
|
mov di,gs
|
||||||
|
%else
|
||||||
|
Protect386Registers
|
||||||
|
%endif
|
||||||
|
%endif
|
||||||
|
|
||||||
|
mov ds,[cs:_DGROUP_]
|
||||||
|
extern _int2F_12_handler
|
||||||
|
call _int2F_12_handler
|
||||||
|
|
||||||
|
%if XCPU >= 386
|
||||||
|
%ifdef WATCOM
|
||||||
|
mov fs,si
|
||||||
|
mov gs,di
|
||||||
|
%else
|
||||||
|
Restore386Registers
|
||||||
|
%endif
|
||||||
|
%endif
|
||||||
|
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop bp
|
||||||
|
pop bx
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop ax
|
||||||
|
|
||||||
|
iret
|
||||||
|
|
||||||
|
global SHARE_CHECK
|
||||||
|
SHARE_CHECK:
|
||||||
|
mov ax, 0x1000
|
||||||
|
int 0x2f
|
||||||
|
ret
|
||||||
|
|
||||||
|
; DOS calls this to see if it's okay to open the file.
|
||||||
|
; Returns a file_table entry number to use (>= 0) if okay
|
||||||
|
; to open. Otherwise returns < 0 and may generate a critical
|
||||||
|
; error. If < 0 is returned, it is the negated error return
|
||||||
|
; code, so DOS simply negates this value and returns it in
|
||||||
|
; AX.
|
||||||
|
; STATIC int share_open_check(char * filename,
|
||||||
|
; /* pointer to fully qualified filename */
|
||||||
|
; unsigned short pspseg,
|
||||||
|
; /* psp segment address of owner process */
|
||||||
|
; int openmode,
|
||||||
|
; /* 0=read-only, 1=write-only, 2=read-write */
|
||||||
|
; int sharemode) /* SHARE_COMPAT, etc... */
|
||||||
|
global SHARE_OPEN_CHECK
|
||||||
|
SHARE_OPEN_CHECK:
|
||||||
|
mov es, si ; save si
|
||||||
|
pop ax ; return address
|
||||||
|
pop dx ; sharemode;
|
||||||
|
pop cx ; openmode;
|
||||||
|
pop bx ; pspseg;
|
||||||
|
pop si ; filename
|
||||||
|
push ax ; return address
|
||||||
|
mov ax, 0x10a0
|
||||||
|
int 0x2f ; returns ax
|
||||||
|
mov si, es ; restore si
|
||||||
|
ret
|
||||||
|
|
||||||
|
; DOS calls this to record the fact that it has successfully
|
||||||
|
; closed a file, or the fact that the open for this file failed.
|
||||||
|
; STATIC void share_close_file(int fileno) /* file_table entry number */
|
||||||
|
|
||||||
|
global SHARE_CLOSE_FILE
|
||||||
|
SHARE_CLOSE_FILE:
|
||||||
|
pop ax
|
||||||
|
pop bx
|
||||||
|
push ax
|
||||||
|
mov ax, 0x10a1
|
||||||
|
int 0x2f
|
||||||
|
ret
|
||||||
|
|
||||||
|
; DOS calls this to determine whether it can access (read or
|
||||||
|
; write) a specific section of a file. We call it internally
|
||||||
|
; from lock_unlock (only when locking) to see if any portion
|
||||||
|
; of the requested region is already locked. If pspseg is zero,
|
||||||
|
; then it matches any pspseg in the lock table. Otherwise, only
|
||||||
|
; locks which DO NOT belong to pspseg will be considered.
|
||||||
|
; Returns zero if okay to access or lock (no portion of the
|
||||||
|
; region is already locked). Otherwise returns non-zero and
|
||||||
|
; generates a critical error (if allowcriter is non-zero).
|
||||||
|
; If non-zero is returned, it is the negated return value for
|
||||||
|
; the DOS call.
|
||||||
|
;STATIC int share_access_check(unsigned short pspseg,
|
||||||
|
; /* psp segment address of owner process */
|
||||||
|
; int fileno, /* file_table entry number */
|
||||||
|
; unsigned long ofs, /* offset into file */
|
||||||
|
; unsigned long len, /* length (in bytes) of region to access */
|
||||||
|
; int allowcriter) /* allow a critical error to be generated */
|
||||||
|
global SHARE_ACCESS_CHECK
|
||||||
|
SHARE_ACCESS_CHECK:
|
||||||
|
mov ax, 0x10a2
|
||||||
|
share_common:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
mov bx, [bp + 16] ; pspseg
|
||||||
|
mov cx, [bp + 14] ; fileno
|
||||||
|
mov si, [bp + 12] ; high word of ofs
|
||||||
|
mov di, [bp + 10] ; low word of ofs
|
||||||
|
les dx, [bp + 6] ; len
|
||||||
|
or ax, [bp + 4] ; allowcriter/unlock
|
||||||
|
int 0x2f
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop bp
|
||||||
|
ret 14 ; returns ax
|
||||||
|
|
||||||
|
; DOS calls this to lock or unlock a specific section of a file.
|
||||||
|
; Returns zero if successfully locked or unlocked. Otherwise
|
||||||
|
; returns non-zero.
|
||||||
|
; If the return value is non-zero, it is the negated error
|
||||||
|
; return code for the DOS 0x5c call. */
|
||||||
|
;STATIC int share_lock_unlock(unsigned short pspseg, /* psp segment address of owner process */
|
||||||
|
; int fileno, /* file_table entry number */
|
||||||
|
; unsigned long ofs, /* offset into file */
|
||||||
|
; unsigned long len, /* length (in bytes) of region to lock or unlock */
|
||||||
|
; int unlock) /* one to unlock; zero to lock */
|
||||||
|
global SHARE_LOCK_UNLOCK
|
||||||
|
SHARE_LOCK_UNLOCK:
|
||||||
|
mov ax,0x10a4
|
||||||
|
jmp short share_common
|
||||||
|
|
||||||
|
; Int 2F Multipurpose Remote System Calls
|
||||||
|
;
|
||||||
|
; added by James Tabor jimtabor@infohwy.com
|
||||||
|
; changed by Bart Oldeman
|
||||||
|
;
|
||||||
|
; assume ss == ds after setup of stack in entry
|
||||||
|
; sumtimes return data *ptr is the push stack word
|
||||||
|
;
|
||||||
|
|
||||||
|
remote_lseek: ; arg is a pointer to the long seek value
|
||||||
|
mov bx, cx
|
||||||
|
mov dx, [bx]
|
||||||
|
mov cx, [bx+2]
|
||||||
|
; "fall through"
|
||||||
|
|
||||||
|
remote_getfattr:
|
||||||
|
clc ; set to succeed
|
||||||
|
int 2fh
|
||||||
|
jc ret_neg_ax
|
||||||
|
jmp short ret_int2f
|
||||||
|
|
||||||
|
remote_lock_unlock:
|
||||||
|
mov dx, cx ; parameter block (dx) in arg
|
||||||
|
mov bx, cx
|
||||||
|
mov bl, [bx + 8] ; unlock or not
|
||||||
|
mov cx, 1
|
||||||
|
int 0x2f
|
||||||
|
jnc ret_set_ax_to_carry
|
||||||
|
mov ah, 0
|
||||||
|
jmp short ret_neg_ax
|
||||||
|
|
||||||
|
;long ASMPASCAL network_redirector_mx(unsigned cmd, void far *s, void *arg)
|
||||||
|
global NETWORK_REDIRECTOR_MX
|
||||||
|
NETWORK_REDIRECTOR_MX:
|
||||||
|
pop bx ; ret address
|
||||||
|
pop cx ; stack value (arg); cx in remote_rw
|
||||||
|
pop dx ; off s
|
||||||
|
pop es ; seg s
|
||||||
|
pop ax ; cmd (ax)
|
||||||
|
push bx ; ret address
|
||||||
|
call_int2f:
|
||||||
|
push bp
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
cmp al, 0fh
|
||||||
|
je remote_getfattr
|
||||||
|
|
||||||
|
mov di, dx ; es:di -> s and dx is used for 1125!
|
||||||
|
cmp al, 08h
|
||||||
|
je remote_rw
|
||||||
|
cmp al, 09h
|
||||||
|
je remote_rw
|
||||||
|
cmp al, 0ah
|
||||||
|
je remote_lock_unlock
|
||||||
|
cmp al, 21h
|
||||||
|
je remote_lseek
|
||||||
|
cmp al, 22h
|
||||||
|
je remote_process_end
|
||||||
|
cmp al, 23h
|
||||||
|
je qremote_fn
|
||||||
|
|
||||||
|
push cx ; arg
|
||||||
|
cmp al, 0ch
|
||||||
|
je remote_getfree
|
||||||
|
cmp al, 1eh
|
||||||
|
je remote_print_doredir
|
||||||
|
cmp al, 1fh
|
||||||
|
je remote_print_doredir
|
||||||
|
|
||||||
|
int2f_call:
|
||||||
|
xor cx, cx ; set to succeed; clear carry and CX
|
||||||
|
int 2fh
|
||||||
|
pop bx
|
||||||
|
jnc ret_set_ax_to_cx
|
||||||
|
ret_neg_ax:
|
||||||
|
neg ax
|
||||||
|
ret_int2f:
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop bp
|
||||||
|
ret
|
||||||
|
|
||||||
|
ret_set_ax_to_cx: ; ext_open or rw -> status from CX in AX
|
||||||
|
; otherwise CX was set to zero above
|
||||||
|
xchg ax, cx ; set ax:=cx (one byte shorter than mov)
|
||||||
|
jmp short ret_int2f
|
||||||
|
|
||||||
|
remote_print_doredir: ; di points to an lregs structure
|
||||||
|
mov es,[di+0xe]
|
||||||
|
mov bx,[di+2]
|
||||||
|
mov cx,[di+4]
|
||||||
|
mov dx,[di+6]
|
||||||
|
mov si,[di+8]
|
||||||
|
lds di,[di+0xa]
|
||||||
|
|
||||||
|
clc ; set to succeed
|
||||||
|
int 2fh
|
||||||
|
pop bx ; restore stack and ds=ss
|
||||||
|
push ss
|
||||||
|
pop ds
|
||||||
|
jc ret_neg_ax
|
||||||
|
ret_set_ax_to_carry: ; carry => -1 else 0 (SUCCESS)
|
||||||
|
sbb ax, ax
|
||||||
|
jmp short ret_int2f
|
||||||
|
|
||||||
|
remote_getfree:
|
||||||
|
clc ; set to succeed
|
||||||
|
int 2fh
|
||||||
|
pop di ; retrieve pushed pointer arg
|
||||||
|
jc ret_set_ax_to_carry
|
||||||
|
mov [di],ax
|
||||||
|
mov [di+2],bx
|
||||||
|
mov [di+4],cx
|
||||||
|
mov [di+6],dx
|
||||||
|
jmp short ret_set_ax_to_carry
|
||||||
|
|
||||||
|
remote_rw:
|
||||||
|
clc ; set to succeed
|
||||||
|
int 2fh
|
||||||
|
jc ret_min_dx_ax
|
||||||
|
xor dx, dx ; dx:ax := dx:cx = bytes read
|
||||||
|
jmp short ret_set_ax_to_cx
|
||||||
|
ret_min_dx_ax: neg ax
|
||||||
|
cwd
|
||||||
|
jmp short ret_int2f
|
||||||
|
|
||||||
|
qremote_fn:
|
||||||
|
mov bx, cx
|
||||||
|
lds si, [bx]
|
||||||
|
jmp short int2f_restore_ds
|
||||||
|
|
||||||
|
remote_process_end: ; Terminate process
|
||||||
|
mov ds, [_cu_psp]
|
||||||
|
int2f_restore_ds:
|
||||||
|
clc
|
||||||
|
int 2fh
|
||||||
|
push ss
|
||||||
|
pop ds
|
||||||
|
jmp short ret_set_ax_to_carry
|
||||||
|
|
||||||
|
; extern UWORD ASMPASCAL call_nls(UWORD bp, UWORD FAR *buf,
|
||||||
|
; UWORD subfct, UWORD cp, UWORD cntry, UWORD bufsize);
|
||||||
|
|
||||||
|
extern _nlsInfo:wrt DGROUP
|
||||||
|
global CALL_NLS
|
||||||
|
CALL_NLS:
|
||||||
|
pop es ; ret addr
|
||||||
|
pop cx ; bufsize
|
||||||
|
pop dx ; cntry
|
||||||
|
pop bx ; cp
|
||||||
|
pop ax ; sub fct
|
||||||
|
mov ah, 0x14
|
||||||
|
push es ; ret addr
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
mov si, _nlsInfo ; nlsinfo
|
||||||
|
les di, [bp + 4] ; buf
|
||||||
|
mov bp, [bp + 8] ; bp
|
||||||
|
int 0x2f
|
||||||
|
mov dx, bx ; return id in high word
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop bp
|
||||||
|
ret 6
|
||||||
|
|
||||||
|
; extern UWORD ASMPASCAL floppy_change(UWORD drives)
|
||||||
|
|
||||||
|
global FLOPPY_CHANGE
|
||||||
|
FLOPPY_CHANGE:
|
||||||
|
pop cx ; ret addr
|
||||||
|
pop dx ; drives
|
||||||
|
push cx ; ret addr
|
||||||
|
mov ax, 0x4a00
|
||||||
|
xor cx, cx
|
||||||
|
int 0x2f
|
||||||
|
mov ax, cx ; return
|
||||||
|
ret
|
||||||
|
|
||||||
|
;
|
||||||
|
; Test to see if a umb driver has been loaded.
|
||||||
|
; if so, retrieve largest available block+size
|
||||||
|
;
|
||||||
|
; From RB list and Dosemu xms.c.
|
||||||
|
;
|
||||||
|
; Call the XMS driver "Request upper memory block" function with:
|
||||||
|
; AH = 10h
|
||||||
|
; DX = size of block in paragraphs
|
||||||
|
; Return: AX = status
|
||||||
|
; 0001h success
|
||||||
|
; BX = segment address of UMB
|
||||||
|
; DX = actual size of block
|
||||||
|
; 0000h failure
|
||||||
|
; BL = error code (80h,B0h,B1h) (see #02775)
|
||||||
|
; DX = largest available block
|
||||||
|
;
|
||||||
|
; (Table 02775)
|
||||||
|
; Values for XMS error code returned in BL:
|
||||||
|
; 00h successful
|
||||||
|
; 80h function not implemented
|
||||||
|
; B0h only a smaller UMB is available
|
||||||
|
; B1h no UMBs are available
|
||||||
|
; B2h UMB segment number is invalid
|
||||||
|
;
|
||||||
|
|
||||||
|
segment INIT_TEXT
|
||||||
|
; int ASMPASCAL UMB_get_largest(void FAR * driverAddress,
|
||||||
|
; UCOUNT * seg, UCOUNT * size);
|
||||||
|
global UMB_GET_LARGEST
|
||||||
|
|
||||||
|
UMB_GET_LARGEST:
|
||||||
|
push bp
|
||||||
|
mov bp,sp
|
||||||
|
|
||||||
|
mov dx,0xffff ; go for broke!
|
||||||
|
mov ax,1000h ; get the UMBs
|
||||||
|
call far [bp+8] ; Call the driver
|
||||||
|
|
||||||
|
;
|
||||||
|
; bl = 0xB0 and ax = 0 so do it again.
|
||||||
|
;
|
||||||
|
cmp bl,0xb0 ; fail safe
|
||||||
|
jne umbt_error
|
||||||
|
|
||||||
|
and dx,dx ; if it returns a size of zero.
|
||||||
|
je umbt_error
|
||||||
|
|
||||||
|
mov ax,1000h ; dx set with largest size
|
||||||
|
call far [bp+8] ; Call the driver
|
||||||
|
|
||||||
|
cmp ax,1
|
||||||
|
jne umbt_error
|
||||||
|
; now return the segment
|
||||||
|
; and the size
|
||||||
|
|
||||||
|
mov cx,bx ; *seg = segment
|
||||||
|
mov bx, [bp+6]
|
||||||
|
mov [bx],cx
|
||||||
|
|
||||||
|
mov bx, [bp+4] ; *size = size
|
||||||
|
mov [bx],dx
|
||||||
|
|
||||||
|
umbt_ret:
|
||||||
|
pop bp
|
||||||
|
ret 8 ; this was called NEAR!!
|
||||||
|
|
||||||
|
umbt_error: xor ax,ax
|
||||||
|
jmp short umbt_ret
|
2086
kernel/inthndlr.c
Normal file
2086
kernel/inthndlr.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user