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
-------- Bart Oldeman (bart@dosemu.org)
+ 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
* patchobj makefile correction
* 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
-------- Bart Oldeman (bart@dosemu.org)
+ Changes Tom

View File

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

View File

@ -37,20 +37,29 @@ static BYTE *Cds_hRcsId =
struct cds {
BYTE cdsCurrentPath[MAX_CDSPATH];
UWORD cdsFlags;
struct dpb FAR *cdsDpb;
UWORD cdsFlags; /* see below */
struct dpb FAR *cdsDpb; /* if != 0, associated DPB */
union {
BYTE FAR *_cdsRedirRec;
BYTE FAR *_cdsRedirRec; /* IFS record */
struct {
UWORD _cdsStrtClst;
UWORD _cdsStrtClst; /* if local path (Flags & CDSPHYSDRV):
start cluster of CWD; root == 0,
never access == 0xFFFF */
UWORD _cdsParam;
} _cdsRedir;
} _cdsUnion;
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 FAR *cdsIfs;
@ -62,17 +71,29 @@ struct cds {
#define cdsRedirRec _cdsUnion._cdsRedirRec
#define cdsParam _cdsUnion._cdsRedir._cdsParam
typedef struct _cdstbl {
struct cds cds_table[26];
} cdstbl;
/* Bits for cdsFlags */
/* Bits for cdsFlags (OR combination) */
#define CDSNETWDRV 0x8000
#define CDSPHYSDRV 0x4000
#define CDSJOINED 0x2000
#define CDSSUBST 0x1000
#define CDSVALID (CDSNETWDRV | CDSPHYSDRV)
#define CDSJOINED 0x2000 /* not in combination with NETWDRV or SUBST */
#define CDSSUBST 0x1000 /* not in combination with NETWDRV or JOINED */
#define CDS_HIDDEN (1 << 7) /* hide drive from redirector's list */
/* NETWORK PHYSICAL meaning
0 0 drive not accessable
0 1 local file system
1 0 networked file system (UNC naming convention)
1 1 installable file system (IFS)
*/
#define CDSMODEMASK (CDSNETWDRV | CDSPHYSDRV)
/* #define CDSVALID (CDSNETWDRV | CDSPHYSDRV) */
#define CDSVALID CDSMODEMASK
#define IS_DEVICE 0x20
#define IS_NETWORK 0x40
#define CDS_MODE_SKIP_PHYSICAL 0x01 /* don't resolve SUBST, JOIN, NETW */
#define CDS_MODE_CHECK_DEV_PATH 0x02 /* check for existence of device path */
/*
* Log: cds.h,v
* 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_MINOR 1
#define REVISION_SEQ 26
#define BUILD "2026"
#define SUB_BUILD "b"
#define KERNEL_VERSION_STRING "1.1.26b" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ */
#define KERNEL_BUILD_STRING "2026b" /*#BUILD SUB_BUILD */
#define REVISION_SEQ 27
#define BUILD "2027"
#define SUB_BUILD "test"
#define KERNEL_VERSION_STRING "1.1.27" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ */
#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_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 FAR *dpbp = CDSp->cds_table[dsk].cdsDpb;
REG struct dpb FAR *dpbp = CDSp[dsk].cdsDpb;
if ((UCOUNT) dsk >= lastdrive)
{
return 0x0201; /* illegal command */
}
if ((CDSp->cds_table[dsk].cdsFlags & (CDSPHYSDRV | CDSNETWDRV)) != CDSPHYSDRV)
if ((CDSp[dsk].cdsFlags & (CDSPHYSDRV | CDSNETWDRV)) != CDSPHYSDRV)
{
return 0x0201; /* illegal command */
}

View File

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

View File

@ -113,7 +113,7 @@ f_node_ptr dir_open(BYTE * dirname)
return NULL;
}
cdsp = &CDSp->cds_table[drive];
cdsp = &CDSp[drive];
/* Generate full path name */
/* 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 */
/* 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)
{
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;
}
cdsp = &CDSp->cds_table[nDrive];
cdsp = &CDSp[nDrive];
/* 11/29/99 jt
* Networking and Cdroms. You can put in here a return.
@ -2187,7 +2187,7 @@ COUNT media_check(REG struct dpb FAR * dpbp)
#endif
/* need to change to root directory if changed */
if (status == M_CHANGED)
CDSp->cds_table[dpbp->dpb_unit].cdsCurrentPath[3] = '\0';
CDSp[dpbp->dpb_unit].cdsCurrentPath[3] = '\0';
return SUCCESS;
}
}
@ -2210,7 +2210,7 @@ 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->cds_table[drive].cdsDpb;
return (struct dhdr FAR *)CDSp[drive].cdsDpb;
}
#endif

View File

@ -261,7 +261,7 @@ CLUSTER next_cluster(struct dpb FAR * dpbp, CLUSTER ClusterNum)
bp = getFATblock(ClusterNum, dpbp);
if (bp == NULL)
return DE_BLKINVLD;
return 1; /* the only error code possible here */
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))
{
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 */
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 struct buffer
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
struct cds FAR * ASM current_ldt;
extern LONG ASM current_filepos; /* current file position */

View File

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

View File

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

View File

@ -32,7 +32,7 @@
#include "dyndata.h"
#include "init-dat.h"
GLOBAL BYTE copyright[] =
char copyright[] =
"(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"
"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 */
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 */
FAR * DOSFAR ASM syscon; /* console device */
@ -169,7 +169,7 @@ VOID ASMCFUNC FreeDOSmain(void)
setvec(0, int0_handler); /* zero divide */
setvec(1, empty_handler); /* single step */
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 */
memset(_ib_start, 0, _ib_end - _ib_start);
@ -315,7 +315,7 @@ STATIC VOID FsConfig(VOID)
/* Initialize the current directory structures */
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);
@ -371,6 +371,8 @@ STATIC VOID signon()
printf(" - MSC");
#elif defined(__WATCOMC__)
printf(" - WATCOMC");
#elif defined(__GNUC__)
printf(" - GNUC"); /* this is hypothetical only */
#else
generate some bullshit error here, as the compiler should be known
#endif
@ -443,20 +445,19 @@ STATIC void kernel()
{
/* 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] == ' ' ||
Cmd.ctBuffer[cmdEnd] == '\t' || Cmd.ctBuffer[cmdEnd] == '\r')
if (*p == ' ' || *p == '\t' || *p == '\r')
{
for (i = sizeof(Cmd.ctBuffer) - slen - 1; i >= cmdEnd; i--)
Cmd.ctBuffer[i + slen] = Cmd.ctBuffer[i];
for (q = &Cmd.ctBuffer[Cmd.ctCount - 1]; q >= p; q--)
q[3] = q[0];
fmemcpy(&Cmd.ctBuffer[cmdEnd], insertString, slen);
Cmd.ctCount += slen;
fmemcpy(p, insertString, 3);
Cmd.ctCount += 3;
printf("%d %s\n", Cmd.ctCount, Cmd.ctBuffer);
break;
}
}
@ -529,8 +530,8 @@ STATIC VOID update_dcb(struct dhdr FAR * dhp)
dpb->dpb_flags = M_CHANGED;
if ((CDSp != 0) && (nblkdev < lastdrive))
{
CDSp->cds_table[nblkdev].cdsDpb = dpb;
CDSp->cds_table[nblkdev].cdsFlags = CDSPHYSDRV;
CDSp[nblkdev].cdsDpb = dpb;
CDSp[nblkdev].cdsFlags = CDSPHYSDRV;
}
++dpb;
++nblkdev;

View File

@ -34,10 +34,6 @@ static BYTE *memmgrRcsId =
"$Id$";
#endif
VOID mcb_init();
VOID mcb_print();
VOID show_chain();
/*#define nxtMCBsize(mcb,size) \
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)
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);
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
*/
VOID FAR * adjust_far(VOID FAR * fp)
void FAR * adjust_far(const void FAR * fp)
{
/* and return an adddress adjusted to the nearest paragraph */
/* boundary. */
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);
}
@ -151,9 +157,13 @@ searchAgain:
/*
Hack to the Umb Region direct for now. Save time and program space.
*/
if ((mode != LARGEST) && (mode & (FIRST_FIT_UO | FIRST_FIT_U)) &&
uppermem_link && uppermem_root != 0xffff)
p = para2far(uppermem_root);
if (uppermem_link && uppermem_root != 0xffff)
{
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 */
FOREVER
@ -290,42 +300,6 @@ COUNT DosMemLargest(UWORD FAR * size)
*size = 0;
DosMemAlloc(0xffff, LARGEST, &dummy, size);
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);
else
return default_drive;
if (drive < lastdrive && CDSp->cds_table[drive].cdsFlags & CDSVALID)
if (drive < lastdrive && CDSp[drive].cdsFlags & CDSVALID)
return drive;
else
return DE_INVLDDRV;
@ -246,7 +246,7 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
while ((src[0] == '.') && (src[1] == '\\'))
src += 2;
current_ldt = &CDSp->cds_table[i];
current_ldt = &CDSp[i];
/* Always give the redirector a chance to rewrite the filename */
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 long2para(ULONG size);
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,
UWORD FAR * asize);
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);
/* task.c */
COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg,
char far * pathname);
VOID new_psp(psp FAR * p, int psize);
VOID return_user(void);
COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp);
LONG DosGetFsize(COUNT hndl);
ULONG DosGetFsize(COUNT hndl);
VOID InitPSP(VOID);
/* newstuff.c */

View File

@ -42,7 +42,12 @@ static BYTE *RcsId =
#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 MAXENV 32768u
@ -53,20 +58,7 @@ static exe_header header;
+ 1 byte: '\0'
-- 1999/04/21 ska */
#ifndef PROTO
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)
ULONG DosGetFsize(COUNT hndl)
{
sft FAR *s;
/* sfttbl FAR *sp;*/
@ -89,8 +81,7 @@ LONG DosGetFsize(COUNT hndl)
return dos_getfsize(s->sft_status);
}
COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg,
char far * pathname)
STATIC COUNT ChildEnv(exec_blk * exp, UWORD * pChildEnvSeg, char far * pathname)
{
BYTE FAR *pSrc;
BYTE FAR *pDest;
@ -157,10 +148,11 @@ COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg,
pDest += sizeof(UWORD) / sizeof(BYTE);
/* copy complete pathname */
if ((RetCode = truename(pathname, pDest, TRUE)) != SUCCESS)
if ((RetCode = truename(pathname, PriPathName, CDS_MODE_SKIP_PHYSICAL)) < SUCCESS)
{
return RetCode;
}
fstrcpy(pDest, PriPathName);
/* Theoretically one could either:
+ 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 ((psp->ps_fcb1.fcb_drive < lastdrive &&
CDSp->cds_table[psp->ps_fcb1.fcb_drive].
cdsFlags & CDSVALID) ? 0 : 0xff) + ((psp->ps_fcb2.fcb_drive <
lastdrive
&& CDSp->cds_table[psp->
ps_fcb2.
fcb_drive].
cdsFlags & CDSVALID) ? 0 :
0xff) * 0x100;
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;
}
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
/* err */
/*,env_size */ ;
COUNT nread;
UWORD mem;
UWORD env, asize;
BYTE FAR *sp;
psp FAR *p;
psp FAR *p = MK_FP(ds, 0);
psp FAR *q = MK_FP(cu_psp, 0);
iregs FAR *irp;
LONG com_size;
int ModeLoadHigh = mode & 0x80;
UBYTE UMBstate = uppermem_link;
mode &= 0x7f;
if (mode != OVERLAY)
/* Transfer control to the executable */
p->ps_parent = cu_psp;
p->ps_prevpsp = q;
q->ps_stack = (BYTE FAR *)user_r;
user_r->FLAGS &= ~FLG_CARRY;
cu_psp = ds;
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;
}
/* 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)
rc = DosMemAlloc(0, LARGEST, para, asize);
if ((mem_access_mode & 0x80) && (rc != SUCCESS))
{
if ((rc =
DosMemAlloc(0, LARGEST, (seg FAR *) & mem,
(UWORD FAR *) & asize)) < 0)
{
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_access_mode &= ~0x80;
rc = DosMemAlloc(0, LARGEST, para, asize);
mem_access_mode |= 0x80;
}
}
++mem;
}
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
printf("DosComLoader. Loading '%S' at %04x\n", namep, mem);
#endif
/* 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 */
sp = MK_FP(mem, 0);
else
{ /* test the filesize against the allocated memory */
BYTE FAR *sp;
ULONG tmp;
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));
/* This is a potential problem, what to do with .COM files larger than
the allocated memory?
MS DOS always only loads the very first 64KB - sizeof(psp) bytes.
-- 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 */
if (com_size > ((LONG) asize << 4)) /* less memory than the .COM file has */
com_size = (LONG) asize << 4;
}
do
{
nread = DosRead(rc, CHUNK, sp, &UnusedRetVal);
sp = add_far((VOID FAR *) sp, (ULONG) nread);
}
while ((com_size -= nread) > 0 && nread == CHUNK);
/* rewind to start */
DosSeek(fd, 0, 0, &tmp);
/* read everything, but at most 64K - sizeof(PSP) */
DosRead(fd, 0xff00, sp, &UnusedRetVal);
DosClose(fd);
}
DosClose(rc);
if (mode == OVERLAY)
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:
{
/* BUG !!
this works only, if COMSIZE >= 64K
in case of LH, this is not necessarily true
*/
UWORD fcbcode;
/* 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);
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;
/* build the user area on the stack */
irp = MK_FP(mem, (0xfffe - sizeof(iregs)));
/* 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;
exp->exec.stack = MK_FP(mem, asize);
exp->exec.start_addr = MK_FP(mem, 0x100);
*((UWORD FAR *) MK_FP(mem, asize)) = (UWORD) 0;
load_transfer(mem, exp, fcbcode, mode);
}
return DE_INVLDFMT;
return SUCCESS;
}
VOID return_user(void)
@ -542,191 +549,105 @@ VOID return_user(void)
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;
/*err, */
/*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;
UWORD mem, env, start_seg, asize = 0;
ULONG exe_size, tmp;
{
ULONG image_size;
ULONG image_offset;
LONG exe_size;
mcb FAR *mp;
/* compute image offset from the header */
image_offset = (ULONG) header.exHeaderSize * 16;
/* compute image offset from the ExeHeader */
image_offset = (ULONG) ExeHeader.exHeaderSize * 16;
/* compute image size by removing the offset from the */
/* number pages scaled to bytes plus the remainder and */
/* the psp */
/* First scale the size */
image_size = (ULONG) header.exPages * 512;
image_size = (ULONG) ExeHeader.exPages * 512;
/* remove the offset */
image_size -= image_offset;
/* and finally add in the psp size */
if (mode != OVERLAY)
image_size += sizeof(psp); /*TE 03/20/01 */
if (mode != OVERLAY)
/* 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.
Jun 11, 2000 - rbc */
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 */
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;
if (rc != SUCCESS)
{
DosMemFree(env);
return rc;
}
}
if (exe_size > asize)
{
DosMemFree(env);
return DE_NOMEM;
}
exe_size = (LONG) long2para(image_size) + header.exMaxAlloc;
/* + long2para((LONG) sizeof(psp)); ?? -- 1999/04/21 ska */
rc = ChildEnv(exp, &env, namep);
if (rc == SUCCESS)
/* Now find out how many paragraphs are available */
rc = ExecMemLargest(&asize, (UWORD)exe_size);
exe_size = (ULONG) long2para(image_size) + ExeHeader.exMaxAlloc;
if (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
and load the image as high as possible into it.
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;
/* /// 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 */
/* We can still get an error on first fit if the above */
/* returned size was a bet fit case */
/* ModeLoadHigh = 80 = try high, then low */
if ((rc =
DosMemAlloc((seg) exe_size, mem_access_mode | ModeLoadHigh,
(seg FAR *) & mem, (UWORD FAR *) & asize)) < 0)
if (rc == SUCCESS)
rc = ExecMemAlloc((UWORD)exe_size, &mem, &asize);
if (rc != SUCCESS)
DosMemFree(env);
if (mode & 0x80)
{
if (rc == DE_NOMEM)
{
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;
}
mem_access_mode = orig_mem_access; /* restore old situation */
DosUmbLink(UMBstate); /* restore link state */
}
else
/* with no error, we got exactly what we asked for */
asize = exe_size;
if (rc != SUCCESS)
return rc;
mode &= 0x7f; /* forget about high loading from now on */
#ifdef DEBUG
printf("DosExeLoader. Loading '%S' at %04x\n", namep, mem);
#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 */
mp = MK_FP(mem, 0);
++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
mem = exp->load.load_seg;
/* create the start seg for later computations */
if (mode == OVERLAY)
start_seg = mem;
else
else /* !!OVERLAY */
{
start_seg = mem + long2para((LONG) sizeof(psp));
mem = exp->load.load_seg;
}
/* 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 */
if (doslseek(rc, image_offset, 0) != image_offset)
DosSeek(fd, image_offset, 0, &tmp);
if (tmp != image_offset)
{
if (mode != OVERLAY)
{
@ -735,41 +656,39 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
}
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)
{
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;
BYTE FAR *sp;
if (mode != OVERLAY)
{
if ((header.exMinAlloc == 0) && (header.exMaxAlloc == 0))
{
/* then the image should be placed as high as possible */
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);
nBytesRead =
DosRead(fd,
(COUNT) (exe_size < CHUNK ? exe_size : CHUNK),
(VOID FAR *) sp, &UnusedRetVal);
if (nBytesRead == 0)
break;
sp = add_far((VOID FAR *) sp, nBytesRead);
exe_size -= nBytesRead;
}
}
@ -777,12 +696,13 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
COUNT i;
UWORD reloc[2];
seg FAR *spot;
ULONG tmp;
doslseek(rc, (LONG) header.exRelocTable, 0);
for (i = 0; i < header.exRelocItems; i++)
DosSeek(fd, ExeHeader.exRelocTable, 0, &tmp);
for (i = 0; i < ExeHeader.exRelocItems; i++)
{
if (DosRead
(rc, sizeof(reloc), (VOID FAR *) & reloc[0],
(fd, sizeof(reloc), (VOID FAR *) & reloc[0],
&UnusedRetVal) != sizeof(reloc))
{
return DE_INVLDDATA;
@ -802,69 +722,29 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
}
/* and finally close the file */
DosClose(rc);
DosClose(fd);
/* exit here for overlay */
if (mode == OVERLAY)
return SUCCESS;
{
psp FAR *p;
psp FAR *q = MK_FP(cu_psp, 0);
UWORD fcbcode;
/* 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);
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 */
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;
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;
}
load_transfer(mem, exp, fcbcode, mode);
}
return DE_INVLDFMT;
return SUCCESS;
}
/* 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 rc;
exec_blk leb;
COUNT fd;
/* BYTE FAR *cp;*/
BOOL bIsCom = FALSE;
if ((mode & 0x7f) > 3 || (mode & 0x7f) == 2)
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 ((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;
}
rc = DosRead(fd, sizeof(exe_header), (BYTE FAR *)&ExeHeader, &UnusedRetVal);
if (DosRead(rc, sizeof(exe_header), (VOID FAR *) & header, &UnusedRetVal)
!= sizeof(exe_header))
if (rc == 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)
{
rc = DosComLoader(lp, &leb, mode);
}
else
{
rc = DosExeLoader(lp, &leb, mode);
}
DosClose(fd);
if (mode == LOAD && rc == SUCCESS)
fmemcpy(ep, &leb, sizeof(exec_blk));
fmemcpy(ep, &TempExeBlock, sizeof(exec_blk));
return rc;
}