⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jobc.c

📁 MMURTL(tm) Computer Operating System Ver x0.8, source code.
💻 C
📖 第 1 页 / 共 2 页
字号:
		  	xprintf("PhyAdd : %08x\r\n", PhyAdd);
			ReadKbd(&KeyCodeE, 1);
			*/

			/* Now we can allocate User Job Memory */
			/* Allocate user memory for Stack Code and Data */
			/* This is done in the OS PD */

			nPages = sStack/4096;
			if (sStack%4096) nPages++;
			erc = AllocPage(nPages, &pStack);
			sStack = nPages * 4096;				/* set to whole pages */

			nPages = sCode/4096;
			if (sCode%4096) nPages++;
			if (!erc)
				erc = AllocPage(nPages, &pCode);

			nPages = sData/4096;
			if (sData%4096) nPages++;
			if (!erc)
				erc = AllocPage(nPages, &pData);

			/* Right now, the OS PD looks exacly like we want
			the User PD to look.  We will now copy the entire
			OS PD into the User's New PD.
			*/

			CopyData(pOSPD,	pPD, 4096);		/* Copy OS PD to User PD */

			/* All Job memory is now allocated, so let's LOAD IT! */

			if (!erc)
				erc = SetFileLFA(fh, oCode);
			if (!erc)
				erc = ReadBytes (fh, pCode, sCode, &dret);

			if (!erc)
				erc = SetFileLFA(fh, oData);
			if (!erc)
				erc = ReadBytes (fh, pData, sData, &dret);

			/* Now that we have read in the code and data we
			apply fixups to these segments from the runfile
			*/

			if (!erc) {

				if (nCDFIX) {
					erc = SetFileLFA(fh, oCDFIX);	/* back to fixups */
					while ((nCDFIX--) && (!erc)) {
						erc = ReadBytes (fh, &i, 4, &dret);
						pFix = pCode + i;		/* Where in CSeg */
						*pFix = *pFix - offData + pData;
					}
				}

				if (nCCFIX) {
					erc = SetFileLFA(fh, oCCFIX);	/* back to fixups */
					while ((nCCFIX--) && (!erc)) {
						erc = ReadBytes (fh, &i, 4, &dret);
						pFix = pCode + i;		/* Where in CSeg */
						*pFix = *pFix - offCode + pCode;
					}
				}

				if (nDCFIX) {
					erc = SetFileLFA(fh, oDCFIX);	/* back to fixups */
					while ((nDCFIX--) && (!erc)) {
						erc = ReadBytes (fh, &i, 4, &dret);
						pFix = pData + i;		/* Where in DSeg */
						*pFix = *pFix - offCode + pCode;
					}
				}

				if (nDDFIX) {
					erc = SetFileLFA(fh, oDDFIX);	/* back to fixups */
					while ((nDDFIX--) && (!erc)) {
						erc = ReadBytes (fh, &i, 4, &dret);
						pFix = pData + i;		/* Where in DSeg */
						*pFix = *pFix - offData + pData;
					}
				}

			}

			/* Clean the OS PD of User memory */

			FillData(&pOSPD[256], 1024, 0);	/* Clean OS PD of User PDEs */
			FillData(&pOSPD[768], 1024, 0);	/* Clean OS PD of User Shadow */

			/* Now we fill in the rest of the User's JCB */

			pNewJCB->pJcbPD = pPD;			/* Lin Add of PD */
			pNewJCB->pJcbStack = pStack;	/* Add of Stack */
			pNewJCB->sJcbStack = sStack;	/* Size of Code */
			pNewJCB->pJcbCode  = pCode;		/* Add of Code */
			pNewJCB->sJcbCode  = sCode; 	/* Size of Code */
			pNewJCB->pJcbData  = pData;		/* Add of Code */
			pNewJCB->sJcbData  = sData; 	/* Size of Code */

			pNewJCB->sbUserName[0] = 0; 	/* Zero UserName */
			pNewJCB->sbPath[0] = 0;		 	/* No Default path */
			pNewJCB->JcbExitRF[0] = 0;	 	/* No Exit Run File */
			pNewJCB->JcbCmdLine[0] = 0;	 	/* No Cmd Line */

			CopyData("KBD", &pNewJCB->JcbSysIn[1], 3);
			pNewJCB->JcbSysIn[0] = 3;	 	/* Size */

			CopyData("VID", &pNewJCB->JcbSysOut[1], 3);
			pNewJCB->JcbSysOut[0] = 3;	 	/* Size */

			pNewJCB->pVidMem = pVid;	 	/* Default to Virt Vid */
			pNewJCB->pVirtVid = pVid;	 	/* Virtual Video memory */
			pNewJCB->CrntX = 0;			 	/* Vid X Position */
			pNewJCB->CrntY = 0;			 	/* Vid Y Position */
			pNewJCB->nCols = 80;		 	/* Columns */
			pNewJCB->nLines = 25;		 	/* Lines */

			pNewJCB->VidMode = 0;		 	/* 80x25 VGA Color Text */
			pNewJCB->fCursOn = 1;		 	/* Cursor On */
			pNewJCB->fCursType = 0;		 	/* UnderLine */


			/* Finally, we crank up the new task and schedule it for
			execution!
			*/
			if (!erc)
				erc = AllocExch(&i);

			if (!erc)
				erc = NewTask(JobNum, 0x18, 25, 0, i,
							  pStack+sStack-4,
							  pStart+pCode-offCode);
			if (!erc)
				SetExchOwner(i, pNewJCB);	/* Exch now belongs to new JCB */
		}

		CloseFile(fh);
	}	/* read run file OK */

	if (!erc)
		*pJobNumRet = JobNum;

	return(erc);
}

/*********************************************************
  This loads a job into an existing PD and JCB.  This is
  called by Chain() and may also be called by ExitJob()
  if an ExitJob was specified in the current JCB.
  The PD, pVid & first PT still exist in OS memory.
  (CleanPD left the first PT for us). ExitJob and Chain
  are responsible for opening and validating the runfile
  and setting up the run file variables.
*********************************************************/

long LoadJob(char *pJCB, long fh)
{
long erc, i, dret, nPages;
long *pFix;

	pNewJCB = pJCB;

	/* Allocate user memory for Stack, Code and Data */
	/* This is done in the USER PD */

	nPages = sStack/4096;
	if (sStack%4096) nPages++;
	erc = AllocPage(nPages, &pStack);
	sStack = nPages * 4096;				/* set to whole pages */

	nPages = sCode/4096;
	if (sCode%4096) nPages++;
	if (!erc)
		erc = AllocPage(nPages, &pCode);

	nPages = sData/4096;
	if (sData%4096) nPages++;

	erc = AllocPage(nPages, &pData);

	/* All Job memory is now allocated, so let's LOAD IT! */

	if (!erc)
		erc = SetFileLFA(fh, oCode);
	if (!erc)
		erc = ReadBytes (fh, pCode, sCode, &dret);

	if (!erc)
		erc = SetFileLFA(fh, oData);
	if (!erc)
		erc = ReadBytes (fh, pData, sData, &dret);

	/* Now that we have read in the code and data we
	apply fixups to these segments from the runfile
	*/

	if (!erc) {
		if (nCDFIX) {
			erc = SetFileLFA(fh, oCDFIX);	/* back to fixups */
			while ((nCDFIX--) && (!erc)) {
				erc = ReadBytes (fh, &i, 4, &dret);
				pFix = pCode + i;		/* Where in CSeg */
				*pFix = *pFix - offData + pData;
			}
		}

		if (nCCFIX) {
			erc = SetFileLFA(fh, oCCFIX);	/* back to fixups */
			while ((nCCFIX--) && (!erc)) {
				erc = ReadBytes (fh, &i, 4, &dret);
				pFix = pCode + i;		/* Where in CSeg */
				*pFix = *pFix - offCode + pCode;
			}
		}

		if (nDCFIX) {
			erc = SetFileLFA(fh, oDCFIX);	/* back to fixups */
			while ((nDCFIX--) && (!erc)) {
				erc = ReadBytes (fh, &i, 4, &dret);
				pFix = pData + i;		/* Where in DSeg */
				*pFix = *pFix - offCode + pCode;
			}
		}

		if (nDDFIX) {
			erc = SetFileLFA(fh, oDDFIX);	/* back to fixups */
			while ((nDDFIX--) && (!erc)) {
				erc = ReadBytes (fh, &i, 4, &dret);
				pFix = pData + i;		/* Where in DSeg */
				*pFix = *pFix - offData + pData;
			}
		}

		/* Now we fill in the rest of the User's JCB */
		pNewJCB->pJcbStack = pStack;	/* Add of Stack */
		pNewJCB->sJcbStack = sStack;	/* Size of Code */
		pNewJCB->pJcbCode  = pCode;		/* Add of Code */
		pNewJCB->sJcbCode  = sCode; 	/* Size of Code */
		pNewJCB->pJcbData  = pData;		/* Add of Code */
		pNewJCB->sJcbData  = sData; 	/* Size of Code */

	}
	CloseFile(fh);

	return(erc);

}

/******************************************************
 This called from Exit() in C or directly from a user
 job or service. This cleans up ALL resources that the
 job had allocated.
 This also checks for an exit run file to load if
 one is specified. If no exit run file is specified
 we just kill the JCB entirely and if video and
 keyboard are assigned we assign them to the Monitor.
******************************************************/

void far ExitJob(long dError)
{
/* NO LOCAL VARIABLES BECAUSE WE SWITCH STACKS!! */

	GetJobNum(&JobNumE);
	GetpJCB(JobNumE, &pCrntJCB);		/* Get pJCB to current Job */
	pCrntJCB->ExitError = dError;

	/* Remove ALL tasks for this job that are at the ReadyQue.
	   The task we are in won't be removed because its RUNNING!
	*/

	RemoveRdyJob(pCrntJCB);	/* It always returns ErcOk */

	/* Deallocate all exchanges for this job except the one belonging
	   to current TSS!  The Dealloc Exchange call will invalidate
	   all TSSs found at exchanges belonging to this user, and
	   will also free up RQBs and Link Blocks.  The job will not be
	   able to initiate requests or send messages after this unless
	   it is done with the TSSExchange because it will get a kernel
	   error (invalid exchange).
	*/

	 /* Find out what our TSS exchange is so
	 we don't deallocate it to! */

	 GetTSSExch(&ExchE);

	 ercE = 0;
	 iE = 0;
	 while (ercE != ErcOutOfRange) {
	 	ercE = GetExchOwner(iE, &pExchJCBE);
		if ((!ercE) && (iE != ExchE) && (pExchJCBE == pCrntJCB))
			DeAllocExch(iE);
		iE++;
	 }
	 ercE = 0;		/* Clear the error */

	/* Now that the user can't make anymore requests,
	   Send Abort messages to all services.
	   This closes all files that were opened by the Job
       and frees up any other resources held for this
       job by any service.
	*/

/*	SendAbort(JobNumE, ExchE); */

	/* We must now switch to a temporary stack so we can
	clean out the user PD (we are on his stack right now!).
	*/

#asm
	MOV EAX, OFFSET _TmpStack
	ADD EAX, 508
	MOV ESP, EAX
	MOV EBP, EAX
#endasm

	/* Clean the PD of all user memory leaving OS memory for next
	job if there is one.
	*/

	pPDE = pCrntJCB->pJcbPD;
	CleanUserPD(pPDE);

	/* Look for Exit Run file to load if any exists.  If no exit run
	file, we deallocate the PD and JCB then return to JOB 1. */

	GetExitJob(FileE, &cbFileE);     	/* Exit Run File!! */

	if (!cbFileE)
		ercE = ErcNoExitJob;

	if (!ercE)
		ercE =  GetRunFile(FileE, cbFileE, &job_fhE);

	if (!ercE)
		ercE = LoadJob(pCrntJCB, job_fhE);

	if (!ercE) {

			pStart = pStart+pCode-offCode;

			/* Now we RETURN to new job's address after we put him
			on his new stack. */

#asm
			MOV EAX, _pStack
			MOV EBX, _sStack
			ADD EAX, EBX
			SUB EAX, 4
			MOV ESP, EAX
			MOV EBP, EAX
			PUSH 18h
			MOV EAX, _pStart
			PUSH EAX
			RETF				;We are history!
#endasm

	}

	if (ercE) {		/* something failed or we don't have an ExitRF */

		/* In case there is no job to run or a fatal error has happened
		we send a message (ISendMsg) to the monitor status
		task with our TSSExch and the Error. Then he will WIPE US OUT!
		We use ISend (vice send) so he can't run before we get to
		the exchange otherwise we will be placed back on the readyQueue!
	    */

		ISendMsg(KillExch, ExchE, ercE);
		WaitMsg(ExchE, BogusMsg);

		/* We are NO MORE */

	}
}

/******************************************************
 This is called to execute a program without changing
 the ExitJob. This is so you can run program B from
 program A and return to program A when program B is
 done.  This runs Job B in the "context" of Job A
 which means Job B inherits the JCB and PD of job A
 so it can use things like the command line and
 path that were set up by A.
 Information can be passed to Job B by calling
 SetCmdLine (if Job B reads it), and also by
 setting the ExitError value in the parameter.
 Chain will only return to you if there was an
 error loading the Job.  In other words, if Chain
 fails in a critial section we try to load the
 ExitJob and pass it the error.
******************************************************/

long far Chain(char *pFileName, long cbFileName, long dExitError)
{
/* NO LOCAL VARIABLES BECAUSE WE SWITCH STACKS!! */

	ercE =  GetRunFile(pFileName, cbFileName, &job_fhE);
	if (ercE)
		return(ercE);

	GetJobNum(&JobNumE);
	GetpJCB(JobNumE, &pCrntJCB);		/* Get pJCB to current Job */
	pCrntJCB->ExitError = dExitError;

	/* Remove ALL tasks for this job that are at the ReadyQue.
	   The task we are in won't be removed because its RUNNING!
	*/

	RemoveRdyJob(pCrntJCB);	/* It always returns ErcOk */

	/* Deallocate all exchanges for this job except the one belonging
	   to current TSS!  The Dealloc Exchange call will invalidate
	   all TSSs found at exchanges belonging to this user, and
	   will also free up RQBs and Link Blocks.  The job will not be
	   able to initiate requests or send messages after this unless
	   it is done with the TSSExchange because it will get a kernel
	   error (invalid exchange).
	*/

	 /* Find out what our TSS exchange is so
	 we don't deallocate it to! */

	 GetTSSExch(&ExchE);

	 ercE = 0;
	 iE = 0;
	 while (ercE != ErcOutOfRange) {
	 	ercE = GetExchOwner(iE, &pExchJCBE);
		if ((!ercE) && (iE != ExchE) && (pExchJCBE == pCrntJCB))
			DeAllocExch(iE);
		iE++;
	 }

	/* Now that the user can't make anymore requests,
	   Send Abort messages to all services.
	   This closes all files that were opened by the Job
       and frees up any other resources held for this
       job by any services.
	*/

/*	SendAbort(JobNumE, ExchE); */

	/* We must now switch to a temporary stack so we can
	clean out the user PD (we are on his stack right now!).
	*/

#asm
	MOV EAX, OFFSET _TmpStack
	ADD EAX, 508
	MOV ESP, EAX
	MOV EBP, EAX
#endasm

	/* Clean the PD of all user memory leaving OS memory for next
	job if there is one.
	*/

	pPDE = pCrntJCB->pJcbPD;
	CleanUserPD(pPDE);

	/* Look for Exit Run file to load if any exists.  If no exit run
	file, we deallocate the PD and JCB then return to the JOB 1. */

	ercE = LoadJob(pCrntJCB, job_fhE);

	if (ercE) {
		/* We have errored in a critical part of Chain (LoadJob).  
		The original user's job is destroyed, and we can run the
		chain file (bummer).
		The only thing left to do is Look for Exit Run file to load
		if any exists.  If no exit run file, we kill this guy
		and return to the monitor if he had the screen. */

		GetExitJob(FileE, &cbFileE);     	/* Exit Run File!! */

		if (!cbFileE)
			ercE = ErcNoExitJob;

		if (!ercE)
			ercE =  GetRunFile(FileE, cbFileE, &job_fhE);

		if (!ercE)
			ercE = LoadJob(pCrntJCB, job_fhE);
	}

	if (!ercE) {		/* No error */

		pStart = pStart+pCode-offCode;

		/* Now we RETURN to new job's address after we put him
		on his new stack. */

#asm
		MOV EAX, _pStack
		MOV EBX, _sStack
		ADD EAX, EBX
		SUB EAX, 4
		MOV ESP, EAX
		MOV EBP, EAX
		PUSH 18h
		MOV EAX, _pStart
		PUSH EAX
		RETF				;We are history!
#endasm
	}

	if (ercE) {		/* Something failed loading the job (Chain or Exit) */

		/* In case there is no job to run or a fatal error has happened
		we send a message (ISendMsg) to the monitor status
		task with our TSSExch and the Error. Then he will WIPE US OUT!
		We use ISend (vice send) so he can't run before we get to
		the exchange otherwise we will be placed back on the readyQueue!
	    */

		ISendMsg(KillExch, ExchE, ercE);  /* ISend clears ints! */
#asm
		STI
#endasm
		WaitMsg(ExchE, BogusMsg);

		/* We are NO MORE */

	}
}


/*********************** End of Module *****************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -