mirror of
https://github.com/FDOS/kernel.git
synced 2025-04-08 17:15:17 +02:00
Changes for kernel 2027rc.
git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@427 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
31591f162c
commit
83b77cbb1b
@ -369,7 +369,7 @@ cluster_next: lodsw ; AX = next cluster to read
|
||||
|
||||
|
||||
boot_error: call print
|
||||
db 13,10,"BOOT error!",13,10,0
|
||||
db 13,10,"BOOT err!",0
|
||||
|
||||
xor ah,ah
|
||||
int 0x16 ; wait for a key
|
||||
@ -417,6 +417,10 @@ read_next: push dx
|
||||
mov ah,041h ;
|
||||
mov bx,055aah ;
|
||||
mov dl, [drive]
|
||||
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
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
These are the know 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 linux-guru@gcfl.net so I can add you to the list!
|
||||
please email me at bart@dosemu.org so I can add you to the list!
|
||||
|
||||
Thanx to all the following for contributing to the FreeDOS kernel:
|
||||
Thanks to all the following for contributing to the FreeDOS kernel:
|
||||
|
||||
ror4 (ror4@angelfire.com)
|
||||
Steffen Kaiser (Steffen.Kaiser@fh-rhein-sieg.de)
|
||||
@ -18,6 +18,9 @@ Jeremy Davis (jeremyd@computer.org)
|
||||
Martin Stromberg (ams@ludd.luth.se)
|
||||
Bart Oldeman (bart@dosemu.org)
|
||||
|
||||
And last, but not least, a big thanx to Pasquale J. Villani
|
||||
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 was the original author of DOS-C, in which the
|
||||
FreeDOS kernel was based.
|
||||
|
@ -1,4 +1,39 @@
|
||||
2002 Aug xx - Build 2027
|
||||
2002 Oct xx - Build 2027rc
|
||||
-------- Bart Oldeman (bart@dosemu.org)
|
||||
+ Changes Bart
|
||||
* reorganized chario.c, got F1-F6, Ins, Del, etc working
|
||||
* fixed bug in extended open
|
||||
* fixed bug in memory manager (realloc should try to defragment;
|
||||
UMB fixes)
|
||||
* consistently pass sft_idx around for all SFT functions (instead of
|
||||
the far pointer)
|
||||
* lpUserStack is gone :)
|
||||
* Idle interrupt: now uses disk i/o stack instead of error stack if it
|
||||
re-enters DOS; can not be called from int21/ah=3f. It also checks
|
||||
InDos now (as documented in "undocumented dos").
|
||||
* int21/ah=59 should use the disk i/o stack, not the character stack.
|
||||
* get_cds: a uniform way to get the CDS for drive X which can do error
|
||||
checking too. get_dpb: similar.
|
||||
* task.c uses mid-level system file handles instead of PSP handles.
|
||||
* SFT sequence is MS/DR DOS like: 0=AUX 1=CON 2=PRN
|
||||
* int21/ah=4d needs to clear the return code after returning it.
|
||||
* Removed need for unusedretval because some functions return a long int
|
||||
now.
|
||||
* Do not warn for some additional LBA partition layouts (begin/end
|
||||
cylinder=1023) in initdisk.c.
|
||||
* support int2f/ax=1213 (uppercase character) (ASCII only for now).
|
||||
* fix for top of memory parameter to device driver - fixes problem
|
||||
with DRDOS emm386
|
||||
* eliminated printf for non-init code -- use put_unsigned and
|
||||
put_string instead
|
||||
* better MK_FP for Turbo C++ 1.01 and later
|
||||
* PSP related task.c cleanups
|
||||
Changes Tom and Bart:
|
||||
* Use Pascal calling convention for memcpy and friends in asmsupt.asm
|
||||
* Fixed make temp file
|
||||
* fix bug in DosFindNext
|
||||
* misc makefile fixes
|
||||
2002 Aug xx - Build 2027test
|
||||
-------- Bart Oldeman (bart@dosemu.org)
|
||||
+ Changes Tom
|
||||
* enable LBA FAT16 booting
|
||||
|
@ -204,7 +204,7 @@ struct _bios_LBA_address_packet
|
||||
};
|
||||
|
||||
struct CHS {
|
||||
ULONG Cylinder;
|
||||
UWORD Cylinder;
|
||||
UWORD Head;
|
||||
UWORD Sector;
|
||||
};
|
||||
@ -365,7 +365,7 @@ typedef struct {
|
||||
LONG _r_huge; /* for > 32Mb drives */
|
||||
} _r_rw;
|
||||
struct {
|
||||
BYTE _r_ndbyte; /* Byte Read From Device */
|
||||
unsigned char _r_ndbyte; /* Byte Read From Device */
|
||||
} _r_nd;
|
||||
} _r_x;
|
||||
} request;
|
||||
|
19
hdr/portab.h
19
hdr/portab.h
@ -63,12 +63,14 @@ static char *portab_hRcsId =
|
||||
|
||||
#define I86
|
||||
#define CDECL cdecl
|
||||
#define PASCAL pascal
|
||||
void __int__(int);
|
||||
|
||||
#elif defined (_MSC_VER)
|
||||
|
||||
#define I86
|
||||
#define CDECL _cdecl
|
||||
#define PASCAL pascal
|
||||
#define __int__(intno) asm int intno;
|
||||
|
||||
#if defined(M_I286) /* /G3 doesn't set M_I386, but sets M_I286 TE */
|
||||
@ -82,6 +84,7 @@ void __int__(int);
|
||||
#define asm __asm
|
||||
#define far __far
|
||||
#define CDECL __cdecl
|
||||
#define PASCAL pascal
|
||||
|
||||
#if _M_IX86 >= 300
|
||||
#define I386
|
||||
@ -112,6 +115,7 @@ anyone knows a _portable_ way to create nice errors ? ?
|
||||
#define NONNATIVE
|
||||
#define PARASIZE 4096 /* "paragraph" size */
|
||||
#define CDECL
|
||||
#define PASCAL
|
||||
#ifdef __GNUC__
|
||||
#define CONST const
|
||||
#define PROTO
|
||||
@ -137,6 +141,7 @@ typedef unsigned size_t;
|
||||
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 */
|
||||
@ -210,13 +215,23 @@ typedef signed long LONG;
|
||||
/* General far pointer macros */
|
||||
#ifdef I86
|
||||
#ifndef MK_FP
|
||||
|
||||
#ifdef __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 FP_SEG(fp) ((unsigned)(UWORD)((ULONG)(VOID FAR *)(fp)>>16))
|
||||
#define FP_OFF(fp) ((unsigned)(UWORD)(fp))
|
||||
|
||||
#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
|
||||
|
||||
|
@ -79,8 +79,7 @@ typedef struct {
|
||||
UWORD ps_maxfiles; /* 32 maximum open files */
|
||||
UBYTE FAR *ps_filetab; /* 34 open file table pointer */
|
||||
VOID FAR *ps_prevpsp; /* 38 previous psp pointer */
|
||||
BYTE FAR *ps_dta; /* 3c process dta address */
|
||||
BYTE ps_fill2[16]; /* 40 */
|
||||
BYTE ps_fill2[20]; /* 3c */
|
||||
UBYTE ps_unix[3]; /* 50 unix style call - 0xcd 0x21 0xcb */
|
||||
BYTE ps_fill3[9]; /* 53 */
|
||||
union {
|
||||
@ -93,18 +92,14 @@ typedef struct {
|
||||
} _u2;
|
||||
struct {
|
||||
BYTE fill5[36];
|
||||
struct {
|
||||
BYTE _ps_cmd_count;
|
||||
BYTE _ps_cmd[127]; /* command tail */
|
||||
} _u4;
|
||||
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._u4._ps_cmd
|
||||
#define ps_cmd_count _u._u3._u4._ps_cmd_count
|
||||
#define ps_cmd _u._u3._ps_cmd
|
||||
|
||||
/*
|
||||
* Log: process.h,v
|
||||
|
13
hdr/time.h
13
hdr/time.h
@ -45,10 +45,21 @@ static BYTE *time_hRcsId =
|
||||
#define TM_MIN(t) (((t)>>5)&0x3f)
|
||||
#define TM_DEC(t) ((t)&0x1f)
|
||||
|
||||
#define TM_ENCODE(h,m,d) ((((h&0x1f))<<11)|(((m)&0x3f)<<5)|((d)&0x1f))
|
||||
#define TM_ENCODE(h,m,d) ((((h)&0x1f)<<11)|(((m)&0x3f)<<5)|((d)&0x1f))
|
||||
|
||||
typedef UWORD time;
|
||||
|
||||
struct dostime
|
||||
{
|
||||
unsigned char minute, hour, hundredth, second;
|
||||
};
|
||||
|
||||
struct dosdate
|
||||
{
|
||||
unsigned short year;
|
||||
unsigned char monthday, month;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -49,6 +49,6 @@ static BYTE *date_hRcsId =
|
||||
#define REVISION_MINOR 1
|
||||
#define REVISION_SEQ 27
|
||||
#define BUILD "2027"
|
||||
#define SUB_BUILD "test"
|
||||
#define SUB_BUILD "rc"
|
||||
#define KERNEL_VERSION_STRING "1.1.27" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ */
|
||||
#define KERNEL_BUILD_STRING "2027test" /*#BUILD SUB_BUILD */
|
||||
#define KERNEL_BUILD_STRING "2027rc" /*#BUILD SUB_BUILD */
|
||||
|
@ -54,7 +54,7 @@ segment HMA_TEXT
|
||||
; fmemset(void FAR *dest, int ch, int count);
|
||||
; fstrncpy(void FAR*dest, void FAR *src, int count);
|
||||
; strcpy (void *dest, void *src);
|
||||
; fstrcpy (void FAR*dest, void FAR *src, int count);
|
||||
; fstrcpy (void FAR*dest, void FAR *src);
|
||||
; strlen (void *dest);
|
||||
; fstrlen (void FAR*dest);
|
||||
; fmemchr (BYTE FAR *src , int ch);
|
||||
@ -68,52 +68,51 @@ segment HMA_TEXT
|
||||
; memcmp(BYTE *s1 , BYTE *s2, int count);
|
||||
|
||||
;***********************************************
|
||||
; common_setup - set up the standard calling frame for C-functions
|
||||
; 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
|
||||
;
|
||||
common_setup:
|
||||
pop bx ; get return address
|
||||
pascal_setup:
|
||||
pop ax ; get return address
|
||||
|
||||
push bp ; Standard C entry
|
||||
mov bp,sp
|
||||
push si
|
||||
push di
|
||||
push es
|
||||
push ds
|
||||
; Set both ds and es to same segment (for near copy)
|
||||
pop es
|
||||
push ds
|
||||
pop es
|
||||
|
||||
; Set direction to autoincrement
|
||||
cld
|
||||
|
||||
; to conserve even some more bytes,
|
||||
; the registers for the near routines
|
||||
; are preloaded here
|
||||
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)
|
||||
|
||||
; the destination pointer, d = arg1
|
||||
mov di,[bp+4]
|
||||
|
||||
; Get the source pointer, s = arg2
|
||||
mov si,[bp+6]
|
||||
|
||||
; Get the repitition count, n = arg3
|
||||
mov cx,[bp+8]
|
||||
|
||||
jmp bx
|
||||
jmp ax
|
||||
|
||||
|
||||
|
||||
|
||||
;***********************************************
|
||||
;
|
||||
; VOID memcpy(REG BYTE *s, REG BYTE *d, REG COUNT n);
|
||||
;
|
||||
global _memcpy
|
||||
_memcpy:
|
||||
call common_setup
|
||||
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:
|
||||
@ -124,19 +123,15 @@ domemcpy:
|
||||
jnc memcpy_return
|
||||
movsb
|
||||
memcpy_return:
|
||||
%if 0 ; only needed for fmemcpyback
|
||||
cld
|
||||
%endif
|
||||
|
||||
;
|
||||
; common_return - pop saved registers and do return
|
||||
; pascal_return - pop saved registers and do return
|
||||
;
|
||||
|
||||
common_return:
|
||||
pop ds
|
||||
pop es
|
||||
pop di
|
||||
pop si
|
||||
pop bp
|
||||
ret
|
||||
|
||||
jmp short pascal_return
|
||||
|
||||
|
||||
|
||||
@ -145,24 +140,24 @@ common_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
|
||||
global FMEMCPY
|
||||
%if 0
|
||||
global _fmemcpyBack
|
||||
_fmemcpyBack:
|
||||
global FMEMCPYBACK
|
||||
FMEMCPYBACK:
|
||||
std ; force to copy the string in reverse order
|
||||
%endif
|
||||
_fmemcpy:
|
||||
call common_setup
|
||||
FMEMCPY:
|
||||
call pascal_setup
|
||||
|
||||
; Get the repetition count, n preset above
|
||||
; mov cx,[bp+4]
|
||||
|
||||
; Get the far source pointer, s
|
||||
lds si,[bp+8]
|
||||
lds si,[bp+6]
|
||||
|
||||
; Get the far destination pointer d
|
||||
les di,[bp+4]
|
||||
|
||||
; Get the repetition count, n
|
||||
mov cx,[bp+12]
|
||||
|
||||
les di,[bp+10]
|
||||
mov bl,10
|
||||
|
||||
jmp short domemcpy
|
||||
|
||||
@ -170,56 +165,69 @@ _fmemcpy:
|
||||
;
|
||||
; VOID fmemset(REG VOID FAR *d, REG BYTE ch, REG COUNT n);
|
||||
;
|
||||
global _fmemset
|
||||
_fmemset:
|
||||
call common_setup
|
||||
global FMEMSET
|
||||
FMEMSET:
|
||||
call pascal_setup
|
||||
|
||||
; Get the repetition count, n
|
||||
mov cx,[bp+10]
|
||||
; Get the repetition count, n - preset above
|
||||
; mov cx,[bp+4]
|
||||
|
||||
; Get the far source pointer, s
|
||||
les di,[bp+4]
|
||||
|
||||
; Get the far destination pointer ch
|
||||
mov al,[bp+8]
|
||||
; 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 common_return
|
||||
jnc pascal_return
|
||||
stosb
|
||||
|
||||
jmp short common_return
|
||||
jmp short pascal_return
|
||||
|
||||
;***************************************************************
|
||||
;
|
||||
; VOID memset(REG VOID *d, REG BYTE ch, REG COUNT n);
|
||||
;
|
||||
global _memset
|
||||
_memset:
|
||||
call common_setup
|
||||
global MEMSET
|
||||
MEMSET:
|
||||
call pascal_setup
|
||||
|
||||
; Get the far source pointer, s
|
||||
; mov di,[bp+4]
|
||||
; Get the repitition count, n - preset above
|
||||
; mov cx,[bp+4]
|
||||
|
||||
; Get the char ch
|
||||
mov ax,si ; mov al, [bp+6]
|
||||
mov ax, [bp+6]
|
||||
|
||||
; Get the repititon count, n
|
||||
; mov cx,[bp+8]
|
||||
; Get the far source pointer, d - preset above
|
||||
; mov di,[bp+8]
|
||||
|
||||
;mov bl, 6 ; preset above
|
||||
|
||||
jmp short domemset
|
||||
|
||||
;*****
|
||||
pascal_return:
|
||||
pop ds
|
||||
pop di
|
||||
pop si
|
||||
pop bp
|
||||
|
||||
|
||||
pop cx
|
||||
sub bh,bh
|
||||
add sp,bx
|
||||
jmp cx
|
||||
|
||||
;***************************************************************
|
||||
%if 0
|
||||
%if 0
|
||||
nix pascal - still untested
|
||||
global _fstrncpy
|
||||
_fstrncpy:
|
||||
call common_setup
|
||||
call pascal_setup
|
||||
|
||||
; Get the source pointer, ss
|
||||
lds si,[bp+8]
|
||||
@ -229,7 +237,7 @@ _fstrncpy:
|
||||
|
||||
mov cx,[bp+12]
|
||||
|
||||
jcxz common_return
|
||||
jcxz pascal_return
|
||||
;; dec cx
|
||||
; jcxz store_one_byte
|
||||
strncpy_loop: lodsb
|
||||
@ -243,35 +251,39 @@ store_one_byte: xor al,al
|
||||
; to fill remaining part of buffer
|
||||
stosb
|
||||
|
||||
jmp short common_return
|
||||
jmp short pascal_return
|
||||
%endif
|
||||
;*****************************************************************
|
||||
|
||||
; fstrcpy (void FAR*dest, void FAR *src);
|
||||
|
||||
|
||||
global _fstrcpy
|
||||
_fstrcpy:
|
||||
call common_setup
|
||||
global FSTRCPY
|
||||
FSTRCPY:
|
||||
call pascal_setup
|
||||
|
||||
; Get the source pointer, ss
|
||||
lds si,[bp+8]
|
||||
lds si,[bp+4]
|
||||
|
||||
; and the destination pointer, d
|
||||
les di,[bp+4]
|
||||
les di,[bp+8]
|
||||
|
||||
mov bl,8
|
||||
|
||||
jmp short dostrcpy
|
||||
|
||||
;******
|
||||
global _strcpy
|
||||
_strcpy:
|
||||
call common_setup
|
||||
global STRCPY
|
||||
STRCPY:
|
||||
call pascal_setup
|
||||
|
||||
|
||||
; Get the source pointer, ss
|
||||
;mov si,[bp+6]
|
||||
mov si,[bp+4]
|
||||
|
||||
; and the destination pointer, d
|
||||
;mov di,[bp+4]
|
||||
mov di,[bp+6]
|
||||
mov bl,4
|
||||
|
||||
dostrcpy:
|
||||
|
||||
@ -281,25 +293,27 @@ strcpy_loop:
|
||||
test al,al
|
||||
jne strcpy_loop
|
||||
|
||||
jmp short common_return
|
||||
jmp short pascal_return
|
||||
|
||||
;******************************************************************
|
||||
|
||||
global _fstrlen
|
||||
_fstrlen:
|
||||
call common_setup
|
||||
global FSTRLEN
|
||||
FSTRLEN:
|
||||
call pascal_setup
|
||||
|
||||
; Get the source pointer, ss
|
||||
les di,[bp+4]
|
||||
les di,[bp+4]
|
||||
mov bl,4
|
||||
|
||||
jmp short dostrlen
|
||||
|
||||
;**********************************************
|
||||
global _strlen
|
||||
_strlen:
|
||||
call common_setup
|
||||
|
||||
; The source pointer, ss, arg1 was loaded as di
|
||||
global STRLEN
|
||||
STRLEN:
|
||||
call pascal_setup
|
||||
; Get the source pointer, ss
|
||||
mov di,[bp+4]
|
||||
mov bl,2
|
||||
|
||||
dostrlen:
|
||||
mov al,0
|
||||
@ -310,22 +324,23 @@ dostrlen:
|
||||
not ax
|
||||
dec ax
|
||||
|
||||
jmp short common_return
|
||||
jmp short pascal_return
|
||||
|
||||
;************************************************************
|
||||
global _strchr
|
||||
_strchr:
|
||||
call common_setup
|
||||
; strchr (BYTE *src , int ch);
|
||||
|
||||
global STRCHR
|
||||
STRCHR:
|
||||
call pascal_setup
|
||||
|
||||
; Get the source pointer, ss
|
||||
; mov si,[bp+4]
|
||||
; mov bx,[bp+6]
|
||||
mov bx,si
|
||||
mov si,di
|
||||
; mov cx,[bp+4] - preset above
|
||||
; mov si,[bp+6] - preset above
|
||||
mov bl,4
|
||||
|
||||
strchr_loop:
|
||||
lodsb
|
||||
cmp al,bl
|
||||
cmp al,cl
|
||||
je strchr_found
|
||||
test al,al
|
||||
jne strchr_loop
|
||||
@ -333,7 +348,7 @@ strchr_loop:
|
||||
strchr_retzero:
|
||||
xor ax, ax ; return NULL if not found
|
||||
mov dx, ax ; for fstrchr()
|
||||
jmp common_return
|
||||
jmp short pascal_return
|
||||
|
||||
strchr_found:
|
||||
mov ax, si
|
||||
@ -341,22 +356,40 @@ strchr_found:
|
||||
strchr_found1:
|
||||
dec ax
|
||||
|
||||
jmp common_return
|
||||
jmp short pascal_return
|
||||
|
||||
|
||||
;*****
|
||||
; 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
|
||||
|
||||
;******
|
||||
%if 0
|
||||
global _fmemchr
|
||||
_fmemchr:
|
||||
call common_setup
|
||||
global FMEMCHR
|
||||
FMEMCHR:
|
||||
call pascal_setup
|
||||
|
||||
; Get the source pointer, ss
|
||||
les di, [bp+4]
|
||||
; Get the length - preset above
|
||||
; mov cx, [bp+4]
|
||||
|
||||
; and the search value
|
||||
mov al, [bp+8]
|
||||
mov ax, [bp+6]
|
||||
|
||||
; and the length
|
||||
mov cx, [bp+10]
|
||||
; and the source pointer, ss
|
||||
les di, [bp+8]
|
||||
|
||||
mov bl, 8
|
||||
|
||||
repne scasb
|
||||
jne strchr_retzero
|
||||
@ -364,25 +397,13 @@ _fmemchr:
|
||||
mov ax, di
|
||||
dec ax
|
||||
jmp short strchr_found1
|
||||
%endif
|
||||
|
||||
global _fstrchr
|
||||
_fstrchr:
|
||||
call common_setup
|
||||
|
||||
; Get the source pointer, ss
|
||||
lds si, [bp+4]
|
||||
|
||||
; and the destination pointer, d
|
||||
mov bx, [bp+8]
|
||||
|
||||
jmp short strchr_loop
|
||||
|
||||
;**********************************************************************
|
||||
%if 0
|
||||
nix pascal - still untested
|
||||
global _fstrcmp
|
||||
_fstrcmp:
|
||||
call common_setup
|
||||
call pascal_setup
|
||||
|
||||
; Get the source pointer, ss
|
||||
lds si,[bp+4]
|
||||
@ -395,7 +416,7 @@ _fstrcmp:
|
||||
;******
|
||||
global _strcmp
|
||||
_strcmp:
|
||||
call common_setup
|
||||
call pascal_setup
|
||||
|
||||
|
||||
; Get the source pointer, ss
|
||||
@ -413,9 +434,9 @@ dostrcmp:
|
||||
|
||||
|
||||
;**********************************************************************
|
||||
global _fstrncmp
|
||||
_fstrncmp:
|
||||
call common_setup
|
||||
global FSTRNCMP
|
||||
FSTRNCMP:
|
||||
call pascal_setup
|
||||
|
||||
; Get the source pointer, ss
|
||||
lds si,[bp+4]
|
||||
@ -429,7 +450,7 @@ _fstrncmp:
|
||||
;******
|
||||
global _strncmp
|
||||
_strncmp:
|
||||
call common_setup
|
||||
call pascal_setup
|
||||
|
||||
; Get the source pointer, ss
|
||||
;mov si,[bp+4]
|
||||
@ -455,36 +476,41 @@ strncmp_retzero:
|
||||
strncmp_done:
|
||||
lahf
|
||||
ror ah,1
|
||||
strncmp_done2: jmp common_return
|
||||
strncmp_done2: jmp pascal_return
|
||||
|
||||
|
||||
;**********************************************************************
|
||||
global _fmemcmp
|
||||
_fmemcmp:
|
||||
call common_setup
|
||||
; 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
|
||||
lds si,[bp+4]
|
||||
les di,[bp+6]
|
||||
|
||||
; and the destination pointer, d
|
||||
les di,[bp+8]
|
||||
lds si,[bp+10]
|
||||
|
||||
mov bl,10
|
||||
|
||||
; the length
|
||||
mov cx, [bp+12]
|
||||
|
||||
jmp short domemcmp
|
||||
|
||||
;******
|
||||
global _memcmp
|
||||
_memcmp:
|
||||
call common_setup
|
||||
; memcmp(BYTE *s1 , BYTE *s2, int count);
|
||||
global MEMCMP
|
||||
MEMCMP:
|
||||
call pascal_setup
|
||||
|
||||
; Get the source pointer, ss
|
||||
; all preset: Get the source pointer, ss
|
||||
;mov si,[bp+6]
|
||||
|
||||
; and the destination pointer, d
|
||||
;mov di,[bp+4]
|
||||
;mov cx,[bp+8]
|
||||
;mov di,[bp+8]
|
||||
;mov cx,[bp+4]
|
||||
;mov bl,6
|
||||
xchg si,di
|
||||
|
||||
domemcmp:
|
||||
|
@ -43,6 +43,8 @@ static BYTE *blockioRcsId =
|
||||
/************************************************************************/
|
||||
/* #define DISPLAY_GETBLOCK */
|
||||
|
||||
STATIC BOOL flush1(struct buffer FAR * bp);
|
||||
|
||||
/* */
|
||||
/* Initialize the buffer structure */
|
||||
/* */
|
||||
@ -76,7 +78,7 @@ STATIC VOID setblkno(struct buffer FAR * bp, ULONG blkno)
|
||||
bp->b_blkno = blkno;
|
||||
/* bp->b_dpbp = &blk_devices[bp->b_unit]; */
|
||||
|
||||
bp->b_dpbp = CDSp[bp->b_unit].cdsDpb;
|
||||
bp->b_dpbp = get_cds(bp->b_unit)->cdsDpb;
|
||||
|
||||
}
|
||||
}
|
||||
@ -101,7 +103,7 @@ STATIC VOID setblkno(struct buffer FAR * bp, ULONG blkno)
|
||||
|
||||
*/
|
||||
|
||||
BOOL searchblock(ULONG blkno, COUNT dsk, struct buffer FAR ** pBuffp)
|
||||
STATIC BOOL searchblock(ULONG blkno, COUNT dsk, struct buffer FAR ** pBuffp)
|
||||
{
|
||||
int fat_count = 0;
|
||||
struct buffer FAR *bp;
|
||||
@ -337,7 +339,7 @@ BOOL flush_buffers(REG COUNT dsk)
|
||||
/* */
|
||||
/* Write one disk buffer */
|
||||
/* */
|
||||
BOOL flush1(struct buffer FAR * bp)
|
||||
STATIC BOOL flush1(struct buffer FAR * bp)
|
||||
{
|
||||
/* All lines with changes on 9/4/00 by BER marked below */
|
||||
|
||||
@ -409,20 +411,11 @@ BOOL flush(void)
|
||||
/* Transfer one or more blocks to/from disk */
|
||||
/* */
|
||||
|
||||
/* Changed to UWORD 9/4/00 BER */
|
||||
UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks,
|
||||
COUNT mode)
|
||||
/* End of change */
|
||||
{
|
||||
/* REG struct dpb *dpbp = &blk_devices[dsk]; */
|
||||
|
||||
REG struct dpb FAR *dpbp = CDSp[dsk].cdsDpb;
|
||||
|
||||
if ((UCOUNT) dsk >= lastdrive)
|
||||
{
|
||||
return 0x0201; /* illegal command */
|
||||
}
|
||||
if ((CDSp[dsk].cdsFlags & (CDSPHYSDRV | CDSNETWDRV)) != CDSPHYSDRV)
|
||||
register struct dpb FAR *dpbp = get_dpb(dsk);
|
||||
if (dpbp == NULL)
|
||||
{
|
||||
return 0x0201; /* illegal command */
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include "portab.h"
|
||||
#include "globals.h"
|
||||
#include "proto.h"
|
||||
|
||||
extern void ASMCFUNC spawn_int23(void);
|
||||
|
||||
@ -60,11 +61,11 @@ int control_break(void)
|
||||
* 3) decrease the InDOS flag as the kernel drops back to user space
|
||||
* 4) invoke INT-23 and never come back
|
||||
*/
|
||||
void handle_break(void)
|
||||
void handle_break(int sft_idx)
|
||||
{
|
||||
mod_cso(CTL_C);
|
||||
echo_char_stdin(CTL_C);
|
||||
CB_FLG &= ~CB_MSK; /* reset the ^Break flag */
|
||||
KbdFlush(); /* Er, this is con_flush() */
|
||||
KbdFlush(sft_idx); /* Er, this is con_flush() */
|
||||
if (!ErrorMode) /* within int21_handler, InDOS is not incremented */
|
||||
if (InDOS)
|
||||
--InDOS; /* fail-safe */
|
||||
|
588
kernel/chario.c
588
kernel/chario.c
@ -37,86 +37,190 @@ static BYTE *charioRcsId =
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
/* Return a pointer to the first driver in the chain that
|
||||
* matches the attributes.
|
||||
* not necessary because we have the syscon pointer.
|
||||
*/
|
||||
#if 0
|
||||
struct dhdr FAR *finddev(UWORD attr_mask)
|
||||
STATIC int CharRequest(struct dhdr FAR *dev)
|
||||
{
|
||||
struct dhdr far *dh;
|
||||
|
||||
for (dh = nul_dev.dh_next; FP_OFF(dh) != 0xFFFF; dh = dh->dh_next)
|
||||
CharReqHdr.r_unit = 0;
|
||||
CharReqHdr.r_status = 0;
|
||||
CharReqHdr.r_length = sizeof(request);
|
||||
execrh(&CharReqHdr, dev);
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
{
|
||||
if (dh->dh_attr & attr_mask)
|
||||
return dh;
|
||||
charloop:
|
||||
switch (char_error(&CharReqHdr, dev))
|
||||
{
|
||||
case ABORT:
|
||||
case FAIL:
|
||||
return DE_INVLDACC;
|
||||
case CONTINUE:
|
||||
CharReqHdr.r_count = 0;
|
||||
return 0;
|
||||
case RETRY:
|
||||
return 1;
|
||||
default:
|
||||
goto charloop;
|
||||
}
|
||||
}
|
||||
|
||||
/* return dev/null if no matching driver found */
|
||||
return &nul_dev;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
UCOUNT BinaryCharIO(struct dhdr FAR * dev, UCOUNT n, void FAR * bp, unsigned command, COUNT *err)
|
||||
long BinaryCharIO(struct dhdr FAR * dev, size_t n, void FAR * bp, unsigned command)
|
||||
{
|
||||
*err = SUCCESS;
|
||||
|
||||
FOREVER
|
||||
int err = SUCCESS;
|
||||
do
|
||||
{
|
||||
CharReqHdr.r_length = sizeof(request);
|
||||
CharReqHdr.r_command = command;
|
||||
CharReqHdr.r_count = n;
|
||||
CharReqHdr.r_trans = bp;
|
||||
CharReqHdr.r_status = 0;
|
||||
execrh(&CharReqHdr, dev);
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
{
|
||||
charloop:
|
||||
switch (char_error(&CharReqHdr, dev))
|
||||
{
|
||||
case ABORT:
|
||||
case FAIL:
|
||||
*err = DE_INVLDACC;
|
||||
return 0;
|
||||
case CONTINUE:
|
||||
break;
|
||||
case RETRY:
|
||||
continue;
|
||||
default:
|
||||
goto charloop;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return CharReqHdr.r_count;
|
||||
} while ((err = CharRequest(dev)) == 1);
|
||||
return err == SUCCESS ? CharReqHdr.r_count : err;
|
||||
}
|
||||
|
||||
VOID _cso(COUNT c)
|
||||
/* STATE FUNCTIONS */
|
||||
|
||||
STATIC struct dhdr FAR *idx_to_dev(int sft_idx)
|
||||
{
|
||||
if (syscon->dh_attr & ATTR_FASTCON)
|
||||
sft FAR *s = idx_to_sft(sft_idx);
|
||||
if (FP_OFF(s) == (size_t)-1 || (s->sft_mode & SFT_MWRITE) ||
|
||||
!(s->sft_flags & SFT_FDEVICE))
|
||||
return syscon;
|
||||
else
|
||||
return s->sft_dev;
|
||||
}
|
||||
|
||||
/* if sft_idx is invalid, then we just monitor syscon */
|
||||
STATIC BOOL Busy(int sft_idx)
|
||||
{
|
||||
sft FAR *s = idx_to_sft(sft_idx);
|
||||
|
||||
if (s->sft_flags & SFT_FDEVICE)
|
||||
{
|
||||
struct dhdr FAR *dev = idx_to_dev(sft_idx);
|
||||
do {
|
||||
CharReqHdr.r_command = C_ISTAT;
|
||||
} while(CharRequest(dev) == 1);
|
||||
if (CharReqHdr.r_status & S_BUSY)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return s->sft_posit >= s->sft_size;
|
||||
}
|
||||
|
||||
BOOL StdinBusy(void)
|
||||
{
|
||||
return Busy(get_sft_idx(STDIN));
|
||||
}
|
||||
|
||||
STATIC void Do_DosIdle_loop(int sft_idx)
|
||||
{
|
||||
/* the idle loop is only safe if we're using the character stack */
|
||||
if (user_r->AH < 0xd)
|
||||
while (Busy(sft_idx))
|
||||
DosIdle_int();
|
||||
}
|
||||
|
||||
/* get character from the console - this is how DOS gets
|
||||
CTL_C/CTL_S/CTL_P when outputting */
|
||||
STATIC int ndread(int sft_idx)
|
||||
{
|
||||
struct dhdr FAR *dev = idx_to_dev(sft_idx);
|
||||
do {
|
||||
CharReqHdr.r_command = C_NDREAD;
|
||||
} while(CharRequest(dev) == 1);
|
||||
if (CharReqHdr.r_status & S_BUSY)
|
||||
return -1;
|
||||
return CharReqHdr.r_ndbyte;
|
||||
}
|
||||
|
||||
STATIC int con_get_char(int sft_idx)
|
||||
{
|
||||
unsigned char c;
|
||||
BinaryCharIO(idx_to_dev(sft_idx), 1, &c, C_INPUT);
|
||||
if (c == CTL_C)
|
||||
handle_break(sft_idx);
|
||||
return c;
|
||||
}
|
||||
|
||||
STATIC void con_hold(int sft_idx)
|
||||
{
|
||||
int c;
|
||||
if (control_break())
|
||||
handle_break(-1);
|
||||
c = ndread(sft_idx);
|
||||
if (c == CTL_S)
|
||||
{
|
||||
con_get_char(sft_idx);
|
||||
Do_DosIdle_loop(sft_idx);
|
||||
/* just wait */
|
||||
c = con_get_char(sft_idx);
|
||||
}
|
||||
if (c == CTL_C)
|
||||
{
|
||||
con_get_char(sft_idx);
|
||||
handle_break(sft_idx);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL con_break(void)
|
||||
{
|
||||
if (ndread(-1) == CTL_C)
|
||||
{
|
||||
con_get_char(-1);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* OUTPUT FUNCTIONS */
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
void int29(char c);
|
||||
#pragma aux int29 = "int 29h" parm[al] modify exact [bx]
|
||||
#endif
|
||||
|
||||
/* writes a character in raw mode; use int29 if possible
|
||||
for speed */
|
||||
STATIC int raw_put_char(int sft_idx, int c)
|
||||
{
|
||||
struct dhdr FAR *dev = idx_to_dev(sft_idx);
|
||||
unsigned char ch = (unsigned char)c;
|
||||
|
||||
if (PrinterEcho)
|
||||
DosWrite(STDPRN, 1, &ch);
|
||||
|
||||
if (dev->dh_attr & ATTR_FASTCON)
|
||||
{
|
||||
#if defined(__TURBOC__)
|
||||
_AL = c;
|
||||
_AL = ch;
|
||||
__int__(0x29);
|
||||
#elif defined(__WATCOMC__)
|
||||
int29(ch);
|
||||
#elif defined(I86)
|
||||
asm
|
||||
{
|
||||
mov al, byte ptr c;
|
||||
mov al, byte ptr ch;
|
||||
int 0x29;
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
BinaryCharIO(syscon, 1, &c, C_OUTPUT, &UnusedRetVal);
|
||||
c = (int)BinaryCharIO(dev, 1, &ch, C_OUTPUT);
|
||||
if (c < 0)
|
||||
return c;
|
||||
else
|
||||
return ch;
|
||||
}
|
||||
|
||||
VOID cso(COUNT c)
|
||||
/* writes a character in cooked mode; maybe with printer echo;
|
||||
handles TAB expansion */
|
||||
STATIC int cooked_put_char(int sft_idx, int c)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
/* Test for hold char */
|
||||
con_hold();
|
||||
|
||||
if (PrinterEcho)
|
||||
DosWrite(STDPRN, 1, (BYTE FAR *) & c, & UnusedRetVal);
|
||||
con_hold(sft_idx);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
@ -132,157 +236,139 @@ VOID cso(COUNT c)
|
||||
break;
|
||||
case HT:
|
||||
do
|
||||
_cso(' ');
|
||||
while ((++scr_pos) & 7);
|
||||
err = raw_put_char(sft_idx, ' ');
|
||||
while (err >= 0 && ((++scr_pos) & 7));
|
||||
break;
|
||||
default:
|
||||
scr_pos++;
|
||||
}
|
||||
if (c != HT)
|
||||
_cso(c);
|
||||
err = raw_put_char(sft_idx, c);
|
||||
return err;
|
||||
}
|
||||
|
||||
VOID sto(COUNT c)
|
||||
long cooked_write(int sft_idx, size_t n, char FAR *bp)
|
||||
{
|
||||
DosWrite(STDOUT, 1, (BYTE FAR *) & c, & UnusedRetVal);
|
||||
size_t xfer;
|
||||
int err = SUCCESS;
|
||||
|
||||
for (xfer = 0; err >= SUCCESS && xfer < n && *bp != CTL_Z; bp++, xfer++)
|
||||
err = cooked_put_char(sft_idx, *bp);
|
||||
return err < SUCCESS ? err : xfer;
|
||||
}
|
||||
|
||||
unsigned mod_cso(register unsigned c)
|
||||
/* writes character for disk file or device */
|
||||
void write_char(int c, int sft_idx)
|
||||
{
|
||||
if (c < ' ' && c != HT)
|
||||
unsigned char ch = (unsigned char)c;
|
||||
DosRWSft(sft_idx, 1, &ch, XFR_FORCE_WRITE);
|
||||
}
|
||||
|
||||
void write_char_stdin(int c)
|
||||
{
|
||||
write_char(c, get_sft_idx(STDIN));
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
if (iscntrl(c) && c != HT && c != LF && c != CR)
|
||||
{
|
||||
cso('^');
|
||||
cso(c + '@');
|
||||
write_char('^', sft_idx);
|
||||
write_char(c + '@', sft_idx);
|
||||
}
|
||||
else
|
||||
cso(c);
|
||||
write_char(c, sft_idx);
|
||||
return c;
|
||||
}
|
||||
|
||||
VOID destr_bs(void)
|
||||
int echo_char_stdin(int c)
|
||||
{
|
||||
cso(BS);
|
||||
cso(' ');
|
||||
cso(BS);
|
||||
return echo_char(get_sft_idx(STDIN), c);
|
||||
}
|
||||
|
||||
VOID Do_DosIdle_loop(void)
|
||||
STATIC void destr_bs(int sft_idx)
|
||||
{
|
||||
FOREVER
|
||||
{
|
||||
if (!StdinBusy())
|
||||
return;
|
||||
else
|
||||
{
|
||||
DosIdle_int();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
write_char(BS, sft_idx);
|
||||
write_char(' ', sft_idx);
|
||||
write_char(BS, sft_idx);
|
||||
}
|
||||
|
||||
COUNT ndread(void)
|
||||
{
|
||||
CharReqHdr.r_unit = 0;
|
||||
CharReqHdr.r_status = 0;
|
||||
CharReqHdr.r_command = C_NDREAD;
|
||||
CharReqHdr.r_length = sizeof(request);
|
||||
execrh((request FAR *) & CharReqHdr, syscon);
|
||||
if (CharReqHdr.r_status & S_BUSY)
|
||||
return -1;
|
||||
return CharReqHdr.r_ndbyte;
|
||||
}
|
||||
/* READ FUNCTIONS */
|
||||
|
||||
COUNT con_read(void)
|
||||
STATIC int raw_get_char(int sft_idx, BOOL check_break)
|
||||
{
|
||||
BYTE c;
|
||||
|
||||
BinaryCharIO(syscon, 1, &c, C_INPUT, &UnusedRetVal);
|
||||
if (c == CTL_C)
|
||||
handle_break();
|
||||
return c;
|
||||
}
|
||||
|
||||
VOID con_hold(void)
|
||||
{
|
||||
UBYTE c = ndread();
|
||||
if (c == CTL_S)
|
||||
{
|
||||
con_read();
|
||||
Do_DosIdle_loop();
|
||||
/* just wait */
|
||||
c = con_read();
|
||||
}
|
||||
if (c == CTL_C)
|
||||
{
|
||||
con_read();
|
||||
handle_break();
|
||||
}
|
||||
}
|
||||
|
||||
UCOUNT _sti(BOOL check_break)
|
||||
{
|
||||
UBYTE c;
|
||||
/*
|
||||
* XXX: If there's a read error, this will just keep retrying the read until
|
||||
* the error disappears. Maybe it should do something else instead. -- ror4
|
||||
*/
|
||||
Do_DosIdle_loop();
|
||||
unsigned char c;
|
||||
int err;
|
||||
|
||||
Do_DosIdle_loop(sft_idx);
|
||||
if (check_break)
|
||||
con_hold();
|
||||
while (BinaryRead(STDIN, &c, & UnusedRetVal) != 1)
|
||||
;
|
||||
con_hold(sft_idx);
|
||||
|
||||
err = (int)BinaryCharIO(idx_to_dev(sft_idx), 1, &c, C_INPUT);
|
||||
return err < 0 ? err : c;
|
||||
}
|
||||
|
||||
long cooked_read(int sft_idx, size_t n, char FAR *bp)
|
||||
{
|
||||
unsigned xfer = 0;
|
||||
int c;
|
||||
while(n--)
|
||||
{
|
||||
c = raw_get_char(sft_idx, TRUE);
|
||||
if (c < 0)
|
||||
return c;
|
||||
*bp++ = c;
|
||||
xfer++;
|
||||
if (bp[-1] == CTL_Z)
|
||||
break;
|
||||
}
|
||||
return xfer;
|
||||
}
|
||||
|
||||
unsigned char read_char(int sft_idx, BOOL check_break)
|
||||
{
|
||||
unsigned char c;
|
||||
sft FAR *s = idx_to_sft(sft_idx);
|
||||
|
||||
if ((FP_OFF(s) == (size_t) -1) || (s->sft_flags & SFT_FDEVICE))
|
||||
return raw_get_char(sft_idx, check_break);
|
||||
|
||||
DosRWSft(sft_idx, 1, &c, XFR_READ);
|
||||
return c;
|
||||
}
|
||||
|
||||
BOOL con_break(void)
|
||||
STATIC unsigned char read_char_check_break(int sft_idx)
|
||||
{
|
||||
if (ndread() == CTL_C)
|
||||
{
|
||||
con_read();
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
return read_char(sft_idx, TRUE);
|
||||
}
|
||||
|
||||
BOOL StdinBusy(void)
|
||||
unsigned char read_char_stdin(BOOL check_break)
|
||||
{
|
||||
sft FAR *s;
|
||||
return read_char(get_sft_idx(STDIN), check_break);
|
||||
}
|
||||
|
||||
if ((s = get_sft(STDIN)) == (sft FAR *) - 1)
|
||||
return FALSE; /* XXX */
|
||||
if (s->sft_count == 0 || (s->sft_mode & SFT_MWRITE))
|
||||
return FALSE; /* XXX */
|
||||
if (s->sft_flags & SFT_FDEVICE)
|
||||
{
|
||||
void KbdFlush(int sft_idx)
|
||||
{
|
||||
struct dhdr FAR *dev = idx_to_dev(sft_idx);
|
||||
|
||||
do {
|
||||
CharReqHdr.r_unit = 0;
|
||||
CharReqHdr.r_status = 0;
|
||||
CharReqHdr.r_command = C_ISTAT;
|
||||
CharReqHdr.r_command = C_IFLUSH;
|
||||
CharReqHdr.r_length = sizeof(request);
|
||||
execrh((request FAR *) & CharReqHdr, s->sft_dev);
|
||||
if (CharReqHdr.r_status & S_BUSY)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return FALSE; /* XXX */
|
||||
} while (CharRequest(dev) == 1);
|
||||
}
|
||||
|
||||
VOID KbdFlush(void)
|
||||
/* reads a line (buffered, called by int21/ah=0ah, 3fh) */
|
||||
void read_line(int sft_in, int sft_out, keyboard FAR * kp)
|
||||
{
|
||||
CharReqHdr.r_unit = 0;
|
||||
CharReqHdr.r_status = 0;
|
||||
CharReqHdr.r_command = C_IFLUSH;
|
||||
CharReqHdr.r_length = sizeof(request);
|
||||
execrh((request FAR *) & CharReqHdr, syscon);
|
||||
}
|
||||
|
||||
/* reads a line */
|
||||
void sti_0a(keyboard FAR * kp)
|
||||
{
|
||||
REG UWORD c, cu_pos = scr_pos;
|
||||
unsigned count = 0, stored_pos = 0, size = kp->kb_size, stored_size = kp->kb_count;
|
||||
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;
|
||||
|
||||
if (size == 0)
|
||||
@ -290,86 +376,76 @@ void sti_0a(keyboard FAR * kp)
|
||||
|
||||
/* the stored line is invalid unless it ends with a CR */
|
||||
if (kp->kb_buf[stored_size] != CR)
|
||||
{
|
||||
stored_size = 0;
|
||||
}
|
||||
|
||||
while ((c = _sti(TRUE)) != CR)
|
||||
do
|
||||
{
|
||||
unsigned new_pos = stored_size;
|
||||
|
||||
c = read_char_check_break(sft_in);
|
||||
if (c == 0)
|
||||
c = (unsigned)read_char_check_break(sft_in) << 8;
|
||||
switch (c)
|
||||
{
|
||||
case CTL_C:
|
||||
handle_break();
|
||||
case CTL_F:
|
||||
continue;
|
||||
|
||||
#ifndef NOSPCL
|
||||
case SPCL:
|
||||
switch (c = _sti(TRUE))
|
||||
{
|
||||
case LEFT:
|
||||
goto backspace;
|
||||
|
||||
case RIGHT:
|
||||
case F1:
|
||||
if (stored_pos < stored_size && count < size - 1)
|
||||
local_buffer[count++] = mod_cso(kp->kb_buf[stored_pos++]);
|
||||
break;
|
||||
|
||||
case F2:
|
||||
c = _sti(TRUE);
|
||||
/* insert up to character c */
|
||||
insert_to_c:
|
||||
while (stored_pos < stored_size && count < size - 1)
|
||||
{
|
||||
char c2 = kp->kb_buf[stored_pos];
|
||||
if (c2 == c)
|
||||
break;
|
||||
stored_pos++;
|
||||
local_buffer[count++] = mod_cso(c2);
|
||||
}
|
||||
break;
|
||||
|
||||
case F3:
|
||||
c = (unsigned)-1;
|
||||
goto insert_to_c;
|
||||
|
||||
case F4:
|
||||
c = _sti(TRUE);
|
||||
/* delete up to character c */
|
||||
while (stored_pos < stored_size && c != kp->kb_buf[stored_pos])
|
||||
stored_pos++;
|
||||
break;
|
||||
|
||||
case F5:
|
||||
fmemcpy(kp->kb_buf, local_buffer, count);
|
||||
stored_size = count;
|
||||
cso('@');
|
||||
goto start_new_line;
|
||||
|
||||
case F6:
|
||||
c = CTL_Z;
|
||||
goto default_case;
|
||||
|
||||
case INS:
|
||||
insert = !insert;
|
||||
break;
|
||||
|
||||
case DEL:
|
||||
stored_pos++;
|
||||
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;
|
||||
#endif
|
||||
|
||||
case F2:
|
||||
case F4:
|
||||
/* insert/delete up to character c */
|
||||
{
|
||||
unsigned char c2 = read_char_check_break(sft_in);
|
||||
new_pos = stored_pos;
|
||||
if (c2 == 0)
|
||||
{
|
||||
read_char_check_break(sft_in);
|
||||
}
|
||||
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:
|
||||
backspace:
|
||||
if (count > 0)
|
||||
{
|
||||
unsigned new_pos;
|
||||
c = local_buffer[--count];
|
||||
if (c == HT)
|
||||
char c2 = local_buffer[--count];
|
||||
if (c2 == HT)
|
||||
{
|
||||
unsigned i;
|
||||
new_pos = cu_pos;
|
||||
@ -377,66 +453,63 @@ void sti_0a(keyboard FAR * kp)
|
||||
{
|
||||
if (local_buffer[i] == HT)
|
||||
new_pos = (new_pos + 8) & ~7;
|
||||
else if (local_buffer[i] < ' ')
|
||||
else if (iscntrl(local_buffer[i]))
|
||||
new_pos += 2;
|
||||
else
|
||||
new_pos++;
|
||||
}
|
||||
do
|
||||
destr_bs();
|
||||
destr_bs(sft_out);
|
||||
while (scr_pos > new_pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c < ' ')
|
||||
destr_bs();
|
||||
destr_bs();
|
||||
if (iscntrl(c2))
|
||||
destr_bs(sft_out);
|
||||
destr_bs(sft_out);
|
||||
}
|
||||
}
|
||||
if (stored_pos > 0 && !insert)
|
||||
if (stored_pos > 0)
|
||||
stored_pos--;
|
||||
break;
|
||||
|
||||
case LF:
|
||||
cso(CR);
|
||||
cso(LF);
|
||||
break;
|
||||
|
||||
case ESC:
|
||||
cso('\\');
|
||||
write_char('\\', sft_out);
|
||||
start_new_line:
|
||||
cso(CR);
|
||||
cso(LF);
|
||||
for (c = 0; c < cu_pos; c++)
|
||||
cso(' ');
|
||||
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:
|
||||
default_case:
|
||||
if (count < size - 1)
|
||||
local_buffer[count++] = mod_cso(c);
|
||||
if (count < size - 1 || c == CR)
|
||||
local_buffer[count++] = echo_char(c, sft_out);
|
||||
else
|
||||
cso(BELL);
|
||||
write_char(BELL, sft_out);
|
||||
if (stored_pos < stored_size && !insert)
|
||||
stored_pos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
local_buffer[count] = CR;
|
||||
cso(CR);
|
||||
fmemcpy(kp->kb_buf, local_buffer, count + 1);
|
||||
} 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;
|
||||
kp->kb_count = count;
|
||||
/* kb_count does not include the final CR */
|
||||
kp->kb_count = count - 1;
|
||||
}
|
||||
|
||||
unsigned sti(unsigned n, char FAR * bp)
|
||||
/* called by handle func READ (int21/ah=3f) */
|
||||
size_t read_line_handle(int sft_idx, size_t n, char FAR * bp)
|
||||
{
|
||||
char *bufend = &kb_buf.kb_buf[kb_buf.kb_count + 2];
|
||||
|
||||
@ -448,10 +521,9 @@ unsigned sti(unsigned n, char FAR * bp)
|
||||
kb_buf.kb_count = 0;
|
||||
kb_buf.kb_size = LINEBUFSIZECON;
|
||||
}
|
||||
sti_0a(&kb_buf);
|
||||
read_line(sft_idx, sft_idx, &kb_buf);
|
||||
bufend = &kb_buf.kb_buf[kb_buf.kb_count + 2];
|
||||
bufend[-1] = LF;
|
||||
cso(LF);
|
||||
bufend[-1] = echo_char(LF, sft_idx);
|
||||
inputptr = kb_buf.kb_buf;
|
||||
if (*inputptr == CTL_Z)
|
||||
{
|
||||
|
@ -144,7 +144,7 @@ STATIC VOID DeviceHigh(BYTE * pLine);
|
||||
STATIC VOID Files(BYTE * pLine);
|
||||
STATIC VOID Fcbs(BYTE * pLine);
|
||||
STATIC VOID CfgLastdrive(BYTE * pLine);
|
||||
STATIC BOOL LoadDevice(BYTE * pLine, COUNT top, COUNT mode);
|
||||
STATIC BOOL LoadDevice(BYTE * pLine, char FAR *top, COUNT mode);
|
||||
STATIC VOID Dosmem(BYTE * pLine);
|
||||
STATIC VOID Country(BYTE * pLine);
|
||||
STATIC VOID InitPgm(BYTE * pLine);
|
||||
@ -155,6 +155,15 @@ STATIC VOID CfgIgnore(BYTE * pLine);
|
||||
STATIC VOID CfgMenu(BYTE * pLine);
|
||||
STATIC VOID DoMenu(void);
|
||||
STATIC VOID CfgMenuDefault(BYTE * pLine);
|
||||
STATIC BYTE * skipwh(BYTE * s);
|
||||
STATIC BYTE * scan(BYTE * s, BYTE * d);
|
||||
STATIC BOOL isnum(BYTE * pszString);
|
||||
STATIC BYTE * GetNumber(REG BYTE * pszString, REG COUNT * pnNum);
|
||||
#if 0
|
||||
STATIC COUNT tolower(COUNT c);
|
||||
#endif
|
||||
STATIC COUNT toupper(COUNT c);
|
||||
STATIC VOID mcb_init(UCOUNT seg, UWORD size);
|
||||
|
||||
STATIC VOID Stacks(BYTE * pLine);
|
||||
STATIC VOID SetAnyDos(BYTE * pLine);
|
||||
@ -170,8 +179,9 @@ STATIC COUNT strcasecmp(REG BYTE * d, REG BYTE * s);
|
||||
void HMAconfig(int finalize);
|
||||
VOID config_init_buffers(COUNT anzBuffers); /* from BLOCKIO.C */
|
||||
|
||||
#ifdef I86
|
||||
STATIC VOID FAR * AlignParagraph(VOID FAR * lpPtr);
|
||||
#ifndef I86
|
||||
#else
|
||||
#define AlignParagraph(x) ((VOID *)x)
|
||||
#endif
|
||||
|
||||
@ -659,12 +669,12 @@ STATIC struct table * LookUp(struct table *p, BYTE * token)
|
||||
0x..LL : asciicode in lower half
|
||||
*/
|
||||
|
||||
ULONG GetBiosTime(VOID)
|
||||
STATIC ULONG GetBiosTime(VOID)
|
||||
{
|
||||
return *(ULONG FAR *) (MK_FP(0x40, 0x6c));
|
||||
}
|
||||
|
||||
UWORD GetBiosKey(int timeout)
|
||||
STATIC UWORD GetBiosKey(int timeout)
|
||||
{
|
||||
iregs r;
|
||||
|
||||
@ -1106,25 +1116,25 @@ STATIC VOID DeviceHigh(BYTE * pLine)
|
||||
{
|
||||
if (UmbState == 1)
|
||||
{
|
||||
if (LoadDevice(pLine, UMB_top, TRUE) == DE_NOMEM)
|
||||
if (LoadDevice(pLine, MK_FP(umb_start + UMB_top, 0), TRUE) == DE_NOMEM)
|
||||
{
|
||||
printf("Not enough free memory in UMB's: loading low\n");
|
||||
LoadDevice(pLine, ram_top, FALSE);
|
||||
LoadDevice(pLine, lpTop, FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("UMB's unavailable!\n");
|
||||
LoadDevice(pLine, ram_top, FALSE);
|
||||
LoadDevice(pLine, lpTop, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void Device(BYTE * pLine)
|
||||
{
|
||||
LoadDevice(pLine, ram_top, FALSE);
|
||||
LoadDevice(pLine, lpTop, FALSE);
|
||||
}
|
||||
|
||||
STATIC BOOL LoadDevice(BYTE * pLine, COUNT top, COUNT mode)
|
||||
STATIC BOOL LoadDevice(BYTE * pLine, char FAR *top, COUNT mode)
|
||||
{
|
||||
exec_blk eb;
|
||||
struct dhdr FAR *dhp;
|
||||
|
326
kernel/dosfns.c
326
kernel/dosfns.c
@ -89,21 +89,41 @@ STATIC int remote_lock_unlock(sft FAR *sftp, /* SFT for file */
|
||||
unsigned long len, /* length (in bytes) of region to lock or unlock */
|
||||
int unlock); /* non-zero to unlock; zero to lock */
|
||||
|
||||
/* get current directory structure for drive
|
||||
return NULL if the CDS is not valid or the
|
||||
drive is not within range */
|
||||
struct cds FAR *get_cds(int drive)
|
||||
{
|
||||
struct cds FAR *cdsp;
|
||||
unsigned flags;
|
||||
|
||||
if (drive >= lastdrive)
|
||||
return NULL;
|
||||
cdsp = &CDSp[drive];
|
||||
flags = cdsp->cdsFlags;
|
||||
/* Entry is disabled or JOINed drives are accessable by the path only */
|
||||
if (!(flags & CDSVALID) || (flags & CDSJOINED) != 0)
|
||||
return NULL;
|
||||
if (!(flags & CDSNETWDRV) && cdsp->cdsDpb == NULL)
|
||||
return NULL;
|
||||
return cdsp;
|
||||
}
|
||||
|
||||
#ifdef WITHFAT32
|
||||
struct dpb FAR * GetDriveDPB(UBYTE drive, COUNT * rc)
|
||||
{
|
||||
struct dpb FAR *dpb;
|
||||
drive = drive == 0 ? default_drive : drive - 1;
|
||||
|
||||
if (drive >= lastdrive)
|
||||
struct cds FAR *cdsp;
|
||||
|
||||
cdsp = get_cds(drive == 0 ? default_drive : drive - 1);
|
||||
|
||||
if (cdsp == NULL)
|
||||
{
|
||||
*rc = DE_INVLDDRV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dpb = CDSp[drive].cdsDpb;
|
||||
if (dpb == 0 || CDSp[drive].cdsFlags & CDSNETWDRV)
|
||||
dpb = cdsp->cdsDpb;
|
||||
if (dpb == 0 || cdsp->cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
*rc = DE_INVLDDRV;
|
||||
return 0;
|
||||
@ -123,7 +143,7 @@ STATIC VOID DosGetFile(BYTE * lpszPath, BYTE FAR * lpszDosFileName)
|
||||
fmemcpy(lpszDosFileName, fcbname, FNAME_SIZE + FEXT_SIZE);
|
||||
}
|
||||
|
||||
sft FAR * idx_to_sft(COUNT SftIndex)
|
||||
sft FAR * idx_to_sft(int SftIndex)
|
||||
{
|
||||
sfttbl FAR *sp;
|
||||
|
||||
@ -152,14 +172,16 @@ sft FAR * idx_to_sft(COUNT SftIndex)
|
||||
return (sft FAR *) - 1;
|
||||
}
|
||||
|
||||
COUNT get_sft_idx(UCOUNT hndl)
|
||||
int get_sft_idx(unsigned hndl)
|
||||
{
|
||||
psp FAR *p = MK_FP(cu_psp, 0);
|
||||
int idx;
|
||||
|
||||
if (hndl >= p->ps_maxfiles)
|
||||
return DE_INVLDHNDL;
|
||||
|
||||
return p->ps_filetab[hndl] == 0xff ? DE_INVLDHNDL : p->ps_filetab[hndl];
|
||||
idx = p->ps_filetab[hndl];
|
||||
return idx == 0xff ? DE_INVLDHNDL : idx;
|
||||
}
|
||||
|
||||
sft FAR *get_sft(UCOUNT hndl)
|
||||
@ -168,21 +190,23 @@ sft FAR *get_sft(UCOUNT hndl)
|
||||
return idx_to_sft(get_sft_idx(hndl));
|
||||
}
|
||||
|
||||
UCOUNT DosRWSft(sft FAR * s, UCOUNT n, void FAR * bp, COUNT * err, int mode)
|
||||
long DosRWSft(int sft_idx, size_t n, void FAR * bp, int mode)
|
||||
{
|
||||
*err = SUCCESS;
|
||||
/* Get the SFT block that contains the SFT */
|
||||
sft FAR *s = idx_to_sft(sft_idx);
|
||||
|
||||
if (FP_OFF(s) == (size_t) - 1)
|
||||
{
|
||||
*err = DE_INVLDHNDL;
|
||||
return 0;
|
||||
return DE_INVLDHNDL;
|
||||
}
|
||||
/* If for read and write-only or for write and read-only then exit */
|
||||
if((mode == XFR_READ && (s->sft_mode & SFT_MWRITE)) ||
|
||||
(mode == XFR_WRITE && !(s->sft_mode & (SFT_MWRITE | SFT_MRDWR))))
|
||||
{
|
||||
*err = DE_ACCESS;
|
||||
return 0;
|
||||
return DE_ACCESS;
|
||||
}
|
||||
if (mode == XFR_FORCE_WRITE)
|
||||
mode = XFR_WRITE;
|
||||
|
||||
/*
|
||||
* Do remote first or return error.
|
||||
@ -191,54 +215,68 @@ UCOUNT DosRWSft(sft FAR * s, UCOUNT n, void FAR * bp, COUNT * err, int mode)
|
||||
if (s->sft_flags & SFT_FSHARED)
|
||||
{
|
||||
UCOUNT XferCount;
|
||||
BYTE FAR *save_dta;
|
||||
VOID FAR *save_dta;
|
||||
int err;
|
||||
|
||||
save_dta = dta;
|
||||
lpCurSft = s;
|
||||
current_filepos = s->sft_posit; /* needed for MSCDEX */
|
||||
dta = bp;
|
||||
XferCount = (mode == XFR_READ ? remote_read : remote_write)(s, n, err);
|
||||
XferCount = (mode == XFR_READ ? remote_read : remote_write)(s, n, &err);
|
||||
dta = save_dta;
|
||||
return *err == SUCCESS ? XferCount : 0;
|
||||
return err == SUCCESS ? XferCount : err;
|
||||
}
|
||||
|
||||
/* Do a device transfer if device */
|
||||
if (s->sft_flags & SFT_FDEVICE)
|
||||
{
|
||||
/* Now handle raw and cooked modes */
|
||||
if (s->sft_flags & SFT_FBINARY)
|
||||
{
|
||||
long rc = BinaryCharIO(s->sft_dev, n, bp,
|
||||
mode == XFR_READ ? C_INPUT : C_OUTPUT);
|
||||
if (mode == XFR_WRITE && rc > 0 && (s->sft_flags & SFT_FCONOUT))
|
||||
{
|
||||
size_t cnt = (size_t)rc;
|
||||
const char FAR *p = bp;
|
||||
while (cnt--)
|
||||
{
|
||||
switch (*p++)
|
||||
{
|
||||
case CR:
|
||||
scr_pos = 0;
|
||||
break;
|
||||
case LF:
|
||||
case BELL:
|
||||
break;
|
||||
case BS:
|
||||
--scr_pos;
|
||||
break;
|
||||
default:
|
||||
++scr_pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* cooked mode */
|
||||
if (mode==XFR_READ)
|
||||
{
|
||||
char c;
|
||||
|
||||
/* First test for eof and exit */
|
||||
long rc;
|
||||
|
||||
/* Test for eof and exit */
|
||||
/* immediately if it is */
|
||||
if (!(s->sft_flags & SFT_FEOF) || (s->sft_flags & SFT_FNUL))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Now handle raw and cooked modes */
|
||||
if (s->sft_flags & SFT_FBINARY)
|
||||
return BinaryCharIO(s->sft_dev, n, bp, C_INPUT, err);
|
||||
if (s->sft_flags & SFT_FCONIN)
|
||||
{
|
||||
n = sti(n, bp);
|
||||
if (n == 0)
|
||||
c = CTL_Z;
|
||||
}
|
||||
rc = read_line_handle(sft_idx, n, bp);
|
||||
else
|
||||
{
|
||||
n = 1;
|
||||
Do_DosIdle_loop();
|
||||
BinaryReadSft(s, &c, err);
|
||||
if (c != CTL_Z)
|
||||
*(char FAR *)bp = c;
|
||||
}
|
||||
if (c == CTL_Z)
|
||||
{
|
||||
n = 0;
|
||||
rc = cooked_read(sft_idx, n, bp);
|
||||
if (*(char *)bp == CTL_Z)
|
||||
s->sft_flags &= ~SFT_FEOF;
|
||||
}
|
||||
return n;
|
||||
return rc;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -248,55 +286,8 @@ UCOUNT DosRWSft(sft FAR * s, UCOUNT n, void FAR * bp, COUNT * err, int mode)
|
||||
/* if null just report full transfer */
|
||||
if (s->sft_flags & SFT_FNUL)
|
||||
return n;
|
||||
|
||||
/* Now handle raw and cooked modes */
|
||||
if (s->sft_flags & SFT_FBINARY)
|
||||
{
|
||||
n = BinaryCharIO(s->sft_dev, n, bp, C_OUTPUT, err);
|
||||
if (n > 0 && (s->sft_flags & SFT_FCONOUT))
|
||||
{
|
||||
UWORD cnt = n;
|
||||
const char FAR *p = bp;
|
||||
while (cnt--)
|
||||
{
|
||||
switch (*p++)
|
||||
{
|
||||
case CR:
|
||||
scr_pos = 0;
|
||||
break;
|
||||
case LF:
|
||||
case BELL:
|
||||
break;
|
||||
case BS:
|
||||
--scr_pos;
|
||||
break;
|
||||
default:
|
||||
++scr_pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
else
|
||||
{
|
||||
REG UWORD xfer;
|
||||
const char FAR *p = bp;
|
||||
|
||||
for (xfer = 0; xfer < n && *p != CTL_Z; p++, xfer++)
|
||||
{
|
||||
if (s->sft_flags & SFT_FCONOUT)
|
||||
cso(*p);
|
||||
else if (BinaryCharIO(s->sft_dev, 1, bp, C_OUTPUT, err) == 0 &&
|
||||
*err != SUCCESS)
|
||||
return xfer;
|
||||
if (control_break())
|
||||
{
|
||||
handle_break();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return xfer;
|
||||
}
|
||||
return cooked_write(sft_idx, n, bp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,10 +295,10 @@ UCOUNT DosRWSft(sft FAR * s, UCOUNT n, void FAR * bp, COUNT * err, int mode)
|
||||
/* /// Added for SHARE - Ron Cemer */
|
||||
if (IsShareInstalled() && (s->sft_shroff >= 0))
|
||||
{
|
||||
*err = share_access_check(cu_psp, s->sft_shroff, s->sft_posit,
|
||||
(unsigned long)n, 1);
|
||||
if (*err != SUCCESS)
|
||||
return 0;
|
||||
int rc = share_access_check(cu_psp, s->sft_shroff, s->sft_posit,
|
||||
(unsigned long)n, 1);
|
||||
if (rc != SUCCESS)
|
||||
return rc;
|
||||
}
|
||||
/* /// End of additions for SHARE - Ron Cemer */
|
||||
{
|
||||
@ -315,37 +306,17 @@ UCOUNT DosRWSft(sft FAR * s, UCOUNT n, void FAR * bp, COUNT * err, int mode)
|
||||
XferCount = rwblock(s->sft_status, bp, n, mode);
|
||||
if (mode == XFR_WRITE)
|
||||
s->sft_size = dos_getfsize(s->sft_status);
|
||||
s->sft_posit += XferCount;
|
||||
return XferCount;
|
||||
}
|
||||
}
|
||||
|
||||
UCOUNT BinaryReadSft(sft FAR * s, void *bp, COUNT *err)
|
||||
{
|
||||
if (FP_OFF(s) == (size_t) - 1)
|
||||
{
|
||||
*err = DE_INVLDHNDL;
|
||||
return 0;
|
||||
}
|
||||
if (s->sft_mode & SFT_MWRITE)
|
||||
{
|
||||
*err = DE_INVLDACC;
|
||||
return 0;
|
||||
}
|
||||
if (s->sft_flags & SFT_FDEVICE)
|
||||
{
|
||||
/* First test for eof and exit */
|
||||
/* immediately if it is */
|
||||
if (!(s->sft_flags & SFT_FEOF) || (s->sft_flags & SFT_FNUL))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return BinaryCharIO(s->sft_dev, 1, bp, C_INPUT, err);
|
||||
}
|
||||
return DosRWSft(s, 1, bp, err, XFR_READ);
|
||||
}
|
||||
|
||||
COUNT SftSeek(sft FAR * s, LONG new_pos, COUNT mode)
|
||||
COUNT SftSeek(int sft_idx, LONG new_pos, COUNT 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)
|
||||
return DE_INVLDFUNC;
|
||||
@ -410,19 +381,16 @@ COUNT SftSeek(sft FAR * s, LONG new_pos, COUNT mode)
|
||||
}
|
||||
}
|
||||
|
||||
ULONG DosSeek(COUNT hndl, LONG new_pos, COUNT mode)
|
||||
ULONG DosSeek(unsigned hndl, LONG new_pos, COUNT mode)
|
||||
{
|
||||
sft FAR *s;
|
||||
int sft_idx = get_sft_idx(hndl);
|
||||
COUNT result;
|
||||
|
||||
/* Get the SFT block that contains the SFT */
|
||||
if ((s = get_sft(hndl)) == (sft FAR *) - 1)
|
||||
return (ULONG)-1;
|
||||
|
||||
result = SftSeek(s, new_pos, mode);
|
||||
result = SftSeek(sft_idx, new_pos, mode);
|
||||
if (result == SUCCESS)
|
||||
{
|
||||
return s->sft_posit;
|
||||
return idx_to_sft(sft_idx)->sft_posit;
|
||||
}
|
||||
return (ULONG)-1;
|
||||
}
|
||||
@ -440,7 +408,7 @@ STATIC long get_free_hndl(void)
|
||||
return DE_TOOMANY;
|
||||
}
|
||||
|
||||
sft FAR *get_free_sft(COUNT * sft_idx)
|
||||
STATIC sft FAR *get_free_sft(COUNT * sft_idx)
|
||||
{
|
||||
COUNT sys_idx = 0;
|
||||
sfttbl FAR *sp;
|
||||
@ -738,7 +706,7 @@ COUNT DosForceDup(unsigned OldHandle, unsigned NewHandle)
|
||||
return DE_INVLDHNDL;
|
||||
}
|
||||
|
||||
COUNT DosCloseSft(WORD sft_idx, BOOL commitonly)
|
||||
COUNT DosCloseSft(int sft_idx, BOOL commitonly)
|
||||
{
|
||||
sft FAR *sftp = idx_to_sft(sft_idx);
|
||||
|
||||
@ -795,7 +763,7 @@ COUNT DosClose(COUNT hndl)
|
||||
BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
|
||||
UWORD * bps, UWORD * nc)
|
||||
{
|
||||
/* *nc==0xffff means: called from FatGetDrvData, fcbfns.c */
|
||||
/* navc==NULL means: called from FatGetDrvData, fcbfns.c */
|
||||
struct dpb FAR *dpbp;
|
||||
struct cds FAR *cdsp;
|
||||
COUNT rg[4];
|
||||
@ -805,12 +773,9 @@ BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
|
||||
|
||||
/* first check for valid drive */
|
||||
*spc = -1;
|
||||
if (drive >= lastdrive)
|
||||
return FALSE;
|
||||
cdsp = get_cds(drive);
|
||||
|
||||
cdsp = &CDSp[drive];
|
||||
|
||||
if (!(cdsp->cdsFlags & CDSVALID))
|
||||
if (cdsp == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (cdsp->cdsFlags & CDSNETWDRV)
|
||||
@ -825,11 +790,10 @@ BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
|
||||
the redirector can provide all info
|
||||
- Bart, 2002 Apr 1 */
|
||||
|
||||
if (*nc != 0xffff)
|
||||
if (navc != NULL)
|
||||
{
|
||||
*navc = (COUNT) rg[3];
|
||||
rg[0] &= 0xff;
|
||||
/* zero media ID (high part) */
|
||||
*spc &= 0xff; /* zero out media ID byte */
|
||||
}
|
||||
|
||||
*spc = (COUNT) rg[0];
|
||||
@ -842,7 +806,7 @@ BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
|
||||
if (dpbp == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (*nc == 0xffff)
|
||||
if (navc == NULL)
|
||||
{
|
||||
/* hazard: no error checking! */
|
||||
flush_buffers(dpbp->dpb_unit);
|
||||
@ -852,7 +816,7 @@ BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
|
||||
if (media_check(dpbp) < 0)
|
||||
return FALSE;
|
||||
/* get the data available from dpb */
|
||||
*spc = dpbp->dpb_clsmask + 1;
|
||||
*spc = (dpbp->dpb_clsmask + 1);
|
||||
*bps = dpbp->dpb_secsize;
|
||||
|
||||
/* now tell fs to give us free cluster */
|
||||
@ -865,7 +829,7 @@ BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
|
||||
/* we shift ntotal until it is equal to or below 0xfff6 */
|
||||
cluster_size = (ULONG) dpbp->dpb_secsize << dpbp->dpb_shftcnt;
|
||||
ntotal = dpbp->dpb_xsize - 1;
|
||||
if (*nc != 0xffff)
|
||||
if (navc != NULL)
|
||||
nfree = dos_free(dpbp);
|
||||
while (ntotal > FAT_MAGIC16 && cluster_size < 0x8000)
|
||||
{
|
||||
@ -879,7 +843,8 @@ BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
|
||||
|
||||
/* now tell fs to give us free cluster */
|
||||
/* count */
|
||||
*navc = nfree > FAT_MAGIC16 ? FAT_MAGIC16 : (UCOUNT) nfree;
|
||||
if (navc != NULL)
|
||||
*navc = nfree > FAT_MAGIC16 ? FAT_MAGIC16 : (UCOUNT) nfree;
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
@ -906,19 +871,15 @@ COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp)
|
||||
{
|
||||
struct dpb FAR *dpbp;
|
||||
struct cds FAR *cdsp;
|
||||
UBYTE drive;
|
||||
UCOUNT rg[4];
|
||||
|
||||
if (IS_SLASH(DriveString[0]) || !IS_SLASH(DriveString[2])
|
||||
|| DriveString[1] != ':')
|
||||
return DE_INVLDDRV;
|
||||
drive = DosUpFChar(*DriveString) - 'A';
|
||||
if (drive >= lastdrive)
|
||||
return DE_INVLDDRV;
|
||||
|
||||
cdsp = &CDSp[drive];
|
||||
cdsp = get_cds(DosUpFChar(*DriveString) - 'A');
|
||||
|
||||
if (!(cdsp->cdsFlags & CDSVALID))
|
||||
if (cdsp == NULL)
|
||||
return DE_INVLDDRV;
|
||||
|
||||
if (cdsp->cdsFlags & CDSNETWDRV)
|
||||
@ -932,7 +893,7 @@ COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp)
|
||||
}
|
||||
else
|
||||
{
|
||||
dpbp = CDSp[drive].cdsDpb;
|
||||
dpbp = cdsp->cdsDpb;
|
||||
if (dpbp == NULL || media_check(dpbp) < 0)
|
||||
return DE_INVLDDRV;
|
||||
xfsp->xfs_secsize = dpbp->dpb_secsize;
|
||||
@ -959,17 +920,12 @@ COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s)
|
||||
struct cds FAR *cdsp;
|
||||
|
||||
/* next - "log" in the drive */
|
||||
drive = (drive == 0 ? default_drive : drive - 1);
|
||||
|
||||
/* first check for valid drive */
|
||||
if (drive >= lastdrive)
|
||||
cdsp = get_cds(drive == 0 ? default_drive : drive - 1);
|
||||
if (cdsp == NULL)
|
||||
return DE_INVLDDRV;
|
||||
|
||||
cdsp = &CDSp[drive];
|
||||
fmemcpy(&TempCDS, cdsp, sizeof(TempCDS));
|
||||
if (!(TempCDS.cdsFlags & CDSVALID))
|
||||
return DE_INVLDDRV;
|
||||
|
||||
cp = TempCDS.cdsCurrentPath;
|
||||
/* ensure termination of fstrcpy */
|
||||
cp[MAX_CDSPATH - 1] = '\0';
|
||||
@ -978,7 +934,7 @@ COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s)
|
||||
{
|
||||
/* dos_cd ensures that the path exists; if not, we
|
||||
need to change to the root directory */
|
||||
int result = dos_cd(cdsp, cp);
|
||||
int result = dos_cd(cp);
|
||||
if (result == DE_PATHNOTFND)
|
||||
cp[TempCDS.cdsBackslashOffset + 1] =
|
||||
cdsp->cdsCurrentPath[TempCDS.cdsBackslashOffset + 1] = '\0';
|
||||
@ -1020,8 +976,7 @@ COUNT DosChangeDir(BYTE FAR * s)
|
||||
#endif
|
||||
/* now get fs to change to new */
|
||||
/* directory */
|
||||
result = (result & IS_NETWORK ? remote_chdir() :
|
||||
dos_cd(current_ldt, PriPathName));
|
||||
result = (result & IS_NETWORK ? remote_chdir() : dos_cd(PriPathName));
|
||||
#if defined(CHDIR_DEBUG)
|
||||
printf("status = %04x, new_path='%Fs'\n", result, cdsd->cdsCurrentPath);
|
||||
#endif
|
||||
@ -1051,8 +1006,8 @@ STATIC VOID pop_dmp(dmatch FAR * dmp)
|
||||
|
||||
COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name)
|
||||
{
|
||||
COUNT rc;
|
||||
REG dmatch FAR *dmp = (dmatch FAR *) dta;
|
||||
int rc;
|
||||
register dmatch FAR *dmp = dta;
|
||||
|
||||
rc = truename(name, PriPathName, CDS_MODE_CHECK_DEV_PATH);
|
||||
if (rc < SUCCESS)
|
||||
@ -1079,8 +1034,8 @@ COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name)
|
||||
printf("Remote Find: n='%Fs\n", PriPathName);
|
||||
#endif
|
||||
|
||||
fmemcpy(TempBuffer, dta, 21);
|
||||
dta = TempBuffer;
|
||||
fmemcpy(&sda_tmp_dm, dta, 21);
|
||||
dta = &sda_tmp_dm;
|
||||
|
||||
if (rc & IS_NETWORK)
|
||||
rc = remote_findfirst(current_ldt);
|
||||
@ -1097,18 +1052,14 @@ COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name)
|
||||
memset(SearchDir.dir_name, ' ', FNAME_SIZE + FEXT_SIZE);
|
||||
for (i = 0; i < FNAME_SIZE && *p && *p != '.'; i++)
|
||||
SearchDir.dir_name[i] = *p++;
|
||||
if (*p == '.')
|
||||
p++;
|
||||
for (i = FNAME_SIZE; i < FNAME_SIZE + FEXT_SIZE && *p && *p != '.'; i++)
|
||||
SearchDir.dir_name[i] = *p++;
|
||||
rc = SUCCESS;
|
||||
/* /// End of additions. - Ron Cemer ; heavily edited - Bart Oldeman */
|
||||
}
|
||||
else
|
||||
rc = dos_findfirst(attr, PriPathName);
|
||||
|
||||
dta = (char FAR *) dmp;
|
||||
fmemcpy(dta, TempBuffer, 21);
|
||||
dta = dmp;
|
||||
fmemcpy(dta, &sda_tmp_dm, 21);
|
||||
pop_dmp(dmp);
|
||||
if (rc != SUCCESS)
|
||||
dmp->dm_attr_fnd = D_DEVICE; /* mark invalid */
|
||||
@ -1118,10 +1069,10 @@ COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name)
|
||||
COUNT DosFindNext(void)
|
||||
{
|
||||
COUNT rc;
|
||||
BYTE FAR *p;
|
||||
register dmatch FAR *dmp = dta;
|
||||
|
||||
/* /// findnext will always fail on a device name. - Ron Cemer */
|
||||
if (((dmatch FAR *) dta)->dm_attr_fnd == D_DEVICE)
|
||||
if (dmp->dm_attr_fnd == D_DEVICE)
|
||||
return DE_NFILES;
|
||||
|
||||
/*
|
||||
@ -1142,19 +1093,17 @@ COUNT DosFindNext(void)
|
||||
* (12h, DE_NFILES)
|
||||
*/
|
||||
#if 0
|
||||
printf("findnext: %d\n", ((dmatch FAR *) dta)->dm_drive);
|
||||
printf("findnext: %d\n", dmp->dm_drive);
|
||||
#endif
|
||||
fmemcpy(TempBuffer, dta, 21);
|
||||
fmemset(dta, 0, sizeof(dmatch));
|
||||
p = dta;
|
||||
dta = (BYTE FAR *) TempBuffer;
|
||||
current_ldt = &CDSp[((dmatch *) TempBuffer)->dm_drive];
|
||||
rc = (((dmatch *) TempBuffer)->dm_drive & 0x80) ?
|
||||
remote_findnext((VOID FAR *) current_ldt) : dos_findnext();
|
||||
fmemcpy(&sda_tmp_dm, dmp, 21);
|
||||
fmemset(dmp, 0, sizeof(*dmp));
|
||||
dta = &sda_tmp_dm;
|
||||
rc = (sda_tmp_dm.dm_drive & 0x80) ?
|
||||
remote_findnext(&sda_tmp_dm) : dos_findnext();
|
||||
|
||||
dta = p;
|
||||
fmemcpy(dta, TempBuffer, 21);
|
||||
pop_dmp((dmatch FAR *) dta);
|
||||
dta = dmp;
|
||||
fmemcpy(dmp, &sda_tmp_dm, 21);
|
||||
pop_dmp(dmp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -1179,7 +1128,7 @@ COUNT DosGetFtime(COUNT hndl, date * dp, time * tp)
|
||||
return dos_getftime(s->sft_status, dp, tp);
|
||||
}
|
||||
|
||||
COUNT DosSetFtimeSft(WORD sft_idx, date dp, time tp)
|
||||
COUNT DosSetFtimeSft(int sft_idx, date dp, time tp)
|
||||
{
|
||||
/* Get the SFT block that contains the SFT */
|
||||
sft FAR *s = idx_to_sft(sft_idx);
|
||||
@ -1292,14 +1241,9 @@ COUNT DosSetFattr(BYTE FAR * name, UWORD attrp)
|
||||
|
||||
UBYTE DosSelectDrv(UBYTE drv)
|
||||
{
|
||||
current_ldt = &CDSp[drv];
|
||||
current_ldt = get_cds(drv);
|
||||
|
||||
if ((drv < lastdrive) && (current_ldt->cdsFlags & CDSVALID))
|
||||
/*
|
||||
&&
|
||||
((cdsp->cdsFlags & CDSNETWDRV) ||
|
||||
(cdsp->cdsDpb!=NULL && media_check(cdsp->cdsDpb)==SUCCESS)))
|
||||
*/
|
||||
if (current_ldt != NULL)
|
||||
default_drive = drv;
|
||||
|
||||
return lastdrive;
|
||||
|
@ -40,9 +40,7 @@ segment HMA_TEXT
|
||||
extern _cu_psp:wrt DGROUP
|
||||
extern _MachineId:wrt DGROUP
|
||||
extern critical_sp:wrt DGROUP
|
||||
extern _lpUserStack:wrt DGROUP
|
||||
extern _user_r:wrt DGROUP
|
||||
extern _dosidle_flag:wrt DGROUP
|
||||
;
|
||||
;
|
||||
_DosIdle_int:
|
||||
@ -51,22 +49,19 @@ _DosIdle_int:
|
||||
mov ax, DGROUP
|
||||
mov ds,ax
|
||||
pop ax
|
||||
cmp byte [_dosidle_flag],0
|
||||
jnz DosId1
|
||||
cmp byte [_InDOS],1
|
||||
ja DosId1
|
||||
call Do_DosI
|
||||
DosId1:
|
||||
pop ds
|
||||
retn
|
||||
|
||||
Do_DosI:
|
||||
inc byte [_dosidle_flag]
|
||||
push ax
|
||||
push es
|
||||
push word [_MachineId]
|
||||
push word [_user_r]
|
||||
push word [_user_r+2]
|
||||
push word [_lpUserStack]
|
||||
push word [_lpUserStack+2]
|
||||
mov es,word [_cu_psp]
|
||||
push word [es:PSP_USERSS]
|
||||
push word [es:PSP_USERSP]
|
||||
@ -76,13 +71,10 @@ Do_DosI:
|
||||
mov es,word [_cu_psp]
|
||||
pop word [es:PSP_USERSP]
|
||||
pop word [es:PSP_USERSS]
|
||||
pop word [_lpUserStack+2]
|
||||
pop word [_lpUserStack]
|
||||
pop word [_user_r+2]
|
||||
pop word [_user_r]
|
||||
pop word [_MachineId]
|
||||
pop es
|
||||
pop ax
|
||||
dec byte [_dosidle_flag]
|
||||
ret
|
||||
|
||||
|
49
kernel/dsk.c
49
kernel/dsk.c
@ -199,6 +199,9 @@ COUNT ASMCFUNC FAR blk_driver(rqptr rp)
|
||||
return ((*dispatch[rp->r_command]) (rp, getddt(rp->r_unit)));
|
||||
}
|
||||
|
||||
STATIC char template_string[] = "XXXXXX diskette in drive X:\n";
|
||||
#define DRIVE_POS (sizeof(template_string) - 2)
|
||||
|
||||
STATIC WORD play_dj(ddt * pddt)
|
||||
{
|
||||
/* play the DJ ... */
|
||||
@ -215,12 +218,16 @@ STATIC WORD play_dj(ddt * pddt)
|
||||
}
|
||||
if (i == nUnits)
|
||||
{
|
||||
printf("Error in the DJ mechanism!\n"); /* should not happen! */
|
||||
put_string("Error in the DJ mechanism!\n"); /* should not happen! */
|
||||
return M_CHANGED;
|
||||
}
|
||||
printf("Remove diskette in drive %c:\n", 'A' + pddt2->ddt_logdriveno);
|
||||
printf("Insert diskette in drive %c:\n", 'A' + pddt->ddt_logdriveno);
|
||||
printf("Press the any key to continue ... \n");
|
||||
memcpy(template_string, "Remove", 6);
|
||||
template_string[DRIVE_POS] = 'A' + pddt2->ddt_logdriveno;
|
||||
put_string(template_string);
|
||||
memcpy(template_string, "Insert", 6);
|
||||
template_string[DRIVE_POS] = 'A' + pddt->ddt_logdriveno;
|
||||
put_string(template_string);
|
||||
put_string("Press the any key to continue ... \n");
|
||||
fl_readkey();
|
||||
pddt2->ddt_descflags &= ~DF_CURLOG;
|
||||
pddt->ddt_descflags |= DF_CURLOG;
|
||||
@ -863,11 +870,13 @@ STATIC WORD dskerr(COUNT code)
|
||||
translate LBA sectors into CHS addressing
|
||||
*/
|
||||
|
||||
STATIC void LBA_to_CHS(struct CHS *chs, ULONG LBA_address, ddt * pddt)
|
||||
STATIC int LBA_to_CHS(struct CHS *chs, ULONG LBA_address, 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 */
|
||||
unsigned long cylinder;
|
||||
|
||||
bpb *pbpb = hd(pddt->ddt_descflags) ? &pddt->ddt_defbpb : &pddt->ddt_bpb;
|
||||
|
||||
chs->Sector = LBA_address % pbpb->bpb_nsecs + 1;
|
||||
@ -875,7 +884,20 @@ STATIC void LBA_to_CHS(struct CHS *chs, ULONG LBA_address, ddt * pddt)
|
||||
LBA_address /= pbpb->bpb_nsecs;
|
||||
|
||||
chs->Head = LBA_address % pbpb->bpb_nheads;
|
||||
chs->Cylinder = LBA_address / pbpb->bpb_nheads;
|
||||
|
||||
cylinder = LBA_address / pbpb->bpb_nheads;
|
||||
|
||||
if (cylinder > 1023ul)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("LBA-Transfer error : cylinder %lu > 1023\n", cylinder);
|
||||
#else
|
||||
put_string("LBA-Transfer error : cylinder > 1023\n");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
chs->Cylinder = cylinder;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Test for 64K boundary crossing and return count small */
|
||||
@ -1014,7 +1036,8 @@ STATIC int LBA_Transfer(ddt * pddt, UWORD mode, VOID FAR * buffer,
|
||||
else
|
||||
{ /* transfer data, using old bios functions */
|
||||
|
||||
LBA_to_CHS(&chs, LBA_address, pddt);
|
||||
if (LBA_to_CHS(&chs, LBA_address, pddt))
|
||||
return 1;
|
||||
|
||||
/* avoid overflow at end of track */
|
||||
|
||||
@ -1023,21 +1046,13 @@ STATIC int LBA_Transfer(ddt * pddt, UWORD mode, VOID FAR * buffer,
|
||||
count = pddt->ddt_bpb.bpb_nsecs + 1 - chs.Sector;
|
||||
}
|
||||
|
||||
if (chs.Cylinder > 1023)
|
||||
{
|
||||
printf("LBA-Transfer error : cylinder %lu > 1023\n",
|
||||
chs.Cylinder);
|
||||
return 1;
|
||||
}
|
||||
|
||||
error_code = (mode == LBA_READ ? fl_read :
|
||||
mode == LBA_VERIFY ? fl_verify :
|
||||
mode ==
|
||||
LBA_FORMAT ? fl_format : fl_write) (pddt->
|
||||
ddt_driveno,
|
||||
chs.Head,
|
||||
(UWORD) chs.
|
||||
Cylinder,
|
||||
chs.Cylinder,
|
||||
chs.Sector,
|
||||
count,
|
||||
transfer_address);
|
||||
@ -1045,7 +1060,7 @@ STATIC int LBA_Transfer(ddt * pddt, UWORD mode, VOID FAR * buffer,
|
||||
if (error_code == 0 && mode == LBA_WRITE_VERIFY)
|
||||
{
|
||||
error_code = fl_verify(pddt->ddt_driveno,
|
||||
chs.Head, (UWORD) chs.Cylinder,
|
||||
chs.Head, chs.Cylinder,
|
||||
chs.Sector, count, transfer_address);
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,6 @@ segment HMA_TEXT
|
||||
extern _error_tos:wrt DGROUP
|
||||
extern _char_api_tos:wrt DGROUP
|
||||
extern _disk_api_tos:wrt DGROUP
|
||||
extern _lpUserStack:wrt DGROUP
|
||||
extern _user_r:wrt DGROUP
|
||||
extern _ErrorMode:wrt DGROUP
|
||||
extern _InDOS:wrt DGROUP
|
||||
@ -49,7 +48,6 @@ segment HMA_TEXT
|
||||
extern int21regs_seg:wrt DGROUP
|
||||
extern int21regs_off:wrt DGROUP
|
||||
|
||||
extern _dosidle_flag:wrt DGROUP
|
||||
extern _Int21AX:wrt DGROUP
|
||||
|
||||
|
||||
@ -116,28 +114,6 @@ reloc_call_cpm_entry:
|
||||
cpm_error: mov al,0
|
||||
iret
|
||||
|
||||
;
|
||||
; Restart the int 21h system call. Call never returns.
|
||||
;
|
||||
; VOID
|
||||
; RestartSysCall(VOID);
|
||||
;
|
||||
; NOTE: On exit, DS must point to kernel stack, SS:SP user stack after
|
||||
; PUSH$ALL and BP == SP.
|
||||
;
|
||||
%if 0 ; this is dead code now
|
||||
_RestartSysCall:
|
||||
cli ; no interrupts
|
||||
mov bp,word [_lpUserStack+2] ;Get frame
|
||||
mov ss,bp
|
||||
mov bp,word [_lpUserStack]
|
||||
mov sp,bp
|
||||
sti
|
||||
POP$ALL ; get the original regs
|
||||
jmp short int21_reentry ; restart the system call
|
||||
%endif
|
||||
|
||||
|
||||
;
|
||||
; interrupt zero divide handler:
|
||||
; print a message 'Interrupt divide by zero'
|
||||
@ -203,6 +179,9 @@ stack_loop:
|
||||
|
||||
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
|
||||
|
||||
@ -272,7 +251,7 @@ int21_user:
|
||||
call _int21_syscall
|
||||
pop cx
|
||||
pop cx
|
||||
jmp int21_ret
|
||||
jmp short int21_ret
|
||||
|
||||
;
|
||||
; normal entry, use one of our 4 stacks
|
||||
@ -292,9 +271,7 @@ int21_1:
|
||||
;
|
||||
; I don't know who needs that, but ... (TE)
|
||||
;
|
||||
mov word [_lpUserStack+2],ss
|
||||
mov word [_user_r+2],ss
|
||||
mov word [_lpUserStack],bp ; store and init
|
||||
mov word [_user_r],bp ; store and init
|
||||
|
||||
;
|
||||
@ -311,16 +288,12 @@ int21_1:
|
||||
; call number. Finally, all others run on the disk stack.
|
||||
; They are evaluated in that order.
|
||||
|
||||
|
||||
cmp byte [_InDOS],0
|
||||
jne int21_onerrorstack
|
||||
|
||||
cmp byte [_ErrorMode],0
|
||||
je int21_2
|
||||
|
||||
int21_onerrorstack:
|
||||
mov cx,_error_tos
|
||||
|
||||
|
||||
|
||||
cli
|
||||
mov ss,dx
|
||||
@ -332,16 +305,14 @@ int21_onerrorstack:
|
||||
|
||||
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
|
||||
jle int21_normalentry
|
||||
cmp ah,59h
|
||||
je int21_normalentry
|
||||
|
||||
int21_3:
|
||||
call dos_crit_sect
|
||||
@ -436,7 +407,7 @@ reloc_call_low_int26_handler:
|
||||
pushf
|
||||
push ax
|
||||
mov ax,026h
|
||||
jmp int2526
|
||||
jmp short int2526
|
||||
reloc_call_low_int25_handler:
|
||||
sti
|
||||
pushf
|
||||
|
@ -51,7 +51,9 @@ VOID dump(void)
|
||||
/* issue a panic message for corrupted data structures */
|
||||
VOID panic(BYTE * s)
|
||||
{
|
||||
printf("\nPANIC: %s\nSystem halted\n", s);
|
||||
put_string("\nPANIC: ");
|
||||
put_string(s);
|
||||
put_string("\nSystem halted");
|
||||
for (;;) ;
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,7 @@ f_node_ptr dir_open(register const char *dirname)
|
||||
{
|
||||
f_node_ptr fnp;
|
||||
int i;
|
||||
char fcbname[FNAME_SIZE + FEXT_SIZE];
|
||||
|
||||
/* Allocate an fnode if possible - error return (0) if not. */
|
||||
if ((fnp = get_f_node()) == (f_node_ptr) 0)
|
||||
@ -83,22 +84,7 @@ f_node_ptr dir_open(register const char *dirname)
|
||||
fnp->f_mode = RDWR;
|
||||
|
||||
/* determine what drive and dpb we are using... */
|
||||
fnp->f_dpb = CDSp[dirname[0]-'A'].cdsDpb;
|
||||
if (fnp->f_dpb == 0)
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* for testing only for now */
|
||||
#if 0
|
||||
if ((CDSp[dirname[0]-'A'].cdsFlags & CDSNETWDRV))
|
||||
{
|
||||
printf("FailSafe %x \n", Int21AX);
|
||||
return fnp;
|
||||
}
|
||||
#endif
|
||||
|
||||
fnp->f_dpb = get_dpb(dirname[0]-'A');
|
||||
/* Perform all directory common handling after all special */
|
||||
/* handling has been performed. */
|
||||
|
||||
@ -133,13 +119,13 @@ f_node_ptr dir_open(register const char *dirname)
|
||||
/* comparison... */
|
||||
/* first the file name with trailing spaces... */
|
||||
|
||||
memset(TempBuffer, ' ', FNAME_SIZE + FEXT_SIZE);
|
||||
memset(fcbname, ' ', FNAME_SIZE + FEXT_SIZE);
|
||||
|
||||
for (i = 0; i < FNAME_SIZE; i++)
|
||||
{
|
||||
if (*dirname != '\0' && *dirname != '.' && *dirname != '/' &&
|
||||
*dirname != '\\')
|
||||
TempBuffer[i] = *dirname++;
|
||||
fcbname[i] = *dirname++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
@ -152,7 +138,7 @@ f_node_ptr dir_open(register const char *dirname)
|
||||
{
|
||||
if (*dirname != '\0' && *dirname != '.' && *dirname != '/' &&
|
||||
*dirname != '\\')
|
||||
TempBuffer[i + FNAME_SIZE] = *dirname++;
|
||||
fcbname[i + FNAME_SIZE] = *dirname++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
@ -164,7 +150,7 @@ f_node_ptr dir_open(register const char *dirname)
|
||||
while (dir_read(fnp) == 1)
|
||||
{
|
||||
if (!(fnp->f_dir.dir_attrib & D_VOLID) &&
|
||||
fcbmatch(TempBuffer, fnp->f_dir.dir_name))
|
||||
fcbmatch(fcbname, fnp->f_dir.dir_name))
|
||||
{
|
||||
i = TRUE;
|
||||
break;
|
||||
@ -410,7 +396,7 @@ VOID dir_close(REG f_node_ptr fnp)
|
||||
COUNT dos_findfirst(UCOUNT attr, BYTE * name)
|
||||
{
|
||||
REG f_node_ptr fnp;
|
||||
REG dmatch *dmp = (dmatch *) TempBuffer;
|
||||
REG dmatch *dmp = &sda_tmp_dm;
|
||||
REG COUNT i;
|
||||
|
||||
/* printf("ff %Fs\n", name);*/
|
||||
@ -507,9 +493,9 @@ COUNT dos_findfirst(UCOUNT attr, BYTE * name)
|
||||
|
||||
COUNT dos_findnext(void)
|
||||
{
|
||||
REG dmatch *dmp = (dmatch *) TempBuffer;
|
||||
REG f_node_ptr fnp;
|
||||
BOOL found = FALSE;
|
||||
REG dmatch *dmp = &sda_tmp_dm;
|
||||
|
||||
/* Allocate an fnode if possible - error return (0) if not. */
|
||||
if ((fnp = get_f_node()) == (f_node_ptr) 0)
|
||||
@ -524,7 +510,7 @@ COUNT dos_findnext(void)
|
||||
|
||||
/* Select the default to help non-drive specified path */
|
||||
/* searches... */
|
||||
fnp->f_dpb = CDSp[dmp->dm_drive].cdsDpb;
|
||||
fnp->f_dpb = get_dpb(dmp->dm_drive);
|
||||
if (media_check(fnp->f_dpb) < 0)
|
||||
{
|
||||
release_f_node(fnp);
|
||||
|
100
kernel/fatfs.c
100
kernel/fatfs.c
@ -47,8 +47,6 @@ STATIC void merge_file_changes(f_node_ptr fnp, int collect);
|
||||
STATIC int is_same_file(f_node_ptr fnp1, f_node_ptr fnp2);
|
||||
/* /// Added - Ron Cemer */
|
||||
STATIC void copy_file_changes(f_node_ptr src, f_node_ptr dst);
|
||||
date dos_getdate(VOID);
|
||||
time dos_gettime(VOID);
|
||||
BOOL find_free(f_node_ptr);
|
||||
CLUSTER find_fat_free(f_node_ptr);
|
||||
VOID wipe_out(f_node_ptr);
|
||||
@ -69,6 +67,37 @@ ULONG clus2phys(CLUSTER cl_no, struct dpb FAR * dpbp)
|
||||
return ((ULONG) (cl_no - 2) << dpbp->dpb_shftcnt) + data;
|
||||
}
|
||||
|
||||
struct dpb FAR *get_dpb(COUNT dsk)
|
||||
{
|
||||
register struct cds FAR *cdsp = get_cds(dsk);
|
||||
|
||||
if (cdsp == NULL || cdsp->cdsFlags & CDSNETWDRV)
|
||||
return NULL;
|
||||
return cdsp->cdsDpb;
|
||||
}
|
||||
|
||||
/* initialize all direntry fields except for the name */
|
||||
STATIC void init_direntry(struct dirent *dentry, unsigned attrib,
|
||||
CLUSTER cluster)
|
||||
{
|
||||
struct dostime dt;
|
||||
|
||||
dentry->dir_size = 0l;
|
||||
#ifndef WITHFAT32
|
||||
dentry->dir_start_high = 0;
|
||||
#endif
|
||||
setdstart((*dentry), cluster);
|
||||
dentry->dir_attrib = attrib;
|
||||
dentry->dir_case = 0;
|
||||
DosGetTime(&dt);
|
||||
dentry->dir_crtimems = dt.hundredth;
|
||||
if (dt.second & 1)
|
||||
dentry->dir_crtimems += 100;
|
||||
dentry->dir_time = dentry->dir_crtime =
|
||||
TM_ENCODE(dt.hour, dt.minute, dt.second >> 1);
|
||||
dentry->dir_date = dentry->dir_crdate = dentry->dir_accdate = dos_getdate();
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* Internal file handlers - open, create, read, write, close, etc. */
|
||||
@ -174,13 +203,8 @@ long dos_open(char *path, unsigned flags, unsigned attrib)
|
||||
fnp->f_mode = flags & 3;
|
||||
|
||||
if (status != S_OPENED)
|
||||
{
|
||||
fnp->f_dir.dir_size = 0l;
|
||||
setdstart(fnp->f_dir, FREE);
|
||||
fnp->f_dir.dir_attrib = attrib;
|
||||
fnp->f_dir.dir_time = dos_gettime();
|
||||
fnp->f_dir.dir_date = dos_getdate();
|
||||
|
||||
{
|
||||
init_direntry(&fnp->f_dir, attrib, FREE);
|
||||
fnp->f_flags.f_dmod = TRUE;
|
||||
fnp->f_flags.f_ddate = FALSE;
|
||||
fnp->f_flags.f_dnew = FALSE;
|
||||
@ -320,7 +344,7 @@ f_node_ptr split_path(char * path, char * fcbname)
|
||||
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
if (CDSp[path[0]-'A'].cdsFlags & CDSNETWDRV)
|
||||
if (get_cds(path[0]-'A')->cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
printf("split path called for redirected file: `%s'\n",
|
||||
fcbname);
|
||||
@ -808,30 +832,27 @@ STATIC BOOL find_free(f_node_ptr fnp)
|
||||
/* */
|
||||
/* dos_getdate for the file date */
|
||||
/* */
|
||||
date dos_getdate()
|
||||
date dos_getdate(void)
|
||||
{
|
||||
UBYTE WeekDay, Month, MonthDay;
|
||||
UWORD Year;
|
||||
date Date;
|
||||
struct dosdate dd;
|
||||
|
||||
/* First - get the system date set by either the user */
|
||||
/* on start-up or the CMOS clock */
|
||||
DosGetDate(&WeekDay, &Month, &MonthDay, &Year);
|
||||
Date = DT_ENCODE(Month, MonthDay, Year - EPOCH_YEAR);
|
||||
return Date;
|
||||
DosGetDate(&dd);
|
||||
return DT_ENCODE(dd.month, dd.monthday, dd.year - EPOCH_YEAR);
|
||||
}
|
||||
|
||||
/* */
|
||||
/* dos_gettime for the file time */
|
||||
/* */
|
||||
time dos_gettime()
|
||||
time dos_gettime(void)
|
||||
{
|
||||
UBYTE Hour, Minute, Second, Hundredth;
|
||||
struct dostime dt;
|
||||
|
||||
/* First - get the system time set by either the user */
|
||||
/* on start-up or the CMOS clock */
|
||||
DosGetTime(&Hour, &Minute, &Second, &Hundredth);
|
||||
return TM_ENCODE(Hour, Minute, Second / 2);
|
||||
DosGetTime(&dt);
|
||||
return TM_ENCODE(dt.hour, dt.minute, dt.second >> 1);
|
||||
}
|
||||
|
||||
/* */
|
||||
@ -1093,10 +1114,7 @@ COUNT dos_mkdir(BYTE * dir)
|
||||
fnp->f_mode = WRONLY;
|
||||
fnp->f_back = LONG_LAST_CLUSTER;
|
||||
|
||||
fnp->f_dir.dir_size = 0l;
|
||||
fnp->f_dir.dir_attrib = D_DIR;
|
||||
fnp->f_dir.dir_time = dos_gettime();
|
||||
fnp->f_dir.dir_date = dos_getdate();
|
||||
init_direntry(&fnp->f_dir, D_DIR, free_fat);
|
||||
|
||||
fnp->f_flags.f_dmod = TRUE;
|
||||
fnp->f_flags.f_dnew = FALSE;
|
||||
@ -1107,7 +1125,6 @@ COUNT dos_mkdir(BYTE * dir)
|
||||
|
||||
/* Mark the cluster in the FAT as used */
|
||||
fnp->f_cluster = free_fat;
|
||||
setdstart(fnp->f_dir, free_fat);
|
||||
dpbp = fnp->f_dpb;
|
||||
link_fat(dpbp, free_fat, LONG_LAST_CLUSTER);
|
||||
|
||||
@ -1127,11 +1144,7 @@ COUNT dos_mkdir(BYTE * dir)
|
||||
/* Create the "." entry */
|
||||
DirEntBuffer.dir_name[0] = '.';
|
||||
memset(DirEntBuffer.dir_name + 1, ' ', FNAME_SIZE + FEXT_SIZE - 1);
|
||||
DirEntBuffer.dir_attrib = D_DIR;
|
||||
DirEntBuffer.dir_time = dos_gettime();
|
||||
DirEntBuffer.dir_date = dos_getdate();
|
||||
setdstart(DirEntBuffer, free_fat);
|
||||
DirEntBuffer.dir_size = 0l;
|
||||
init_direntry(&DirEntBuffer, D_DIR, free_fat);
|
||||
|
||||
/* And put it out */
|
||||
putdirent(&DirEntBuffer, bp->b_buffer);
|
||||
@ -1177,7 +1190,7 @@ COUNT dos_mkdir(BYTE * dir)
|
||||
|
||||
/* flush the drive buffers so that all info is written */
|
||||
/* hazard: no error checking! */
|
||||
flush_buffers((COUNT) (dpbp->dpb_unit));
|
||||
flush_buffers(dpbp->dpb_unit);
|
||||
|
||||
/* Close the directory so that the entry is updated */
|
||||
fnp->f_flags.f_dmod = TRUE;
|
||||
@ -1258,7 +1271,7 @@ STATIC COUNT extend_dir(f_node_ptr fnp)
|
||||
|
||||
/* flush the drive buffers so that all info is written */
|
||||
/* hazard: no error checking! */
|
||||
flush_buffers((COUNT) (fnp->f_dpb->dpb_unit));
|
||||
flush_buffers(fnp->f_dpb->dpb_unit);
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
@ -1875,13 +1888,10 @@ CLUSTER dos_free(struct dpb FAR * dpbp)
|
||||
}
|
||||
|
||||
#ifndef IPL
|
||||
COUNT dos_cd(struct cds FAR * cdsp, BYTE * PathName)
|
||||
int dos_cd(char * PathName)
|
||||
{
|
||||
f_node_ptr fnp;
|
||||
|
||||
/* first check for valid drive */
|
||||
if (cdsp->cdsDpb == 0)
|
||||
return DE_INVLDDRV;
|
||||
struct cds FAR *cdsp = get_cds(PathName[0] - 'A');
|
||||
|
||||
if ((media_check(cdsp->cdsDpb) < 0))
|
||||
return DE_INVLDDRV;
|
||||
@ -2050,6 +2060,9 @@ VOID bpb_to_dpb(bpb FAR * bpbp, REG struct dpb FAR * dpbp)
|
||||
|
||||
COUNT media_check(REG struct dpb FAR * dpbp)
|
||||
{
|
||||
if (dpbp == NULL)
|
||||
return DE_INVLDDRV;
|
||||
|
||||
/* First test if anyone has changed the removable media */
|
||||
FOREVER
|
||||
{
|
||||
@ -2153,17 +2166,6 @@ COUNT xlt_fnp(f_node_ptr fnp)
|
||||
return (COUNT) (fnp - f_nodes);
|
||||
}
|
||||
|
||||
#if 0
|
||||
struct dhdr FAR *select_unit(COUNT drive)
|
||||
{
|
||||
/* Just get the header from the dhdr array */
|
||||
/* return blk_devices[drive].dpb_device; */
|
||||
|
||||
return (struct dhdr FAR *)CDSp[drive].cdsDpb;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/* TE
|
||||
if the current filesize in FAT is larger then the dir_size
|
||||
it's truncated here.
|
||||
|
@ -55,16 +55,13 @@ static dmatch Dmatch;
|
||||
BYTE FAR *FatGetDrvData(UBYTE drive, UWORD * spc, UWORD * bps, UWORD * nc)
|
||||
{
|
||||
static BYTE mdb;
|
||||
UWORD navc;
|
||||
|
||||
/* get the data available from dpb */
|
||||
*nc = 0xffff; /* pass 0xffff to skip free count */
|
||||
if (DosGetFree(drive, spc, &navc, bps, nc))
|
||||
if (DosGetFree(drive, spc, NULL, bps, nc))
|
||||
{
|
||||
struct cds FAR *cdsp =
|
||||
&CDSp[(drive == 0 ? default_drive : drive - 1)];
|
||||
struct dpb FAR *dpbp = get_dpb(drive == 0 ? default_drive : drive - 1);
|
||||
/* Point to the media desctriptor for this drive */
|
||||
if (cdsp->cdsFlags & CDSNETWDRV)
|
||||
if (dpbp == NULL)
|
||||
{
|
||||
mdb = *spc >> 8;
|
||||
*spc &= 0xff;
|
||||
@ -72,7 +69,7 @@ BYTE FAR *FatGetDrvData(UBYTE drive, UWORD * spc, UWORD * bps, UWORD * nc)
|
||||
}
|
||||
else
|
||||
{
|
||||
return (BYTE FAR *) & (cdsp->cdsDpb->dpb_mdb);
|
||||
return (BYTE FAR *) & (dpbp->dpb_mdb);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@ -231,7 +228,7 @@ const BYTE FAR * GetNameField(const BYTE FAR * lpFileName, BYTE FAR * lpDestFiel
|
||||
|
||||
STATIC VOID FcbNextRecord(fcb FAR * lpFcb)
|
||||
{
|
||||
if (++lpFcb->fcb_curec > 128)
|
||||
if (++lpFcb->fcb_curec >= 128)
|
||||
{
|
||||
lpFcb->fcb_curec = 0;
|
||||
++lpFcb->fcb_cublock;
|
||||
@ -245,10 +242,11 @@ STATIC ULONG FcbRec(VOID)
|
||||
|
||||
UBYTE FcbReadWrite(xfcb FAR * lpXfcb, UCOUNT recno, int mode)
|
||||
{
|
||||
sft FAR *s;
|
||||
ULONG lPosit;
|
||||
UCOUNT nTransfer;
|
||||
BYTE far * FcbIoPtr = dta + recno * lpFcb->fcb_recsiz;
|
||||
long nTransfer;
|
||||
BYTE FAR * FcbIoPtr = dta;
|
||||
|
||||
FcbIoPtr += recno * lpFcb->fcb_recsiz;
|
||||
|
||||
if ((ULONG)recno * lpFcb->fcb_recsiz >= 0x10000ul ||
|
||||
FP_OFF(FcbIoPtr) < FP_OFF(dta))
|
||||
@ -257,34 +255,27 @@ UBYTE FcbReadWrite(xfcb FAR * lpXfcb, UCOUNT recno, int mode)
|
||||
/* Convert to fcb if necessary */
|
||||
lpFcb = ExtFcbToFcb(lpXfcb);
|
||||
|
||||
/* Get the SFT block that contains the SFT */
|
||||
if ((s = idx_to_sft(lpFcb->fcb_sftno)) == (sft FAR *) - 1)
|
||||
return FCB_ERR_NODATA;
|
||||
|
||||
/* If this is not opened another error */
|
||||
if (s->sft_count == 0)
|
||||
return FCB_ERR_NODATA;
|
||||
|
||||
/* Now update the fcb and compute where we need to position */
|
||||
/* to. */
|
||||
lPosit = FcbRec() * lpFcb->fcb_recsiz;
|
||||
if ((CritErrCode = -SftSeek(s, lPosit, 0)) != SUCCESS)
|
||||
if ((CritErrCode = -SftSeek(lpFcb->fcb_sftno, lPosit, 0)) != SUCCESS)
|
||||
return FCB_ERR_NODATA;
|
||||
|
||||
/* Do the read */
|
||||
nTransfer = DosRWSft(s, lpFcb->fcb_recsiz, FcbIoPtr, &CritErrCode, mode);
|
||||
CritErrCode = -CritErrCode;
|
||||
nTransfer = DosRWSft(lpFcb->fcb_sftno, lpFcb->fcb_recsiz, FcbIoPtr, mode);
|
||||
if (nTransfer < 0)
|
||||
CritErrCode = -(int)nTransfer;
|
||||
|
||||
/* Now find out how we will return and do it. */
|
||||
if (nTransfer == lpFcb->fcb_recsiz)
|
||||
{
|
||||
if (mode == XFR_WRITE) lpFcb->fcb_fsize = s->sft_size;
|
||||
if (mode == XFR_WRITE) lpFcb->fcb_fsize = SftGetFsize(lpFcb->fcb_sftno);
|
||||
FcbNextRecord(lpFcb);
|
||||
return FCB_SUCCESS;
|
||||
}
|
||||
if (mode == XFR_READ && nTransfer > 0)
|
||||
{
|
||||
fmemset(FcbIoPtr + nTransfer, 0, lpFcb->fcb_recsiz - nTransfer);
|
||||
fmemset(FcbIoPtr + (unsigned)nTransfer, 0, lpFcb->fcb_recsiz - (unsigned)nTransfer);
|
||||
FcbNextRecord(lpFcb);
|
||||
return FCB_ERR_EOF;
|
||||
}
|
||||
@ -293,7 +284,7 @@ UBYTE FcbReadWrite(xfcb FAR * lpXfcb, UCOUNT recno, int mode)
|
||||
|
||||
UBYTE FcbGetFileSize(xfcb FAR * lpXfcb)
|
||||
{
|
||||
COUNT FcbDrive, hndl;
|
||||
int FcbDrive, sft_idx;
|
||||
|
||||
/* Build a traditional DOS file name */
|
||||
lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
||||
@ -302,13 +293,13 @@ UBYTE FcbGetFileSize(xfcb FAR * lpXfcb)
|
||||
if (!lpFcb || IsDevice(SecPathName) || (lpFcb->fcb_recsiz == 0))
|
||||
return FCB_ERROR;
|
||||
|
||||
hndl = (short)DosOpen(SecPathName, O_LEGACY | O_RDONLY | O_OPEN, 0);
|
||||
if (hndl >= 0)
|
||||
sft_idx = (short)DosOpenSft(SecPathName, O_LEGACY | O_RDONLY | O_OPEN, 0);
|
||||
if (sft_idx >= 0)
|
||||
{
|
||||
ULONG fsize;
|
||||
|
||||
/* Get the size */
|
||||
fsize = DosGetFsize(hndl);
|
||||
fsize = SftGetFsize(sft_idx);
|
||||
|
||||
/* compute the size and update the fcb */
|
||||
lpFcb->fcb_rndm = fsize / lpFcb->fcb_recsiz;
|
||||
@ -316,11 +307,11 @@ UBYTE FcbGetFileSize(xfcb FAR * lpXfcb)
|
||||
++lpFcb->fcb_rndm;
|
||||
|
||||
/* close the file and leave */
|
||||
if ((CritErrCode = -DosClose(hndl)) == SUCCESS)
|
||||
if ((CritErrCode = -DosCloseSft(sft_idx, FALSE)) == SUCCESS)
|
||||
return FCB_SUCCESS;
|
||||
}
|
||||
else
|
||||
CritErrCode = -hndl;
|
||||
CritErrCode = -sft_idx;
|
||||
return FCB_ERROR;
|
||||
}
|
||||
|
||||
@ -471,7 +462,7 @@ int FcbNameInit(fcb FAR * lpFcb, BYTE * szBuffer, COUNT * pCurDrive)
|
||||
{
|
||||
*pCurDrive = default_drive + 1;
|
||||
}
|
||||
ConvertName83ToNameSZ(pszBuffer, (BYTE FAR *) lpFcb->fcb_fname);
|
||||
ConvertName83ToNameSZ(pszBuffer, lpFcb->fcb_fname);
|
||||
return truename(loc_szBuffer, szBuffer, CDS_MODE_CHECK_DEV_PATH);
|
||||
}
|
||||
|
||||
@ -479,7 +470,7 @@ UBYTE FcbDelete(xfcb FAR * lpXfcb)
|
||||
{
|
||||
COUNT FcbDrive;
|
||||
UBYTE result = FCB_SUCCESS;
|
||||
BYTE FAR *lpOldDta = dta;
|
||||
void FAR *lpOldDta = dta;
|
||||
|
||||
/* Build a traditional DOS file name */
|
||||
CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
||||
@ -493,7 +484,7 @@ UBYTE FcbDelete(xfcb FAR * lpXfcb)
|
||||
int attr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL);
|
||||
dmatch Dmatch;
|
||||
|
||||
dta = (BYTE FAR *) & Dmatch;
|
||||
dta = &Dmatch;
|
||||
if ((CritErrCode = -DosFindFirst(attr, SecPathName)) != SUCCESS)
|
||||
{
|
||||
result = FCB_ERROR;
|
||||
@ -520,7 +511,7 @@ UBYTE FcbRename(xfcb FAR * lpXfcb)
|
||||
rfcb FAR *lpRenameFcb;
|
||||
COUNT FcbDrive;
|
||||
UBYTE result = FCB_SUCCESS;
|
||||
BYTE FAR *lpOldDta = dta;
|
||||
void FAR *lpOldDta = dta;
|
||||
|
||||
/* Build a traditional DOS file name */
|
||||
lpRenameFcb = (rfcb FAR *) CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
||||
@ -536,7 +527,7 @@ UBYTE FcbRename(xfcb FAR * lpXfcb)
|
||||
COUNT result;
|
||||
|
||||
wAttr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL);
|
||||
dta = (BYTE FAR *) & Dmatch;
|
||||
dta = &Dmatch;
|
||||
if ((CritErrCode = -DosFindFirst(wAttr, SecPathName)) != SUCCESS)
|
||||
{
|
||||
result = FCB_ERROR;
|
||||
@ -639,14 +630,14 @@ VOID FcbCloseAll()
|
||||
|
||||
UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First)
|
||||
{
|
||||
void FAR *orig_dta = dta;
|
||||
BYTE FAR *lpDir;
|
||||
COUNT FcbDrive;
|
||||
psp FAR *lpPsp = MK_FP(cu_psp, 0);
|
||||
|
||||
/* First, move the dta to a local and change it around to match */
|
||||
/* our functions. */
|
||||
lpDir = (BYTE FAR *) dta;
|
||||
dta = (BYTE FAR *) & Dmatch;
|
||||
lpDir = dta;
|
||||
dta = &Dmatch;
|
||||
|
||||
/* Next initialze local variables by moving them from the fcb */
|
||||
lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
||||
@ -675,7 +666,7 @@ UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First)
|
||||
CritErrCode = -(First ? DosFindFirst(wAttr, SecPathName) : DosFindNext());
|
||||
if (CritErrCode != SUCCESS)
|
||||
{
|
||||
dta = lpPsp->ps_dta;
|
||||
dta = orig_dta;
|
||||
return FCB_ERROR;
|
||||
}
|
||||
|
||||
@ -696,7 +687,7 @@ UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First)
|
||||
lpFcb->fcb_cublock *= 0x100;
|
||||
lpFcb->fcb_cublock += wAttr;
|
||||
#endif
|
||||
dta = lpPsp->ps_dta;
|
||||
dta = orig_dta;
|
||||
return FCB_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
@ -110,6 +110,7 @@ FAR * ASM DPBp; /* First drive Parameter Block */
|
||||
/* internal transfer direction flags */
|
||||
#define XFR_READ 1
|
||||
#define XFR_WRITE 2
|
||||
#define XFR_FORCE_WRITE 3
|
||||
|
||||
#define RDONLY 0
|
||||
#define WRONLY 1
|
||||
@ -131,17 +132,17 @@ FAR * ASM DPBp; /* First drive Parameter Block */
|
||||
#define ESC 0x1b
|
||||
#define CTL_BS 0x7f
|
||||
|
||||
#define INS 0x52
|
||||
#define DEL 0x53
|
||||
#define INS 0x5200
|
||||
#define DEL 0x5300
|
||||
|
||||
#define F1 0x3b
|
||||
#define F2 0x3c
|
||||
#define F3 0x3d
|
||||
#define F4 0x3e
|
||||
#define F5 0x3f
|
||||
#define F6 0x40
|
||||
#define LEFT 0x4b
|
||||
#define RIGHT 0x4d
|
||||
#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 */
|
||||
@ -324,14 +325,15 @@ extern UWORD ASM wAttr;
|
||||
|
||||
extern BYTE ASM default_drive; /* default drive for dos */
|
||||
|
||||
extern BYTE ASM TempBuffer[], /* Temporary general purpose buffer */
|
||||
extern dmatch ASM sda_tmp_dm; /* Temporary directory match buffer */
|
||||
extern BYTE
|
||||
FAR ASM internal_data[], /* sda areas */
|
||||
FAR ASM swap_always[], /* " " */
|
||||
FAR 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 BYTE FAR * ASM dta; /* Disk transfer area (kludge) */
|
||||
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 */
|
||||
|
||||
@ -343,11 +345,10 @@ extern fcb FAR * ASM lpFcb; /* Pointer to users fcb */
|
||||
extern sft FAR * ASM lpCurSft;
|
||||
|
||||
extern BYTE ASM verify_ena, /* verify enabled flag */
|
||||
ASM switchar, /* switch char */
|
||||
ASM return_mode, /* Process termination rets */
|
||||
ASM return_code; /* " " " */
|
||||
ASM switchar; /* switch char */
|
||||
extern UWORD ASM return_code; /* Process termination rets */
|
||||
|
||||
extern BYTE ASM BootDrive, /* Drive we came up from */
|
||||
extern UBYTE ASM BootDrive, /* Drive we came up from */
|
||||
ASM scr_pos; /* screen position for bs, ht, etc */
|
||||
/*extern WORD
|
||||
NumFloppies; !!*//* How many floppies we have */
|
||||
@ -359,12 +360,6 @@ extern struct cds
|
||||
ASM TempCDS;
|
||||
|
||||
/* start of uncontrolled variables */
|
||||
GLOBAL seg RootPsp; /* Root process -- do not abort */
|
||||
|
||||
/* don't know what it should do, but its no longer in use TE
|
||||
GLOBAL struct f_node
|
||||
*pDirFileNode;
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
GLOBAL iregs error_regs; /* registers for dump */
|
||||
@ -455,13 +450,9 @@ VOID fputbyte(VOID FAR *, UBYTE);
|
||||
|
||||
/* ^Break handling */
|
||||
void ASMCFUNC spawn_int23(void); /* procsupt.asm */
|
||||
int control_break(void); /* break.c */
|
||||
void handle_break(void); /* break.c */
|
||||
|
||||
GLOBAL BYTE ReturnAnyDosVersionExpected;
|
||||
|
||||
GLOBAL COUNT UnusedRetVal; /* put unused errors here (to save stack space) */
|
||||
|
||||
/*
|
||||
* Log: globals.h,v
|
||||
*
|
||||
|
@ -109,14 +109,8 @@ extern struct config Config;
|
||||
VOID PreConfig(VOID);
|
||||
VOID DoConfig(int pass);
|
||||
VOID PostConfig(VOID);
|
||||
VOID configDone(VOID);
|
||||
VOID FAR * KernelAlloc(size_t nBytes);
|
||||
BYTE * skipwh(BYTE * s);
|
||||
BYTE * scan(BYTE * s, BYTE * d);
|
||||
BOOL isnum(BYTE * pszString);
|
||||
BYTE * GetNumber(REG BYTE * pszString, REG COUNT * pnNum);
|
||||
COUNT tolower(COUNT c);
|
||||
COUNT toupper(COUNT c);
|
||||
VOID mcb_init(UCOUNT seg, UWORD size);
|
||||
char *strcat(char * d, const char * s);
|
||||
COUNT ASMCFUNC Umb_Test(void);
|
||||
COUNT ASMCFUNC UMB_get_largest(UCOUNT * seg, UCOUNT * size);
|
||||
@ -174,7 +168,7 @@ VOID ASMCFUNC FAR int2f_handler(void);
|
||||
/* main.c */
|
||||
VOID ASMCFUNC FreeDOSmain(void);
|
||||
BOOL init_device(struct dhdr FAR * dhp, BYTE FAR * cmdLine,
|
||||
COUNT mode, COUNT top);
|
||||
COUNT mode, char FAR *top);
|
||||
VOID init_fatal(BYTE * err_msg);
|
||||
|
||||
/* prf.c */
|
||||
|
@ -354,18 +354,21 @@ COUNT init_getdriveparm(UBYTE drive, bpb FAR * pbpbarray)
|
||||
void init_LBA_to_CHS(struct CHS *chs, ULONG LBA_address,
|
||||
struct DriveParamS *driveparam)
|
||||
{
|
||||
unsigned long cylinder;
|
||||
|
||||
chs->Sector = LBA_address % driveparam->chs.Sector + 1;
|
||||
|
||||
LBA_address /= driveparam->chs.Sector;
|
||||
|
||||
chs->Head = LBA_address % driveparam->chs.Head;
|
||||
chs->Cylinder = LBA_address / driveparam->chs.Head;
|
||||
cylinder = LBA_address / driveparam->chs.Head;
|
||||
chs->Cylinder = cylinder >= 0x10000ul ? 0xffffu : cylinder;
|
||||
}
|
||||
|
||||
void printCHS(char *title, struct CHS *chs)
|
||||
{
|
||||
printf("%s", title);
|
||||
printf("%4lu-%u-%u", chs->Cylinder, chs->Head, chs->Sector);
|
||||
printf("%4u-%u-%u", chs->Cylinder, chs->Head, chs->Sector);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -845,10 +848,11 @@ BOOL ScanForPrimaryPartitions(struct DriveParamS * driveParam, int scan_type,
|
||||
> 8 GB cyl = 1023, other (cyl&1023)
|
||||
*/
|
||||
|
||||
if (((chs.Cylinder & 0x3ff) != pEntry->Begin.Cylinder &&
|
||||
1023 != pEntry->Begin.Cylinder) ||
|
||||
chs.Head != pEntry->Begin.Head ||
|
||||
chs.Sector != pEntry->Begin.Sector)
|
||||
if (!((chs.Cylinder & 0x3ff) == pEntry->Begin.Cylinder ||
|
||||
1023 == pEntry->Begin.Cylinder ||
|
||||
(chs.Cylinder == pEntry->Begin.Cylinder &&
|
||||
chs.Head == pEntry->Begin.Head &&
|
||||
chs.Sector == pEntry->Begin.Sector)))
|
||||
{
|
||||
printf("WARNING: using suspect partition %s FS %02x:",
|
||||
partitionName, pEntry->FileSystem);
|
||||
@ -859,9 +863,11 @@ BOOL ScanForPrimaryPartitions(struct DriveParamS * driveParam, int scan_type,
|
||||
|
||||
}
|
||||
|
||||
if (((end.Cylinder & 0x3ff) != pEntry->End.Cylinder &&
|
||||
1023 != pEntry->End.Cylinder) ||
|
||||
end.Head != pEntry->End.Head || end.Sector != pEntry->End.Sector)
|
||||
if (!((end.Cylinder & 0x3ff) == pEntry->End.Cylinder ||
|
||||
1023 == pEntry->End.Cylinder ||
|
||||
(end.Cylinder == pEntry->End.Cylinder &&
|
||||
end.Head == pEntry->End.Head &&
|
||||
end.Sector == pEntry->End.Sector)))
|
||||
{
|
||||
if (pEntry->NumSect == 0)
|
||||
{
|
||||
@ -982,7 +988,7 @@ int Read1LBASector(struct DriveParamS *driveParam, unsigned drive,
|
||||
}
|
||||
else
|
||||
{ /* transfer data, using old bios functions */
|
||||
init_LBA_to_CHS(&chs, LBA_address, driveParam);
|
||||
LBA_to_CHS(&chs, LBA_address, driveParam);
|
||||
/* avoid overflow at end of track */
|
||||
|
||||
if (chs.Cylinder > 1023)
|
||||
|
@ -101,12 +101,12 @@ 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;
|
||||
;};
|
||||
Protect386Registers
|
||||
;}
|
||||
push ax
|
||||
push cx
|
||||
push dx
|
||||
@ -117,10 +117,30 @@ IntDosCal:
|
||||
push ds
|
||||
push es
|
||||
|
||||
cld
|
||||
|
||||
%IFDEF I386
|
||||
%ifdef WATCOM
|
||||
mov si,fs
|
||||
mov di,gs
|
||||
%else
|
||||
Protect386Registers
|
||||
%endif
|
||||
%endif
|
||||
|
||||
mov ax,DGROUP
|
||||
mov ds,ax
|
||||
extern _int2F_12_handler:wrt HGROUP
|
||||
call _int2F_12_handler
|
||||
|
||||
%IFDEF I386
|
||||
%ifdef WATCOM
|
||||
mov fs,si
|
||||
mov gs,di
|
||||
%else
|
||||
Restore386Registers
|
||||
%endif
|
||||
%endif
|
||||
|
||||
pop es
|
||||
pop ds
|
||||
@ -131,7 +151,6 @@ IntDosCal:
|
||||
pop dx
|
||||
pop cx
|
||||
pop ax
|
||||
Restore386Registers
|
||||
|
||||
iret
|
||||
|
||||
@ -346,6 +365,7 @@ print_doredir:
|
||||
pop bx
|
||||
pop ds
|
||||
jc no_clear_ax
|
||||
xor cx, cx
|
||||
jmp short clear_ax
|
||||
|
||||
remote_getfree:
|
||||
@ -357,6 +377,7 @@ remote_getfree:
|
||||
mov [di+2],bx
|
||||
mov [di+4],cx
|
||||
mov [di+6],dx
|
||||
xor cx, cx
|
||||
jmp short clear_ax
|
||||
|
||||
remote_printredir:
|
||||
@ -374,6 +395,7 @@ qremote_fn:
|
||||
pop ds
|
||||
mov ax,0xffff
|
||||
jc no_neg_ax
|
||||
xor cx, cx
|
||||
jmp short clear_ax
|
||||
|
||||
remote_rw1: mov cx, [bp+8]
|
||||
@ -534,23 +556,23 @@ _UMB_get_largest:
|
||||
|
||||
cmp ax,1
|
||||
jne umbt_error
|
||||
; now return the segment
|
||||
; and the size
|
||||
; now return the segment
|
||||
; and the size
|
||||
|
||||
mov cx,bx ; *seg = segment
|
||||
mov bx, [bp+4]
|
||||
mov [bx],cx
|
||||
mov cx,bx ; *seg = segment
|
||||
mov bx, [bp+4]
|
||||
mov [bx],cx
|
||||
|
||||
mov bx, [bp+6] ; *size = size
|
||||
mov [bx],dx
|
||||
mov bx, [bp+6] ; *size = size
|
||||
mov [bx],dx
|
||||
|
||||
umbt_ret:
|
||||
mov sp,bp
|
||||
pop bp
|
||||
ret ; this was called NEAR!!
|
||||
ret ; this was called NEAR!!
|
||||
|
||||
umbt_error: xor ax,ax
|
||||
jmp umbt_ret
|
||||
umbt_error: xor ax,ax
|
||||
jmp short umbt_ret
|
||||
|
||||
; Log: int2f.asm,v
|
||||
; Revision 1.4 2000/03/31 05:40:09 jtabor
|
||||
|
@ -415,7 +415,7 @@ dispatch:
|
||||
case 0x0a:
|
||||
case 0x0b:
|
||||
if (control_break())
|
||||
handle_break();
|
||||
handle_break(-1);
|
||||
}
|
||||
|
||||
/* The dispatch handler */
|
||||
@ -429,33 +429,33 @@ dispatch:
|
||||
|
||||
/* Read Keyboard with Echo */
|
||||
case 0x01:
|
||||
lr.AL = _sti(TRUE);
|
||||
sto(lr.AL);
|
||||
lr.AL = read_char_stdin(TRUE);
|
||||
write_char_stdin(lr.AL);
|
||||
break;
|
||||
|
||||
/* Display Character */
|
||||
case 0x02:
|
||||
sto(lr.DL);
|
||||
write_char_stdin(lr.DL);
|
||||
break;
|
||||
|
||||
/* Auxiliary Input */
|
||||
case 0x03:
|
||||
BinaryRead(STDAUX, &lr.AL, &UnusedRetVal);
|
||||
lr.AL = read_char(get_sft_idx(STDAUX), TRUE);
|
||||
break;
|
||||
|
||||
/* Auxiliary Output */
|
||||
case 0x04:
|
||||
DosWrite(STDAUX, 1, (BYTE FAR *) & lr.DL, & UnusedRetVal);
|
||||
write_char(get_sft_idx(STDAUX), lr.DL);
|
||||
break;
|
||||
/* Print Character */
|
||||
case 0x05:
|
||||
DosWrite(STDPRN, 1, (BYTE FAR *) & lr.DL, & UnusedRetVal);
|
||||
write_char(get_sft_idx(STDPRN), lr.DL);
|
||||
break;
|
||||
|
||||
/* Direct Console I/O */
|
||||
case 0x06:
|
||||
if (lr.DL != 0xff)
|
||||
sto(lr.DL);
|
||||
write_char_stdin(lr.DL);
|
||||
else if (StdinBusy())
|
||||
{
|
||||
lr.AL = 0x00;
|
||||
@ -464,38 +464,37 @@ dispatch:
|
||||
else
|
||||
{
|
||||
r->FLAGS &= ~FLG_ZERO;
|
||||
lr.AL = _sti(FALSE);
|
||||
lr.AL = read_char_stdin(FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Direct Console Input */
|
||||
case 0x07:
|
||||
lr.AL = _sti(FALSE);
|
||||
lr.AL = read_char_stdin(FALSE);
|
||||
break;
|
||||
|
||||
/* Read Keyboard Without Echo */
|
||||
case 0x08:
|
||||
lr.AL = _sti(TRUE);
|
||||
lr.AL = read_char_stdin(TRUE);
|
||||
break;
|
||||
|
||||
/* Display String */
|
||||
case 0x09:
|
||||
{
|
||||
unsigned count;
|
||||
|
||||
for (count = 0; ; count++)
|
||||
if (((UBYTE FAR *)FP_DS_DX)[count] == '$')
|
||||
break;
|
||||
{
|
||||
size_t count = 0;
|
||||
char FAR *bp = FP_DS_DX;
|
||||
|
||||
DosWrite(STDOUT, count, FP_DS_DX,
|
||||
& UnusedRetVal);
|
||||
while (bp[count] != '$')
|
||||
count++;
|
||||
|
||||
DosWrite(STDOUT, count, bp);
|
||||
lr.AL = '$';
|
||||
}
|
||||
lr.AL = '$';
|
||||
break;
|
||||
|
||||
/* Buffered Keyboard Input */
|
||||
case 0x0a:
|
||||
sti_0a((keyboard FAR *) FP_DS_DX);
|
||||
read_line(get_sft_idx(STDIN), get_sft_idx(STDOUT), FP_DS_DX);
|
||||
break;
|
||||
|
||||
/* Check Stdin Status */
|
||||
@ -506,9 +505,9 @@ dispatch:
|
||||
lr.AL = 0xFF;
|
||||
break;
|
||||
|
||||
/* Flush Buffer, Read Keayboard */
|
||||
/* Flush Buffer, Read Keyboard */
|
||||
case 0x0c:
|
||||
KbdFlush();
|
||||
KbdFlush(get_sft_idx(STDIN));
|
||||
switch (lr.AL)
|
||||
{
|
||||
case 0x01:
|
||||
@ -598,12 +597,7 @@ dispatch:
|
||||
|
||||
/* Set DTA */
|
||||
case 0x1a:
|
||||
{
|
||||
psp FAR *p = MK_FP(cu_psp, 0);
|
||||
|
||||
p->ps_dta = FP_DS_DX;
|
||||
dos_setdta(p->ps_dta);
|
||||
}
|
||||
dos_setdta(FP_DS_DX);
|
||||
break;
|
||||
|
||||
/* Get Default Drive Data */
|
||||
@ -658,7 +652,7 @@ dispatch:
|
||||
{
|
||||
psp FAR *p = MK_FP(cu_psp, 0);
|
||||
|
||||
new_psp((psp FAR *) MK_FP(lr.DX, 0), p->ps_size);
|
||||
new_psp(lr.DX, p->ps_size);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -683,34 +677,23 @@ dispatch:
|
||||
|
||||
/* Get Date */
|
||||
case 0x2a:
|
||||
DosGetDate(&lr.AL, /* WeekDay */
|
||||
&lr.DH, /* Month */
|
||||
&lr.DL, /* MonthDay */
|
||||
&lr.CX); /* Year */
|
||||
lr.AL = DosGetDate((struct dosdate *)&lr.CX);
|
||||
break;
|
||||
|
||||
/* Set Date */
|
||||
case 0x2b:
|
||||
rc = DosSetDate(lr.DH, /* Month */
|
||||
lr.DL, /* MonthDay */
|
||||
lr.CX); /* Year */
|
||||
rc = DosSetDate((struct dosdate *)&lr.CX);
|
||||
lr.AL = (rc != SUCCESS ? 0xff : 0);
|
||||
break;
|
||||
|
||||
/* Get Time */
|
||||
case 0x2c:
|
||||
DosGetTime(&lr.CH, /* Hour */
|
||||
&lr.CL, /* Minutes */
|
||||
&lr.DH, /* Seconds */
|
||||
&lr.DL); /* Hundredths */
|
||||
DosGetTime((struct dostime *)&lr.CL);
|
||||
break;
|
||||
|
||||
/* Set Date */
|
||||
case 0x2d:
|
||||
rc = DosSetTime(lr.CH, /* Hour */
|
||||
lr.CL, /* Minutes */
|
||||
lr.DH, /* Seconds */
|
||||
lr.DL); /* Hundredths */
|
||||
rc = DosSetTime((struct dostime *)&lr.CL);
|
||||
lr.AL = (rc != SUCCESS ? 0xff : 0);
|
||||
break;
|
||||
|
||||
@ -765,8 +748,7 @@ dispatch:
|
||||
/* Keep Program (Terminate and stay resident) */
|
||||
case 0x31:
|
||||
DosMemChange(cu_psp, lr.DX < 6 ? 6 : lr.DX, 0);
|
||||
return_mode = 3;
|
||||
return_code = lr.AL;
|
||||
return_code = lr.AL | 0x300;
|
||||
tsr = TRUE;
|
||||
return_user();
|
||||
break;
|
||||
@ -778,23 +760,10 @@ dispatch:
|
||||
/* r->DL is NOT changed by MS 6.22 */
|
||||
/* INT21/32 is documented to reread the DPB */
|
||||
{
|
||||
struct dpb FAR *dpb;
|
||||
UCOUNT drv = lr.DL;
|
||||
|
||||
if (drv == 0 || lr.AH == 0x1f)
|
||||
drv = default_drive;
|
||||
else
|
||||
drv--;
|
||||
|
||||
if (drv >= lastdrive)
|
||||
{
|
||||
lr.AL = 0xFF;
|
||||
CritErrCode = 0x0f;
|
||||
break;
|
||||
}
|
||||
|
||||
dpb = CDSp[drv].cdsDpb;
|
||||
if (dpb == 0 || CDSp[drv].cdsFlags & CDSNETWDRV)
|
||||
int drv = (lr.DL == 0 || lr.AH == 0x1f) ? default_drive : lr.DL - 1;
|
||||
struct dpb FAR *dpb = get_dpb(drv);
|
||||
|
||||
if (dpb == NULL)
|
||||
{
|
||||
lr.AL = 0xFF;
|
||||
CritErrCode = 0x0f;
|
||||
@ -950,17 +919,29 @@ dispatch:
|
||||
break;
|
||||
|
||||
/* Dos Read */
|
||||
case 0x3f:
|
||||
lr.AX = DosRead(lr.BX, lr.CX, FP_DS_DX, & rc);
|
||||
if (rc != SUCCESS)
|
||||
goto error_exit;
|
||||
case 0x3f:
|
||||
{
|
||||
long lrc = DosRead(lr.BX, lr.CX, FP_DS_DX);
|
||||
if (lrc < SUCCESS)
|
||||
{
|
||||
rc = (int)lrc;
|
||||
goto error_exit;
|
||||
}
|
||||
lr.AX = (UWORD)lrc;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Dos Write */
|
||||
case 0x40:
|
||||
lr.AX = DosWrite(lr.BX, lr.CX, FP_DS_DX, & rc);
|
||||
if (rc != SUCCESS)
|
||||
goto error_exit;
|
||||
{
|
||||
long lrc = DosWrite(lr.BX, lr.CX, FP_DS_DX);
|
||||
if (lrc < SUCCESS)
|
||||
{
|
||||
rc = (int)lrc;
|
||||
goto error_exit;
|
||||
}
|
||||
lr.AX = (UWORD)lrc;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Dos Delete File */
|
||||
@ -1002,6 +983,8 @@ dispatch:
|
||||
|
||||
case 0x01:
|
||||
rc = DosSetFattr((BYTE FAR *) FP_DS_DX, lr.CX);
|
||||
if (rc >= SUCCESS)
|
||||
lr.AX = lr.CX;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1058,6 +1041,10 @@ dispatch:
|
||||
DosMemAlloc(lr.BX, mem_access_mode, &(lr.AX), &(lr.BX))) < 0)
|
||||
{
|
||||
DosMemLargest(&(lr.BX));
|
||||
{
|
||||
if (DosMemCheck() != SUCCESS)
|
||||
panic("MCB chain corrupted");
|
||||
}
|
||||
goto error_exit;
|
||||
}
|
||||
else
|
||||
@ -1067,11 +1054,18 @@ dispatch:
|
||||
/* Free memory */
|
||||
case 0x49:
|
||||
if ((rc = DosMemFree((lr.ES) - 1)) < 0)
|
||||
goto error_exit;
|
||||
{
|
||||
if (DosMemCheck() != SUCCESS)
|
||||
panic("MCB chain corrupted");
|
||||
goto error_exit;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Set memory block size */
|
||||
case 0x4a:
|
||||
if (DosMemCheck() != SUCCESS)
|
||||
panic("before 4a: MCB chain corrupted");
|
||||
|
||||
if ((rc = DosMemChange(lr.ES, lr.BX, &lr.BX)) < 0)
|
||||
{
|
||||
#if 0
|
||||
@ -1084,6 +1078,8 @@ dispatch:
|
||||
p->ps_size = lr.BX + cu_psp;
|
||||
}
|
||||
#endif
|
||||
if (DosMemCheck() != SUCCESS)
|
||||
panic("after 4a: MCB chain corrupted");
|
||||
goto error_exit;
|
||||
}
|
||||
break;
|
||||
@ -1102,25 +1098,24 @@ dispatch:
|
||||
|
||||
/* End Program */
|
||||
case 0x4c:
|
||||
if (cu_psp == RootPsp
|
||||
|| ((psp FAR *) (MK_FP(cu_psp, 0)))->ps_parent == cu_psp)
|
||||
if (((psp FAR *)MK_FP(cu_psp, 0))->ps_parent == cu_psp)
|
||||
break;
|
||||
tsr = FALSE;
|
||||
if (ErrorMode)
|
||||
{
|
||||
ErrorMode = FALSE;
|
||||
return_mode = 2;
|
||||
rc = 2;
|
||||
}
|
||||
else if (break_flg)
|
||||
{
|
||||
break_flg = FALSE;
|
||||
return_mode = 1;
|
||||
rc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return_mode = 0;
|
||||
rc = 0;
|
||||
}
|
||||
return_code = lr.AL;
|
||||
return_code = lr.AL | (rc << 8);
|
||||
if (DosMemCheck() != SUCCESS)
|
||||
panic("MCB chain corrupted");
|
||||
#ifdef TSC
|
||||
@ -1131,8 +1126,9 @@ dispatch:
|
||||
|
||||
/* Get Child-program Return Value */
|
||||
case 0x4d:
|
||||
lr.AL = return_code;
|
||||
lr.AH = return_mode;
|
||||
lr.AX = return_code;
|
||||
/* needs to be cleared (RBIL) */
|
||||
return_code = 0;
|
||||
break;
|
||||
|
||||
/* Dos Find First */
|
||||
@ -1182,7 +1178,7 @@ dispatch:
|
||||
/* ************UNDOCUMENTED************************************* */
|
||||
/* Dos Create New Psp & set p_size */
|
||||
case 0x55:
|
||||
new_psp((psp FAR *) MK_FP(lr.DX, 0), lr.SI);
|
||||
new_psp(lr.DX, lr.SI);
|
||||
cu_psp = lr.DX;
|
||||
break;
|
||||
|
||||
@ -1368,40 +1364,46 @@ dispatch:
|
||||
|
||||
case 0x5f:
|
||||
CLEAR_CARRY_FLAG();
|
||||
switch (lr.AL)
|
||||
if (lr.AL == 7 || lr.AL == 8)
|
||||
{
|
||||
case 0x07:
|
||||
if (lr.DL < lastdrive)
|
||||
struct cds FAR *cdsp;
|
||||
if (lr.DL < lastdrive)
|
||||
{
|
||||
rc = DE_INVLDDRV;
|
||||
goto error_exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
cdsp = &CDSp[lr.DL];
|
||||
if (lr.AL == 7)
|
||||
{
|
||||
CDSp[lr.DL].cdsFlags |= 0x100;
|
||||
cdsp->cdsFlags |= 0x100;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
if (lr.DL < lastdrive)
|
||||
else
|
||||
{
|
||||
CDSp[lr.DL].cdsFlags &= ~0x100;
|
||||
cdsp->cdsFlags &= ~0x100;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
void int_2f_111e_call(iregs FAR *r);
|
||||
int_2f_111e_call(r);
|
||||
break;*/
|
||||
|
||||
rc = remote_doredirect(lr.BX, lr.CX, lr.DX,
|
||||
rc = remote_doredirect(lr.BX, lr.CX, lr.DX,
|
||||
(FP_ES_DI), lr.SI,
|
||||
(MK_FP(lr.DS, 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;
|
||||
/* 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;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1537,34 +1539,26 @@ dispatch:
|
||||
case 0x69:
|
||||
CLEAR_CARRY_FLAG();
|
||||
rc = (lr.BL == 0 ? default_drive : lr.BL - 1);
|
||||
if (rc < lastdrive)
|
||||
if (lr.AL == 0 || lr.AL == 1)
|
||||
{
|
||||
UWORD saveCX = lr.CX;
|
||||
if (CDSp[rc].cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
if (get_cds(rc) == NULL)
|
||||
rc = DE_INVLDDRV;
|
||||
else if (get_dpb(rc) == NULL)
|
||||
goto error_invalid;
|
||||
}
|
||||
switch (lr.AL)
|
||||
else
|
||||
{
|
||||
case 0x00:
|
||||
lr.AL = 0x0d;
|
||||
lr.CX = 0x0866;
|
||||
rc = DosDevIOctl(&lr);
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
lr.AL = 0x0d;
|
||||
lr.CX = 0x0846;
|
||||
rc = DosDevIOctl(&lr);
|
||||
break;
|
||||
lr.CX = lr.AL == 0 ? 0x0866 : 0x0846;
|
||||
lr.AL = 0x0d;
|
||||
rc = DosDevIOctl(&lr);
|
||||
lr.CX = saveCX;
|
||||
if (rc != SUCCESS)
|
||||
goto error_exit;
|
||||
break;
|
||||
}
|
||||
lr.CX = saveCX;
|
||||
if (rc != SUCCESS)
|
||||
goto error_exit;
|
||||
break;
|
||||
}
|
||||
else
|
||||
lr.AL = 0xFF;
|
||||
goto error_invalid;
|
||||
break;
|
||||
/*
|
||||
case 0x6a: see case 0x68
|
||||
@ -1580,7 +1574,7 @@ dispatch:
|
||||
(lr.DL & 0x0f) > 0x2 || (lr.DL & 0xf0) > 0x10)
|
||||
goto error_invalid;
|
||||
lrc = DosOpen(MK_FP(lr.DS, lr.SI),
|
||||
(lr.BX & 0x7000) | ((lr.DL & 3) << 8) |
|
||||
(lr.BX & 0x70ff) | ((lr.DL & 3) << 8) |
|
||||
((lr.DL & 0x10) << 6), lr.CL);
|
||||
if (lrc < 0)
|
||||
{
|
||||
@ -1731,12 +1725,14 @@ VOID ASMCFUNC int2526_handler(WORD mode, struct int25regs FAR * r)
|
||||
}
|
||||
|
||||
#ifdef WITHFAT32
|
||||
if (!(CDSp[drv].cdsFlags & CDSNETWDRV) &&
|
||||
ISFAT32(CDSp[drv].cdsDpb))
|
||||
{
|
||||
r->ax = 0x207;
|
||||
r->flags |= FLG_CARRY;
|
||||
return;
|
||||
struct dpb FAR *dpbp = get_dpb(drv);
|
||||
if (dpbp != NULL && ISFAT32(dpbp))
|
||||
{
|
||||
r->ax = 0x207;
|
||||
r->flags |= FLG_CARRY;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1801,13 +1797,20 @@ STATIC VOID StartTrace(VOID)
|
||||
and serves the internal dos calls - int2f/12xx
|
||||
*/
|
||||
struct int2f12regs {
|
||||
#ifdef I386
|
||||
#ifdef __WATCOMC__
|
||||
/* UWORD gs, fs; ** GS/FS are protected through SI/DI */
|
||||
#else
|
||||
UWORD high_edx, high_ecx, high_ebx, high_eax;
|
||||
#endif
|
||||
#endif
|
||||
UWORD es, ds;
|
||||
UWORD di, si, bp, bx, dx, cx, ax;
|
||||
UWORD ip, cs, flags;
|
||||
UWORD callerARG1; /* used if called from INT2F/12 */
|
||||
};
|
||||
|
||||
VOID ASMCFUNC int2F_12_handler(volatile struct int2f12regs r)
|
||||
VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
|
||||
{
|
||||
UWORD function = r.ax & 0xff;
|
||||
|
||||
@ -1873,6 +1876,14 @@ VOID ASMCFUNC int2F_12_handler(volatile struct int2f12regs r)
|
||||
|
||||
break;
|
||||
|
||||
case 0x13:
|
||||
/* uppercase character */
|
||||
/* for now, ASCII only because nls.c cannot handle DS!=SS */
|
||||
r.ax = (unsigned char)r.callerARG1;
|
||||
if (r.ax >= 'a' && r.ax <= 'z')
|
||||
r.ax -= 'a' - 'A';
|
||||
break;
|
||||
|
||||
case 0x16: /* get address of system file table entry - used by NET.EXE
|
||||
BX system file table entry number ( such as returned from 2F/1220)
|
||||
returns
|
||||
@ -1899,14 +1910,14 @@ VOID ASMCFUNC int2F_12_handler(volatile struct int2f12regs r)
|
||||
; probable use: get sizeof(CDSentry)
|
||||
*/
|
||||
{
|
||||
UWORD drv = r.callerARG1 & 0xff;
|
||||
struct cds FAR *cdsp = get_cds(r.callerARG1 & 0xff);
|
||||
|
||||
if (drv >= lastdrive)
|
||||
if (cdsp == NULL)
|
||||
r.flags |= FLG_CARRY;
|
||||
else
|
||||
{
|
||||
r.ds = FP_SEG(CDSp);
|
||||
r.si = FP_OFF(&CDSp[drv]);
|
||||
r.ds = FP_SEG(cdsp);
|
||||
r.si = FP_OFF(cdsp);
|
||||
r.flags &= ~FLG_CARRY;
|
||||
}
|
||||
break;
|
||||
@ -1974,8 +1985,9 @@ VOID ASMCFUNC int2F_12_handler(volatile struct int2f12regs r)
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("unimplemented internal dos function INT2F/12%02x\n",
|
||||
function);
|
||||
put_string("unimplemented internal dos function INT2F/12");
|
||||
put_unsigned(function, 16, 2);
|
||||
put_string("\n");
|
||||
r.flags |= FLG_CARRY;
|
||||
break;
|
||||
|
||||
|
@ -201,13 +201,7 @@ COUNT DosDevIOctl(lregs * r)
|
||||
|
||||
CharReqHdr.r_unit = (r->BL == 0 ? default_drive : r->BL - 1);
|
||||
|
||||
if (CharReqHdr.r_unit >= lastdrive)
|
||||
return DE_INVLDDRV;
|
||||
else
|
||||
{
|
||||
/* cdsp = &CDSp[CharReqHdr.r_unit]; */
|
||||
dpbp = CDSp[CharReqHdr.r_unit].cdsDpb;
|
||||
}
|
||||
dpbp = get_dpb(CharReqHdr.r_unit);
|
||||
|
||||
switch (r->AL)
|
||||
{
|
||||
@ -229,7 +223,7 @@ COUNT DosDevIOctl(lregs * r)
|
||||
}
|
||||
return DE_INVLDFUNC;
|
||||
case 0x09:
|
||||
if (CDSp[CharReqHdr.r_unit].cdsFlags & CDSNETWDRV)
|
||||
if (get_cds(CharReqHdr.r_unit) != NULL && dpbp == NULL)
|
||||
{
|
||||
r->DX = ATTR_REMOTE;
|
||||
r->AX = S_DONE | S_BUSY;
|
||||
|
@ -420,7 +420,7 @@ _net_name db ' ' ;-27 - 15 Character Network Name
|
||||
global _dta
|
||||
global _cu_psp, _default_drive
|
||||
global _break_ena
|
||||
global _return_code, _return_mode
|
||||
global _return_code
|
||||
global _internal_data
|
||||
|
||||
global _CritPatch
|
||||
@ -439,12 +439,11 @@ _CritErrCode dw 0 ; 04 - DOS format error Code
|
||||
_CritErrAction db 0 ; 06 - Error Action Code
|
||||
_CritErrClass db 0 ; 07 - Error Class
|
||||
_CritErrDev dd 0 ; 08 - Failing Device Address
|
||||
_dta dw _TempBuffer, seg _TempBuffer
|
||||
_dta dw _sda_tmp_dm, seg _sda_tmp_dm
|
||||
; 0C - current DTA, initialize to TempBuffer.
|
||||
_cu_psp dw 0 ; 10 - Current PSP
|
||||
break_sp dw 0 ; 12 - used in int 23
|
||||
_return_code db 0 ; 14 - return code from process
|
||||
_return_mode db 0 ; 15 - reason for process terminate
|
||||
_return_code dw 0 ; 14 - return code from process
|
||||
_default_drive db 0 ; 16 - Current Drive
|
||||
_break_ena db 1 ; 17 - Break Flag (default TRUE)
|
||||
db 0 ; 18 - flag, code page switching
|
||||
@ -481,10 +480,10 @@ daysSince1980 dw 0FFFFh ; 34 - number of days since epoch
|
||||
; force rebuild on first clock read
|
||||
global _DayOfWeek
|
||||
_DayOfWeek db 2 ; 36 - day of week
|
||||
global _Year
|
||||
_Year dw 1980 ; 37 - year
|
||||
global _dosidle_flag
|
||||
_dosidle_flag db 0 ; 39 - unknown *no more*
|
||||
_console_swap db 0 ; 37 console swapped during read from dev
|
||||
global _dosidle_flag
|
||||
_dosidle_flag db 1 ; 38 - safe to call int28 if nonzero
|
||||
_abort_progress db 0 ; 39 - abort in progress
|
||||
global _CharReqHdr
|
||||
_CharReqHdr:
|
||||
global _ClkReqHdr
|
||||
@ -502,8 +501,8 @@ _ClkRecord times 6 db 0 ; 96 - CLOCK$ transfer record
|
||||
__PriPathBuffer times 80h db 0 ; 9E - buffer for file name
|
||||
global __SecPathBuffer
|
||||
__SecPathBuffer times 80h db 0 ;11E - buffer for file name
|
||||
global _TempBuffer
|
||||
_TempBuffer times 21 db 0 ;19E - 21 byte srch state
|
||||
global _sda_tmp_dm
|
||||
_sda_tmp_dm times 21 db 0 ;19E - 21 byte srch state
|
||||
global _SearchDir
|
||||
_SearchDir times 32 db 0 ;1B3 - 32 byte dir entry
|
||||
global _TempCDS
|
||||
@ -523,10 +522,7 @@ _OpenMode db 0 ;24E - File Open Attribute
|
||||
global _Server_Call
|
||||
_Server_Call db 0 ;252 - Server call Func 5D sub 0
|
||||
db 0
|
||||
global _lpUserStack
|
||||
_lpUserStack dd 0 ;254 - pointer to user stack frame
|
||||
|
||||
; Pad to 057Ch
|
||||
; Pad to 05CCh
|
||||
times (25ch - ($ - _internal_data)) db 0
|
||||
|
||||
global _tsr ; used by break and critical error
|
||||
|
@ -51,7 +51,7 @@ VOID unicode_to_lfn(UNICODE FAR **name, struct lfn_entry FAR *lep);
|
||||
COUNT lfn_allocate_inode(VOID)
|
||||
{
|
||||
f_node_ptr fnp = get_f_node();
|
||||
struct cds FAR *cdsp;
|
||||
struct dpb FAR *dpbp;
|
||||
COUNT handle;
|
||||
if (fnp == 0) return LHE_NOFREEHNDL;
|
||||
|
||||
@ -64,17 +64,17 @@ COUNT lfn_allocate_inode(VOID)
|
||||
}
|
||||
|
||||
/* Check that default drive is a block device */
|
||||
cdsp = &CDSp[default_drive];
|
||||
dpbp = get_dpb(default_drive);
|
||||
|
||||
if (cdsp->cdsDpb == 0)
|
||||
if (dpbp == 0)
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return LHE_INVLDDRV;
|
||||
}
|
||||
|
||||
fnp->f_dpb = cdsp->cdsDpb;
|
||||
fnp->f_dpb = dpbp;
|
||||
|
||||
if (media_check(fnp->f_dpb) < 0)
|
||||
if (media_check(dpbp) < 0)
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return LHE_INVLDDRV;
|
||||
|
@ -51,11 +51,10 @@ extern UBYTE DOSFAR ASM nblkdev, DOSFAR ASM lastdrive; /* value of last drive
|
||||
|
||||
GLOBAL BYTE DOSFAR os_major, /* major version number */
|
||||
DOSFAR os_minor, /* minor version number */
|
||||
DOSFAR dosidle_flag, DOSFAR ASM BootDrive, /* Drive we came up from */
|
||||
DOSFAR ASM default_drive; /* default drive for dos */
|
||||
GLOBAL UBYTE DOSFAR ASM BootDrive; /* Drive we came up from */
|
||||
|
||||
GLOBAL BYTE DOSFAR os_release[];
|
||||
GLOBAL seg DOSFAR RootPsp; /* Root process -- do not abort */
|
||||
|
||||
extern struct dpb FAR *DOSFAR ASM DPBp; /* First drive Parameter Block */
|
||||
extern struct cds FAR *DOSFAR ASM CDSp; /* Current Directory Structure */
|
||||
@ -85,7 +84,6 @@ extern BYTE FAR *upBase;
|
||||
extern BYTE ASM _ib_start[], ASM _ib_end[], ASM _init_end[];
|
||||
extern UWORD ram_top; /* How much ram in Kbytes */
|
||||
|
||||
VOID configDone(VOID);
|
||||
STATIC VOID InitIO(void);
|
||||
|
||||
STATIC VOID update_dcb(struct dhdr FAR *);
|
||||
@ -156,7 +154,7 @@ VOID ASMCFUNC FreeDOSmain(void)
|
||||
|
||||
BootDrive = *(BYTE FAR *)MK_FP(0x50,0xe0) + 1;
|
||||
|
||||
if ((unsigned)BootDrive >= 0x80)
|
||||
if (BootDrive >= 0x80)
|
||||
BootDrive = 3; /* C: */
|
||||
|
||||
*(DWORD FAR *)MK_FP(0x50,0xe0+2) = 0;
|
||||
@ -339,18 +337,22 @@ STATIC VOID FsConfig(VOID)
|
||||
|
||||
/* The system file tables need special handling and are "hand */
|
||||
/* built. Included is the stdin, stdout, stdaux and stdprn. */
|
||||
/* a little bit of shuffling is necessary for compatibility */
|
||||
|
||||
/* 0 is /dev/con (stdin) */
|
||||
/* sft_idx=0 is /dev/aux */
|
||||
open("AUX", O_RDWR);
|
||||
|
||||
/* handle 1, sft_idx=1 is /dev/con (stdout) */
|
||||
open("CON", O_RDWR);
|
||||
|
||||
/* 1 is /dev/con (stdout) */
|
||||
dup2(STDIN, STDOUT);
|
||||
/* 3 is /dev/aux */
|
||||
dup2(STDIN, STDAUX);
|
||||
|
||||
/* 2 is /dev/con (stderr) */
|
||||
dup2(STDIN, STDERR);
|
||||
/* 0 is /dev/con (stdin) */
|
||||
dup2(STDOUT, STDIN);
|
||||
|
||||
/* 3 is /dev/aux */
|
||||
open("AUX", O_RDWR);
|
||||
/* 2 is /dev/con (stdin) */
|
||||
dup2(STDOUT, STDERR);
|
||||
|
||||
/* 4 is /dev/prn */
|
||||
open("PRN", O_WRONLY);
|
||||
@ -416,8 +418,6 @@ STATIC void kernel()
|
||||
exb.exec.env_seg = DOS_PSP + 8;
|
||||
fmemcpy(MK_FP(exb.exec.env_seg, 0), master_env, sizeof(master_env));
|
||||
|
||||
RootPsp = ~0;
|
||||
|
||||
/* process 0 */
|
||||
/* Execute command.com /P from the drive we just booted from */
|
||||
memset(Cmd.ctBuffer, 0, sizeof(Cmd.ctBuffer));
|
||||
@ -541,22 +541,15 @@ STATIC VOID update_dcb(struct dhdr FAR * dhp)
|
||||
/* If cmdLine is NULL, this is an internal driver */
|
||||
|
||||
BOOL init_device(struct dhdr FAR * dhp, BYTE FAR * cmdLine, COUNT mode,
|
||||
COUNT r_top)
|
||||
char FAR *r_top)
|
||||
{
|
||||
request rq;
|
||||
|
||||
UCOUNT maxmem = ((UCOUNT) r_top << 6) - FP_SEG(dhp);
|
||||
|
||||
if (maxmem >= 0x1000)
|
||||
maxmem = 0xFFFF;
|
||||
else
|
||||
maxmem <<= 4;
|
||||
|
||||
rq.r_unit = 0;
|
||||
rq.r_status = 0;
|
||||
rq.r_command = C_INIT;
|
||||
rq.r_length = sizeof(request);
|
||||
rq.r_endaddr = MK_FP(FP_SEG(dhp), maxmem);
|
||||
rq.r_endaddr = r_top;
|
||||
rq.r_bpbptr = (void FAR *)(cmdLine ? cmdLine : "\n");
|
||||
rq.r_firstunit = nblkdev;
|
||||
|
||||
@ -605,8 +598,8 @@ STATIC void InitIO(void)
|
||||
{
|
||||
/* Initialize driver chain */
|
||||
setvec(0x29, int29_handler); /* Requires Fast Con Driver */
|
||||
init_device(&con_dev, NULL, NULL, ram_top);
|
||||
init_device(&clk_dev, NULL, NULL, ram_top);
|
||||
init_device(&con_dev, NULL, NULL, lpTop);
|
||||
init_device(&clk_dev, NULL, NULL, lpTop);
|
||||
}
|
||||
|
||||
/* issue an internal error message */
|
||||
|
@ -99,11 +99,12 @@ clobber: clean
|
||||
-$(RM) kernel.exe kernel.sys status.me
|
||||
|
||||
clean:
|
||||
-$(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.cod *.err
|
||||
-$(RM) *.res *.obj *.bak *.crf *.xrf *.map *.lst *.cod *.err
|
||||
|
||||
# XXX: This is a very ugly way of linking the kernel, forced upon us by the
|
||||
# inability of Turbo `make' 2.0 to perform command line redirection. -- ror4
|
||||
kernel.exe: $(EXE_dependencies) $(LIBS)
|
||||
|
||||
kernel.res: $(EXE_dependencies) $(LIBS)
|
||||
-$(RM) kernel.res
|
||||
..\utils\echoto kernel.res kernel.obj iprf.obj+
|
||||
..\utils\echoto kernel.res entry.obj io.obj blockio.obj chario.obj dosfns.obj console.obj+
|
||||
@ -117,8 +118,9 @@ kernel.exe: $(EXE_dependencies) $(LIBS)
|
||||
..\utils\echoto kernel.res kernel.exe
|
||||
..\utils\echoto kernel.res kernel.map
|
||||
..\utils\echoto kernel.res ..\lib\libm.lib ..\lib\device.lib
|
||||
|
||||
kernel.exe: kernel.res $(EXE_dependencies) $(LIBS)
|
||||
$(LINK) @kernel.res;
|
||||
-$(RM) kernel.res
|
||||
|
||||
# *Individual File Dependencies*
|
||||
kernel.obj: kernel.asm segs.inc ludivmul.inc
|
||||
|
@ -299,6 +299,15 @@ COUNT DosMemLargest(UWORD FAR * size)
|
||||
seg dummy;
|
||||
*size = 0;
|
||||
DosMemAlloc(0xffff, LARGEST, &dummy, size);
|
||||
if (mem_access_mode & 0x80) /* then the largest block is probably low! */
|
||||
{
|
||||
UWORD lowsize = 0;
|
||||
mem_access_mode &= ~0x80;
|
||||
DosMemAlloc(0xffff, LARGEST, &dummy, &lowsize);
|
||||
mem_access_mode |= 0x80;
|
||||
if (lowsize > *size)
|
||||
*size = lowsize;
|
||||
}
|
||||
return *size ? SUCCESS : DE_NOMEM;
|
||||
}
|
||||
|
||||
@ -395,7 +404,6 @@ COUNT DosMemChange(UWORD para, UWORD size, UWORD * maxSize)
|
||||
}
|
||||
|
||||
/* shrink it down */
|
||||
/* From here on, nothing can fail */
|
||||
if (size < p->m_size)
|
||||
{
|
||||
/* make q a pointer to the new next block */
|
||||
@ -414,6 +422,10 @@ COUNT DosMemChange(UWORD para, UWORD size, UWORD * maxSize)
|
||||
q->m_psp = FREE_PSP;
|
||||
for (i = 0; i < 8; i++)
|
||||
q->m_name[i] = '\0';
|
||||
|
||||
/* try to join q with the free mcb's following it if possible */
|
||||
if (joinMCBs(q) != SUCCESS)
|
||||
return DE_MCBDESTRY;
|
||||
}
|
||||
|
||||
/* MS network client NET.EXE: DosMemChange sets the PSP *
|
||||
@ -441,8 +453,9 @@ COUNT DosMemCheck(void)
|
||||
/* check for corruption */
|
||||
if (p->m_type != MCB_NORMAL)
|
||||
{
|
||||
printf("dos mem corrupt, first_mcb=%04x\n", first_mcb);
|
||||
hexd("prev ", pprev, 16);
|
||||
put_string("dos mem corrupt, first_mcb=");
|
||||
put_unsigned(first_mcb, 16, 4);
|
||||
hexd("\nprev ", pprev, 16);
|
||||
hexd("notMZ", p, 16);
|
||||
return DE_MCBDESTRY;
|
||||
}
|
||||
|
@ -69,36 +69,33 @@ int SetJFTSize(UWORD nHandles)
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* this is the same, is shorter (~170)and slightly easier to understand TE*/
|
||||
int DosMkTmp(BYTE FAR * pathname, UWORD attr)
|
||||
{
|
||||
/* create filename from current date and time */
|
||||
char FAR *ptmp = pathname;
|
||||
UBYTE wd, month, day;
|
||||
UBYTE h, m, s, hund;
|
||||
UWORD sh;
|
||||
UWORD year;
|
||||
char FAR *ptmp;
|
||||
unsigned long randvar;
|
||||
int rc;
|
||||
char name83[13];
|
||||
int loop = 0;
|
||||
|
||||
while (*ptmp)
|
||||
ptmp++;
|
||||
int loop;
|
||||
|
||||
ptmp = pathname + fstrlen(pathname);
|
||||
if (ptmp == pathname || (ptmp[-1] != '\\' && ptmp[-1] != '/'))
|
||||
*ptmp++ = '\\';
|
||||
ptmp[8] = '\0';
|
||||
|
||||
DosGetDate(&wd, &month, &day, &year);
|
||||
DosGetTime(&h, &m, &s, &hund);
|
||||
|
||||
sh = s * 100 + hund;
|
||||
randvar = ((unsigned long)dos_getdate() << 16) | dos_gettime();
|
||||
|
||||
loop = 0;
|
||||
do {
|
||||
sprintf(name83, "%x%x%x%x%x%03x.%03x",
|
||||
year & 0xf, month & 0xf, day & 0xf, h & 0xf, m & 0xf,
|
||||
sh & 0xfff, loop & 0xfff);
|
||||
unsigned long tmp = randvar++;
|
||||
int i;
|
||||
for(i = 7; i >= 0; tmp >>= 4, i--)
|
||||
ptmp[i] = (tmp & 0xf) + 'A';
|
||||
|
||||
fmemcpy(ptmp, name83, 13);
|
||||
/* DOS versions: > 5: characters A - P
|
||||
< 5: hex digits */
|
||||
if (os_major < 5)
|
||||
for (i = 0; i < 8; i++)
|
||||
ptmp[i] -= (ptmp[i] < 'A' + 10) ? '0' - 'A' : 10;
|
||||
|
||||
/* only create new file -- 2001/09/22 ska*/
|
||||
rc = (short)DosOpen(pathname, O_LEGACY | O_CREAT | O_RDWR, attr);
|
||||
@ -122,8 +119,7 @@ int DosMkTmp(BYTE FAR * pathname, UWORD attr)
|
||||
|
||||
COUNT get_verify_drive(const char FAR * src)
|
||||
{
|
||||
UBYTE drive;
|
||||
unsigned flags;
|
||||
int drive;
|
||||
|
||||
/* Do we have a drive? */
|
||||
if (src[1] == ':')
|
||||
@ -131,14 +127,9 @@ COUNT get_verify_drive(const char FAR * src)
|
||||
else
|
||||
drive = default_drive;
|
||||
|
||||
if (drive >= lastdrive)
|
||||
if (get_cds(drive) == NULL)
|
||||
return DE_INVLDDRV;
|
||||
|
||||
/* Entry is disabled or JOINed drives are accessable by the path only */
|
||||
flags = CDSp[drive].cdsFlags;
|
||||
if ((flags & CDSMODEMASK) == 0 || (flags & CDSJOINED) != 0)
|
||||
return DE_INVLDDRV;
|
||||
|
||||
return drive;
|
||||
}
|
||||
|
||||
@ -363,7 +354,7 @@ COUNT truename(const char FAR * src, char * dest, COUNT mode)
|
||||
dest[0] = '\0'; /* better probable for sanity check below --
|
||||
included by original truename() */
|
||||
/* MUX succeeded and really something */
|
||||
if (QRemote_Fn(dest, src) && dest[0] != '\0')
|
||||
if (QRemote_Fn(dest, src) == SUCCESS && dest[0] != '\0')
|
||||
{
|
||||
tn_printf(("QRemoteFn() returned: \"%S\"\n", dest));
|
||||
#ifdef DEBUG_TRUENAME
|
||||
@ -450,7 +441,7 @@ COUNT truename(const char FAR * src, char * dest, COUNT mode)
|
||||
*p = '\\'; /* force backslash! */
|
||||
}
|
||||
p++;
|
||||
DosGetCuDir((result & 0x1f) + 1, p);
|
||||
DosGetCuDir((UBYTE)((result & 0x1f) + 1), p);
|
||||
if (*src != '\\' && *src != '/')
|
||||
p += strlen(p);
|
||||
else /* skip the absolute path marker */
|
||||
@ -541,11 +532,12 @@ COUNT truename(const char FAR * src, char * dest, COUNT mode)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (addSep == ADD)
|
||||
if (addSep == ADD || p == dest + 2)
|
||||
{
|
||||
/* MS DOS preserves a trailing '\\', so an access to "C:\\DOS\\"
|
||||
or "CDS.C\\" fails. */
|
||||
/* But don't add the separator, if the last component was ".." */
|
||||
/* we must also add a seperator if dest = "c:" */
|
||||
addChar('\\');
|
||||
}
|
||||
|
||||
@ -564,14 +556,15 @@ COUNT truename(const char FAR * src, char * dest, COUNT mode)
|
||||
|
||||
if (dest[2] != '/' && (!(mode & CDS_MODE_SKIP_PHYSICAL)) && njoined)
|
||||
{
|
||||
for(i = 0; i < lastdrive; ++i)
|
||||
struct cds FAR *cdsp = CDSp;
|
||||
for(i = 0; i < lastdrive; ++i, ++cdsp)
|
||||
{
|
||||
/* How many bytes must match */
|
||||
size_t j = fstrlen(CDSp[i].cdsCurrentPath);
|
||||
size_t j = fstrlen(cdsp->cdsCurrentPath);
|
||||
/* the last component must end before the backslash offset and */
|
||||
/* the path the drive is joined to leads the logical path */
|
||||
if ((CDSp[i].cdsFlags & CDSJOINED) && (dest[j] == '\\' || dest[j] == '\0')
|
||||
&& fmemcmp(dest, CDSp[i].cdsCurrentPath, j) == 0)
|
||||
if ((cdsp->cdsFlags & CDSJOINED) && (dest[j] == '\\' || dest[j] == '\0')
|
||||
&& fmemcmp(dest, cdsp->cdsCurrentPath, j) == 0)
|
||||
{ /* JOINed drive found */
|
||||
dest[0] = drNrToLetter(i); /* index is physical here */
|
||||
dest[1] = ':';
|
||||
@ -586,9 +579,9 @@ COUNT truename(const char FAR * src, char * dest, COUNT mode)
|
||||
strcpy(dest + 2, dest + j);
|
||||
}
|
||||
result = (result & 0xffe0) | i;
|
||||
current_ldt = &CDSp[i];
|
||||
current_ldt = cdsp;
|
||||
result &= ~IS_NETWORK;
|
||||
if (current_ldt->cdsFlags & CDSNETWDRV)
|
||||
if (cdsp->cdsFlags & CDSNETWDRV)
|
||||
result |= IS_NETWORK;
|
||||
tn_printf(("JOINed path: \"%S\"\n", dest));
|
||||
return result;
|
||||
|
@ -348,7 +348,7 @@ STATIC int nlsGetData(struct nlsPackage FAR * nls, int subfct,
|
||||
VOID nlsCPchange(UWORD cp)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(cp);
|
||||
printf("\7\nchange codepage not yet done ska\n");
|
||||
put_string("\7\nchange codepage not yet done ska\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -43,18 +43,18 @@ _reloc_call_CharMapSrvc:
|
||||
Protect386Registers
|
||||
push ds
|
||||
push es
|
||||
push bp
|
||||
push si
|
||||
push di
|
||||
; push bp
|
||||
; push si
|
||||
; push di
|
||||
push dx
|
||||
push cx
|
||||
push bx
|
||||
|
||||
push ax ; arg of _upChar
|
||||
push ax
|
||||
; push ax
|
||||
mov ax,DGROUP
|
||||
mov ds, ax
|
||||
pop ax
|
||||
; pop ax
|
||||
|
||||
call _DosUpChar
|
||||
;add sp, byte 2 // next POP retrieves orig AX
|
||||
@ -65,9 +65,9 @@ _reloc_call_CharMapSrvc:
|
||||
pop bx
|
||||
pop cx
|
||||
pop dx
|
||||
pop di
|
||||
pop si
|
||||
pop bp
|
||||
; pop di
|
||||
; pop si
|
||||
; pop bp
|
||||
pop es
|
||||
pop ds
|
||||
Restore386Registers
|
||||
|
72
kernel/prf.c
72
kernel/prf.c
@ -28,6 +28,8 @@
|
||||
|
||||
#include "portab.h"
|
||||
|
||||
#if defined(DEBUG) || defined(FORSYS) || defined(_INIT)
|
||||
|
||||
#ifdef FORSYS
|
||||
#include <io.h>
|
||||
#include <stdarg.h>
|
||||
@ -86,7 +88,7 @@ COUNT fstrlen(BYTE FAR * s) /* don't want globals.h, sorry */
|
||||
return i;
|
||||
}
|
||||
#else
|
||||
COUNT ASMCFUNC fstrlen(BYTE FAR * s); /* don't want globals.h, sorry */
|
||||
COUNT /*ASMCFUNC*/ pascal fstrlen(BYTE FAR * s); /* don't want globals.h, sorry */
|
||||
#endif
|
||||
|
||||
/* special console output routine */
|
||||
@ -370,24 +372,78 @@ COUNT do_printf(CONST BYTE * fmt, va_list arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef _INIT
|
||||
#else
|
||||
void put_console(int c)
|
||||
{
|
||||
if (c == '\n')
|
||||
put_console('\r');
|
||||
|
||||
#if defined(__TURBOC__)
|
||||
_AX = 0x0e00 | c;
|
||||
_BX = 0x0070;
|
||||
__int__(0x10);
|
||||
#elif defined(I86)
|
||||
__asm
|
||||
{
|
||||
mov al, byte ptr c;
|
||||
mov ah, 0x0e;
|
||||
mov bx, 0x0070;
|
||||
int 0x10;
|
||||
}
|
||||
#endif /* __TURBO__ */
|
||||
}
|
||||
|
||||
extern void put_string(const char *);
|
||||
extern void put_unsigned(unsigned, int, int);
|
||||
|
||||
void hexd(char *title, UBYTE FAR * p, COUNT numBytes)
|
||||
{
|
||||
int loop, start = 0;
|
||||
printf("%s", title);
|
||||
put_string(title);
|
||||
if (numBytes > 16)
|
||||
printf("\n");
|
||||
put_console('\n');
|
||||
|
||||
for (start = 0; start < numBytes; start += 16)
|
||||
{
|
||||
printf("%p|", p+start);
|
||||
put_unsigned(FP_SEG(p), 16, 4);
|
||||
put_console(':');
|
||||
put_unsigned(FP_OFF(p + start), 16, 4);
|
||||
put_console('|');
|
||||
for (loop = start; loop < numBytes && loop < start+16;loop++)
|
||||
printf("%02x ", p[loop]);
|
||||
{
|
||||
put_unsigned(p[loop], 16, 2);
|
||||
put_console(' ');
|
||||
}
|
||||
for (loop = start; loop < numBytes && loop < start+16;loop++)
|
||||
printf("%c", p[loop] < 0x20 ? '.' : p[loop]);
|
||||
printf("\n");
|
||||
put_console(p[loop] < 0x20 ? '.' : p[loop]);
|
||||
put_console('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/* put_unsigned -- print unsigned int in base 2--16 */
|
||||
void put_unsigned(unsigned n, int base, int width)
|
||||
{
|
||||
char s[6];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < width; i++)
|
||||
{ /* generate digits in reverse order */
|
||||
s[i] = "0123456789abcdef"[(UWORD) (n % base)];
|
||||
n /= base;
|
||||
}
|
||||
|
||||
while(i != 0)
|
||||
{ /* print digits in reverse order */
|
||||
put_console(s[--i]);
|
||||
}
|
||||
}
|
||||
|
||||
void put_string(const char *s)
|
||||
{
|
||||
while(*s != '\0')
|
||||
put_console(*s++);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
%include "segs.inc"
|
||||
|
||||
extern _lpUserStack:wrt DGROUP
|
||||
extern _user_r:wrt DGROUP
|
||||
|
||||
extern _break_flg:wrt DGROUP ; break detected flag
|
||||
extern _int21_handler:wrt TGROUP ; far call system services
|
||||
@ -140,8 +140,8 @@ _spawn_int23:
|
||||
;
|
||||
; this patch helps FreeDos to survive CtrlC,
|
||||
; but should clearly be done somehow else.
|
||||
mov ss, [_lpUserStack+2]
|
||||
mov sp, [_lpUserStack]
|
||||
mov ss, [_user_r+2]
|
||||
mov sp, [_user_r]
|
||||
|
||||
sti
|
||||
|
||||
|
121
kernel/proto.h
121
kernel/proto.h
@ -40,7 +40,6 @@ struct buffer FAR *getblock(ULONG blkno, COUNT dsk);
|
||||
struct buffer FAR *getblockOver(ULONG blkno, COUNT dsk);
|
||||
VOID setinvld(REG COUNT dsk);
|
||||
BOOL flush_buffers(REG COUNT dsk);
|
||||
BOOL flush1(struct buffer FAR * bp);
|
||||
BOOL flush(void);
|
||||
BOOL fill(REG struct buffer FAR * bp, ULONG blkno, COUNT dsk);
|
||||
BOOL DeleteBlockInBufferCache(ULONG blknolow, ULONG blknohigh, COUNT dsk);
|
||||
@ -49,20 +48,24 @@ UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks,
|
||||
COUNT mode);
|
||||
/* *** End of change */
|
||||
|
||||
/* break.c */
|
||||
int control_break(void);
|
||||
void handle_break(int sft_idx);
|
||||
|
||||
/* chario.c */
|
||||
UCOUNT BinaryCharIO(struct dhdr FAR * dev, UCOUNT n, void FAR * bp, unsigned command, COUNT *err);
|
||||
VOID sto(COUNT c);
|
||||
VOID cso(COUNT c);
|
||||
unsigned mod_cso(unsigned c);
|
||||
VOID destr_bs(void);
|
||||
UCOUNT _sti(BOOL check_break);
|
||||
VOID con_hold(void);
|
||||
long BinaryCharIO(struct dhdr FAR * dev, size_t n, void FAR * bp, unsigned command);
|
||||
int echo_char_stdin(int c);
|
||||
BOOL con_break(void);
|
||||
BOOL StdinBusy(void);
|
||||
VOID KbdFlush(void);
|
||||
VOID Do_DosIdle_loop(void);
|
||||
void sti_0a(keyboard FAR * kp);
|
||||
unsigned sti(unsigned n, char FAR * bp);
|
||||
void KbdFlush(int sft_idx);
|
||||
unsigned char read_char(int sft_idx, BOOL check_break);
|
||||
unsigned char read_char_stdin(BOOL check_break);
|
||||
long cooked_read(int sft_idx, size_t n, char FAR *bp);
|
||||
void read_line(int sft_in, int sft_out, keyboard FAR * kp);
|
||||
size_t read_line_handle(int sft_idx, size_t n, char FAR * bp);
|
||||
void write_char(int c, int sft_idx);
|
||||
void write_char_stdin(int c);
|
||||
long cooked_write(int sft_idx, size_t n, char FAR *bp);
|
||||
|
||||
sft FAR *get_sft(UCOUNT);
|
||||
|
||||
@ -71,21 +74,21 @@ 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(sft FAR * sftp, LONG new_pos, COUNT mode);
|
||||
COUNT SftSeek(int sft_idx, LONG new_pos, COUNT mode);
|
||||
/*COUNT DosRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err); */
|
||||
UCOUNT BinaryReadSft(sft FAR * s, void *bp, COUNT *err);
|
||||
#define BinaryRead(hndl, bp, err) BinaryReadSft(get_sft(hndl), bp, err)
|
||||
UCOUNT DosRWSft(sft FAR * s, UCOUNT n, void FAR * bp, COUNT *err, int mode);
|
||||
#define DosRead(hndl, n, bp, err) DosRWSft(get_sft(hndl), n, bp, err, XFR_READ)
|
||||
#define DosWrite(hndl, n, bp, err) DosRWSft(get_sft(hndl), n, bp, err, XFR_WRITE)
|
||||
ULONG DosSeek(COUNT hndl, LONG new_pos, COUNT mode);
|
||||
void BinarySftIO(int sft_idx, void *bp, int mode);
|
||||
#define BinaryIO(hndl, bp, mode) BinarySftIO(get_sft_idx(hndl), bp, mode)
|
||||
long DosRWSft(int sft_idx, size_t n, void FAR * bp, int mode);
|
||||
#define DosRead(hndl, n, bp) DosRWSft(get_sft_idx(hndl), n, bp, XFR_READ)
|
||||
#define DosWrite(hndl, n, bp) DosRWSft(get_sft_idx(hndl), n, bp, XFR_WRITE)
|
||||
ULONG DosSeek(unsigned hndl, LONG new_pos, COUNT mode);
|
||||
long DosOpen(char FAR * fname, unsigned flags, unsigned attrib);
|
||||
COUNT CloneHandle(unsigned hndl);
|
||||
long DosDup(unsigned Handle);
|
||||
COUNT DosForceDup(unsigned OldHandle, unsigned NewHandle);
|
||||
long DosOpenSft(char FAR * fname, unsigned flags, unsigned attrib);
|
||||
COUNT DosClose(COUNT hndl);
|
||||
COUNT DosCloseSft(WORD sft_idx, BOOL commitonly);
|
||||
COUNT DosCloseSft(int sft_idx, BOOL commitonly);
|
||||
#define DosCommit(hndl) DosCloseSft(get_sft_idx(hndl), TRUE)
|
||||
BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
|
||||
UWORD * bps, UWORD * nc);
|
||||
@ -94,7 +97,7 @@ COUNT DosChangeDir(BYTE FAR * s);
|
||||
COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name);
|
||||
COUNT DosFindNext(void);
|
||||
COUNT DosGetFtime(COUNT hndl, date * dp, time * tp);
|
||||
COUNT DosSetFtimeSft(WORD sft_idx, date dp, time tp);
|
||||
COUNT DosSetFtimeSft(int sft_idx, date dp, time tp);
|
||||
#define DosSetFtime(hndl, dp, tp) DosSetFtimeSft(get_sft_idx(hndl), (dp), (tp))
|
||||
COUNT DosGetFattr(BYTE FAR * name);
|
||||
COUNT DosSetFattr(BYTE FAR * name, UWORD attrp);
|
||||
@ -107,8 +110,9 @@ COUNT DosRmdir(const char FAR * dir);
|
||||
struct dhdr FAR *IsDevice(const char FAR * FileName);
|
||||
BOOL IsShareInstalled(void);
|
||||
COUNT DosLockUnlock(COUNT hndl, LONG pos, LONG len, COUNT unlock);
|
||||
sft FAR *idx_to_sft(COUNT SftIndex);
|
||||
COUNT get_sft_idx(UCOUNT hndl);
|
||||
sft FAR *idx_to_sft(int SftIndex);
|
||||
int get_sft_idx(UCOUNT hndl);
|
||||
struct cds FAR *get_cds(int dsk);
|
||||
COUNT DosTruename(const char FAR * src, char FAR * dest);
|
||||
|
||||
/*dosidle.asm */
|
||||
@ -134,6 +138,7 @@ void ConvertName83ToNameSZ(BYTE FAR * destSZ, BYTE FAR * srcFCBName);
|
||||
int FileName83Length(BYTE * filename83);
|
||||
|
||||
/* fatfs.c */
|
||||
struct dpb FAR *get_dpb(COUNT dsk);
|
||||
ULONG clus2phys(CLUSTER cl_no, struct dpb FAR * dpbp);
|
||||
long dos_open(char * path, unsigned flag, unsigned attrib);
|
||||
BOOL fcbmatch(const char *fcbname1, const char *fcbname2);
|
||||
@ -162,7 +167,7 @@ BOOL dir_exists(char * path);
|
||||
|
||||
VOID trim_path(BYTE FAR * s);
|
||||
|
||||
COUNT dos_cd(struct cds FAR * cdsp, BYTE * PathName);
|
||||
int dos_cd(char * PathName);
|
||||
|
||||
f_node_ptr get_f_node(void);
|
||||
VOID release_f_node(f_node_ptr fnp);
|
||||
@ -230,18 +235,6 @@ VOID show_chain(void);
|
||||
VOID DosUmbLink(BYTE n);
|
||||
VOID mcb_print(mcb FAR * mcbp);
|
||||
|
||||
/* misc.c */
|
||||
char * ASMCFUNC strcpy(char * d, const char * s);
|
||||
void ASMCFUNC fmemcpyBack(void FAR * d, const void FAR * s, size_t n);
|
||||
void ASMCFUNC fmemcpy(void FAR * d, const void FAR * s, size_t n);
|
||||
void ASMCFUNC fstrcpy(char FAR * d, const char FAR * s);
|
||||
void * ASMCFUNC memcpy(void *d, const void * s, size_t n);
|
||||
void ASMCFUNC fmemset(void FAR * s, int ch, size_t n);
|
||||
void * ASMCFUNC memset(void * s, int ch, size_t n);
|
||||
|
||||
int ASMCFUNC memcmp(const void *m1, const void *m2, size_t n);
|
||||
int ASMCFUNC fmemcmp(const void FAR *m1, const void FAR *m2, size_t n);
|
||||
|
||||
/* lfnapi.c */
|
||||
COUNT lfn_allocate_inode(VOID);
|
||||
COUNT lfn_free_inode(COUNT handle);
|
||||
@ -277,24 +270,42 @@ COUNT DosSetCodepage(UWORD actCP, UWORD sysCP);
|
||||
UWORD ASMCFUNC syscall_MUX14(DIRECT_IREGS);
|
||||
|
||||
/* prf.c */
|
||||
VOID put_console(COUNT c);
|
||||
#ifdef DEBUG
|
||||
int CDECL printf(CONST BYTE * fmt, ...);
|
||||
int CDECL sprintf(BYTE * buff, CONST BYTE * fmt, ...);
|
||||
#endif
|
||||
VOID put_console(COUNT c);
|
||||
VOID hexd(char *title, VOID FAR * p, COUNT numBytes);
|
||||
void put_unsigned(unsigned n, int base, int width);
|
||||
void put_string(const char *s);
|
||||
|
||||
/* strings.c */
|
||||
size_t ASMCFUNC strlen(const char * s);
|
||||
size_t ASMCFUNC fstrlen(const char FAR * s);
|
||||
char FAR * ASMCFUNC _fstrcpy(char FAR * d, const char FAR * s);
|
||||
char * ASMCFUNC strncpy(char * d, const char * s, size_t l);
|
||||
int ASMCFUNC strcmp(const char * d, const char * s);
|
||||
int ASMCFUNC fstrcmp(const char FAR * d, const char FAR * s);
|
||||
int ASMCFUNC fstrncmp(const char FAR * d, const char FAR * s, size_t l);
|
||||
int ASMCFUNC strncmp(const char * d, const char * s, size_t l);
|
||||
void ASMCFUNC fstrncpy(char FAR * d, const char FAR * s, size_t l);
|
||||
char * ASMCFUNC strchr(const char * s, int c);
|
||||
char FAR * ASMCFUNC fstrchr(const char FAR * s, int c);
|
||||
void FAR * ASMCFUNC fmemchr(const void FAR * s, int c, size_t n);
|
||||
size_t /* ASMCFUNC */ ASMPASCAL strlen(const char * s);
|
||||
size_t /* ASMCFUNC */ ASMPASCAL fstrlen(const char FAR * s);
|
||||
char FAR * /*ASMCFUNC*/ ASMPASCAL _fstrcpy(char FAR * d, const char FAR * s);
|
||||
char * /*ASMCFUNC*/ ASMPASCAL strncpy(char * d, const char * s, size_t l);
|
||||
int /*ASMCFUNC*/ ASMPASCAL strcmp(const char * d, const char * s);
|
||||
int /*ASMCFUNC*/ ASMPASCAL fstrcmp(const char FAR * d, const char FAR * s);
|
||||
int /*ASMCFUNC*/ ASMPASCAL fstrncmp(const char FAR * d, const char FAR * s, size_t l);
|
||||
int /*ASMCFUNC*/ ASMPASCAL strncmp(const char * d, const char * s, size_t l);
|
||||
void /*ASMCFUNC*/ ASMPASCAL fstrncpy(char FAR * d, const char FAR * s, size_t l);
|
||||
char * /*ASMCFUNC*/ ASMPASCAL strchr(const char * s, int c);
|
||||
char FAR * /*ASMCFUNC*/ ASMPASCAL fstrchr(const char FAR * s, int c);
|
||||
void FAR * /*ASMCFUNC*/ ASMPASCAL fmemchr(const void FAR * s, int c, size_t n);
|
||||
|
||||
/* misc.c */
|
||||
char * /*ASMCFUNC*/ ASMPASCAL strcpy(char * d, const char * s);
|
||||
void /*ASMCFUNC*/ ASMPASCAL fmemcpyBack(void FAR * d, const void FAR * s, size_t n);
|
||||
void /*ASMCFUNC*/ ASMPASCAL fmemcpy(void FAR * d, const void FAR * s, size_t n);
|
||||
void /*ASMCFUNC*/ ASMPASCAL fstrcpy(char FAR * d, const char FAR * s);
|
||||
void * /*ASMCFUNC*/ ASMPASCAL memcpy(void *d, const void * s, size_t n);
|
||||
void * /*ASMCFUNC*/ ASMPASCAL fmemset(void FAR * s, int ch, size_t n);
|
||||
void * /*ASMCFUNC*/ ASMPASCAL memset(void * s, int ch, size_t n);
|
||||
|
||||
int /*ASMCFUNC*/ ASMPASCAL memcmp(const void *m1, const void *m2, size_t n);
|
||||
int /*ASMCFUNC*/ ASMPASCAL fmemcmp(const void FAR *m1, const void FAR *m2, size_t n);
|
||||
|
||||
|
||||
|
||||
/* sysclk.c */
|
||||
COUNT BcdToByte(COUNT x);
|
||||
@ -312,19 +323,19 @@ VOID putdirent(struct dirent FAR * dp, UBYTE FAR * vp);
|
||||
#endif
|
||||
|
||||
/* systime.c */
|
||||
VOID DosGetTime(UBYTE * hp, UBYTE * mp, UBYTE * sp, UBYTE * hdp);
|
||||
COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd);
|
||||
VOID DosGetDate(UBYTE * wdp, UBYTE * mp, UBYTE * mdp, UWORD * yp);
|
||||
COUNT DosSetDate(UWORD Month, UWORD DayOfMonth, UWORD Year);
|
||||
void DosGetTime(struct dostime *dt);
|
||||
int DosSetTime(const struct dostime *dt);
|
||||
unsigned char DosGetDate(struct dosdate *dd);
|
||||
int DosSetDate(const struct dosdate *dd);
|
||||
|
||||
const UWORD *is_leap_year_monthdays(UWORD year);
|
||||
UWORD DaysFromYearMonthDay(UWORD Year, UWORD Month, UWORD DayOfMonth);
|
||||
|
||||
/* task.c */
|
||||
VOID new_psp(psp FAR * p, int psize);
|
||||
VOID new_psp(seg para, int psize);
|
||||
VOID return_user(void);
|
||||
COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp);
|
||||
ULONG DosGetFsize(COUNT hndl);
|
||||
ULONG SftGetFsize(int sft_idx);
|
||||
VOID InitPSP(VOID);
|
||||
|
||||
/* newstuff.c */
|
||||
|
@ -74,31 +74,31 @@ UWORD DaysFromYearMonthDay(UWORD Year, UWORD Month, UWORD DayOfMonth)
|
||||
/* common - call the clock driver */
|
||||
void ExecuteClockDriverRequest(BYTE command)
|
||||
{
|
||||
BinaryCharIO(clock, sizeof(struct ClockRecord), &ClkRecord, command, &UnusedRetVal);
|
||||
BinaryCharIO(clock, sizeof(struct ClockRecord), &ClkRecord, command);
|
||||
}
|
||||
|
||||
VOID DosGetTime(UBYTE * hp, UBYTE * mp, UBYTE * sp, UBYTE * hdp)
|
||||
void DosGetTime(struct dostime *dt)
|
||||
{
|
||||
ExecuteClockDriverRequest(C_INPUT);
|
||||
|
||||
if (ClkReqHdr.r_status & S_ERROR)
|
||||
return;
|
||||
|
||||
*hp = ClkRecord.clkHours;
|
||||
*mp = ClkRecord.clkMinutes;
|
||||
*sp = ClkRecord.clkSeconds;
|
||||
*hdp = ClkRecord.clkHundredths;
|
||||
dt->hour = ClkRecord.clkHours;
|
||||
dt->minute = ClkRecord.clkMinutes;
|
||||
dt->second = ClkRecord.clkSeconds;
|
||||
dt->hundredth = ClkRecord.clkHundredths;
|
||||
}
|
||||
|
||||
COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd)
|
||||
int DosSetTime(const struct dostime *dt)
|
||||
{
|
||||
/* for ClkRecord.clkDays */
|
||||
ExecuteClockDriverRequest(C_INPUT);
|
||||
|
||||
ClkRecord.clkHours = h;
|
||||
ClkRecord.clkMinutes = m;
|
||||
ClkRecord.clkSeconds = s;
|
||||
ClkRecord.clkHundredths = hd;
|
||||
ClkRecord.clkHours = dt->hour;
|
||||
ClkRecord.clkMinutes = dt->minute;
|
||||
ClkRecord.clkSeconds = dt->second;
|
||||
ClkRecord.clkHundredths = dt->hundredth;
|
||||
|
||||
ExecuteClockDriverRequest(C_OUTPUT);
|
||||
|
||||
@ -107,7 +107,7 @@ COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd)
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
VOID DosGetDate(UBYTE *wdp, UBYTE *mp, UBYTE *mdp, UWORD *yp)
|
||||
unsigned char DosGetDate(struct dosdate *dd)
|
||||
{
|
||||
UWORD c;
|
||||
const UWORD *pdays;
|
||||
@ -116,7 +116,7 @@ VOID DosGetDate(UBYTE *wdp, UBYTE *mp, UBYTE *mdp, UWORD *yp)
|
||||
ExecuteClockDriverRequest(C_INPUT);
|
||||
|
||||
if (ClkReqHdr.r_status & S_ERROR)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
for (Year = 1980, c = ClkRecord.clkDays;;)
|
||||
{
|
||||
@ -138,25 +138,27 @@ VOID DosGetDate(UBYTE *wdp, UBYTE *mp, UBYTE *mdp, UWORD *yp)
|
||||
++Month;
|
||||
}
|
||||
|
||||
*mp = Month;
|
||||
*mdp = c - pdays[Month - 1] + 1;
|
||||
*yp = Year;
|
||||
dd->year = Year;
|
||||
dd->month = Month;
|
||||
dd->monthday = c - pdays[Month - 1] + 1;
|
||||
|
||||
/* Day of week is simple. Take mod 7, add 2 (for Tuesday */
|
||||
/* 1-1-80) and take mod again */
|
||||
|
||||
*wdp = (ClkRecord.clkDays + 2) % 7;
|
||||
return (ClkRecord.clkDays + 2) % 7;
|
||||
}
|
||||
|
||||
COUNT DosSetDate(Month, DayOfMonth, Year)
|
||||
UWORD Month, DayOfMonth, Year;
|
||||
int DosSetDate(const struct dosdate *dd)
|
||||
{
|
||||
const UWORD *pdays;
|
||||
pdays = is_leap_year_monthdays(Year);
|
||||
UWORD Year = dd->year;
|
||||
UWORD Month = dd->month;
|
||||
UWORD DayOfMonth = dd->monthday;
|
||||
const UWORD *pdays = is_leap_year_monthdays(Year);
|
||||
|
||||
if (Year < 1980 || Year > 2099
|
||||
|| Month < 1 || Month > 12
|
||||
|| DayOfMonth < 1 || DayOfMonth > pdays[Month] - pdays[Month - 1])
|
||||
|| DayOfMonth < 1
|
||||
|| DayOfMonth > pdays[Month] - pdays[Month - 1])
|
||||
return DE_INVLDDATA;
|
||||
|
||||
ExecuteClockDriverRequest(C_INPUT);
|
||||
|
130
kernel/task.c
130
kernel/task.c
@ -58,19 +58,14 @@ static BYTE *RcsId =
|
||||
+ 1 byte: '\0'
|
||||
-- 1999/04/21 ska */
|
||||
|
||||
ULONG DosGetFsize(COUNT hndl)
|
||||
ULONG SftGetFsize(int sft_idx)
|
||||
{
|
||||
sft FAR *s;
|
||||
/* sfttbl FAR *sp;*/
|
||||
sft FAR *s = idx_to_sft(sft_idx);
|
||||
|
||||
/* Get the SFT block that contains the SFT */
|
||||
if ((s = get_sft(hndl)) == (sft FAR *) - 1)
|
||||
if (FP_OFF(s) == (size_t) -1)
|
||||
return DE_INVLDHNDL;
|
||||
|
||||
/* If this is not opened another error */
|
||||
if (s->sft_count == 0)
|
||||
return DE_ACCESS;
|
||||
|
||||
/* If SFT entry refers to a device, return the date and time of opening */
|
||||
if (s->sft_flags & (SFT_FDEVICE | SFT_FSHARED))
|
||||
{
|
||||
@ -163,11 +158,12 @@ STATIC COUNT ChildEnv(exec_blk * exp, UWORD * pChildEnvSeg, char far * pathname)
|
||||
}
|
||||
|
||||
/* The following code is 8086 dependant */
|
||||
VOID new_psp(psp FAR * p, int psize)
|
||||
void new_psp(seg para, int psize)
|
||||
{
|
||||
REG COUNT i;
|
||||
psp FAR *p = MK_FP(para, 0);
|
||||
psp FAR *q = MK_FP(cu_psp, 0);
|
||||
|
||||
int i;
|
||||
|
||||
/* Clear out new psp first */
|
||||
fmemset(p, 0, sizeof(psp));
|
||||
|
||||
@ -193,10 +189,7 @@ VOID new_psp(psp FAR * p, int psize)
|
||||
/* memory size in paragraphs */
|
||||
p->ps_size = psize;
|
||||
/* environment paragraph */
|
||||
p->ps_environ = 0;
|
||||
/* process dta */
|
||||
p->ps_dta = (BYTE FAR *) (&p->ps_cmd_count);
|
||||
|
||||
/* p->ps_environ = 0; cleared above */
|
||||
/* terminate address */
|
||||
p->ps_isv22 = getvec(0x22);
|
||||
/* break address */
|
||||
@ -204,45 +197,32 @@ VOID new_psp(psp FAR * p, int psize)
|
||||
/* critical error address */
|
||||
p->ps_isv24 = getvec(0x24);
|
||||
|
||||
/* File System parameters */
|
||||
/* user stack pointer - int 21 */
|
||||
p->ps_stack = q->ps_stack;
|
||||
/* file table - 0xff is unused */
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
p->ps_files[i] = 0xff;
|
||||
|
||||
/* File System parameters */
|
||||
/* maximum open files */
|
||||
p->ps_maxfiles = 20;
|
||||
fmemset(p->ps_files, 0xff, 20);
|
||||
|
||||
/* open file table pointer */
|
||||
p->ps_filetab = p->ps_files;
|
||||
|
||||
/* clone the file table */
|
||||
if (p != q)
|
||||
{
|
||||
REG COUNT i;
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
{
|
||||
if (q->ps_filetab[i] != 0xff && CloneHandle(i) >= 0)
|
||||
p->ps_filetab[i] = q->ps_filetab[i];
|
||||
else
|
||||
p->ps_filetab[i] = 0xff;
|
||||
}
|
||||
}
|
||||
/* clone the file table -- 0xff is unused */
|
||||
for (i = 0; i < 20; i++)
|
||||
if (CloneHandle(i) >= 0)
|
||||
p->ps_files[i] = q->ps_filetab[i];
|
||||
|
||||
/* first command line argument */
|
||||
p->ps_fcb1.fcb_drive = 0;
|
||||
/* p->ps_fcb1.fcb_drive = 0; already set */
|
||||
fmemset(p->ps_fcb1.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE);
|
||||
/* second command line argument */
|
||||
p->ps_fcb2.fcb_drive = 0;
|
||||
/* p->ps_fcb2.fcb_drive = 0; already set */
|
||||
fmemset(p->ps_fcb2.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE);
|
||||
|
||||
/* local command line */
|
||||
p->ps_cmd_count = 0; /* command tail */
|
||||
p->ps_cmd[0] = 0; /* command tail */
|
||||
if (RootPsp == (seg) ~ 0)
|
||||
RootPsp = FP_SEG(p);
|
||||
/* p->ps_cmd.ctCount = 0; command tail, already set */
|
||||
p->ps_cmd.ctBuffer[0] = 0xd; /* command tail */
|
||||
}
|
||||
|
||||
STATIC UWORD patchPSP(UWORD pspseg, UWORD envseg, exec_blk FAR * exb,
|
||||
@ -258,24 +238,22 @@ STATIC UWORD patchPSP(UWORD pspseg, UWORD envseg, exec_blk FAR * exb,
|
||||
psp = MK_FP(pspseg, 0);
|
||||
|
||||
/* complete the psp by adding the command line and FCBs */
|
||||
fmemcpy(psp->ps_cmd, exb->exec.cmd_line->ctBuffer, 127);
|
||||
fmemcpy(&psp->ps_cmd, exb->exec.cmd_line, sizeof(CommandTail));
|
||||
if (FP_OFF(exb->exec.fcb_1) != 0xffff)
|
||||
{
|
||||
fmemcpy(&psp->ps_fcb1, exb->exec.fcb_1, 16);
|
||||
fmemcpy(&psp->ps_fcb2, exb->exec.fcb_2, 16);
|
||||
}
|
||||
psp->ps_cmd_count = exb->exec.cmd_line->ctCount;
|
||||
|
||||
/* identify the mcb as this functions' */
|
||||
pspmcb->m_psp = pspseg;
|
||||
/* Patch in environment segment, if present, also adjust its MCB */
|
||||
if (envseg)
|
||||
{
|
||||
psp->ps_environ = envseg + 1;
|
||||
((mcb FAR *) MK_FP(envseg, 0))->m_psp = pspseg;
|
||||
envseg++;
|
||||
}
|
||||
else
|
||||
psp->ps_environ = 0;
|
||||
psp->ps_environ = envseg;
|
||||
|
||||
/* use the file name less extension - left adjusted and */
|
||||
np = fnam;
|
||||
@ -300,10 +278,8 @@ set_name:
|
||||
pspmcb->m_name[i] = '\0';
|
||||
|
||||
/* return value: AX value to be passed based on FCB values */
|
||||
return ((psp->ps_fcb1.fcb_drive < lastdrive &&
|
||||
CDSp[psp->ps_fcb1.fcb_drive].cdsFlags & CDSVALID) ? 0 : 0xff) +
|
||||
((psp->ps_fcb2.fcb_drive < lastdrive &&
|
||||
CDSp[psp->ps_fcb2.fcb_drive].cdsFlags & CDSVALID) ? 0 : 0xff) * 0x100;
|
||||
return (get_cds(psp->ps_fcb1.fcb_drive) ? 0 : 0xff) |
|
||||
(get_cds(psp->ps_fcb2.fcb_drive) ? 0 : 0xff00);
|
||||
}
|
||||
|
||||
int load_transfer(UWORD ds, exec_blk *exp, UWORD fcbcode, COUNT mode)
|
||||
@ -318,7 +294,8 @@ int load_transfer(UWORD ds, exec_blk *exp, UWORD fcbcode, COUNT mode)
|
||||
user_r->FLAGS &= ~FLG_CARRY;
|
||||
|
||||
cu_psp = ds;
|
||||
dta = p->ps_dta;
|
||||
/* process dta */
|
||||
dta = &p->ps_cmd;
|
||||
|
||||
if (mode == LOADNGO)
|
||||
{
|
||||
@ -350,16 +327,21 @@ int load_transfer(UWORD ds, exec_blk *exp, UWORD fcbcode, COUNT mode)
|
||||
considering a threshold, trying HIGH then LOW */
|
||||
STATIC int ExecMemLargest(UWORD *asize, UWORD threshold)
|
||||
{
|
||||
int rc = DosMemLargest(asize);
|
||||
/* less memory than the .COM/.EXE file has:
|
||||
try low memory first */
|
||||
if ((mem_access_mode & 0x80) &&
|
||||
(rc != SUCCESS || *asize < threshold))
|
||||
int rc;
|
||||
if (mem_access_mode & 0x80)
|
||||
{
|
||||
mem_access_mode &= ~0x80;
|
||||
mem_access_mode |= 0x40;
|
||||
rc = DosMemLargest(asize);
|
||||
mem_access_mode &= ~0x40;
|
||||
/* less memory than the .COM/.EXE file has:
|
||||
try low memory first */
|
||||
if (rc != SUCCESS || *asize < threshold)
|
||||
rc = DosMemLargest(asize);
|
||||
mem_access_mode |= 0x80;
|
||||
}
|
||||
else
|
||||
rc = DosMemLargest(asize);
|
||||
return (*asize < threshold ? DE_NOMEM : rc);
|
||||
}
|
||||
|
||||
@ -406,7 +388,7 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
|
||||
{
|
||||
UWORD com_size;
|
||||
{
|
||||
ULONG com_size_long = DosGetFsize(fd);
|
||||
ULONG com_size_long = SftGetFsize(fd);
|
||||
/* maximally 64k - 256 bytes stack -
|
||||
256 bytes psp */
|
||||
com_size = (min(com_size_long, 0xfe00u) >> 4) + 0x10;
|
||||
@ -471,10 +453,10 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
|
||||
-- 1999/04/21 ska */
|
||||
|
||||
/* rewind to start */
|
||||
DosSeek(fd, 0, 0);
|
||||
SftSeek(fd, 0, 0);
|
||||
/* read everything, but at most 64K - sizeof(PSP) */
|
||||
DosRead(fd, 0xff00, sp, &UnusedRetVal);
|
||||
DosClose(fd);
|
||||
DosRWSft(fd, 0xff00, sp, XFR_READ);
|
||||
DosCloseSft(fd, FALSE);
|
||||
}
|
||||
|
||||
if (mode == OVERLAY)
|
||||
@ -485,7 +467,7 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
|
||||
|
||||
/* point to the PSP so we can build it */
|
||||
setvec(0x22, MK_FP(user_r->CS, user_r->IP));
|
||||
new_psp(MK_FP(mem, 0), mem + asize);
|
||||
new_psp(mem, mem + asize);
|
||||
|
||||
fcbcode = patchPSP(mem - 1, env, exp, namep);
|
||||
/* set asize to end of segment */
|
||||
@ -536,7 +518,6 @@ VOID return_user(void)
|
||||
|
||||
cu_psp = p->ps_parent;
|
||||
q = MK_FP(cu_psp, 0);
|
||||
dta = q->ps_dta;
|
||||
|
||||
irp = (iregs FAR *) q->ps_stack;
|
||||
|
||||
@ -583,7 +564,7 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
|
||||
exe_size = (ULONG) long2para(image_size) + ExeHeader.exMinAlloc;
|
||||
|
||||
/* Clone the environement and create a memory arena */
|
||||
if ((mode & 0x7f) != OVERLAY && (mode & 0x80))
|
||||
if (mode & 0x80)
|
||||
{
|
||||
DosUmbLink(1); /* link in UMB's */
|
||||
mem_access_mode |= 0x80;
|
||||
@ -645,7 +626,7 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
|
||||
|
||||
/* Now load the executable */
|
||||
/* offset to start of image */
|
||||
if (DosSeek(fd, image_offset, 0) != image_offset)
|
||||
if (SftSeek(fd, image_offset, 0) != SUCCESS)
|
||||
{
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
@ -674,16 +655,16 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
|
||||
|
||||
/* read in the image in 32K chunks */
|
||||
{
|
||||
UCOUNT nBytesRead;
|
||||
int nBytesRead;
|
||||
BYTE FAR *sp = MK_FP(start_seg, 0x0);
|
||||
|
||||
while (exe_size > 0)
|
||||
{
|
||||
nBytesRead =
|
||||
DosRead(fd,
|
||||
(int)DosRWSft(fd,
|
||||
(COUNT) (exe_size < CHUNK ? exe_size : CHUNK),
|
||||
(VOID FAR *) sp, &UnusedRetVal);
|
||||
if (nBytesRead == 0)
|
||||
(VOID FAR *) sp, XFR_READ);
|
||||
if (nBytesRead <= 0)
|
||||
break;
|
||||
sp = add_far((VOID FAR *) sp, nBytesRead);
|
||||
exe_size -= nBytesRead;
|
||||
@ -695,12 +676,11 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
|
||||
UWORD reloc[2];
|
||||
seg FAR *spot;
|
||||
|
||||
DosSeek(fd, ExeHeader.exRelocTable, 0);
|
||||
SftSeek(fd, ExeHeader.exRelocTable, 0);
|
||||
for (i = 0; i < ExeHeader.exRelocItems; i++)
|
||||
{
|
||||
if (DosRead
|
||||
(fd, sizeof(reloc), (VOID FAR *) & reloc[0],
|
||||
&UnusedRetVal) != sizeof(reloc))
|
||||
if (DosRWSft
|
||||
(fd, sizeof(reloc), (VOID FAR *) & reloc[0], XFR_READ) != sizeof(reloc))
|
||||
{
|
||||
return DE_INVLDDATA;
|
||||
}
|
||||
@ -719,7 +699,7 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
|
||||
}
|
||||
|
||||
/* and finally close the file */
|
||||
DosClose(fd);
|
||||
DosCloseSft(fd, FALSE);
|
||||
|
||||
/* exit here for overlay */
|
||||
if (mode == OVERLAY)
|
||||
@ -730,7 +710,7 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
|
||||
|
||||
/* point to the PSP so we can build it */
|
||||
setvec(0x22, MK_FP(user_r->CS, user_r->IP));
|
||||
new_psp(MK_FP(mem, 0), mem + asize);
|
||||
new_psp(mem, mem + asize);
|
||||
|
||||
fcbcode = patchPSP(mem - 1, env, exp, namep);
|
||||
exp->exec.stack =
|
||||
@ -762,12 +742,12 @@ COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp)
|
||||
/* If file not found - free ram and return error */
|
||||
|
||||
if (IsDevice(lp) || /* we don't want to execute C:>NUL */
|
||||
(fd = (short)DosOpen(lp, O_LEGACY | O_OPEN | O_RDONLY, 0)) < 0)
|
||||
(fd = (short)DosOpenSft(lp, O_LEGACY | O_OPEN | O_RDONLY, 0)) < 0)
|
||||
{
|
||||
return DE_FILENOTFND;
|
||||
}
|
||||
|
||||
rc = DosRead(fd, sizeof(exe_header), (BYTE FAR *)&ExeHeader, &UnusedRetVal);
|
||||
rc = (int)DosRWSft(fd, sizeof(exe_header), (BYTE FAR *)&ExeHeader, XFR_READ);
|
||||
|
||||
if (rc == sizeof(exe_header) &&
|
||||
(ExeHeader.exSignature == MAGIC || ExeHeader.exSignature == OLD_MAGIC))
|
||||
@ -779,7 +759,7 @@ COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp)
|
||||
rc = DosComLoader(lp, &TempExeBlock, mode, fd);
|
||||
}
|
||||
|
||||
DosClose(fd);
|
||||
DosCloseSft(fd, FALSE);
|
||||
|
||||
if (mode == LOAD && rc == SUCCESS)
|
||||
fmemcpy(ep, &TempExeBlock, sizeof(exec_blk));
|
||||
|
@ -15,7 +15,7 @@ LIBTERM=
|
||||
LIBPLUS=+
|
||||
|
||||
TINY=-lt
|
||||
CFLAGSS=-L$(LIBPATH) -mt -a- -k- -f- -ff- -O -Z -d
|
||||
CFLAGST=-L$(LIBPATH) -mt -a- -k- -f- -ff- -O -Z -d
|
||||
CFLAGSC=-L$(LIBPATH) -a- -mc
|
||||
|
||||
TARGET=KBC
|
||||
|
@ -7,7 +7,7 @@ COMPILERPATH=$(MS_BASE)
|
||||
COMPILERBIN=$(COMPILERPATH)\bin
|
||||
INCLUDEPATH=$(COMPILERPATH)\include
|
||||
CC=$(COMPILERBIN)\cl -c
|
||||
CC=$(COMPILERBIN)\cl
|
||||
CL=$(COMPILERBIN)\cl
|
||||
TINY=
|
||||
CFLAGST=/Fm /AT /Os /Zp1
|
||||
CFLAGSC=/Fm /AL /Os /Zp1
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
# Use these for WATCOM 11.0c
|
||||
COMPILERPATH=$(WATCOM)
|
||||
CC=wcc
|
||||
CC=*wcc
|
||||
CL=wcl
|
||||
INCLUDEPATH=$(COMPILERPATH)\H
|
||||
INCLUDE=$(COMPILERPATH)\h
|
||||
|
30
sys/sys.c
30
sys/sys.c
@ -36,7 +36,7 @@
|
||||
#define DEBUG
|
||||
/* #define DDEBUG */
|
||||
|
||||
#define SYS_VERSION "v2.4"
|
||||
#define SYS_VERSION "v2.5"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <dos.h>
|
||||
@ -293,13 +293,6 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("\nCopying COMMAND.COM...\n");
|
||||
if (!copy(drive, srcPath, rootPath, "command.com"))
|
||||
{
|
||||
printf("\n%s: cannot copy \"COMMAND.COM\"\n", pgm);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (argc > drivearg + 1)
|
||||
bsFile = argv[drivearg + 1];
|
||||
|
||||
@ -308,6 +301,23 @@ int main(int argc, char **argv)
|
||||
(argc > drivearg + 2)
|
||||
&& memicmp(argv[drivearg + 2], "BOTH", 4) == 0);
|
||||
|
||||
printf("\nCopying COMMAND.COM...\n");
|
||||
if (!copy(drive, srcPath, rootPath, "COMMAND.COM"))
|
||||
{
|
||||
char *comspec = getenv("COMSPEC");
|
||||
if (comspec != NULL)
|
||||
{
|
||||
printf("%s: Trying \"%s\"\n", pgm, comspec);
|
||||
if (!copy(drive, comspec, NULL, "COMMAND.COM"))
|
||||
comspec = NULL;
|
||||
}
|
||||
if (comspec == NULL)
|
||||
{
|
||||
printf("\n%s: cannot copy \"COMMAND.COM\"\n", pgm);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nSystem transferred.\n");
|
||||
return 0;
|
||||
}
|
||||
@ -743,7 +753,9 @@ BOOL copy(COUNT drive, BYTE * srcPath, BYTE * rootPath, BYTE * file)
|
||||
struct stat fstatbuf;
|
||||
|
||||
sprintf(dest, "%c:\\%s", 'A' + drive, file);
|
||||
sprintf(source, "%s%s", srcPath, file);
|
||||
strcpy(source, srcPath);
|
||||
if (rootPath != NULL) /* trick for comspec */
|
||||
strcat(source, file);
|
||||
|
||||
if (stat(source, &fstatbuf))
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user