📄 pci.cpp
字号:
//*************************************************************************// MODULE : PCI - Kernel resident P-code Interpreter for the RCOS system *// AUTHOR : Ron Chernich *// PURPOSE: Passed the "context" of an RCOS process, execute the next *// p-code. Interpereter developed from the stand-alone ANSI C *// version which was modeled after a Pascal version by Kin-Man *// Chung and Herbert Yuen from their October 1978 BYTE article, *// "A 'Tiny' Pascal Compiler - Part 1: The p_code Interpereter" *// HISTORY: *// 19-DEC-92 First ANSI MSC version *// 24-MAY-93 New p-code "CSP 0/EXEC" added to load & execute programs *// 27-MAY-93 Hallelujah - RCOS multi-tasks two "Hello World" programs! *// 02-JUN-93 Detect and abort on User Break messages from line driver *// 06-MAR-94 CSP Semaphore functions added *// 01-APR-94 Force TTY Auto LF mode during CSP *IN executions. *// 13-APR-94 Semaphore count initialisation added to SEM_CREATE CSP *// 18-APR-94 CSP Shared Memory support added *// 01-SEP-94 CSP File operations added (RunProc now officialy too big) *// 12-SEP-94 EOF detect added (G'wing lounge, BN-SY delayed again!) *//*************************************************************************#include "pci.hpp"#include "fsiface.hpp"#define BUF_SIZE 64 // Number of integers in buffer for program load///////////// local level function protos..//static BOOL ValidCode (UINT16, INT16);///////////////////// Execute a pcode: Fetch the next pcode and its argument (two 16 bit words)// Decode and execute, adjusting process IP, SP and BP accordingly. Begin// with a Pre-fetch of the 32 bit word at IP (the IP is a 32 bit offset):// giving: hhll aaaa// where: ll = p-code; hh = base ref; aaaa = immediate argument//// If the passed PCB struct has a reply attached, it must be as a result of// a Read/ReadBlk/SemWait from a CSP pcode, so process that. If not, pre-fetch// the top-of-stack (just about everything needs that) and parse and execute..//// Lament: This thing is getting bigger than the giant MS Windows case// statement from hell that ate Cleaveland!//void Exec::RunProc (PCB& pcbx, MCB& mcbx){ char *cp; BOOL bIsLegal; MMU_MSG memXfer; UINT16 uFsRet = FS_Ok; INT16 nFunc, nFuncBase; UINT16 uText[2], uStack[3], uTemp, *pu; static char *pszErr[] = { "\n\rHalted - %s", "User Break", "Illegal p-code", "Shared mem violation" }; memXfer.uLen = 2; memXfer.pData = uText; memXfer.uOffset = (pcbx.uIP << 1); MSG msg(uCurProc, KM_ReadBlk, mcbx.hText, &memXfer); pTx->SendMsg(ID_MMU, &msg); memXfer.uLen = 1; memXfer.pData = uStack; memXfer.uOffset = pcbx.uSP; msg = message(uCurProc, KM_ReadBlk, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); pcbx.lCode = (UINT32)uText[0] + ((UINT32)uText[1] << 16); pcbx.uTos = uStack[0]; nFunc = (INT16)(uText[0] & 0xff); nFuncBase = (INT16)(0xff & (uText[0] >> 8)); bIsLegal = ValidCode(uText[0], uText[1]); msg = message(ID_Kernel, ANI_UPDAT_PCB); pTx->SendMsg(ID_ANIM, &msg); if (!bIsLegal) { pcbx.uStatus = PS_Illegal; if (pcbx.pDev) { char str[64]; sprintf(str, pszErr[0], pszErr[2]); msg = message(pcbx.uPid, KM_WriteBlk, strlen(str), str); pTx->SendMsg(ID_LNDRV + pcbx.uPid, &msg); } return; } pcbx.uIP++; if (pcbx.pReply) { if (pcbx.pReply->wMsgType == KM_Break) { delete pcbx.pReply; pcbx.pReply = NULL; pcbx.uStatus = PS_Halted; char str[64]; sprintf(str, pszErr[0], pszErr[1]); msg = message(pcbx.uPid, KM_WriteBlk, strlen(str), str); pTx->SendMsg(ID_LNDRV + pcbx.uPid, &msg); return; } if (nFunc == CSP) if ((F_ALLOC <= uText[1]) && (uText[1] <= F_WRITE)) { uFsRet = pcbx.pReply->wMsgType; delete pcbx.pReply; pcbx.pReply = NULL; } else { if (uText[1] == 0) uStack[0] = pcbx.pReply->wParam; else if (pcbx.pReply->wMsgType != KM_Signal) { cp = new char[pcbx.pReply->wParam + 1]; strncpy(cp, (char*)pcbx.pReply->pBody, pcbx.pReply->wParam); cp[pcbx.pReply->wParam] = '\0'; sscanf(cp, ((uText[1] == HEXIN) ? "%x" : "%d"), &uStack[0]); DELETE_ARRAY pcbx.pReply->pBody; DELETE_ARRAY cp; msg = message(uCurProc, KM_IoCtrl, DM_GetMode); pTx->SendMsg(pcbx.uPid + ID_LNDRV, &msg); uTemp = msg.wParam & ~TTY_AutoLF; msg = message(uCurProc, KM_IoCtrl, DM_SetMode, &uTemp); pTx->SendMsg(pcbx.uPid + ID_LNDRV, &msg); } delete pcbx.pReply; pcbx.pReply = NULL; memXfer.pData = &uStack[0]; memXfer.uOffset = ++pcbx.uSP; MSG msg(uCurProc, KM_Write, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); return; } } switch (nFunc) { case INT: pcbx.uSP += uText[1]; break; case JMP: pcbx.uIP = uText[1]; break; case JPC: msg = message(uCurProc, KM_Read, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); if (uStack[0] == (UINT16)nFuncBase) pcbx.uIP = uText[1]; pcbx.uSP--; break; case LIT: memXfer.pData = &uText[1]; memXfer.uOffset = ++pcbx.uSP; msg = message(uCurProc, KM_Write, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); break; case LOD: case LODX: if (nFunc == LODX) uText[1] += uStack[0]; else ++pcbx.uSP; memXfer.pData = &uStack[0]; memXfer.uOffset = pcbx.uBP; msg = message(uCurProc, KM_Read, mcbx.hStack, &memXfer); while (nFuncBase--) { pTx->SendMsg(ID_MMU, &msg); memXfer.uOffset = uStack[0]; } memXfer.uOffset += uText[1]; msg = message(uCurProc, KM_Read, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); memXfer.uOffset = pcbx.uSP; msg = message(uCurProc, KM_Write, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); break; case STO: case STOX: uStack[1] = uStack[0]; if (nFunc == STOX) { memXfer.uOffset = pcbx.uSP - 1; msg = message(uCurProc, KM_Read, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); uText[1] += uStack[0]; } memXfer.pData = &uStack[0]; memXfer.uOffset = pcbx.uBP; msg = message(uCurProc, KM_Read, mcbx.hStack, &memXfer); while (nFuncBase--) { pTx->SendMsg(ID_MMU, &msg); memXfer.uOffset = uStack[0]; } memXfer.uOffset += uText[1]; memXfer.pData = &uStack[1]; msg = message(uCurProc, KM_Write, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); pcbx.uSP -= ((nFunc == STOX) ? 2 : 1); break; case CAL: msg = message(uCurProc, KM_Read, mcbx.hStack, &memXfer); memXfer.pData = &uStack[0]; memXfer.uOffset = pcbx.uBP; while (nFuncBase--) { pTx->SendMsg(ID_MMU, &msg); memXfer.uOffset = uStack[0]; } uStack[0] = memXfer.uOffset; uStack[1] = pcbx.uBP; uStack[2] = pcbx.uIP; memXfer.uLen = 3; memXfer.uOffset = pcbx.uSP + 1; msg = message(uCurProc, KM_WriteBlk, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); pcbx.uIP = uText[1]; pcbx.uBP = pcbx.uSP + 1; break; case OPR: switch (uText[1]) { case _RET: pcbx.uSP = pcbx.uBP - 1; memXfer.uLen = 2; memXfer.pData = uStack; memXfer.uOffset = pcbx.uSP + 2; msg = message(pcbx.uPid, KM_ReadBlk, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); pcbx.uBP = uStack[0]; pcbx.uIP = uStack[1]; if ((INT16)pcbx.uBP < 0) { pcbx.uStatus = PS_Halted; if (pcbx.pDev) { char str[16]; strcpy(str, "\n\rHalted - Ok"); msg = message(pcbx.uPid, KM_WriteBlk, strlen(str), str); pTx->SendMsg(ID_LNDRV + pcbx.uPid, &msg); } } break; case _NEG: uStack[0] = (UINT16)(0 - (INT16)uStack[0]); break; case _CPY: pcbx.uSP++; break; case _NOT: uStack[0] = ~uStack[0]; break; case _INC: ++uStack[0]; break; case _DEC: --uStack[0]; break; case _LOW: uStack[0] &= 1; break; default: uStack[1] = uStack[0]; memXfer.uOffset = --pcbx.uSP; msg = message(uCurProc, KM_Read, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); switch (uText[1]) { case _ADD: uStack[0] = (UINT16)((INT16)uStack[0] + (INT16)uStack[1]); break; case _SUB: uStack[0] = (UINT16)((INT16)uStack[0] - (INT16)uStack[1]); break; case _MUL: uStack[0] = (UINT16)((INT16)uStack[0] * (INT16)uStack[1]); break; case _DIV: uStack[0] = (UINT16)((INT16)uStack[0] / (INT16)uStack[1]); break; case _MOD: uStack[0] = (UINT16)((INT16)uStack[0] % (INT16)uStack[1]); break; case _AND: uStack[0] &= uStack[1]; break; case _OR: uStack[0] |= uStack[1]; break; case _XOR: uStack[0] ^= uStack[1]; break; case _SHR: uStack[0] >>= uStack[1]; break; case _SHL: uStack[0] <<= uStack[1]; break; case _EQ: uStack[0] = (uStack[0] == uStack[1]) ? 1 : 0; break; case _NE: uStack[0] = (uStack[0] != uStack[1]) ? 1 : 0; break; case _LT: uStack[0] = ((INT16)uStack[0] < (INT16)uStack[1]) ? 1 : 0; break; case _GT: uStack[0] = ((INT16)uStack[0] > (INT16)uStack[1]) ? 1 : 0; break; case _LE: uStack[0] = ((INT16)uStack[0] <= (INT16)uStack[1]) ? 1 : 0; break; case _GE: uStack[0] = ((INT16)uStack[0] >= (INT16)uStack[1]) ? 1 : 0; break; } break; } if (uText[1] != _RET) { memXfer.uOffset = pcbx.uSP; msg = message(uCurProc, KM_Write, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); } break; case CSP: switch (uText[1]) { case CHIN: case NUMIN: case HEXIN: pcbx.uIP--; msg = message(uCurProc, KM_IoCtrl, DM_GetMode); pTx->SendMsg(pcbx.uPid + ID_LNDRV, &msg); uTemp = msg.wParam | TTY_AutoLF; msg = message(uCurProc, KM_IoCtrl, DM_SetMode, &uTemp); pTx->SendMsg(pcbx.uPid + ID_LNDRV, &msg); msg = message(uCurProc,((uText[1] == CHIN) ? KM_Read : KM_ReadBlk)); pTx->PostMsg(pcbx.uPid + ID_LNDRV, &msg); break; case CHOUT: msg = message(uCurProc, KM_Write, uStack[0]); pTx->SendMsg(pcbx.uPid + ID_LNDRV, &msg); pcbx.uSP--; break; case NUMOUT: if (cp = new char[8]) { sprintf(cp, " %d", uStack[0]); msg = message(uCurProc, KM_WriteBlk, strlen(cp), (void*)cp); pTx->SendMsg(pcbx.uPid + ID_LNDRV, &msg); DELETE_ARRAY cp; } pcbx.uSP--; break; case HEXOUT: if (cp = new char[8]) { sprintf(cp, " %x", uStack[0]); msg = message(uCurProc, KM_WriteBlk, strlen(cp), (void*)cp); pTx->SendMsg(pcbx.uPid + ID_LNDRV, &msg); DELETE_ARRAY cp; } pcbx.uSP--; break; case STROUT: if (pu = new UINT16[uStack[0]]) { memXfer.pData = pu; memXfer.uLen = uStack[0]; memXfer.uOffset = pcbx.uSP - uStack[0]; msg = message(uCurProc, KM_ReadBlk, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); if (cp = new char[uStack[0]]) { for (INT16 i = 0; i < (INT16)uStack[0]; i++) cp[i] = (char)pu[i]; msg = message(uCurProc, KM_WriteBlk, uStack[0], cp); pTx->SendMsg(pcbx.uPid + ID_LNDRV, &msg); DELETE_ARRAY cp; } DELETE_ARRAY pu; } pcbx.uSP -= (uStack[0] + 1); break; case FORK: uStack[0] = Fork(); memXfer.uLen = 1; memXfer.pData = uStack; memXfer.uOffset = pcbx.uSP; msg = message(uCurProc, KM_ReadBlk, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); if (uStack[0] != NO_PROC) { msg = message(uStack[0], KM_ReadBlk, mcbx.hStack, &memXfer); uStack[0] = 0; pTx->SendMsg(ID_MMU, &msg); } break; case EXEC: if (pu = new UINT16[uStack[0]]) { memXfer.pData = pu; memXfer.uLen = uStack[0]; memXfer.uOffset = pcbx.uSP - uStack[0]; msg = message(uCurProc, KM_ReadBlk, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); if (cp = new char[uStack[0] + 1]) { INT16 i; for ( i = 0; i < (INT16)uStack[0]; i++) cp[i] = (char)pu[i]; cp[i] = '\0'; FILE *ipf = fopen(cp, "rb"); if (ipf) { UINT16 uBuf[BUF_SIZE]; memXfer.uLen = BUF_SIZE; memXfer.uOffset = 0; memXfer.pData = uBuf; msg = message(uCurProc, KM_WriteBlk, mcbx.hText, &memXfer); while (fread(uBuf, sizeof(UINT16), BUF_SIZE, ipf)) { pTx->SendMsg(ID_MMU, &msg); memXfer.uOffset += BUF_SIZE; } fclose(ipf); } DELETE_ARRAY cp; } DELETE_ARRAY pu; } pcbx.uBP = 1; pcbx.uIP = pcbx.uSP = 0; msg = message(uCurProc, KM_WriteBlk, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); // // ************ // TEMP MEASURE // ************ // pcbx.pDev = new LnDrv(pcbx.uPid, ID_LNDRV + pcbx.uPid, pTx); break; case SEM_CREATE: uTemp = uStack[0]; pcbx.uSP--; memXfer.uLen = 1; memXfer.pData = uStack; memXfer.uOffset = pcbx.uSP; msg = message(uCurProc, KM_ReadBlk, mcbx.hStack, &memXfer); pTx->SendMsg(ID_MMU, &msg); if (nFuncBase) if (pu = new UINT16[uStack[0]]) { UINT16 uSid; memXfer.pData = pu; memXfer.uLen = uStack[0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -