diff --git a/boot/boot.asm b/boot/boot.asm index d6d393e..7536264 100644 --- a/boot/boot.asm +++ b/boot/boot.asm @@ -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 diff --git a/docs/contrib.txt b/docs/contrib.txt index 923014d..ba77e2d 100644 --- a/docs/contrib.txt +++ b/docs/contrib.txt @@ -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. diff --git a/docs/history.txt b/docs/history.txt index 600928b..7b10ecd 100644 --- a/docs/history.txt +++ b/docs/history.txt @@ -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 diff --git a/hdr/device.h b/hdr/device.h index d2d3ac8..022d33f 100644 --- a/hdr/device.h +++ b/hdr/device.h @@ -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; diff --git a/hdr/portab.h b/hdr/portab.h index 9f399aa..de95912 100644 --- a/hdr/portab.h +++ b/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 diff --git a/hdr/process.h b/hdr/process.h index f25347c..f6cd3c4 100644 --- a/hdr/process.h +++ b/hdr/process.h @@ -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 diff --git a/hdr/time.h b/hdr/time.h index 951450a..867e5bd 100644 --- a/hdr/time.h +++ b/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 /* diff --git a/hdr/version.h b/hdr/version.h index 3a9a866..5f38bab 100644 --- a/hdr/version.h +++ b/hdr/version.h @@ -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 */ diff --git a/kernel/asmsupt.asm b/kernel/asmsupt.asm index 5174f82..1410f5c 100644 --- a/kernel/asmsupt.asm +++ b/kernel/asmsupt.asm @@ -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: diff --git a/kernel/blockio.c b/kernel/blockio.c index faa71ea..ff91dbc 100644 --- a/kernel/blockio.c +++ b/kernel/blockio.c @@ -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 */ } diff --git a/kernel/break.c b/kernel/break.c index c41b72b..1cbcb06 100644 --- a/kernel/break.c +++ b/kernel/break.c @@ -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 */ diff --git a/kernel/chario.c b/kernel/chario.c index 004d227..5290f6f 100644 --- a/kernel/chario.c +++ b/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) { diff --git a/kernel/config.c b/kernel/config.c index 46df25d..82a7e7b 100644 --- a/kernel/config.c +++ b/kernel/config.c @@ -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; diff --git a/kernel/dosfns.c b/kernel/dosfns.c index 0de7c08..d0f18b8 100644 --- a/kernel/dosfns.c +++ b/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; diff --git a/kernel/dosidle.asm b/kernel/dosidle.asm index bbcdf47..e0e4cab 100644 --- a/kernel/dosidle.asm +++ b/kernel/dosidle.asm @@ -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 diff --git a/kernel/dsk.c b/kernel/dsk.c index 53df579..0efb8df 100644 --- a/kernel/dsk.c +++ b/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); } } diff --git a/kernel/entry.asm b/kernel/entry.asm index 2424368..92cd25a 100644 --- a/kernel/entry.asm +++ b/kernel/entry.asm @@ -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 diff --git a/kernel/error.c b/kernel/error.c index 8139f0f..88457df 100644 --- a/kernel/error.c +++ b/kernel/error.c @@ -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 (;;) ; } diff --git a/kernel/fatdir.c b/kernel/fatdir.c index 25ca4ef..225a8b0 100644 --- a/kernel/fatdir.c +++ b/kernel/fatdir.c @@ -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); diff --git a/kernel/fatfs.c b/kernel/fatfs.c index a9d9b9e..0872fb4 100644 --- a/kernel/fatfs.c +++ b/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. diff --git a/kernel/fcbfns.c b/kernel/fcbfns.c index c010ff6..c218057 100644 --- a/kernel/fcbfns.c +++ b/kernel/fcbfns.c @@ -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 diff --git a/kernel/globals.h b/kernel/globals.h index 9d4289c..3165df9 100644 --- a/kernel/globals.h +++ b/kernel/globals.h @@ -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 * diff --git a/kernel/init-mod.h b/kernel/init-mod.h index b1d28b1..1f2d82e 100644 --- a/kernel/init-mod.h +++ b/kernel/init-mod.h @@ -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 */ diff --git a/kernel/initdisk.c b/kernel/initdisk.c index f054c3e..430db64 100644 --- a/kernel/initdisk.c +++ b/kernel/initdisk.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) diff --git a/kernel/int2f.asm b/kernel/int2f.asm index cc33659..c902524 100644 --- a/kernel/int2f.asm +++ b/kernel/int2f.asm @@ -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 diff --git a/kernel/inthndlr.c b/kernel/inthndlr.c index d33ab91..7015208 100644 --- a/kernel/inthndlr.c +++ b/kernel/inthndlr.c @@ -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; diff --git a/kernel/ioctl.c b/kernel/ioctl.c index 1a591a5..1a68c62 100644 --- a/kernel/ioctl.c +++ b/kernel/ioctl.c @@ -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; diff --git a/kernel/kernel.asm b/kernel/kernel.asm index 810bdde..f93babc 100644 --- a/kernel/kernel.asm +++ b/kernel/kernel.asm @@ -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 diff --git a/kernel/lfnapi.c b/kernel/lfnapi.c index ca8d25d..89a5fbd 100644 --- a/kernel/lfnapi.c +++ b/kernel/lfnapi.c @@ -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; diff --git a/kernel/main.c b/kernel/main.c index df6602f..0c50120 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -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 */ diff --git a/kernel/makefile b/kernel/makefile index 200103a..97cceea 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -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 diff --git a/kernel/memmgr.c b/kernel/memmgr.c index 05d5fe9..b8ff513 100644 --- a/kernel/memmgr.c +++ b/kernel/memmgr.c @@ -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; } diff --git a/kernel/newstuff.c b/kernel/newstuff.c index de926e2..325bc19 100644 --- a/kernel/newstuff.c +++ b/kernel/newstuff.c @@ -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; diff --git a/kernel/nls.c b/kernel/nls.c index 80ec641..0736abf 100644 --- a/kernel/nls.c +++ b/kernel/nls.c @@ -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"); } /* diff --git a/kernel/nlssupt.asm b/kernel/nlssupt.asm index 8fca40f..50e1df5 100644 --- a/kernel/nlssupt.asm +++ b/kernel/nlssupt.asm @@ -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 diff --git a/kernel/prf.c b/kernel/prf.c index 6bfa7b1..647f535 100644 --- a/kernel/prf.c +++ b/kernel/prf.c @@ -28,6 +28,8 @@ #include "portab.h" +#if defined(DEBUG) || defined(FORSYS) || defined(_INIT) + #ifdef FORSYS #include #include @@ -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 diff --git a/kernel/procsupt.asm b/kernel/procsupt.asm index 582b1b8..28d4d6b 100644 --- a/kernel/procsupt.asm +++ b/kernel/procsupt.asm @@ -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 diff --git a/kernel/proto.h b/kernel/proto.h index 3021b44..27f098d 100644 --- a/kernel/proto.h +++ b/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 */ diff --git a/kernel/systime.c b/kernel/systime.c index a73711b..ed2e716 100644 --- a/kernel/systime.c +++ b/kernel/systime.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); diff --git a/kernel/task.c b/kernel/task.c index 3fcc09b..ecc5dc8 100644 --- a/kernel/task.c +++ b/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)); diff --git a/mkfiles/bc5.mak b/mkfiles/bc5.mak index e2dc7f9..699dc47 100644 --- a/mkfiles/bc5.mak +++ b/mkfiles/bc5.mak @@ -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 diff --git a/mkfiles/mscl8.mak b/mkfiles/mscl8.mak index 328c1c1..35b21b6 100644 --- a/mkfiles/mscl8.mak +++ b/mkfiles/mscl8.mak @@ -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 diff --git a/mkfiles/watcom.mak b/mkfiles/watcom.mak index baa204a..64a83cb 100644 --- a/mkfiles/watcom.mak +++ b/mkfiles/watcom.mak @@ -4,7 +4,7 @@ # Use these for WATCOM 11.0c COMPILERPATH=$(WATCOM) -CC=wcc +CC=*wcc CL=wcl INCLUDEPATH=$(COMPILERPATH)\H INCLUDE=$(COMPILERPATH)\h diff --git a/sys/sys.c b/sys/sys.c index 9046ce0..352c423 100644 --- a/sys/sys.c +++ b/sys/sys.c @@ -36,7 +36,7 @@ #define DEBUG /* #define DDEBUG */ -#define SYS_VERSION "v2.4" +#define SYS_VERSION "v2.5" #include #include @@ -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)) {