Cleaned up task.c (merged much of DOSExe/ComLoader); transform the CDS into

a proper array.


git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@413 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2002-08-03 16:54:09 +00:00
parent 3b5e79890e
commit 511bf63d16
19 changed files with 462 additions and 555 deletions

View File

@ -1,10 +1,39 @@
2002 Aug xx - Build 2027 2002 Aug xx - Build 2027
-------- Bart Oldeman (bart@dosemu.org) -------- Bart Oldeman (bart@dosemu.org)
+ Changes Tom + Changes Tom
* enable LBA FAT16 booting
* workaround for redirectors that do/do not set the opencount
* int25/26 should fail for redirectors
* set the number of sectors per track in the INT 1E table when
reading/writing floppies
* disabled fatal() in error.c
* Disable the A20 line upon exec (int21/ah=4B). This is necessary for some
brain-dead exepacked programs.
* removed unnecessary buffer fields
* proper check for network/non-existing drive for int25/26.
* save more bytes on the stack at various places
+ Changes Bart + Changes Bart
* patchobj makefile correction * patchobj makefile correction
* printf uses va_list etc. * printf uses va_list etc.
* quicker and more robust Watcom build
* use FS: and GS: for Watcom 386.
* workaround: don't use DL for floppy boots, but fixed A:
* disable unused functions in floppy.asm
* cleaner prototypes (thanks to gcc)
* reorganized ioctl.c; there was an uninitialized variable.
* inlined some functions of fattab.c
* added (f)strcmp, (f)memcmp and (f)memchr to asmsupt.asm
* initially suggested by Arkady: dsk.c FS_info copy optimization
* initialize a VDISK signature in the HMA
* sysclk.c: small size optimization
* small UMB fixes
* made the CDS into a proper array instead of a structure with
one member
* large task.c cleanups -
merge as much as possible from DosExeLoader and DosComLoader
(from Tom:) eliminate some structures in low memory
* main.c: slightly cleanup "SHELL=" line parsing.
2002 May 9 - Build 2026b 2002 May 9 - Build 2026b
-------- Bart Oldeman (bart@dosemu.org) -------- Bart Oldeman (bart@dosemu.org)
+ Changes Tom + Changes Tom

View File

@ -72,7 +72,7 @@ fl_rst1: xor ax,ax ; FALSE on error
; 2 Drive present, can detect disk change ; 2 Drive present, can detect disk change
; 3 Fixed disk ; 3 Fixed disk
; ;
%if 0
global _fl_readdasd global _fl_readdasd
_fl_readdasd: _fl_readdasd:
push bp push bp
@ -93,7 +93,7 @@ fl_rdasd1: mov ah,0 ; BIOS reset disketter & fixed disk
mov ax,0FFh ; 0xFF on error mov ax,0FFh ; 0xFF on error
pop bp ; C exit pop bp ; C exit
ret ret
%endif
; ;
; ;
@ -138,7 +138,7 @@ fl_dc_error: mov ax,0FFh ; 0xFF on error
; ;
; See Phoenix Bios Book for error code meanings ; See Phoenix Bios Book for error code meanings
; ;
%if 0
global _fl_rd_status global _fl_rd_status
_fl_rd_status: _fl_rd_status:
push bp ; C entry push bp ; C entry
@ -153,7 +153,7 @@ _fl_rd_status:
pop bp ; C exit pop bp ; C exit
ret ret
%endif
; ;
; Format Sectors ; Format Sectors

View File

@ -37,20 +37,29 @@ static BYTE *Cds_hRcsId =
struct cds { struct cds {
BYTE cdsCurrentPath[MAX_CDSPATH]; BYTE cdsCurrentPath[MAX_CDSPATH];
UWORD cdsFlags; UWORD cdsFlags; /* see below */
struct dpb FAR *cdsDpb; struct dpb FAR *cdsDpb; /* if != 0, associated DPB */
union { union {
BYTE FAR *_cdsRedirRec; BYTE FAR *_cdsRedirRec; /* IFS record */
struct { struct {
UWORD _cdsStrtClst; UWORD _cdsStrtClst; /* if local path (Flags & CDSPHYSDRV):
start cluster of CWD; root == 0,
never access == 0xFFFF */
UWORD _cdsParam; UWORD _cdsParam;
} _cdsRedir; } _cdsRedir;
} _cdsUnion; } _cdsUnion;
UWORD cdsStoreUData; UWORD cdsStoreUData;
WORD cdsJoinOffset; #define cdsJoinOffset cdsBackslashOffset
WORD cdsBackslashOffset; /* Position of "root directory" backslash for
this drive within CurrentPath[]
prerequisites:
+ ofs <= strlen(currentPath)
+ if UNC: ofs > share component
if local path: ofs > colon
*/
BYTE cdsNetFlag1; BYTE cdsNetFlag1;
BYTE FAR *cdsIfs; BYTE FAR *cdsIfs;
@ -62,17 +71,29 @@ struct cds {
#define cdsRedirRec _cdsUnion._cdsRedirRec #define cdsRedirRec _cdsUnion._cdsRedirRec
#define cdsParam _cdsUnion._cdsRedir._cdsParam #define cdsParam _cdsUnion._cdsRedir._cdsParam
typedef struct _cdstbl { /* Bits for cdsFlags (OR combination) */
struct cds cds_table[26];
} cdstbl;
/* Bits for cdsFlags */
#define CDSNETWDRV 0x8000 #define CDSNETWDRV 0x8000
#define CDSPHYSDRV 0x4000 #define CDSPHYSDRV 0x4000
#define CDSJOINED 0x2000 #define CDSJOINED 0x2000 /* not in combination with NETWDRV or SUBST */
#define CDSSUBST 0x1000 #define CDSSUBST 0x1000 /* not in combination with NETWDRV or JOINED */
#define CDSVALID (CDSNETWDRV | CDSPHYSDRV) #define CDS_HIDDEN (1 << 7) /* hide drive from redirector's list */
/* NETWORK PHYSICAL meaning
0 0 drive not accessable
0 1 local file system
1 0 networked file system (UNC naming convention)
1 1 installable file system (IFS)
*/
#define CDSMODEMASK (CDSNETWDRV | CDSPHYSDRV)
/* #define CDSVALID (CDSNETWDRV | CDSPHYSDRV) */
#define CDSVALID CDSMODEMASK
#define IS_DEVICE 0x20
#define IS_NETWORK 0x40
#define CDS_MODE_SKIP_PHYSICAL 0x01 /* don't resolve SUBST, JOIN, NETW */
#define CDS_MODE_CHECK_DEV_PATH 0x02 /* check for existence of device path */
/* /*
* Log: cds.h,v * Log: cds.h,v
* Revision 1.2 2000/03/09 06:06:38 kernel * Revision 1.2 2000/03/09 06:06:38 kernel

View File

@ -47,8 +47,8 @@ static BYTE *date_hRcsId =
#define REVISION_MAJOR 1 #define REVISION_MAJOR 1
#define REVISION_MINOR 1 #define REVISION_MINOR 1
#define REVISION_SEQ 26 #define REVISION_SEQ 27
#define BUILD "2026" #define BUILD "2027"
#define SUB_BUILD "b" #define SUB_BUILD "test"
#define KERNEL_VERSION_STRING "1.1.26b" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ */ #define KERNEL_VERSION_STRING "1.1.27" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ */
#define KERNEL_BUILD_STRING "2026b" /*#BUILD SUB_BUILD */ #define KERNEL_BUILD_STRING "2027test" /*#BUILD SUB_BUILD */

View File

@ -76,7 +76,7 @@ STATIC VOID setblkno(struct buffer FAR * bp, ULONG blkno)
bp->b_blkno = blkno; bp->b_blkno = blkno;
/* bp->b_dpbp = &blk_devices[bp->b_unit]; */ /* bp->b_dpbp = &blk_devices[bp->b_unit]; */
bp->b_dpbp = CDSp->cds_table[bp->b_unit].cdsDpb; bp->b_dpbp = CDSp[bp->b_unit].cdsDpb;
} }
} }
@ -416,13 +416,13 @@ UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks,
{ {
/* REG struct dpb *dpbp = &blk_devices[dsk]; */ /* REG struct dpb *dpbp = &blk_devices[dsk]; */
REG struct dpb FAR *dpbp = CDSp->cds_table[dsk].cdsDpb; REG struct dpb FAR *dpbp = CDSp[dsk].cdsDpb;
if ((UCOUNT) dsk >= lastdrive) if ((UCOUNT) dsk >= lastdrive)
{ {
return 0x0201; /* illegal command */ return 0x0201; /* illegal command */
} }
if ((CDSp->cds_table[dsk].cdsFlags & (CDSPHYSDRV | CDSNETWDRV)) != CDSPHYSDRV) if ((CDSp[dsk].cdsFlags & (CDSPHYSDRV | CDSNETWDRV)) != CDSPHYSDRV)
{ {
return 0x0201; /* illegal command */ return 0x0201; /* illegal command */
} }

View File

@ -107,8 +107,8 @@ struct dpb FAR * GetDriveDPB(UBYTE drive, COUNT * rc)
return 0; return 0;
} }
dpb = CDSp->cds_table[drive].cdsDpb; dpb = CDSp[drive].cdsDpb;
if (dpb == 0 || CDSp->cds_table[drive].cdsFlags & CDSNETWDRV) if (dpb == 0 || CDSp[drive].cdsFlags & CDSNETWDRV)
{ {
*rc = DE_INVLDDRV; *rc = DE_INVLDDRV;
return 0; return 0;
@ -1020,7 +1020,7 @@ BOOL DosGetFree(UBYTE drive, UCOUNT FAR * spc, UCOUNT FAR * navc,
if (drive >= lastdrive) if (drive >= lastdrive)
return FALSE; return FALSE;
cdsp = &CDSp->cds_table[drive]; cdsp = &CDSp[drive];
if (!(cdsp->cdsFlags & CDSVALID)) if (!(cdsp->cdsFlags & CDSVALID))
return FALSE; return FALSE;
@ -1050,7 +1050,7 @@ BOOL DosGetFree(UBYTE drive, UCOUNT FAR * spc, UCOUNT FAR * navc,
return TRUE; return TRUE;
} }
dpbp = CDSp->cds_table[drive].cdsDpb; dpbp = CDSp[drive].cdsDpb;
if (dpbp == NULL) if (dpbp == NULL)
return FALSE; return FALSE;
@ -1127,7 +1127,7 @@ COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp)
if (drive >= lastdrive) if (drive >= lastdrive)
return DE_INVLDDRV; return DE_INVLDDRV;
cdsp = &CDSp->cds_table[drive]; cdsp = &CDSp[drive];
if (!(cdsp->cdsFlags & CDSVALID)) if (!(cdsp->cdsFlags & CDSVALID))
return DE_INVLDDRV; return DE_INVLDDRV;
@ -1143,7 +1143,7 @@ COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp)
} }
else else
{ {
dpbp = CDSp->cds_table[drive].cdsDpb; dpbp = CDSp[drive].cdsDpb;
if (dpbp == NULL || media_check(dpbp) < 0) if (dpbp == NULL || media_check(dpbp) < 0)
return DE_INVLDDRV; return DE_INVLDDRV;
xfsp->xfs_secsize = dpbp->dpb_secsize; xfsp->xfs_secsize = dpbp->dpb_secsize;
@ -1172,12 +1172,12 @@ COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s)
drive = (drive == 0 ? default_drive : drive - 1); drive = (drive == 0 ? default_drive : drive - 1);
/* first check for valid drive */ /* first check for valid drive */
if (drive >= lastdrive || !(CDSp->cds_table[drive].cdsFlags & CDSVALID)) if (drive >= lastdrive || !(CDSp[drive].cdsFlags & CDSVALID))
{ {
return DE_INVLDDRV; return DE_INVLDDRV;
} }
current_ldt = &CDSp->cds_table[drive]; current_ldt = &CDSp[drive];
/* ensure termination of fstrcpy */ /* ensure termination of fstrcpy */
cp[MAX_CDSPATH - 1] = '\0'; cp[MAX_CDSPATH - 1] = '\0';
@ -1223,7 +1223,7 @@ COUNT DosChangeDir(BYTE FAR * s)
return result; return result;
} }
current_ldt = &CDSp->cds_table[drive]; current_ldt = &CDSp[drive];
if (strlen(PriPathName) > sizeof(current_ldt->cdsCurrentPath) - 1) if (strlen(PriPathName) > sizeof(current_ldt->cdsCurrentPath) - 1)
return DE_PATHNOTFND; return DE_PATHNOTFND;
@ -1364,7 +1364,7 @@ COUNT DosFindNext(void)
fmemset(dta, 0, sizeof(dmatch)); fmemset(dta, 0, sizeof(dmatch));
p = dta; p = dta;
dta = (BYTE FAR *) TempBuffer; dta = (BYTE FAR *) TempBuffer;
current_ldt = &CDSp->cds_table[((dmatch *) TempBuffer)->dm_drive]; current_ldt = &CDSp[((dmatch *) TempBuffer)->dm_drive];
rc = (((dmatch *) TempBuffer)->dm_drive & 0x80) ? rc = (((dmatch *) TempBuffer)->dm_drive & 0x80) ?
remote_findnext((VOID FAR *) current_ldt) : dos_findnext(); remote_findnext((VOID FAR *) current_ldt) : dos_findnext();
@ -1457,7 +1457,7 @@ COUNT DosGetFattr(BYTE FAR * name)
return 0x10; return 0x10;
} }
current_ldt = &CDSp->cds_table[drive]; current_ldt = &CDSp[drive];
if (current_ldt->cdsFlags & CDSNETWDRV) if (current_ldt->cdsFlags & CDSNETWDRV)
{ {
return remote_getfattr(); return remote_getfattr();
@ -1518,7 +1518,7 @@ COUNT DosSetFattr(BYTE FAR * name, UWORD attrp)
return result; return result;
} }
current_ldt = &CDSp->cds_table[drive]; current_ldt = &CDSp[drive];
if (current_ldt->cdsFlags & CDSNETWDRV) if (current_ldt->cdsFlags & CDSNETWDRV)
{ {
return remote_setfattr(attrp); return remote_setfattr(attrp);
@ -1543,7 +1543,7 @@ COUNT DosSetFattr(BYTE FAR * name, UWORD attrp)
UBYTE DosSelectDrv(UBYTE drv) UBYTE DosSelectDrv(UBYTE drv)
{ {
current_ldt = &CDSp->cds_table[drv]; current_ldt = &CDSp[drv];
if ((drv < lastdrive) && (current_ldt->cdsFlags & CDSVALID)) if ((drv < lastdrive) && (current_ldt->cdsFlags & CDSVALID))
/* /*
@ -1575,7 +1575,7 @@ COUNT DosDelete(BYTE FAR * path, int attrib)
{ {
return result; return result;
} }
current_ldt = &CDSp->cds_table[drive]; current_ldt = &CDSp[drive];
if (current_ldt->cdsFlags & CDSNETWDRV) if (current_ldt->cdsFlags & CDSNETWDRV)
{ {
return remote_delete(); return remote_delete();
@ -1601,7 +1601,7 @@ COUNT DosRenameTrue(BYTE * path1, BYTE * path2, int attrib)
{ {
return DE_INVLDDRV; return DE_INVLDDRV;
} }
current_ldt = &CDSp->cds_table[drive1]; current_ldt = &CDSp[drive1];
if (current_ldt->cdsFlags & CDSNETWDRV) if (current_ldt->cdsFlags & CDSNETWDRV)
{ {
return remote_rename(); return remote_rename();
@ -1650,7 +1650,7 @@ COUNT DosMkdir(BYTE FAR * dir)
{ {
return result; return result;
} }
current_ldt = &CDSp->cds_table[drive]; current_ldt = &CDSp[drive];
if (current_ldt->cdsFlags & CDSNETWDRV) if (current_ldt->cdsFlags & CDSNETWDRV)
{ {
return remote_mkdir(); return remote_mkdir();
@ -1680,8 +1680,8 @@ COUNT DosRmdir(BYTE FAR * dir)
{ {
return result; return result;
} }
current_ldt = &CDSp->cds_table[drive]; current_ldt = &CDSp[drive];
if (CDSp->cds_table[drive].cdsFlags & CDSNETWDRV) if (CDSp[drive].cdsFlags & CDSNETWDRV)
{ {
return remote_rmdir(); return remote_rmdir();
} }

View File

@ -113,7 +113,7 @@ f_node_ptr dir_open(BYTE * dirname)
return NULL; return NULL;
} }
cdsp = &CDSp->cds_table[drive]; cdsp = &CDSp[drive];
/* Generate full path name */ /* Generate full path name */
/* not necessary anymore, since truename did that already /* not necessary anymore, since truename did that already
@ -576,7 +576,7 @@ COUNT dos_findnext(void)
/* Select the default to help non-drive specified path */ /* Select the default to help non-drive specified path */
/* searches... */ /* searches... */
fnp->f_dpb = CDSp->cds_table[dmp->dm_drive].cdsDpb; fnp->f_dpb = CDSp[dmp->dm_drive].cdsDpb;
if (media_check(fnp->f_dpb) < 0) if (media_check(fnp->f_dpb) < 0)
{ {
release_f_node(fnp); release_f_node(fnp);

View File

@ -227,7 +227,7 @@ f_node_ptr split_path(BYTE * path, BYTE * fname, BYTE * fext)
{ {
return (f_node_ptr) 0; return (f_node_ptr) 0;
} }
cdsp = &CDSp->cds_table[nDrive]; cdsp = &CDSp[nDrive];
/* 11/29/99 jt /* 11/29/99 jt
* Networking and Cdroms. You can put in here a return. * Networking and Cdroms. You can put in here a return.
@ -2187,7 +2187,7 @@ COUNT media_check(REG struct dpb FAR * dpbp)
#endif #endif
/* need to change to root directory if changed */ /* need to change to root directory if changed */
if (status == M_CHANGED) if (status == M_CHANGED)
CDSp->cds_table[dpbp->dpb_unit].cdsCurrentPath[3] = '\0'; CDSp[dpbp->dpb_unit].cdsCurrentPath[3] = '\0';
return SUCCESS; return SUCCESS;
} }
} }
@ -2210,7 +2210,7 @@ struct dhdr FAR *select_unit(COUNT drive)
/* Just get the header from the dhdr array */ /* Just get the header from the dhdr array */
/* return blk_devices[drive].dpb_device; */ /* return blk_devices[drive].dpb_device; */
return (struct dhdr FAR *)CDSp->cds_table[drive].cdsDpb; return (struct dhdr FAR *)CDSp[drive].cdsDpb;
} }
#endif #endif

View File

@ -261,7 +261,7 @@ CLUSTER next_cluster(struct dpb FAR * dpbp, CLUSTER ClusterNum)
bp = getFATblock(ClusterNum, dpbp); bp = getFATblock(ClusterNum, dpbp);
if (bp == NULL) if (bp == NULL)
return DE_BLKINVLD; return 1; /* the only error code possible here */
if (ISFAT12(dpbp)) if (ISFAT12(dpbp))
{ {

View File

@ -70,7 +70,7 @@ VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps,
if (DosGetFree((UBYTE) drive, spc, &navc, bps, nc)) if (DosGetFree((UBYTE) drive, spc, &navc, bps, nc))
{ {
struct cds FAR *cdsp = struct cds FAR *cdsp =
&CDSp->cds_table[(drive == 0 ? default_drive : drive - 1)]; &CDSp[(drive == 0 ? default_drive : drive - 1)];
/* Point to the media desctriptor for this drive */ /* Point to the media desctriptor for this drive */
if (cdsp->cdsFlags & CDSNETWDRV) if (cdsp->cdsFlags & CDSNETWDRV)
{ {

View File

@ -267,7 +267,7 @@ FAR * ASM clock, /* CLOCK$ device */
extern WORD ASM maxbksize; /* Number of Drives in system */ extern WORD ASM maxbksize; /* Number of Drives in system */
extern struct buffer extern struct buffer
FAR *ASM firstbuf; /* head of buffers linked list */ FAR *ASM firstbuf; /* head of buffers linked list */
extern cdstbl FAR * ASM CDSp; /* Current Directory Structure */ extern struct cds FAR * ASM CDSp; /* Current Directory Structure */
extern extern
struct cds FAR * ASM current_ldt; struct cds FAR * ASM current_ldt;
extern LONG ASM current_filepos; /* current file position */ extern LONG ASM current_filepos; /* current file position */

View File

@ -655,8 +655,8 @@ dispatch:
break; break;
} }
dpb = CDSp->cds_table[drv].cdsDpb; dpb = CDSp[drv].cdsDpb;
if (dpb == 0 || CDSp->cds_table[drv].cdsFlags & CDSNETWDRV) if (dpb == 0 || CDSp[drv].cdsFlags & CDSNETWDRV)
{ {
r->AL = 0xFF; r->AL = 0xFF;
CritErrCode = 0x0f; CritErrCode = 0x0f;
@ -1264,14 +1264,14 @@ dispatch:
case 0x07: case 0x07:
if (r->DL < lastdrive) if (r->DL < lastdrive)
{ {
CDSp->cds_table[r->DL].cdsFlags |= 0x100; CDSp[r->DL].cdsFlags |= 0x100;
} }
break; break;
case 0x08: case 0x08:
if (r->DL < lastdrive) if (r->DL < lastdrive)
{ {
CDSp->cds_table[r->DL].cdsFlags &= ~0x100; CDSp[r->DL].cdsFlags &= ~0x100;
} }
break; break;
@ -1432,7 +1432,7 @@ dispatch:
if (rc < lastdrive) if (rc < lastdrive)
{ {
UWORD saveCX = r->CX; UWORD saveCX = r->CX;
if (CDSp->cds_table[rc].cdsFlags & CDSNETWDRV) if (CDSp[rc].cdsFlags & CDSNETWDRV)
{ {
goto error_invalid; goto error_invalid;
} }
@ -1842,8 +1842,8 @@ VOID ASMCFUNC int2526_handler(WORD mode, struct int25regs FAR * r)
} }
#ifdef WITHFAT32 #ifdef WITHFAT32
if (!(CDSp->cds_table[drv].cdsFlags & CDSNETWDRV) && if (!(CDSp[drv].cdsFlags & CDSNETWDRV) &&
ISFAT32(CDSp->cds_table[drv].cdsDpb)) ISFAT32(CDSp[drv].cdsDpb))
{ {
r->ax = 0x207; r->ax = 0x207;
r->flags |= FLG_CARRY; r->flags |= FLG_CARRY;
@ -2017,7 +2017,7 @@ VOID ASMCFUNC int2F_12_handler(volatile struct int2f12regs r)
else else
{ {
r.ds = FP_SEG(CDSp); r.ds = FP_SEG(CDSp);
r.si = FP_OFF(&CDSp->cds_table[drv]); r.si = FP_OFF(&CDSp[drv]);
r.flags &= ~FLG_CARRY; r.flags &= ~FLG_CARRY;
} }
break; break;

View File

@ -110,8 +110,8 @@ COUNT DosDevIOctl(iregs FAR * r)
return DE_INVLDDRV; return DE_INVLDDRV;
else else
{ {
/* cdsp = &CDSp->cds_table[CharReqHdr.r_unit]; */ /* cdsp = &CDSp[CharReqHdr.r_unit]; */
dpbp = CDSp->cds_table[CharReqHdr.r_unit].cdsDpb; dpbp = CDSp[CharReqHdr.r_unit].cdsDpb;
} }
break; break;
@ -278,7 +278,7 @@ COUNT DosDevIOctl(iregs FAR * r)
return DE_INVLDFUNC; return DE_INVLDFUNC;
case 0x09: case 0x09:
if (CDSp->cds_table[CharReqHdr.r_unit].cdsFlags & CDSNETWDRV) if (CDSp[CharReqHdr.r_unit].cdsFlags & CDSNETWDRV)
{ {
r->DX = ATTR_REMOTE; r->DX = ATTR_REMOTE;
r->AX = S_DONE | S_BUSY; r->AX = S_DONE | S_BUSY;

View File

@ -64,7 +64,7 @@ COUNT lfn_allocate_inode(VOID)
} }
/* Check that default drive is a block device */ /* Check that default drive is a block device */
cdsp = &CDSp->cds_table[default_drive]; cdsp = &CDSp[default_drive];
if (cdsp->cdsDpb == 0) if (cdsp->cdsDpb == 0)
{ {

View File

@ -32,7 +32,7 @@
#include "dyndata.h" #include "dyndata.h"
#include "init-dat.h" #include "init-dat.h"
GLOBAL BYTE copyright[] = char copyright[] =
"(C) Copyright 1995-2002 Pasquale J. Villani and The FreeDOS Project.\n" "(C) Copyright 1995-2002 Pasquale J. Villani and The FreeDOS Project.\n"
"All Rights Reserved. This is free software and comes with ABSOLUTELY NO\n" "All Rights Reserved. This is free software and comes with ABSOLUTELY NO\n"
"WARRANTY; you can redistribute it and/or modify it under the terms of the\n" "WARRANTY; you can redistribute it and/or modify it under the terms of the\n"
@ -58,7 +58,7 @@ GLOBAL BYTE DOSFAR os_release[];
GLOBAL seg DOSFAR RootPsp; /* Root process -- do not abort */ GLOBAL seg DOSFAR RootPsp; /* Root process -- do not abort */
extern struct dpb FAR *DOSFAR ASM DPBp; /* First drive Parameter Block */ extern struct dpb FAR *DOSFAR ASM DPBp; /* First drive Parameter Block */
extern cdstbl FAR *DOSFAR ASM CDSp; /* Current Directory Structure */ extern struct cds FAR *DOSFAR ASM CDSp; /* Current Directory Structure */
extern struct dhdr FAR *DOSFAR ASM clock, /* CLOCK$ device */ extern struct dhdr FAR *DOSFAR ASM clock, /* CLOCK$ device */
FAR * DOSFAR ASM syscon; /* console device */ FAR * DOSFAR ASM syscon; /* console device */
@ -169,7 +169,7 @@ VOID ASMCFUNC FreeDOSmain(void)
setvec(0, int0_handler); /* zero divide */ setvec(0, int0_handler); /* zero divide */
setvec(1, empty_handler); /* single step */ setvec(1, empty_handler); /* single step */
setvec(3, empty_handler); /* debug breakpoint */ setvec(3, empty_handler); /* debug breakpoint */
setvec(6, empty_handler); /* invalid opcode */ setvec(6, int6_handler); /* invalid opcode */
/* clear the Init BSS area (what normally the RTL does */ /* clear the Init BSS area (what normally the RTL does */
memset(_ib_start, 0, _ib_end - _ib_start); memset(_ib_start, 0, _ib_end - _ib_start);
@ -315,7 +315,7 @@ STATIC VOID FsConfig(VOID)
/* Initialize the current directory structures */ /* Initialize the current directory structures */
for (i = 0; i < lastdrive; i++) for (i = 0; i < lastdrive; i++)
{ {
struct cds FAR *pcds_table = &CDSp->cds_table[i]; struct cds FAR *pcds_table = &CDSp[i];
fmemcpy(pcds_table->cdsCurrentPath, "A:\\\0", 4); fmemcpy(pcds_table->cdsCurrentPath, "A:\\\0", 4);
@ -371,6 +371,8 @@ STATIC VOID signon()
printf(" - MSC"); printf(" - MSC");
#elif defined(__WATCOMC__) #elif defined(__WATCOMC__)
printf(" - WATCOMC"); printf(" - WATCOMC");
#elif defined(__GNUC__)
printf(" - GNUC"); /* this is hypothetical only */
#else #else
generate some bullshit error here, as the compiler should be known generate some bullshit error here, as the compiler should be known
#endif #endif
@ -443,20 +445,19 @@ STATIC void kernel()
{ {
/* insert /D, /Y as first argument */ /* insert /D, /Y as first argument */
int cmdEnd, i, slen = 3; /* strlen(insertString); */ char *p, *q;
for (cmdEnd = 0; cmdEnd < sizeof(Cmd.ctBuffer); cmdEnd++) for (p = Cmd.ctBuffer; p < &Cmd.ctBuffer[Cmd.ctCount]; p++)
{ {
if (Cmd.ctBuffer[cmdEnd] == ' ' || if (*p == ' ' || *p == '\t' || *p == '\r')
Cmd.ctBuffer[cmdEnd] == '\t' || Cmd.ctBuffer[cmdEnd] == '\r')
{ {
for (i = sizeof(Cmd.ctBuffer) - slen - 1; i >= cmdEnd; i--) for (q = &Cmd.ctBuffer[Cmd.ctCount - 1]; q >= p; q--)
Cmd.ctBuffer[i + slen] = Cmd.ctBuffer[i]; q[3] = q[0];
fmemcpy(&Cmd.ctBuffer[cmdEnd], insertString, slen); fmemcpy(p, insertString, 3);
Cmd.ctCount += slen;
Cmd.ctCount += 3;
printf("%d %s\n", Cmd.ctCount, Cmd.ctBuffer);
break; break;
} }
} }
@ -529,8 +530,8 @@ STATIC VOID update_dcb(struct dhdr FAR * dhp)
dpb->dpb_flags = M_CHANGED; dpb->dpb_flags = M_CHANGED;
if ((CDSp != 0) && (nblkdev < lastdrive)) if ((CDSp != 0) && (nblkdev < lastdrive))
{ {
CDSp->cds_table[nblkdev].cdsDpb = dpb; CDSp[nblkdev].cdsDpb = dpb;
CDSp->cds_table[nblkdev].cdsFlags = CDSPHYSDRV; CDSp[nblkdev].cdsFlags = CDSPHYSDRV;
} }
++dpb; ++dpb;
++nblkdev; ++nblkdev;

View File

@ -34,10 +34,6 @@ static BYTE *memmgrRcsId =
"$Id$"; "$Id$";
#endif #endif
VOID mcb_init();
VOID mcb_print();
VOID show_chain();
/*#define nxtMCBsize(mcb,size) \ /*#define nxtMCBsize(mcb,size) \
MK_FP(far2para((VOID FAR *) (mcb)) + (size) + 1, 0) */ MK_FP(far2para((VOID FAR *) (mcb)) + (size) + 1, 0) */
@ -102,6 +98,11 @@ VOID FAR * add_far(VOID FAR * fp, ULONG off)
if (FP_SEG(fp) == 0xffff) if (FP_SEG(fp) == 0xffff)
return ((BYTE FAR *) fp) + FP_OFF(off); return ((BYTE FAR *) fp) + FP_OFF(off);
#ifndef I86
if (FP_SEG(fp) == 0)
return ((BYTE FAR *) fp) + FP_OFF(off);
#endif
off += FP_OFF(fp); off += FP_OFF(fp);
off2 = ((off >> 16) << 12) + ((UWORD) off >> 4); off2 = ((off >> 16) << 12) + ((UWORD) off >> 4);
@ -111,13 +112,18 @@ VOID FAR * add_far(VOID FAR * fp, ULONG off)
/* /*
* Return a normalized far pointer * Return a normalized far pointer
*/ */
VOID FAR * adjust_far(VOID FAR * fp) void FAR * adjust_far(const void FAR * fp)
{ {
/* and return an adddress adjusted to the nearest paragraph */ /* and return an adddress adjusted to the nearest paragraph */
/* boundary. */ /* boundary. */
if (FP_SEG(fp) == 0xffff) if (FP_SEG(fp) == 0xffff)
return fp; return (void FAR *)fp;
#ifndef I86
if (FP_SEG(fp) == 0)
return (void FAR *)fp;
#endif
return MK_FP(FP_SEG(fp) + (FP_OFF(fp) >> 4), FP_OFF(fp) & 0xf); return MK_FP(FP_SEG(fp) + (FP_OFF(fp) >> 4), FP_OFF(fp) & 0xf);
} }
@ -151,9 +157,13 @@ searchAgain:
/* /*
Hack to the Umb Region direct for now. Save time and program space. Hack to the Umb Region direct for now. Save time and program space.
*/ */
if ((mode != LARGEST) && (mode & (FIRST_FIT_UO | FIRST_FIT_U)) && if (uppermem_link && uppermem_root != 0xffff)
uppermem_link && uppermem_root != 0xffff) {
p = para2far(uppermem_root); COUNT tmpmode = (mode == LARGEST ? mem_access_mode : mode);
if ((mode != LARGEST || size == 0xffff) &&
(tmpmode & (FIRST_FIT_UO | FIRST_FIT_U)))
p = para2far(uppermem_root);
}
/* Search through memory blocks */ /* Search through memory blocks */
FOREVER FOREVER
@ -290,42 +300,6 @@ COUNT DosMemLargest(UWORD FAR * size)
*size = 0; *size = 0;
DosMemAlloc(0xffff, LARGEST, &dummy, size); DosMemAlloc(0xffff, LARGEST, &dummy, size);
return *size ? SUCCESS : DE_NOMEM; return *size ? SUCCESS : DE_NOMEM;
#if 0
REG mcb FAR *p;
/* Initialize */
p = ((mem_access_mode & (FIRST_FIT_UO | FIRST_FIT_U)) && uppermem_link
&& uppermem_root != 0xffff) ? para2far(uppermem_root) : para2far(first_mcb);
/* Cycle through the whole MCB chain to find the largest unused
area. Join all unused areas together. */
*size = 0; /* nothing found */
FOREVER
{
if (!mcbValid(p)) /* corrupted MCB chain */
return DE_MCBDESTRY;
if (mcbFree(p))
{ /* test if this is the largest block */
/* first join this unused block with all following unused
blocks */
if (joinMCBs(p) != SUCCESS)
return DE_MCBDESTRY;
/* Now test */
if (*size < p->m_size)
*size = p->m_size;
}
if (p->m_type == MCB_LAST) /* that was last one in chain */
break;
p = nxtMCB(p);
}
/* If *size is still zero, aka nothing had changed, either no unused
block was found at all or a zero-length block only.
Both is considered as a failure */
#endif
} }
/* /*

View File

@ -128,7 +128,7 @@ COUNT get_verify_drive(char FAR * src)
drive = ((src[0] - 1) | 0x20) - ('a' - 1); drive = ((src[0] - 1) | 0x20) - ('a' - 1);
else else
return default_drive; return default_drive;
if (drive < lastdrive && CDSp->cds_table[drive].cdsFlags & CDSVALID) if (drive < lastdrive && CDSp[drive].cdsFlags & CDSVALID)
return drive; return drive;
else else
return DE_INVLDDRV; return DE_INVLDDRV;
@ -246,7 +246,7 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
while ((src[0] == '.') && (src[1] == '\\')) while ((src[0] == '.') && (src[1] == '\\'))
src += 2; src += 2;
current_ldt = &CDSp->cds_table[i]; current_ldt = &CDSp[i];
/* Always give the redirector a chance to rewrite the filename */ /* Always give the redirector a chance to rewrite the filename */
fmemcpy(bufp - 1, src, sizeof(buf) - (bufp - buf)); fmemcpy(bufp - 1, src, sizeof(buf) - (bufp - buf));

View File

@ -228,7 +228,7 @@ COUNT DosDevIOctl(iregs FAR * r);
seg far2para(VOID FAR * p); seg far2para(VOID FAR * p);
seg long2para(ULONG size); seg long2para(ULONG size);
VOID FAR *add_far(VOID FAR * fp, ULONG off); VOID FAR *add_far(VOID FAR * fp, ULONG off);
VOID FAR *adjust_far(VOID FAR * fp); void FAR *adjust_far(const void FAR * fp);
COUNT DosMemAlloc(UWORD size, COUNT mode, seg FAR * para, COUNT DosMemAlloc(UWORD size, COUNT mode, seg FAR * para,
UWORD FAR * asize); UWORD FAR * asize);
COUNT DosMemLargest(UWORD FAR * size); COUNT DosMemLargest(UWORD FAR * size);
@ -328,12 +328,10 @@ const UWORD *is_leap_year_monthdays(UWORD year);
UWORD DaysFromYearMonthDay(UWORD Year, UWORD Month, UWORD DayOfMonth); UWORD DaysFromYearMonthDay(UWORD Year, UWORD Month, UWORD DayOfMonth);
/* task.c */ /* task.c */
COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg,
char far * pathname);
VOID new_psp(psp FAR * p, int psize); VOID new_psp(psp FAR * p, int psize);
VOID return_user(void); VOID return_user(void);
COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp); COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp);
LONG DosGetFsize(COUNT hndl); ULONG DosGetFsize(COUNT hndl);
VOID InitPSP(VOID); VOID InitPSP(VOID);
/* newstuff.c */ /* newstuff.c */

View File

@ -42,7 +42,12 @@ static BYTE *RcsId =
#define LOAD_HIGH 0x80 #define LOAD_HIGH 0x80
static exe_header header; /* static exe_header ExeHeader;
to save some bytes, both static and on stack,
we recycle SecPathBuffer TE */
#define ExeHeader (*(exe_header *)(SecPathName + 0))
#define TempExeBlock (*(exec_blk *)(SecPathName + sizeof(exe_header)))
#define CHUNK 32256 #define CHUNK 32256
#define MAXENV 32768u #define MAXENV 32768u
@ -53,20 +58,7 @@ static exe_header header;
+ 1 byte: '\0' + 1 byte: '\0'
-- 1999/04/21 ska */ -- 1999/04/21 ska */
#ifndef PROTO ULONG DosGetFsize(COUNT hndl)
COUNT ChildEnv(exec_blk FAR *, UWORD *, char far *);
#else
COUNT ChildEnv();
#endif
LONG doslseek(COUNT fd, LONG foffset, COUNT origin)
{
LONG set_pos;
DosSeek(fd, foffset, origin, (ULONG *) & set_pos);
return set_pos;
}
LONG DosGetFsize(COUNT hndl)
{ {
sft FAR *s; sft FAR *s;
/* sfttbl FAR *sp;*/ /* sfttbl FAR *sp;*/
@ -89,8 +81,7 @@ LONG DosGetFsize(COUNT hndl)
return dos_getfsize(s->sft_status); return dos_getfsize(s->sft_status);
} }
COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg, STATIC COUNT ChildEnv(exec_blk * exp, UWORD * pChildEnvSeg, char far * pathname)
char far * pathname)
{ {
BYTE FAR *pSrc; BYTE FAR *pSrc;
BYTE FAR *pDest; BYTE FAR *pDest;
@ -157,10 +148,11 @@ COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg,
pDest += sizeof(UWORD) / sizeof(BYTE); pDest += sizeof(UWORD) / sizeof(BYTE);
/* copy complete pathname */ /* copy complete pathname */
if ((RetCode = truename(pathname, pDest, TRUE)) != SUCCESS) if ((RetCode = truename(pathname, PriPathName, CDS_MODE_SKIP_PHYSICAL)) < SUCCESS)
{ {
return RetCode; return RetCode;
} }
fstrcpy(pDest, PriPathName);
/* Theoretically one could either: /* Theoretically one could either:
+ resize the already allocated block to best-fit behind the pathname, or + resize the already allocated block to best-fit behind the pathname, or
@ -309,194 +301,209 @@ set_name:
/* return value: AX value to be passed based on FCB values */ /* return value: AX value to be passed based on FCB values */
return ((psp->ps_fcb1.fcb_drive < lastdrive && return ((psp->ps_fcb1.fcb_drive < lastdrive &&
CDSp->cds_table[psp->ps_fcb1.fcb_drive]. CDSp[psp->ps_fcb1.fcb_drive].cdsFlags & CDSVALID) ? 0 : 0xff) +
cdsFlags & CDSVALID) ? 0 : 0xff) + ((psp->ps_fcb2.fcb_drive < ((psp->ps_fcb2.fcb_drive < lastdrive &&
lastdrive CDSp[psp->ps_fcb2.fcb_drive].cdsFlags & CDSVALID) ? 0 : 0xff) * 0x100;
&& CDSp->cds_table[psp->
ps_fcb2.
fcb_drive].
cdsFlags & CDSVALID) ? 0 :
0xff) * 0x100;
} }
COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) int load_transfer(UWORD ds, exec_blk *exp, UWORD fcbcode, COUNT mode)
{ {
COUNT rc psp FAR *p = MK_FP(ds, 0);
/* err */
/*,env_size */ ;
COUNT nread;
UWORD mem;
UWORD env, asize;
BYTE FAR *sp;
psp FAR *p;
psp FAR *q = MK_FP(cu_psp, 0); psp FAR *q = MK_FP(cu_psp, 0);
iregs FAR *irp;
LONG com_size; /* Transfer control to the executable */
p->ps_parent = cu_psp;
int ModeLoadHigh = mode & 0x80; p->ps_prevpsp = q;
UBYTE UMBstate = uppermem_link; q->ps_stack = (BYTE FAR *)user_r;
user_r->FLAGS &= ~FLG_CARRY;
mode &= 0x7f;
cu_psp = ds;
if (mode != OVERLAY) dta = p->ps_dta;
if (mode == LOADNGO)
{ {
iregs FAR *irp;
/* build the user area on the stack */
irp = (iregs FAR *)(exp->exec.stack - sizeof(iregs));
/* start allocating REGs */
irp->ES = irp->DS = ds;
irp->CS = FP_SEG(exp->exec.start_addr);
irp->IP = FP_OFF(exp->exec.start_addr);
irp->AX = fcbcode;
irp->BX = irp->CX = irp->DX = irp->SI = irp->DI = irp->BP = 0;
irp->FLAGS = 0x200;
if (InDOS)
--InDOS;
exec_user(irp);
/* We should never be here
fatal("KERNEL RETURNED!!!"); */
}
/* mode == LOAD */
return SUCCESS;
}
if ((rc = ChildEnv(exp, &env, namep)) != SUCCESS) /* Now find out how many paragraphs are available
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))
{
mem_access_mode &= ~0x80;
rc = DosMemLargest(asize);
mem_access_mode |= 0x80;
}
return (*asize < threshold ? DE_NOMEM : rc);
}
STATIC int ExecMemAlloc(UWORD size, seg *para, UWORD *asize)
{
/* We can still get an error on first fit if the above */
/* returned size was a best fit case */
/* ModeLoadHigh = 80 = try high, then low */
int rc = DosMemAlloc(size, mem_access_mode, para, asize);
if (rc != SUCCESS)
{
if (rc == DE_NOMEM)
{ {
return rc; rc = DosMemAlloc(0, LARGEST, para, asize);
} if ((mem_access_mode & 0x80) && (rc != SUCCESS))
/* COMFILES will always be loaded in largest area. is that true TE */
/* Now find out how many paragraphs are available */
if ((rc = DosMemLargest((seg FAR *) & asize)) != SUCCESS)
{
DosMemFree(env);
return rc;
}
com_size = asize;
if (ModeLoadHigh)
{
DosUmbLink(1); /* link in UMB's */
}
/* Allocate our memory and pass back any errors */
if ((rc =
DosMemAlloc((seg) com_size, mem_access_mode, (seg FAR *) & mem,
(UWORD FAR *) & asize)) < 0)
{
if (rc == DE_NOMEM)
{ {
if ((rc = mem_access_mode &= ~0x80;
DosMemAlloc(0, LARGEST, (seg FAR *) & mem, rc = DosMemAlloc(0, LARGEST, para, asize);
(UWORD FAR *) & asize)) < 0) mem_access_mode |= 0x80;
{
DosMemFree(env);
return rc;
}
/* This should never happen, but ... */
if (asize < com_size)
{
DosMemFree(mem);
DosMemFree(env);
return rc;
}
}
else
{
DosMemFree(env); /* env may be 0 */
return rc;
} }
} }
++mem;
} }
else else
mem = exp->load.load_seg;
if (ModeLoadHigh)
{ {
DosUmbLink(UMBstate); /* restore link state */ /* with no error, we got exactly what we asked for */
*asize = size;
}
/* This should never happen, but ... */
if (rc == SUCCESS && *asize < size)
{
DosMemFree(*para);
return DE_NOMEM;
}
return rc;
}
COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
{
UWORD mem;
UWORD env, asize = 0;
{
UWORD com_size;
{
ULONG com_size_long = DosGetFsize(fd);
/* maximally 64k - 256 bytes stack -
256 bytes psp */
com_size = (min(com_size_long, 0xfe00u) >> 4) + 0x10;
}
if ((mode & 0x7f) != OVERLAY)
{
COUNT rc;
UBYTE UMBstate = uppermem_link;
UBYTE orig_mem_access = mem_access_mode;
if (mode & 0x80)
{
mem_access_mode |= 0x80;
DosUmbLink(1); /* link in UMB's */
}
rc = ChildEnv(exp, &env, namep);
/* COMFILES will always be loaded in largest area. is that true TE */
/* yes, see RBIL, int21/ah=48 -- Bart */
if (rc == SUCCESS)
rc = ExecMemLargest(&asize, com_size);
if (rc == SUCCESS)
/* Allocate our memory and pass back any errors */
rc = ExecMemAlloc(asize, &mem, &asize);
if (rc != SUCCESS)
DosMemFree(env);
if (mode & 0x80)
{
DosUmbLink(UMBstate); /* restore link state */
mem_access_mode = orig_mem_access;
mode &= 0x7f;
}
if (rc != SUCCESS)
return rc;
++mem;
}
else
mem = exp->load.load_seg;
} }
#ifdef DEBUG #ifdef DEBUG
printf("DosComLoader. Loading '%S' at %04x\n", namep, mem); printf("DosComLoader. Loading '%S' at %04x\n", namep, mem);
#endif #endif
/* Now load the executable */ /* Now load the executable */
/* If file not found - error */
/* NOTE - this is fatal because we lost it in transit */
/* from DosExec! */
if ((rc = DosOpen(namep, 0)) < 0)
#if 0
fatal("(DosComLoader) com file lost in transit")
#endif
;
/* do it in 32K chunks */
if ((com_size = DosGetFsize(rc)) != 0)
{ {
if (mode == OVERLAY) /* memory already allocated */ BYTE FAR *sp;
sp = MK_FP(mem, 0); ULONG tmp;
else
{ /* test the filesize against the allocated memory */
if (mode == OVERLAY) /* memory already allocated */
sp = MK_FP(mem, 0);
else /* test the filesize against the allocated memory */
sp = MK_FP(mem, sizeof(psp)); sp = MK_FP(mem, sizeof(psp));
/* This is a potential problem, what to do with .COM files larger than /* MS DOS always only loads the very first 64KB - sizeof(psp) bytes.
the allocated memory? -- 1999/04/21 ska */
MS DOS always only loads the very first 64KB - sizeof(psp) bytes.
-- 1999/04/21 ska */
/* BUG !! in case of LH, memory may be smaller then 64K TE */ /* rewind to start */
DosSeek(fd, 0, 0, &tmp);
if (com_size > ((LONG) asize << 4)) /* less memory than the .COM file has */ /* read everything, but at most 64K - sizeof(PSP) */
com_size = (LONG) asize << 4; DosRead(fd, 0xff00, sp, &UnusedRetVal);
} DosClose(fd);
do
{
nread = DosRead(rc, CHUNK, sp, &UnusedRetVal);
sp = add_far((VOID FAR *) sp, (ULONG) nread);
}
while ((com_size -= nread) > 0 && nread == CHUNK);
} }
DosClose(rc);
if (mode == OVERLAY) if (mode == OVERLAY)
return SUCCESS; return SUCCESS;
/* point to the PSP so we can build it */
p = MK_FP(mem, 0);
setvec(0x22, MK_FP(user_r->CS, user_r->IP));
new_psp(p, mem + asize);
asize = patchPSP(mem - 1, env, exp, namep); /* asize=fcbcode for ax */
/* Transfer control to the executable */
p->ps_parent = cu_psp;
p->ps_prevpsp = (BYTE FAR *) MK_FP(cu_psp, 0);
q->ps_stack = (BYTE FAR *) user_r;
user_r->FLAGS &= ~FLG_CARRY;
cu_psp = mem;
dta = p->ps_dta;
switch (mode)
{ {
case LOADNGO: UWORD fcbcode;
{
/* BUG !! /* point to the PSP so we can build it */
this works only, if COMSIZE >= 64K setvec(0x22, MK_FP(user_r->CS, user_r->IP));
in case of LH, this is not necessarily true new_psp(MK_FP(mem, 0), mem + asize);
*/
fcbcode = patchPSP(mem - 1, env, exp, namep);
/* set asize to end of segment */
if (asize < 0x1000)
asize = (asize << 4) - 2;
else
asize = 0xfffe;
/* TODO: worry about PSP+6:
CP/M compatibility--size of first segment for .COM files,
while preserving the far call */
*((UWORD FAR *) MK_FP(mem, 0xfffe)) = (UWORD) 0; exp->exec.stack = MK_FP(mem, asize);
exp->exec.start_addr = MK_FP(mem, 0x100);
/* build the user area on the stack */ *((UWORD FAR *) MK_FP(mem, asize)) = (UWORD) 0;
irp = MK_FP(mem, (0xfffe - sizeof(iregs))); load_transfer(mem, exp, fcbcode, mode);
/* start allocating REGs */
irp->ES = irp->DS = mem;
irp->CS = mem;
irp->IP = 0x100;
irp->AX = asize; /* fcbcode */
irp->BX = irp->CX = irp->DX = irp->SI = irp->DI = irp->BP = 0;
irp->FLAGS = 0x200;
if (InDOS)
--InDOS;
exec_user(irp);
/* We should never be here
fatal("KERNEL RETURNED!!!"); */
break;
}
case LOAD:
exp->exec.stack = MK_FP(mem, 0xfffe);
*((UWORD FAR *) exp->exec.stack) = asize;
exp->exec.start_addr = MK_FP(mem, 0x100);
return SUCCESS;
} }
return SUCCESS;
return DE_INVLDFMT;
} }
VOID return_user(void) VOID return_user(void)
@ -542,191 +549,105 @@ VOID return_user(void)
exec_user((iregs FAR *) q->ps_stack); exec_user((iregs FAR *) q->ps_stack);
} }
COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
{ {
COUNT rc; UWORD mem, env, start_seg, asize = 0;
/*err, */ ULONG exe_size, tmp;
/*env_size, */
UWORD mem, env, asize, start_seg;
int ModeLoadHigh = mode & 0x80;
UBYTE UMBstate = uppermem_link;
mode &= 0x7f;
/* Clone the environement and create a memory arena */
if (mode != OVERLAY)
{
if ((rc = ChildEnv(exp, &env, namep)) != SUCCESS)
return rc;
}
else
mem = exp->load.load_seg;
{ {
ULONG image_size; ULONG image_size;
ULONG image_offset; ULONG image_offset;
LONG exe_size;
mcb FAR *mp; /* compute image offset from the ExeHeader */
image_offset = (ULONG) ExeHeader.exHeaderSize * 16;
/* compute image offset from the header */
image_offset = (ULONG) header.exHeaderSize * 16;
/* compute image size by removing the offset from the */ /* compute image size by removing the offset from the */
/* number pages scaled to bytes plus the remainder and */ /* number pages scaled to bytes plus the remainder and */
/* the psp */ /* the psp */
/* First scale the size */ /* First scale the size */
image_size = (ULONG) header.exPages * 512; image_size = (ULONG) ExeHeader.exPages * 512;
/* remove the offset */ /* remove the offset */
image_size -= image_offset; image_size -= image_offset;
/* and finally add in the psp size */ /* We should not attempt to allocate
if (mode != OVERLAY) memory if we are overlaying the current process, because the new
image_size += sizeof(psp); /*TE 03/20/01 */ process will simply re-use the block we already have allocated.
Jun 11, 2000 - rbc */
if (mode != OVERLAY)
if ((mode & 0x7f) != OVERLAY)
{ {
if (ModeLoadHigh) UBYTE UMBstate = uppermem_link;
UBYTE orig_mem_access = mem_access_mode;
COUNT rc;
/* and finally add in the psp size */
image_size += sizeof(psp); /*TE 03/20/01 */
exe_size = (ULONG) long2para(image_size) + ExeHeader.exMinAlloc;
/* Clone the environement and create a memory arena */
if ((mode & 0x7f) != OVERLAY && (mode & 0x80))
{ {
DosUmbLink(1); /* link in UMB's */ DosUmbLink(1); /* link in UMB's */
mem_access_mode |= ModeLoadHigh;
}
/* Now find out how many paragraphs are available */
if ((rc = DosMemLargest((seg FAR *) & asize)) != SUCCESS)
{
DosMemFree(env);
return rc;
}
exe_size = (LONG) long2para(image_size) + header.exMinAlloc;
/* + long2para((LONG) sizeof(psp)); ?? see above
image_size += sizeof(psp) -- 1999/04/21 ska */
if (exe_size > asize && (mem_access_mode & 0x80))
{
/* First try low memory */
mem_access_mode &= ~0x80;
rc = DosMemLargest((seg FAR *) & asize);
mem_access_mode |= 0x80; mem_access_mode |= 0x80;
if (rc != SUCCESS)
{
DosMemFree(env);
return rc;
}
} }
if (exe_size > asize)
{ rc = ChildEnv(exp, &env, namep);
DosMemFree(env);
return DE_NOMEM; if (rc == SUCCESS)
} /* Now find out how many paragraphs are available */
exe_size = (LONG) long2para(image_size) + header.exMaxAlloc; rc = ExecMemLargest(&asize, (UWORD)exe_size);
/* + long2para((LONG) sizeof(psp)); ?? -- 1999/04/21 ska */
exe_size = (ULONG) long2para(image_size) + ExeHeader.exMaxAlloc;
if (exe_size > asize) if (exe_size > asize)
exe_size = asize; exe_size = asize;
/* TE if header.exMinAlloc == header.exMaxAlloc == 0, /* TE if ExeHeader.exMinAlloc == ExeHeader.exMaxAlloc == 0,
DOS will allocate the largest possible memory area DOS will allocate the largest possible memory area
and load the image as high as possible into it. and load the image as high as possible into it.
discovered (and after that found in RBIL), when testing NET */ discovered (and after that found in RBIL), when testing NET */
if ((header.exMinAlloc | header.exMaxAlloc) == 0) if ((ExeHeader.exMinAlloc | ExeHeader.exMaxAlloc) == 0)
exe_size = asize; exe_size = asize;
/* /// Removed closing curly brace. We should not attempt to allocate
memory if we are overlaying the current process, because the new
process will simply re-use the block we already have allocated.
This was causing execl() to fail in applications which use it to
overlay (replace) the current exe file with a new one.
Jun 11, 2000 - rbc
} */
/* Allocate our memory and pass back any errors */ /* Allocate our memory and pass back any errors */
/* We can still get an error on first fit if the above */ if (rc == SUCCESS)
/* returned size was a bet fit case */ rc = ExecMemAlloc((UWORD)exe_size, &mem, &asize);
/* ModeLoadHigh = 80 = try high, then low */
if ((rc = if (rc != SUCCESS)
DosMemAlloc((seg) exe_size, mem_access_mode | ModeLoadHigh, DosMemFree(env);
(seg FAR *) & mem, (UWORD FAR *) & asize)) < 0)
if (mode & 0x80)
{ {
if (rc == DE_NOMEM) mem_access_mode = orig_mem_access; /* restore old situation */
{ DosUmbLink(UMBstate); /* restore link state */
if ((rc =
DosMemAlloc(0, LARGEST, (seg FAR *) & mem,
(UWORD FAR *) & asize)) < 0)
{
DosMemFree(env);
return rc;
}
/* This should never happen, but ... */
if (asize < exe_size)
{
DosMemFree(mem);
DosMemFree(env);
return rc;
}
}
else
{
DosMemFree(env);
return rc;
}
} }
else if (rc != SUCCESS)
/* with no error, we got exactly what we asked for */ return rc;
asize = exe_size;
mode &= 0x7f; /* forget about high loading from now on */
#ifdef DEBUG #ifdef DEBUG
printf("DosExeLoader. Loading '%S' at %04x\n", namep, mem); printf("DosExeLoader. Loading '%S' at %04x\n", namep, mem);
#endif #endif
/* /// Added open curly brace and "else" clause. We should not attempt
to allocate memory if we are overlaying the current process, because
the new process will simply re-use the block we already have allocated.
This was causing execl() to fail in applications which use it to
overlay (replace) the current exe file with a new one.
Jun 11, 2000 - rbc */
}
else
asize = exe_size;
/* /// End of additions. Jun 11, 2000 - rbc */
if (ModeLoadHigh)
{
mem_access_mode &= ~ModeLoadHigh; /* restore old situation */
DosUmbLink(UMBstate); /* restore link state */
}
if (mode != OVERLAY)
{
/* memory found large enough - continue processing */ /* memory found large enough - continue processing */
mp = MK_FP(mem, 0);
++mem; ++mem;
/* /// Added open curly brace and "else" clause. We should not attempt
to allocate memory if we are overlaying the current process, because
the new process will simply re-use the block we already have allocated.
This was causing execl() to fail in applications which use it to
overlay (replace) the current exe file with a new one.
Jun 11, 2000 - rbc */
} }
else else /* !!OVERLAY */
mem = exp->load.load_seg;
/* create the start seg for later computations */
if (mode == OVERLAY)
start_seg = mem;
else
{ {
start_seg = mem + long2para((LONG) sizeof(psp)); mem = exp->load.load_seg;
} }
/* Now load the executable */ /* Now load the executable */
/* If file not found - error */
/* NOTE - this is fatal because we lost it in transit */
/* from DosExec! */
if ((rc = DosOpen(namep, 0)) < 0)
{
#if 0
fatal("(DosExeLoader) exe file lost in transit");
#endif
}
/* offset to start of image */ /* offset to start of image */
if (doslseek(rc, image_offset, 0) != image_offset) DosSeek(fd, image_offset, 0, &tmp);
if (tmp != image_offset)
{ {
if (mode != OVERLAY) if (mode != OVERLAY)
{ {
@ -735,41 +656,39 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
} }
return DE_INVLDDATA; return DE_INVLDDATA;
} }
/* read in the image in 32K chunks */ /* create the start seg for later computations */
start_seg = mem;
exe_size = image_size;
if (mode != OVERLAY) if (mode != OVERLAY)
{ {
exe_size = image_size - sizeof(psp); exe_size -= sizeof(psp);
start_seg += long2para(sizeof(psp));
if (exe_size > 0 && (ExeHeader.exMinAlloc == 0) && (ExeHeader.exMaxAlloc == 0))
{
mcb FAR *mp = MK_FP(mem - 1, 0);
/* then the image should be placed as high as possible */
start_seg = start_seg + mp->m_size - (image_size + 15) / 16;
}
} }
else }
exe_size = image_size;
if (exe_size > 0) /* read in the image in 32K chunks */
{
UCOUNT nBytesRead;
BYTE FAR *sp = MK_FP(start_seg, 0x0);
while (exe_size > 0)
{ {
UCOUNT nBytesRead; nBytesRead =
BYTE FAR *sp; DosRead(fd,
(COUNT) (exe_size < CHUNK ? exe_size : CHUNK),
if (mode != OVERLAY) (VOID FAR *) sp, &UnusedRetVal);
{ if (nBytesRead == 0)
if ((header.exMinAlloc == 0) && (header.exMaxAlloc == 0)) break;
{ sp = add_far((VOID FAR *) sp, nBytesRead);
/* then the image should be placed as high as possible */ exe_size -= nBytesRead;
start_seg = start_seg + mp->m_size - (image_size + 15) / 16;
}
}
sp = MK_FP(start_seg, 0x0);
do
{
nBytesRead =
DosRead((COUNT) rc,
(COUNT) (exe_size < CHUNK ? exe_size : CHUNK),
(VOID FAR *) sp, &UnusedRetVal);
sp = add_far((VOID FAR *) sp, (ULONG) nBytesRead);
exe_size -= nBytesRead;
}
while (nBytesRead && exe_size > 0);
} }
} }
@ -777,12 +696,13 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
COUNT i; COUNT i;
UWORD reloc[2]; UWORD reloc[2];
seg FAR *spot; seg FAR *spot;
ULONG tmp;
doslseek(rc, (LONG) header.exRelocTable, 0); DosSeek(fd, ExeHeader.exRelocTable, 0, &tmp);
for (i = 0; i < header.exRelocItems; i++) for (i = 0; i < ExeHeader.exRelocItems; i++)
{ {
if (DosRead if (DosRead
(rc, sizeof(reloc), (VOID FAR *) & reloc[0], (fd, sizeof(reloc), (VOID FAR *) & reloc[0],
&UnusedRetVal) != sizeof(reloc)) &UnusedRetVal) != sizeof(reloc))
{ {
return DE_INVLDDATA; return DE_INVLDDATA;
@ -802,69 +722,29 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
} }
/* and finally close the file */ /* and finally close the file */
DosClose(rc); DosClose(fd);
/* exit here for overlay */ /* exit here for overlay */
if (mode == OVERLAY) if (mode == OVERLAY)
return SUCCESS; return SUCCESS;
{ {
psp FAR *p; UWORD fcbcode;
psp FAR *q = MK_FP(cu_psp, 0);
/* point to the PSP so we can build it */ /* point to the PSP so we can build it */
p = MK_FP(mem, 0);
setvec(0x22, MK_FP(user_r->CS, user_r->IP)); setvec(0x22, MK_FP(user_r->CS, user_r->IP));
new_psp(p, mem + asize); new_psp(MK_FP(mem, 0), mem + asize);
asize = patchPSP(mem - 1, env, exp, namep); /* asize = fcbcode */ fcbcode = patchPSP(mem - 1, env, exp, namep);
exp->exec.stack =
MK_FP(ExeHeader.exInitSS + start_seg, ExeHeader.exInitSP);
exp->exec.start_addr =
MK_FP(ExeHeader.exInitCS + start_seg, ExeHeader.exInitIP);
/* Transfer control to the executable */ /* Transfer control to the executable */
p->ps_parent = cu_psp; load_transfer(mem, exp, fcbcode, mode);
p->ps_prevpsp = (BYTE FAR *) MK_FP(cu_psp, 0);
q->ps_stack = (BYTE FAR *) user_r;
user_r->FLAGS &= ~FLG_CARRY;
switch (mode)
{
case LOADNGO:
{
/* build the user area on the stack */
iregs FAR *irp = MK_FP(header.exInitSS + start_seg,
((header.exInitSP -
sizeof(iregs)) & 0xffff));
/* start allocating REGs */
/* Note: must match es & ds memory segment */
irp->ES = irp->DS = mem;
irp->CS = header.exInitCS + start_seg;
irp->IP = header.exInitIP;
irp->AX = asize; /* asize = fcbcode */
irp->BX = irp->CX = irp->DX = irp->SI = irp->DI = irp->BP = 0;
irp->FLAGS = 0x200;
cu_psp = mem;
dta = p->ps_dta;
if (InDOS)
--InDOS;
exec_user(irp);
/* We should never be here
fatal("KERNEL RETURNED!!!"); */
break;
}
case LOAD:
cu_psp = mem;
exp->exec.stack =
MK_FP(header.exInitSS + start_seg, header.exInitSP);
*((UWORD FAR *) exp->exec.stack) = asize; /* fcbcode */
exp->exec.start_addr =
MK_FP(header.exInitCS + start_seg, header.exInitIP);
return SUCCESS;
}
} }
return DE_INVLDFMT; return SUCCESS;
} }
/* mode = LOAD or EXECUTE /* mode = LOAD or EXECUTE
@ -876,36 +756,40 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp) COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp)
{ {
COUNT rc; COUNT rc;
exec_blk leb; COUNT fd;
/* BYTE FAR *cp;*/ if ((mode & 0x7f) > 3 || (mode & 0x7f) == 2)
BOOL bIsCom = FALSE; return DE_INVLDFMT;
fmemcpy(&leb, ep, sizeof(exec_blk)); fmemcpy(&TempExeBlock, ep, sizeof(exec_blk));
/* If file not found - free ram and return error */ /* If file not found - free ram and return error */
if ((rc = DosOpen(lp, 0)) < 0) if (IsDevice(lp) || /* we don't want to execute C:>NUL */
#if 0
(fd = (short)DosOpen(lp, O_LEGACY | O_OPEN | O_RDONLY, 0)) < 0)
#else
(fd = (short)DosOpen(lp, 0)) < 0)
#endif
{ {
return DE_FILENOTFND; return DE_FILENOTFND;
} }
rc = DosRead(fd, sizeof(exe_header), (BYTE FAR *)&ExeHeader, &UnusedRetVal);
if (DosRead(rc, sizeof(exe_header), (VOID FAR *) & header, &UnusedRetVal) if (rc == sizeof(exe_header) &&
!= sizeof(exe_header)) (ExeHeader.exSignature == MAGIC || ExeHeader.exSignature == OLD_MAGIC))
{ {
bIsCom = TRUE; rc = DosExeLoader(lp, &TempExeBlock, mode, fd);
}
else if (rc != 0)
{
rc = DosComLoader(lp, &TempExeBlock, mode, fd);
} }
DosClose(rc);
if (bIsCom || header.exSignature != MAGIC) DosClose(fd);
{
rc = DosComLoader(lp, &leb, mode);
}
else
{
rc = DosExeLoader(lp, &leb, mode);
}
if (mode == LOAD && rc == SUCCESS) if (mode == LOAD && rc == SUCCESS)
fmemcpy(ep, &leb, sizeof(exec_blk)); fmemcpy(ep, &TempExeBlock, sizeof(exec_blk));
return rc; return rc;
} }