patches from Arkady, Lucho, and Bart -- see history.txt for details

git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/branches/UNSTABLE@1009 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Kenneth J Davis 2004-07-25 09:55:58 +00:00
parent 640ab403e2
commit f4ab00c556
25 changed files with 599 additions and 423 deletions

View File

@ -91,50 +91,6 @@ Entry: jmp short real_start
;%define StoreSI bp+3h ;temp store
; To save space, functions that are just called once are
; implemented as macros instead. Four bytes are saved by
; avoiding the call / ret instructions.
; GETDRIVEPARMS: Calculate start of some disk areas.
;
%macro GETDRIVEPARMS 0
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
add si, ax
adc di, byte 0 ; DI:SI = first data sector
mov [data_start], si
mov [data_start+2], di
%endmacro
;-----------------------------------------------------------------------
times 0x3E-$+$$ db 0
@ -216,10 +172,42 @@ dont_use_dl: ; no, rely on [drive] written by SYS
mov LBA_SIZE, 10h
mov LBA_SECNUM,1 ; initialise LBA packet constants
call print
db "FreeDOS",0
GETDRIVEPARMS
; 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
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.
@ -235,8 +223,6 @@ dont_use_dl: ; no, rely on [drive] written by SYS
mov di, word [RootDirSecs]
les bx, [loadsegoff_60] ; es:bx = 60:0
call readDisk
jc jmp_boot_error
les di, [loadsegoff_60] ; es:di = 60:0
@ -258,10 +244,6 @@ next_entry: mov cx, 11
ffDone:
push ax ; store first cluster number
; call print
; db " FAT",0
; GETFATCHAIN:
;
@ -271,20 +253,16 @@ ffDone:
;
; 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 around 3 kb.
; 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, so it should fit in the temporary buffer.
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
jmp_boot_error: jc boot_error
; Set ES:DI to the temporary storage for the FAT chain.
push ds
@ -342,9 +320,6 @@ finished: ; Mark end of FAT chain with 0, so we have a single
push cs
pop ds
;call print
;db " Kernel",0 ; "KERNEL"
; loadFile: Loads the file into memory, one cluster at a time.
@ -353,10 +328,12 @@ finished: ; Mark end of FAT chain with 0, so we have a single
mov si, FATBUF ; set DS:SI to the FAT chain
cluster_next: lodsw ; AX = next cluster to read
or ax, ax ; if EOF...
je boot_success ; ...boot was successful
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
dec ax ; cluster numbers start with 2
load_next: dec ax ; cluster numbers start with 2
dec ax
mov di, word [bsSecPerClust]
@ -365,35 +342,26 @@ cluster_next: lodsw ; AX = next cluster to read
add ax, [data_start]
adc dx, [data_start+2] ; DX:AX = first sector to read
call readDisk
jnc cluster_next
jmp short cluster_next
; shows text after the call to this function.
boot_error: call print
db " err",0
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
xor ah,ah
int 0x16 ; wait for a key
int 0x19 ; reboot the machine
boot_error: call show
db "Error! Hit a key to reboot."
boot_success:
;call print
;db " GO! ",0
mov bl, [drive]
jmp far [loadsegoff_60]
; 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
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.
@ -401,7 +369,6 @@ print1: lodsb ; get token
; Call with: DX:AX = 32-bit DOS sector number
; DI = number of sectors to read
; ES:BX = destination buffer
; ES must be 64k aligned (1000h, 2000h etc).
;
; Returns: CF set on error
; ES:BX points one byte after the last byte read.
@ -413,6 +380,8 @@ readDisk: push si
mov word [LBA_SEG],es
mov word [LBA_OFF],bx
call show
db "."
read_next:
;******************** LBA_READ *******************************
@ -487,25 +456,15 @@ read_normal_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)
mov al, byte [sectPerTrack]
sub al, ah ; al has # of sectors left
inc ah ; sector offset from 1
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:
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
read_ok:
jc boot_error ; exit on error
mov ax, word [bsBytesPerSec]
div byte[LBA_PACKET] ; luckily 16 !!
add word [LBA_SEG], ax
@ -513,7 +472,7 @@ read_ok:
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_chained ; continue
jnz read_next ; continue
mov es,word [LBA_SEG]
; clear carry: unnecessary since adc clears it

View File

@ -4,7 +4,7 @@
:- $Id$
:-----------------------------------------------------------------------
:- Syntax: BUILD [-r] [fat32|fat16] [msc|wc|tc|tcpp] [86|186|386]
:- Syntax: BUILD [-r] [fat32|fat16] [msc|wc|tc|tcpp] [86|186|386] [debug] [lfnapi]
:- option case is significant !!
:-----------------------------------------------------------------------
@ -39,6 +39,9 @@ if "%1" == "86" set XCPU=86
if "%1" == "186" set XCPU=186
if "%1" == "386" set XCPU=386
if "%1" == "debug" set ALLCFLAGS=%ALLCFLAGS% -DDEBUG
if "%1" == "lfnapi" set ALLCFLAGS=%ALLCFLAGS% -DWITHLFNAPI
shift
if not "%1" == "" goto loop_commandline
@ -108,10 +111,13 @@ goto end
:-----------------------------------------------------------------------
:abort-cd
cd ..
:noenv
echo Unable to set necessary environment variables!
goto abort
:abort-cd
cd ..
:abort
echo Compilation was aborted!

View File

@ -109,6 +109,7 @@ set XUPX=upx --8086 --best
:-----------------------------------------------------------------------
:- select default target: CPU type (default is 86) and
:- what FAT system (default is 32) to support
:- NOTE: Turbo C doesn't support 386 CPU.
::set XCPU=86
::set XCPU=186

View File

@ -80,6 +80,7 @@ set MAKE=
set XUPX=
set XCPU=
set XFAT=
set ALLCFLAGS=
if not "%OLDPATH%" == "" set PATH=%OLDPATH%
set OLDPATH=

View File

@ -1,51 +1,220 @@
Advanced - FreeDOS specific - CONFIG.SYS processing
a new command DOSDATA=UMB
DOSDATA=UMB loads some FreeDOS specific stuff in Upper Memory Blocks,
like the RAM that FILESHIGH, LASTDRIVEHIGH, and STACKSHIGH occupy
a new command ECHO
ECHO does ECHO its argument (surprised ?-) and is executed at
the time the DEVICE= lines are executed.
use it similarly to
ECHO loading driver 1
device=Driver1.sys
ECHO driver1 successfully loaded
a new command called EECHO is also available, for echo-ing ANSI Escape Sequences
(redefines keyboard input for example).
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
kernels 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.
an undocumented command SCREEN=xx
SCREEN= switches into videomode xxx (INT10/11xx/000)
useful
SCREEN=0x11 -- 28 lines
SCREEN=0x12 -- 43/50 lines (on EGA/VGA)
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.
e.g. break=off
BUFFERS
BUFFERSHIGH
Usage: buffers=nn[,n] where nn is in range 1-99 & n 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.
e.g. buffers=20
COUNTRY
Usage: country=nnn[,[mmm][,[d:][path]file]]
Only limited country=nnn support is presently available.
Enables/sets international features of DOS
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
e.g. 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.
e.g. 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.
e.g. devicehigh=atapicdd.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
e.g. dos=high,umb
or 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=).
e.g. 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).
e.g.
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 loaded prior to use.
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) most applications will not need this value adjusted.
e.g. 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
e.g. files=20
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.
e.g. install=nansi.com
LASTDRIVE
LASTDRIVEHIGH
Usage: lastdrive=x
where x is last drive letter available for use; A-Z
e.g. lastdrive=z
NUMLOCK
Usage: numlock=on|off
Set the keyboard number lock to on or off.
e.g. 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 are ignored. This may also be used to temporarily disable
loading a particular device or other option.
SCREEN
Usage: screen=xx
Switches into videomode xxx (INT10/11xx/000)
where xx should be 0x11 for 28 lines or 0x12 for 43/50 (EGA/VGA) lines
SET
Usage: set ENVVAR=value
Sets the environment variable to provided value.
e.g. 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.
e.g. shell=C:\COMMAND.COM /E:256 /P
STACKS
STACKSHIGH
Usage: stacks=nn,nnn
where nn is in range 0,8-64 and nnn is in range 32-512
Changes number of stacks available
nn is number of different stacks and nnn is size in bytes of each one
e.g. 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.
e.g. switchar=-
VERSION
Usage: version=x.y
FreeDOS specific command to specify what DOS version to report.
e.g. version=6.2
the following advanced config.sys processing options are available:
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:
@ -66,8 +235,11 @@ MENUDEFAULT=0,1 ( configuration 0, wait 1 second)
2? device=MyNetworkDriver.SYS
Although this is definitively worse then MSDOS menuing possibilities,
IMHO it's better then nothing.
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.
@ -165,11 +337,7 @@ MENUDEFAULT=1,10 ( configuration 1, wait 10 seconds)
4? ECHO You selected menu #4
2002-11-28 - Tom Ehlert
2003-07-15 - Bernd Blaauw
2003-09-18 - Bart Oldeman
2003-09-18 - Bart Oldeman
2004-07-24 - Jeremy Davis

View File

@ -1,6 +1,6 @@
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 me at bart@dosemu.org so I can add you to the 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:

View File

@ -1,5 +1,8 @@
2004 July 8 - UNSTABLE branch
-------- Jeremy Davis (jeremyd@computer.org)
+ Changes Bart
* int2f.asm
- bugfix: call_nls: DI register was not preserved
+ Changes Tom
* inthndlr.c
- improve handling of case where eg. FindFirst(I:\*.*) fails, causes Int24,
@ -264,6 +267,16 @@
bytes, because Shell=SecPathName+50 and sizeof SecPathName=128).
- P_0(): now supported command line without space between command and
options (starting from '/').
* dosfns.c
- common code from DosFindFirst() and DosFindNext() moved to pop_dmp()
- optimization for SftSeek()
* ludivmul.inc
- bugfix: division of long numbers in LDIVMODU macro (used for Watcom)
was wrong. Example: 100000h%8000Fh was gives 0FFFF1h instead 7_FFF1h.
- shorter code.
* inthndlr.c
- fix: INT21/3301 now returns in DL low bit of input value (as in MS-DOS).
- callerARG1 declared as xreg instead UWORD.
+ Changes Bernd, Aitor, & Arkady
* config.c
- source: (Bernd) the codepage table rewritten into a smaller layout.
@ -276,6 +289,19 @@
- fix: for MSVC CONST segment should be class CONST, not DATA.
* dsk.c
- play_dj() now says same words as MS-DOS6.
* boot.asm
- optimize and make more user friendly instead of retrying endlessly
* sys.c
- change OEM Name field to FRDOS4.1 per Eric Auer for better compatibility.
* ludivmul.inc
- 32-bit division code for 386-enabled Watcom kernel.
* inthndlr.c
- fix: for INT21/5F07 and 5F08, before changing bit CDSPHYSDRV,
MS-DOS checks if physical device associated with drive letter. Without
this check MS-FORMAT under FreeDOS was destroys RAMDISK.
+ Changes Jeremy
* config.txt
- update to include all CONFIG.SYS options (except ANYDOS)
*** Sync - Stable Build 2035 ***
2004 May 30 - Build 2035

View File

@ -17,7 +17,7 @@ all: ..\lib\device.lib
-$(RM) $*.lib
$(LIBUTIL) $(LIBFLAGS) $* $(LIBOBJS) $(LIBTERM)
$(OBJS): $(DEPENDS)
$(OBJS): $(DEPENDS) ../kernel/segs.inc
########################################################################

View File

@ -146,6 +146,7 @@
*/*/sys/makefile
*/*/sys/sys.c
*/*/sys/talloc.c
*/*/sys/turboc.cfg
*/*/utils/echoto.bat
*/*/utils/exeflat.c
*/*/utils/makefile
@ -153,3 +154,4 @@
*/*/utils/relocinf.c
*/*/utils/rmfiles.bat
*/*/utils/wlinker.bat
*/*/utils/turboc.cfg

View File

@ -80,8 +80,8 @@ struct dpb {
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 */
CLUSTER dpb_xrootclst; /* starting cluster of root dir */
CLUSTER dpb_xcluster; /* cluster # of first free */
/* -1 if not known */
#endif
};
@ -89,4 +89,3 @@ struct dpb {
#define UNKNCLUSTER 0x0000 /* see RBIL INT 21/AH=52 entry */
#define XUNKNCLSTFREE 0xffffffffl /* unknown for DOS */
#define UNKNCLSTFREE 0xffff /* unknown for DOS */

View File

@ -174,7 +174,7 @@ typedef struct {
/* bits 6-4: reserved (0) */
/* bits 3-0: active FAT number */
UWORD bpb_xfsversion; /* filesystem version */
ULONG bpb_xrootclst; /* starting cluster of root dir */
CLUSTER bpb_xrootclst; /* starting cluster of root dir */
UWORD bpb_xfsinfosec; /* FS info sector number, */
/* 0xFFFF if unknown */
UWORD bpb_xbackupsec; /* backup boot sector number */

View File

@ -38,32 +38,25 @@ static BYTE *dirmatch_hRcsId =
typedef struct {
UBYTE dm_drive;
BYTE dm_name_pat[FNAME_SIZE + FEXT_SIZE];
BYTE dm_attr_srch;
BYTE dm_attr_srch; /* !!! should be UBYTE --avb */
UWORD dm_entry;
#ifdef WITHFAT32
ULONG dm_dircluster;
#else
UWORD dm_dircluster;
CLUSTER dm_dircluster;
#ifndef WITHFAT32
UWORD reserved;
#endif
struct {
BITS /* directory has been modified */
f_dmod:1;
BITS /* directory is the root */
f_droot:1;
BITS /* fnode is new and needs fill */
f_dnew:1;
BITS /* fnode is assigned to dir */
f_ddir:1;
BITS /* filler to avoid a bad bug (feature?) in */
f_filler:12; /* TC 2.01 */
BITS f_dmod:1; /* directory has been modified */
BITS f_droot:1; /* directory is the root */
BITS f_dnew:1; /* fnode is new and needs fill */
BITS f_ddir:1; /* fnode is assigned to dir */
BITS f_filler:12; /* filler to avoid a bad bug */
/* (feature?) in TC 2.01 */
} dm_flags; /* file flags */
BYTE dm_attr_fnd; /* found file attribute */
UBYTE dm_attr_fnd; /* found file attribute */
time dm_time; /* file time */
date dm_date; /* file date */
LONG dm_size; /* file size */
ULONG dm_size; /* file size */
BYTE dm_name[FNAME_SIZE + FEXT_SIZE + 2]; /* file name */
} dmatch;

View File

@ -308,22 +308,27 @@ long DosRWSft(int sft_idx, size_t n, void FAR * bp, int mode)
}
}
COUNT SftSeek(int sft_idx, LONG new_pos, COUNT mode)
COUNT SftSeek(int sft_idx, LONG new_pos, unsigned mode)
{
sft FAR *s = idx_to_sft(sft_idx);
if (FP_OFF(s) == (size_t) -1)
return DE_INVLDHNDL;
/* Test for invalid mode */
if (mode < 0 || mode > 2)
if (mode > SEEK_END) /* 2 */
return DE_INVLDFUNC;
lpCurSft = s;
if (s->sft_flags & SFT_FSHARED)
{
/* SEEK_SET handled below (s->sft_posit=new_pos) */
if (mode == SEEK_CUR)
{
new_pos += s->sft_posit;
}
/* seek from end of file */
if (mode == 2)
else if (mode == SEEK_END)
{
/*
* RB list has it as Note:
@ -336,41 +341,24 @@ COUNT SftSeek(int sft_idx, LONG new_pos, COUNT mode)
* Mfs.c looks for these mode bits set, so here is my best guess.;^)
*/
if (s->sft_mode & (O_DENYREAD | O_DENYNONE))
s->sft_posit = remote_lseek(s, new_pos);
new_pos = remote_lseek(s, new_pos);
else
s->sft_posit = s->sft_size + new_pos;
return SUCCESS;
new_pos += s->sft_size;
}
if (mode == 0)
{
s->sft_posit = new_pos;
return SUCCESS;
}
if (mode == 1)
{
s->sft_posit += new_pos;
return SUCCESS;
}
return DE_INVLDFUNC;
}
/* Do special return for character devices */
if (s->sft_flags & SFT_FDEVICE)
else if (s->sft_flags & SFT_FDEVICE)
{
s->sft_posit = 0l;
return SUCCESS;
new_pos = 0;
}
else
{
LONG result = dos_lseek(s->sft_status, new_pos, mode);
if (result < 0l)
return (int)result;
else
{
s->sft_posit = result;
return SUCCESS;
}
if ((new_pos = dos_lseek(s->sft_status, new_pos, mode)) < 0)
return (int)new_pos;
}
s->sft_posit = new_pos;
return SUCCESS;
}
ULONG DosSeek(unsigned hndl, LONG new_pos, COUNT mode)
@ -1018,22 +1006,26 @@ COUNT DosChangeDir(BYTE FAR * s)
return SUCCESS;
}
STATIC VOID pop_dmp(dmatch FAR * dmp)
STATIC int pop_dmp(int rc, dmatch FAR * save_dta)
{
dmp->dm_attr_fnd = (BYTE) SearchDir.dir_attrib;
dmp->dm_time = SearchDir.dir_time;
dmp->dm_date = SearchDir.dir_date;
dmp->dm_size = (LONG) SearchDir.dir_size;
ConvertName83ToNameSZ(dmp->dm_name, (BYTE FAR *) SearchDir.dir_name);
dta = save_dta;
if (rc == SUCCESS)
{
fmemcpy(save_dta, &sda_tmp_dm, 21 /*offsetof(save_dta->dm_attr_fnd)*/ );
save_dta->dm_attr_fnd = SearchDir.dir_attrib;
save_dta->dm_time = SearchDir.dir_time;
save_dta->dm_date = SearchDir.dir_date;
save_dta->dm_size = SearchDir.dir_size;
ConvertName83ToNameSZ(save_dta->dm_name, SearchDir.dir_name);
}
return rc;
}
COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name)
COUNT DosFindFirst(UCOUNT attr, const char FAR * name)
{
int rc;
register dmatch FAR *dmp = dta;
rc = truename(name, PriPathName,
CDS_MODE_CHECK_DEV_PATH | CDS_MODE_ALLOW_WILDCARDS);
dmatch FAR *save_dta = dta;
int rc = truename(name, PriPathName,
CDS_MODE_CHECK_DEV_PATH | CDS_MODE_ALLOW_WILDCARDS);
if (rc < SUCCESS)
return rc;
@ -1065,32 +1057,26 @@ COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name)
SearchDir.dir_attrib = D_DEVICE;
SearchDir.dir_time = dos_gettime();
SearchDir.dir_date = dos_getdate();
p = (char *)FP_OFF(get_root(PriPathName));
memset(SearchDir.dir_name, ' ', FNAME_SIZE + FEXT_SIZE);
p = (const char *)get_root(PriPathName);
for (i = 0; i < FNAME_SIZE && *p && *p != '.'; i++)
SearchDir.dir_name[i] = *p++;
for (; i < FNAME_SIZE + FEXT_SIZE; i++)
SearchDir.dir_name[i] = ' ';
rc = SUCCESS;
/* /// End of additions. - Ron Cemer ; heavily edited - Bart Oldeman */
}
else
rc = dos_findfirst(attr, PriPathName);
dta = dmp;
if (rc == SUCCESS)
{
fmemcpy(dta, &sda_tmp_dm, 21);
pop_dmp(dmp);
}
return rc;
return pop_dmp(rc, save_dta);
}
COUNT DosFindNext(void)
{
COUNT rc;
register dmatch FAR *dmp = dta;
dmatch FAR *save_dta = dta;
/* findnext will always fail on a device name device name or volume id */
if (dmp->dm_attr_fnd & (D_DEVICE | D_VOLID))
/* findnext will always fail on a device name or volume id */
if (save_dta->dm_attr_fnd & (D_DEVICE | D_VOLID))
return DE_NFILES;
/*
@ -1111,21 +1097,13 @@ COUNT DosFindNext(void)
* (12h, DE_NFILES)
*/
#if 0
printf("findnext: %d\n", dmp->dm_drive);
printf("findnext: %d\n", save_dta->dm_drive);
#endif
fmemcpy(&sda_tmp_dm, dmp, 21);
fmemcpy(dta = &sda_tmp_dm, save_dta, 21 /*offsetof(save_dta->dm_attr_fnd)*/ );
memset(&SearchDir, 0, sizeof(struct dirent));
dta = &sda_tmp_dm;
rc = (sda_tmp_dm.dm_drive & 0x80) ?
network_redirector_fp(REM_FINDNEXT, &sda_tmp_dm) : dos_findnext();
dta = dmp;
if (rc == SUCCESS)
{
fmemcpy(dmp, &sda_tmp_dm, 21);
pop_dmp(dmp);
}
return rc;
return pop_dmp(sda_tmp_dm.dm_drive & 0x80
? network_redirector_fp(REM_FINDNEXT, &sda_tmp_dm)
: dos_findnext(), save_dta);
}
COUNT DosGetFtime(COUNT hndl, date * dp, time * tp)

View File

@ -711,7 +711,7 @@ STATIC WORD Genblkdev(rqptr rp, ddt * pddt)
break;
}
case 0x67: /* get access flag */
rp->r_ai->AI_Flag = (descflags / DF_NOACCESS) & 1; /* bit 9 */
rp->r_ai->AI_Flag = (UBYTE)~(descflags / DF_NOACCESS) & 1; /* bit 9 */
break;
default:
return failure(E_CMD);
@ -804,32 +804,22 @@ STATIC WORD dskerr(COUNT code)
translate LBA sectors into CHS addressing
*/
STATIC int LBA_to_CHS(ULONG LBA_address, struct CHS *chs, const ddt * pddt)
STATIC void LBA_to_CHS(ULONG LBA_address, struct CHS *chs, const ddt * pddt)
{
/* we need the defbpb values since those are taken from the
BIOS, not from some random boot sector, except when
we're dealing with a floppy */
const bpb *pbpb = hd(pddt->ddt_descflags) ? &pddt->ddt_defbpb : &pddt->ddt_bpb;
unsigned hs = pbpb->bpb_nsecs * pbpb->bpb_nheads;
unsigned hsrem = (unsigned)(LBA_address % hs);
LBA_address /= hs;
if (LBA_address > 1023ul)
const bpb *p = hd(pddt->ddt_descflags) ? &pddt->ddt_defbpb : &pddt->ddt_bpb;
unsigned hs = p->bpb_nsecs * p->bpb_nheads;
chs->Cylinder = 0xffffu;
if (hs > hiword(LBA_address)) /* LBA_address < hs * 0x10000ul */
{
#ifdef DEBUG
printf("LBA-Transfer error : cylinder %lu > 1023\n", LBA_address);
#else
put_string("LBA-Transfer error : cylinder > 1023\n");
#endif
return 1;
chs->Cylinder = (unsigned)(LBA_address / hs);
hs = (unsigned)(LBA_address % hs);
chs->Head = hs / p->bpb_nsecs;
chs->Sector = hs % p->bpb_nsecs + 1;
}
chs->Cylinder = (UWORD)LBA_address;
chs->Head = hsrem / pbpb->bpb_nsecs;
chs->Sector = hsrem % pbpb->bpb_nsecs + 1;
return 0;
}
/* Test for 64K boundary crossing and return count small */
@ -945,8 +935,16 @@ STATIC int LBA_Transfer(ddt * pddt, UWORD mode, VOID FAR * buffer,
else
{ /* transfer data, using old bios functions */
struct CHS chs;
if (LBA_to_CHS(LBA_address, &chs, pddt))
LBA_to_CHS(LBA_address, &chs, pddt);
if (chs.Cylinder > 1023u)
{
#ifdef DEBUG
printf("IO error: cylinder (%u) > 1023\n", chs.Cylinder);
#else
put_string("IO error: cylinder > 1023\n");
#endif
return failure(E_CMD); /*dskerr(1)*/
}
/* avoid overflow at end of track */
if (count > pddt->ddt_bpb.bpb_nsecs + 1 - chs.Sector)

View File

@ -411,6 +411,7 @@ _call_nls:
push bp
mov bp, sp
push si
push di
mov al, [bp + 4] ; subfct
mov ah, 0x14
mov si, [bp + 6] ; nlsinfo
@ -427,6 +428,7 @@ _call_nls:
jz nostore
mov [bp], bx
nostore:
pop di
pop si
pop bp
ret

View File

@ -74,21 +74,18 @@ VOID ASMCFUNC int21_syscall(iregs FAR * irp)
setvec(irp->AL, (intvec)MK_FP(irp->DS, irp->DX));
break;
/* DosVars - get/set dos variables */
case 0x33:
case 0x33: /* DosVars - get/set dos variables */
switch (irp->AL)
{
/* Get Ctrl-C flag */
case 0x00:
case 0x01: /* Set Ctrl-C flag */
break_ena = irp->DL & 1;
/* fall through so DL only low bit (as in MS-DOS) */
case 0x00: /* Get Ctrl-C flag */
irp->DL = break_ena;
break;
/* Set Ctrl-C flag */
case 0x01:
break_ena = irp->DL & 1;
break;
case 0x02: /* andrew schulman: get/set extended control break */
case 0x02: /* andrew schulman: get/set extended control break */
{
UBYTE tmp = break_ena;
break_ena = irp->DL & 1;
@ -1247,31 +1244,31 @@ dispatch:
case 0x5f:
if (lr.AL == 7 || lr.AL == 8)
{
struct cds FAR *cdsp = &CDSp[lr.DL];
if (lr.DL >= lastdrive || FP_OFF(cdsp->cdsDpb) == 0)
if (lr.DL < lastdrive)
{
rc = DE_INVLDDRV;
goto error_exit;
struct cds FAR *cdsp = CDSp + lr.DL;
if (FP_OFF(cdsp->cdsDpb)) /* letter of physical drive? */
{
cdsp->cdsFlags &= ~CDSPHYSDRV;
if (lr.AL == 7)
cdsp->cdsFlags |= CDSPHYSDRV;
break;
}
}
if (lr.AL == 7)
cdsp->cdsFlags |= CDSPHYSDRV;
else
cdsp->cdsFlags &= ~CDSPHYSDRV;
rc = DE_INVLDDRV;
goto error_exit;
}
else
rc = -(int)network_redirector_mx(REM_DOREDIRECT, &lr, (void *)Int21AX);
/* the remote function manipulates *r directly !,
so we should not copy lr to r here */
r->AX = rc;
if (rc != SUCCESS)
{
rc = (int)network_redirector_mx(REM_DOREDIRECT, &lr, (void *)Int21AX);
/* the remote function manipulates *r directly !,
so we should not copy lr to r here */
if (rc != SUCCESS)
{
CritErrCode = -rc; /* Maybe set */
SET_CARRY_FLAG();
}
r->AX = -rc;
goto real_exit;
SET_CARRY_FLAG();
CritErrCode = rc; /* Maybe set */
}
break;
goto real_exit;
case 0x60: /* TRUENAME */
rc = DosTruename(MK_FP(lr.DS, lr.SI), adjust_far(FP_ES_DI));
@ -1633,9 +1630,10 @@ STATIC VOID StartTrace(VOID)
}
#endif
/* this function is called from an assembler wrapper function
and serves the internal dos calls - int2f/12xx and int2f/4a01,4a02.
/* this function is called from an assembler wrapper function and
serves the internal dos calls - int2f/12xx and int2f/4a01,4a02
*/
struct int2f12regs {
#ifdef I386
#ifdef __WATCOMC__
@ -1654,7 +1652,7 @@ struct int2f12regs {
UWORD di, si, bp;
xreg b, d, c, a;
UWORD ip, cs, flags;
UWORD callerARG1; /* used if called from INT2F/12 */
xreg callerARG1; /* used if called from INT2F/12 */
};
/* WARNING: modifications in `r' are used outside of int2F_12_handler()
@ -1694,12 +1692,12 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
r.DS = FP_SEG(&nul_dev);
break;
case 0x06: /* invoke critical error */
/* code, drive number, error, device header */
r.AL = CriticalError(r.callerARG1 >> 8,
(r.callerARG1 & (EFLG_CHAR << 8)) ? 0 :
r.callerARG1 & 0xff, r.DI, MK_FP(r.BP, r.SI));
case 0x06: /* invoke critical error */
/* code, drive number, error, device header */
r.AL = CriticalError(r.callerARG1.b.h,
(r.callerARG1.b.h & EFLG_CHAR)
? 0 : r.callerARG1.b.l,
r.DI, MK_FP(r.BP, r.SI));
break;
case 0x08: /* decrease SFT reference count */
@ -1757,18 +1755,15 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
break;
}
case 0x12: /* get length of asciiz string */
case 0x12: /* get length of asciiz string */
r.CX = fstrlen(MK_FP(r.ES, r.DI)) + 1;
break;
case 0x13:
/* uppercase character */
/* for now, ASCII only because nls.c cannot handle DS!=SS */
r.AL = (unsigned char)r.callerARG1;
if (r.AL >= 'a' && r.AL <= 'z')
r.AL -= 'a' - 'A';
case 0x13: /* uppercase character */
/* for now, ASCII only because nls.c cannot handle DS!=SS */
r.AL = r.callerARG1.b.l;
if (_islower(r.AL))
r.AL -= (UBYTE)('a' - 'A');
break;
case 0x16:
@ -1805,10 +1800,9 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
;
; probable use: get sizeof(CDSentry)
*/
{
struct cds FAR *cdsp = get_cds(r.callerARG1 & 0xff);
if (cdsp == NULL)
{
const struct cds FAR *cdsp;
if ((cdsp = get_cds(r.callerARG1.b.l)) == NULL)
{
r.FLAGS |= FLG_CARRY;
break;
@ -1817,7 +1811,7 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
r.SI = FP_OFF(cdsp);
r.FLAGS &= ~FLG_CARRY;
break;
}
}
case 0x18: /* get caller's registers */
@ -1880,6 +1874,15 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
r.FLAGS &= ~FLG_CARRY;
break;
/* 0x26-0x29 & 0x2B, internal functions necessary for NLSFUNC */
case 0x26: /* Open File */
case 0x27: /* Close File */
case 0x28: /* Move File Pointer */
case 0x29: /* Read From File */
case 0x2B: /* IOctl */
r.FLAGS |= FLG_CARRY; /* Not implemented yet! */
break;
case 0x2c: /* added by James Tabor For Zip Drives
Return Null Device Pointer */
/* by UDOS+RBIL: get header of SECOND device driver in device chain,

View File

@ -124,11 +124,20 @@ COUNT DosDevIOctl(lregs * r)
attr = dev->dh_attr;
break;
case 0x0d:
/* NOTE: CX checked before check if get_dpb()->dpb_device->dh_attr
contains ATTR_GENIOCTL bit set
*/
if ((r->CX & ~0x4021) == 0x084A)
{ /* 084A/484A, 084B/484B, 086A/486A, 086B/486B */
r->AX = 0; /* (lock/unlock logical/physical volume) */
return SUCCESS; /* simulate success for MS-DOS 7+ SCANDISK etc. --LG */
}
case 0x04:
case 0x05:
case 0x08:
case 0x09:
case 0x0d:
case 0x0e:
case 0x0f:
case 0x11:
@ -258,17 +267,10 @@ COUNT DosDevIOctl(lregs * r)
break;
}
case 0x0d:
if ((r->CX & ~0x4021) == 0x084A)
{ /* 084A/484A, 084B/484B, 086A/486A, 086B/486B */
r->AX = 0; /* (lock/unlock logical/physical volume) */
break; /* simulate success for MS-DOS 7+ SCANDISK etc. --LG */
}
/* fall through */
case 0x04:
case 0x05:
case 0x08:
case 0x0d:
case 0x11:
execrequest:
execrh(&CharReqHdr, dev);

View File

@ -1,21 +1,26 @@
; this one adapted from elks, http://elks.sourceforge.net
; multiply cx:bx * dx:ax, result in dx:ax
; this one adapted from elks, http://elks.sourceforge.net
; multiply cx:bx * dx:ax, result in dx:ax
; optimized by Arkady Belousov:
; dx:ax * cx:bx
; = xh:xl * yh:yl
; = xh:xl*yh*w + xh:xl*yl
; = [xh*yh*w*w +] (xl*yh + xh*yl)*w + xl*yl
%macro LMULU 0
push si
push cx
mov si, ax ; save _ax in si
mov ax, bx ; cx:ax = _cx:_bx
mul dx ; dx:ax = _bx*_dx (forget dx)
xchg cx, ax ; cx = low(_dx*_bx)
mul si ; dx:ax = _cx*_ax (forget dx)
add cx, ax ; cx = low(_cx*_ax + _dx*_bx)
mov ax, si ; restore _ax
mul bx ; dx:ax = _bx*_ax
add dx, cx ; dx = high(_bx*_ax)+low(_cx*_ax + _dx*_bx)
pop cx
pop si
push cx
push si
xchg si,ax ; si=xl (XCHG instead MOV)
xchg ax,dx ; ax=xh (XCHG instead MOV)
mul bx ; dx:ax=xh*yl (forget dx)
xchg cx,ax ; cx=low(xh*yl), ax=yh
mul si ; dx:ax=xl*yh (forget dx)
add cx,ax ; cx=low(xl*yh+xh*yl)
xchg ax,si ; ax=xl (XCHG instead MOV)
mul bx ; dx:ax=xl*yl
add dx,cx
pop si
pop cx
ret
%endmacro
@ -25,86 +30,111 @@
%macro LDIVMODU 0
; this one is adapted from an assembly gem:
; gem writer: Norbert Juffa, norbert.juffa@amd.com
; Dividing 64-bit unsigned integers Assembler / 80386
; Here is a division routine for dividing two 64-bit unsigned integers.
; I derived it by modifying some old
; 16-bit code for dividing 32-bit integers that I did several years ago for a
; Turbo-Pascal replacement library.
; If a 64-bit signed integer division is needed, appropriate shell code for
; this routine can easily be written.
;
; (adapted back to 32-bit by Bart Oldeman ;-))
;
; __U4D divides two unsigned long numbers, the dividend and the divisor
; ...bugfixed and optimized by Arkady Belousov.
; This macro divides two unsigned long numbers, the dividend and the divisor
; resulting in a quotient and a remainder.
;
; input:
; dx:ax = dividend
; cx:bx = divisor
;
; dx:ax = dividend (x=xh:xl)
; cx:bx = divisor (y=yh:yl)
; output:
; dx:ax = quotient of division of dividend by divisor
; cx:bx = remainder of division of dividend by divisor
;
; dx:ax = quotient of division of dividend by divisor (q=x/y)
; cx:bx = remainder of division of dividend by divisor (r=x%y)
; destroys:
; flags
;
%if XCPU < 386
test cx, cx ; divisor > 2^32-1 ?
jnz %%big_divisor ; yes, divisor > 32^32-1
cmp dx, bx ; only one division needed ? (ecx = 0)
jb %%one_div ; yes, one division sufficient
jcxz %%div3216 ; cx=0 -> divisor < 2^16
push si ; save temp
push di ; variables
xchg cx, ax ; save dividend-lo in cx, ax=0
xchg ax, dx ; get dividend-hi in ax, dx=0
div bx ; quotient-hi in eax
xchg ax, cx ; cx = quotient-hi, ax =dividend-lo
push dx ; save
push ax ; dividend x
mov si,bx ; si=yl
mov di,cx ; di:si=cx:bx=y
%%one_div:
div bx ; ax = quotient-lo
mov bx, dx ; bx = remainder-lo
mov dx, cx ; dx = quotient-hi(quotient in dx:ax)
xor cx, cx ; cx = remainder-hi (rem. in cx:bx)
ret
%%big_divisor:
push si ; save temp
push di ; variables
push dx ; save
push ax ; dividend
mov si, bx ; divisor now in
mov di, cx ; di:bx and cx:si
%%shift_loop:
shr dx, 1 ; shift both
rcr ax, 1 ; divisor and
shr di, 1 ; and dividend
rcr bx, 1 ; right by 1 bit
jnz %%shift_loop ; loop if di non-zero (rcr does not touch ZF)
mov di, cx ; restore original divisor (di:si)
div bx ; compute quotient
pop bx ; get dividend lo-word
mov cx, ax ; save quotient
mul di ; quotient * divisor hi-word (low only)
xchg ax, di ; save in di
mov ax, cx ; ax=quotient
mul si ; quotient * divisor lo-word
add dx, di ; dx:ax = quotient * divisor
sub bx, ax ; dividend-lo - (quot.*divisor)-lo
mov ax, cx ; get quotient
pop cx ; restore dividend hi-word
sbb cx, dx ; subtract divisor * quot. from dividend
sbb dx, dx ; 0 if remainder > 0, else FFFFFFFFh
and si, dx ; nothing to add
and di, dx ; back if remainder positive
add bx, si ; correct remaider
adc cx, di ; and quotient if
add ax, dx ; necessary
xor dx, dx ; clear hi-word of quot (ax<=FFFFFFFFh)
pop di ; restore temp
pop si ; variables
shr dx,1 ; shift both
rcr ax,1 ; divisor and
shr cx,1 ; and dividend
rcr bx,1 ; right by 1 bit (rcr preserves ZF)
jnz %%shift_loop ; until zero in cx (divisor < 2^16)
div bx ; ax=quotient q, di:si=y
mov cx,ax ; cx=q
mul di ; dx:ax=q*yh (forget dx)
xchg bx,ax ; bx=low(q*yh) (XCHG instead MOV)
mov ax,cx ; ax=q
mul si ; dx:ax=q*yl
add dx,bx ; dx:ax=q*y, cx=q
pop bx ; bx=xl
sub bx,ax ; bx=xl-low(q*y)
xchg ax,cx ; ax=q (XCHG instead MOV)
pop cx ; cx=xh
sbb cx,dx ; cx:bx=x-q*y=remainder r, ax=q
jae %%div_done ; if remainder < 0
add bx,si
adc cx,di ; correct remainder (r+=y)
dec ax ; and quotient (q-=1)
%%div_done:
xor dx,dx ; dx:ax=0:q=q
pop di ; restore temp
pop si ; variables
ret
%endmacro
; dx:ax=x, bx=y, cx=0
; x=xh:xl=xh*w+xl=[xh/y]*y*w+xh%y*w+xl=[xh/y]*y*w+xt
; w=2^16, xh=x/w, xl=x%w, xt=xh%y*w+xl
; remainder = x%y = xt%y
; quotient = [x/y] = [xh/y]*w+xt/y
%%div3216:
cmp dx,bx ; xh < y ?
jb %%one_div ; yes, one division sufficient
xchg cx,ax ; ax=0, cx=xl
xchg ax,dx ; dx:ax=0:xh, cx=xl
div bx ; ax=xh/y, dx=xh%y, cx=xl
xchg ax,cx ; dx:ax=xh%y*w+xl=xt, cx=xh/y
%%one_div:
div bx ; ax=xt/y, dx=xt%d=x%d, cx=xh/y
mov bx,dx ; bx=x%d
mov dx,cx ; dx:ax=xh/y*w+xt/y=x/y
xor cx,cx ; cx:bx=x%d
ret
%else ; XCPU >= 386 (Svilen Stoianov and Luchezar Georgiev, Varna, Bulgaria)
push eax ; save eax.high
pop ax
push edx ; save edx.high
push ax
pop eax ; eax=x
push ecx ; save ecx.high
push bx
pop ecx ; ecx=y
xor edx,edx
div ecx ; eax=q, edx=r
push edx
pop bx
pop ecx ; restore ecx.high, cx:bx=r
push eax
pop ax
pop edx ; restore edx.high, dx:ax=q
push ax
pop eax ; restore eax.high
ret
%endif
%endmacro

View File

@ -195,6 +195,12 @@ STATIC void PSPInit(void)
/* this area reused for master environment */
/*p->ps_cmd.ctCount = 0;*/ /* local command line */
/*p->ps_cmd.ctBuffer[0] = '\r';*/ /* command tail */
/* !!! dirty hack: because bug in old FreeCOM, which wrongly
process empty environment in MS-DOS style, garbage empty
environment by dummy variable: --avb
*/
fmemcpy(&p->ps_cmd, "PATH=.", 6/*strlen("PATH=.")*/);
}
#ifndef __WATCOMC__
@ -328,8 +334,10 @@ STATIC VOID FsConfig(VOID)
for (i = 0; i < LoL->lastdrive; i++)
{
struct cds FAR *pcds_table = &LoL->CDSp[i];
fmemcpy(pcds_table->cdsCurrentPath, "A:\\\0", 4);
pcds_table->cdsCurrentPath[0] += i;
pcds_table->cdsCurrentPath[0] = 'A' + i;
pcds_table->cdsCurrentPath[1] = ':';
pcds_table->cdsCurrentPath[2] = '\\';
pcds_table->cdsCurrentPath[3] = '\0';
pcds_table->cdsFlags = 0;
if (i < LoL->nblkdev && (LONG) dpb != -1l)
{

View File

@ -122,8 +122,14 @@ COUNT muxLoadPkg(UWORD cp, UWORD cntry)
/* make sure the NLSFUNC ID is updated */
#error "NLS_FREEDOS_NLSFUNC_VERSION == NLS_FREEDOS_NLSFUNC_ID"
#endif
if (muxGo(0, 0, NLS_FREEDOS_NLSFUNC_VERSION, 0, NLS_FREEDOS_NLSFUNC_ID, 0,
(UWORD *)&id) != 0x14ff)
/* Install check must pass the FreeDOS NLSFUNC version as codepage (cp) and
the FreeDOS NLSFUNC ID as buffer size (bufsize). If they match the
version in NLSFUNC, on return it will set BX (cp on entry) to FreeDOS
NLSFUNC ID. If not NULL, call_nls will set *id = BX on return.
Note: &id should be the pointer offset addressable via SS (SS:BP == &id)
*/
if (muxGo(NLSFUNC_INSTALL_CHECK, 0, NLS_FREEDOS_NLSFUNC_VERSION,
0, NLS_FREEDOS_NLSFUNC_ID, 0, (UWORD *)&id) != 0x14ff)
return DE_FILENOTFND; /* No NLSFUNC --> no load */
if (id != NLS_FREEDOS_NLSFUNC_ID) /* FreeDOS NLSFUNC will return */
return DE_INVLDACC; /* This magic number */

View File

@ -77,11 +77,14 @@ long cooked_write(struct dhdr FAR **pdev, size_t n, char FAR *bp);
sft FAR *get_sft(UCOUNT);
/* dosfns.c */
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
const char FAR *get_root(const char FAR *);
BOOL check_break(void);
UCOUNT GenericReadSft(sft far * sftp, UCOUNT n, void FAR * bp,
COUNT * err, BOOL force_binary);
COUNT SftSeek(int sft_idx, LONG new_pos, COUNT mode);
COUNT SftSeek(int sft_idx, LONG new_pos, unsigned mode);
/*COUNT DosRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err); */
void BinarySftIO(int sft_idx, void *bp, int mode);
#define BinaryIO(hndl, bp, mode) BinarySftIO(get_sft_idx(hndl), bp, mode)
@ -101,7 +104,7 @@ BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
UWORD * bps, UWORD * nc);
COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s);
COUNT DosChangeDir(BYTE FAR * s);
COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name);
COUNT DosFindFirst(UCOUNT attr, const char FAR * name);
COUNT DosFindNext(void);
COUNT DosGetFtime(COUNT hndl, date * dp, time * tp);
COUNT DosSetFtimeSft(int sft_idx, date dp, time tp);
@ -374,7 +377,6 @@ void child_psp(seg_t para, seg_t cur_psp, seg_t beyond);
void return_user(void);
COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp);
ULONG SftGetFsize(int sft_idx);
VOID InitPSP(VOID);
#ifdef __WATCOMC__
# pragma aux return_user aborts
#endif

View File

@ -303,7 +303,7 @@ static void load_transfer(seg_t ds, exec_blk *ep, int mode)
if (mode == LOADNGO)
{
/* build the user area on the stack */
iregs FAR *irp = (iregs FAR *)(ep->exec.stack - sizeof(iregs));
iregs FAR *irp = (iregs FAR *)ep->exec.stack - 1;
/* start allocating REGs (as in MS-DOS - some demos expect them so --LG) */
/* see http://www.beroset.com/asm/showregs.asm */

View File

@ -1,5 +0,0 @@
-batch -nologo -WX
-Zlp1
-f- -Osb1V4e -Gsry
-Fc
-I..\hdr

View File

@ -59,10 +59,6 @@ typedef signed short sword;
typedef unsigned long dword;
typedef signed long sdword;
/* These structures need to be byte packed, if your compiler
does not do this by default, add the appropriate command,
such as #pragma pack(1) here, protected with #ifdefs of course.
*/
/* Displays command line syntax */
void showUsage(void)

View File

@ -29,7 +29,7 @@
#define DEBUG
/* #define DDEBUG */
#define SYS_VERSION "v3.2"
#define SYS_VERSION "v3.3"
#include <stdlib.h>
#include <dos.h>
@ -483,13 +483,13 @@ void truename(char far *dest, const char *src);
"int 0x21" \
parm [es di] [si];
int generic_block_ioctl(unsigned char drive, unsigned cx, unsigned char *par);
int generic_block_ioctl(unsigned drive, unsigned cx, unsigned char *par);
#pragma aux generic_block_ioctl = \
"mov ax, 0x440d" \
"int 0x21" \
"sbb ax, ax" \
value [ax] \
parm [bl] [cx] [dx];
parm [bx] [cx] [dx]; /* BH must be 0 for lock! */
#else
@ -541,14 +541,14 @@ void reset_drive(int DosDrive)
intdos(&regs, &regs);
} /* reset_drive */
int generic_block_ioctl(unsigned char drive, unsigned cx, unsigned char *par)
int generic_block_ioctl(unsigned drive, unsigned cx, unsigned char *par)
{
union REGS regs;
regs.x.ax = 0x440d;
regs.x.cx = cx;
regs.x.dx = (unsigned)par;
regs.h.bl = drive + 1;
regs.x.bx = drive; /* BH must be 0 for lock! */
intdos(&regs, &regs);
return regs.x.cflag;
} /* generic_block_ioctl */
@ -692,7 +692,7 @@ void put_boot(int drive, char *bsFile, char *kernel_name, int load_seg, int both
#endif
/* lock drive */
generic_block_ioctl((unsigned char)drive + 1, 0x84a, NULL);
generic_block_ioctl(drive + 1, 0x84a, NULL);
reset_drive(drive);
/* suggestion: allow reading from a boot sector or image file here */
@ -752,7 +752,7 @@ void put_boot(int drive, char *bsFile, char *kernel_name, int load_seg, int both
printf("FAT type: FAT32\n");
/* get default bpb (but not for floppies) */
if (drive >= 2 &&
generic_block_ioctl((unsigned char)drive + 1, 0x4860, default_bpb) == 0)
generic_block_ioctl(drive + 1, 0x4860, default_bpb) == 0)
correct_bpb((struct bootsectortype *)(default_bpb + 7 - 11), bs);
#ifdef WITHFAT32 /* copy one of the FAT32 boot sectors */
@ -767,7 +767,7 @@ void put_boot(int drive, char *bsFile, char *kernel_name, int load_seg, int both
{ /* copy the FAT12/16 CHS+LBA boot sector */
printf("FAT type: FAT1%c\n", fs + '0' - 10);
if (drive >= 2 &&
generic_block_ioctl((unsigned char)drive + 1, 0x860, default_bpb) == 0)
generic_block_ioctl(drive + 1, 0x860, default_bpb) == 0)
correct_bpb((struct bootsectortype *)(default_bpb + 7 - 11), bs);
memcpy(newboot, fs == FAT16 ? fat16com : fat12com, SEC_SIZE);
}
@ -782,7 +782,8 @@ void put_boot(int drive, char *bsFile, char *kernel_name, int load_seg, int both
bs = (struct bootsectortype *)&newboot;
memcpy(bs->OemName, "FreeDOS ", 8);
/* originally OemName was "FreeDOS", changed for better compatibility */
memcpy(bs->OemName, "FRDOS4.1", 8);
#ifdef WITHFAT32
if (fs == FAT32)
@ -893,7 +894,7 @@ void put_boot(int drive, char *bsFile, char *kernel_name, int load_seg, int both
reset_drive(drive);
/* unlock_drive */
generic_block_ioctl((unsigned char)drive + 1, 0x86a, NULL);
generic_block_ioctl(drive + 1, 0x86a, NULL);
} /* put_boot */