📄 task.c
字号:
iregs FAR *irp;
long j;
/* restore parent */
p = MK_FP(cu_psp, 0);
/* When process returns - restore the isv */
setvec(0x22, p -> ps_isv22);
setvec(0x23, p -> ps_isv23);
setvec(0x24, p -> ps_isv24);
/* And free all process memory if not a TSR return */
if(!tsr)
{
for(i = 0; i < p -> ps_maxfiles; i++)
{
DosClose(i);
}
FreeProcessMem(cu_psp);
}
cu_psp = p -> ps_parent;
q = MK_FP(cu_psp, 0);
dta = q -> ps_dta;
irp = (iregs FAR *)q -> ps_stack;
irp -> CS = FP_SEG(p -> ps_isv22);
irp -> IP = FP_OFF(p -> ps_isv22);
if (InDOS)
--InDOS;
exec_user((iregs FAR *)q -> ps_stack);
}
#endif
static COUNT
DosExeLoader (BYTE FAR *namep, exec_blk FAR *exp, COUNT mode)
{
COUNT rc, env_size, i, nBytesRead;
UWORD mem, env, asize, start_seg;
ULONG image_size;
ULONG image_offset;
BYTE FAR *sp, FAR * dp;
psp FAR *p;
psp FAR *q = MK_FP(cu_psp, 0);
mcb FAR *mp, FAR *envp = 0;
iregs FAR *irp;
UWORD reloc[2];
seg FAR *spot;
LONG exe_size;
#ifdef IPL
BYTE szNameBuffer[64];
#endif
#ifndef IPL
/* 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;
envp = MK_FP(env, 0);
#endif
/* compute image offset from the header */
#ifdef IPL
fscopy(namep, (BYTE FAR *)szNameBuffer);
printf("\nEXE loader loading: %s", szNameBuffer);
#endif
image_offset = (ULONG)header.exHeaderSize * 16l;
/* 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) * 512l;
/* remove the offset */
image_size -= image_offset;
#if 0
/* add in the remainder bytes */
if(header.exExtraBytes != 0)
image_size -= (ULONG)(512 - header.exExtraBytes);
#endif
/* and finally add in the psp size */
if(mode != OVERLAY)
image_size += (ULONG)long2para((LONG)sizeof(psp));
#ifndef IPL
if(mode != OVERLAY)
{
/* Now find out how many paragraphs are available */
if((rc = DosMemLargest((seg FAR *)&asize)) != SUCCESS)
{
return rc;
}
else
{
exe_size = (LONG)long2para(image_size) + header.exMinAlloc + long2para((LONG)sizeof(psp));
if(exe_size > asize)
return DE_NOMEM;
else if(((LONG)long2para(image_size) + header.exMaxAlloc + long2para((LONG)sizeof(psp))) < asize)
exe_size = (LONG)long2para(image_size) + header.exMaxAlloc + long2para((LONG)sizeof(psp));
else
exe_size = asize;
}
/* 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 */
if((rc = DosMemAlloc((seg)exe_size, FIRST_FIT, (seg FAR *)&mem, (UWORD FAR *)&asize)) < 0)
{
if(rc == DE_NOMEM)
{
if((rc = DosMemAlloc(0, LARGEST, (seg FAR *)&mem, (UWORD FAR *)&asize)) < 0)
{
if(env != 0)
DosMemFree(env);
return rc;
}
/* This should never happen, but ... */
if(asize < exe_size)
{
if(env != 0)
DosMemFree(env);
DosMemFree(mem);
return rc;
}
}
else
{
if(env != 0)
DosMemFree(env);
return rc;
}
}
else
/* with no error, we got exactly what we asked for */
asize = exe_size;
}
#else
mem = KERNSEG;
#endif
#ifndef IPL
if(mode != OVERLAY)
{
#endif
/* memory found large enough - continue processing */
mp = MK_FP(mem, 0);
++mem;
#ifndef IPL
}
else
mem = exp -> load.load_seg;
#endif
#ifdef IPL
printf(".");
#endif
/* create the start seg for later computations */
if(mode == OVERLAY)
start_seg = mem;
else
{
start_seg = mem + long2para((LONG)sizeof(psp));
}
/* Now load the executable */
/* If file not found - error */
/* NOTE - this is fatal because we lost it in transit */
/* from DosExec! */
if((rc = dos_open(namep, 0)) < 0)
{
fatal("(DosExeLoader) exe file lost in transit");
}
#ifdef IPL
printf(".");
#endif
/* offset to start of image */
if (dos_lseek(rc, image_offset, 0) != image_offset)
{
#ifndef IPL
if(mode != OVERLAY)
{
DosMemFree(--mem);
if(env != 0)
DosMemFree(env);
}
#endif
return DE_INVLDDATA;
}
#ifdef IPL
printf(".");
#endif
/* read in the image in 32K chunks */
if(mode != OVERLAY)
{
exe_size = image_size - long2para((LONG)sizeof(psp));
}
else
exe_size = image_size;
sp = MK_FP(start_seg, 0x0);
if(mode != OVERLAY)
{
if((header.exMinAlloc == 0) && (header.exMaxAlloc == 0))
{
sp = MK_FP(start_seg + mp -> m_size
- (image_size + 15) /16, 0);
}
}
while(exe_size > 0)
{
nBytesRead = dos_read((COUNT)rc, (VOID FAR *)sp, (COUNT)(exe_size < CHUNK ? exe_size : CHUNK));
sp = add_far((VOID FAR *)sp, (ULONG)CHUNK);
exe_size -= nBytesRead;
if(nBytesRead == 0 || exe_size <= 0)
break;
#ifdef IPL
printf(".");
#endif
}
#if 0
/* Error if we did not read the entire image */
if(exe_size != 0)
fatal("Broken exe loader (exe_size != 0)");
#endif
/* relocate the image for new segment */
dos_lseek(rc, (LONG)header.exRelocTable, 0);
for (i=0; i < header.exRelocItems; i++)
{
if (dos_read(rc, (VOID FAR *)&reloc[0], sizeof(reloc)) != sizeof(reloc))
{
return DE_INVLDDATA;
}
if(mode == OVERLAY)
{
spot = MK_FP(reloc[1] + mem, reloc[0]);
*spot = *spot + exp -> load.reloc;
}
else
{
/* spot = MK_FP(reloc[1] + mem + 0x10, reloc[0]);*/
spot = MK_FP(reloc[1] + start_seg, reloc[0]);
*spot = *spot + start_seg;
}
}
#ifdef IPL
printf(".");
#endif
/* and finally close the file */
dos_close(rc);
/* exit here for overlay */
if(mode == OVERLAY)
return SUCCESS;
/* point to the PSP so we can build it */
p = MK_FP(mem, 0);
setvec(0x22, (VOID (INRPT FAR *)(VOID))MK_FP(user_r -> CS, user_r -> IP));
new_psp(p, mem + asize);
#ifndef IPL
p -> ps_environ = env == 0 ? 0 : env + 1;
#else
p -> ps_environ = 0;
#endif
/* complete the psp by adding the command line */
p -> ps_cmd_count = exp -> exec.cmd_line -> ctCount;
fbcopy(exp -> exec.cmd_line -> ctBuffer, p -> ps_cmd, 127);
#if 0
/* stick a new line on the end for safe measure */
p -> ps_cmd[p -> ps_cmd_count] = '\r';
#endif
/* identify the mcb as this functions' */
/* use the file name less extension - left adjusted and */
/* space filled */
mp -> m_psp = mem;
if (envp) envp -> m_psp = mem;
for(i = 0; i < 8; i++)
{
if(namep[i] != '.')
mp -> m_name[i] = namep[i];
else
break;
}
for(; i < 8; i++)
mp -> m_name[i] = ' ';
/* build the user area on the stack */
irp = MK_FP(header.exInitSS + start_seg, ((header.exInitSP - sizeof(iregs)) & 0xffff));
#ifdef IPL
printf(".\n");
#endif
/* 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 = 0xffff; /* for now, until fcb code is in */
#ifdef IPL
irp -> BX = BootDrive;
irp -> CX = NumFloppies;
#else
irp -> BX =
irp -> CX =
#endif
irp -> DX =
irp -> SI =
irp -> DI =
irp -> BP = 0;
irp -> FLAGS = 0x200;
/* 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;
#ifdef IPL
printf("Starting kernel ...\n");
#endif
switch(mode)
{
case LOADNGO:
cu_psp = mem;
dta = p -> ps_dta;
if (InDOS) --InDOS;
exec_user(irp);
/* We should never be here */
fatal("KERNEL RETURNED!!!");
break;
#ifndef IPL
case LOAD:
cu_psp = mem;
exp -> exec.stack = (BYTE FAR *)irp;
exp -> exec.start_addr = MK_FP(irp -> CS, irp -> IP);
return SUCCESS;
#endif
}
return DE_INVLDFMT;
}
COUNT
DosExec (COUNT mode, exec_blk FAR *ep, BYTE FAR *lp)
{
COUNT rc;
exec_blk leb = *ep;
BYTE FAR *cp;
BOOL bIsCom = FALSE;
/* If file not found - free ram and return error */
#ifdef IPL
printf(".");
#endif
if((rc = dos_open(lp, 0)) < 0)
{
return DE_FILENOTFND;
}
if(dos_read(rc, (VOID FAR *)&header, sizeof(exe_header))
!= sizeof(exe_header))
{
#ifdef IPL
printf("Internal IPL error - Read failure");
return DE_INVLDDATA;
#else
bIsCom = TRUE;
#endif
}
dos_close(rc);
#ifdef IPL
printf(".");
#endif
if(bIsCom || header.exSignature != MAGIC)
#ifndef IPL
{
rc = DosComLoader(lp, &leb, mode);
}
#else
{
char szFileName[32];
fmemcpy((BYTE FAR *)szFileName, lp);
printf("\nFile: %s (MAGIC = %04x)", szFileName, header.exSignature);
fatal("IPL can't load .com files!");
}
#endif
else
{
rc = DosExeLoader(lp, &leb, mode);
}
if (mode == LOAD && rc == SUCCESS)
*ep = leb;
return rc;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -