📄 rcos.cpp
字号:
Rcos.AppDestroy(RC_RadioBtn, RB_TTY1); Rcos.AppDestroy(RC_RadioBtn, RB_TTY2); } Rcos.AppDestroy(RC_PushBtn, PB_RUN); Rcos.AppDestroy(RC_PushBtn, PB_PAUSE); Rcos.AppDestroy(RC_PushBtn, PB_STEP); Rcos.AppDestroy(RC_PushBtn, PB_ABOUT); Rcos.AppDestroy(RC_RadioBtn, RB_PM); Rcos.AppDestroy(RC_RadioBtn, RB_MM); Rcos.AppDestroy(RC_RadioBtn, RB_RM); Rcos.AppDestroy(RC_RadioBtn, RB_DM); Rcos.AppDestroy(RC_CheckBox, CB_CONF);}////////////////////////////////////////////////////////////////////////////// //// RCOS is controlled from here. To give the appearence of concurrency //// without pre-emptive interrupts, the three operations in the main //// program loop should do as little as possible before yielding to each //// other. Actual control (supervision) of the OS is ALL performed here. //// Supervisor gadgets set booleans which control running and stepping. //// The Kernel runs on Messages. These are posted into its queue by the //// Operator's Console Command parser, Device Drivers and Kernel itself //// (it's usefull to post messages to youself!) On each pass through the //// loop, Kernel extracts and actions one message - if there are any. If //// there are no messages in the queue, the Kernel scheduler gets control //// and runs the P-code interpreter to execute a single p-code. //// ////////////////////////////////////////////////////////////////////////////////void main( void ){// rect r; UINT32 lParam; UINT16 msg, wParam, nRbLast; BOOL bState, bRun = FALSE, bStep = FALSE, bFirst = TRUE, bActive = TRUE, bReTitle = FALSE; static char *pszDisp[] = {"cpu scheduler", "memory manager", "resource manager", "devices", NULL }; static char *pszExit[] = {"RCOS is about to terminate.", " ", "Are you sure you want to exit now?", NULL }; static char *pszHelp[] = {"This program is CUA complient.", " ", "Use the mouse, or press ALT+Underlined char to", "activate a control. Press ALT+F4 to terminate.", NULL }; static char *pszRcos[] = {"RCOS - A multi-tasking OS simulator.", "Written by Ronald A Chernich (1993)", "for the Department of Maths and Computing", "of the University of Central Queensland.", NULL }; if (Rcos.AppRunning()) { // // Since the application framework seems to be running, we can // instantiate the Kernel, followed by all the device drivers, // passing their constructors a pointer to the Kernel. They will // notify it of their existance by message passing. This greatly // simplifies design changes. // Preferences Prefs; Knl Kernel(Prefs.GetPrefInt(PREFS_QUAN, PCD_QUANTUM)); tty OpCon(ID_TTY0, CLS_VDU, &Kernel, rect(CON_X1, CON_Y1, CON_X2-CON_X1, CON_Y2-CON_Y1), _Black, _BrightWhite); UINT16 nTerms = Prefs.GetPrefInt(PREFS_TTYS, NUM_TTY); if ( nTerms == 0 ) nTerms = 2; Mmu MemMan(ID_MMU, CLS_SysRes, &Kernel); CpmFs FileSys(ID_FS, CLS_SysRes, &Kernel); Animate Ani(ID_ANIM, CLS_SysRes, &Kernel, nTerms); DskModel ADrive(ID_DISK_A, CLS_FSF, &Kernel, "CPMA", _IBM3740, _SSSD.nLid); if (ADrive.IsOnLine()) FileSys.MountDrive(ID_DISK_A, 'A', _IBM3740, _SSSD); //_SSSD.nLid = 1; //DskModel BDrive(ID_DISK_B, CLS_FSF, &Kernel, "CPMB", _IBM3740, _SSSD.nLid); //if (BDrive.IsOnLine()) // FileSys.MountDrive(ID_DISK_B, 'B', _IBM3740, IBM_SSSD); Mickey.HidePointer(); { char st[32]; Prefs.GetPrefStr(PREFS_VIEW, pszDisp[0], st, sizeof(st)); UINT16 nInit = 0; while (pszDisp[nInit]) if (strcmp(pszDisp[nInit], st)) ++nInit; else break; if (NULL == pszDisp[nInit]) nInit = 0; PaintCtrls(nInit); Ani.SetCurWin(nInit, bReTitle); nRbLast = RB_PM + nInit; } if (Ani.GetCurWin() == CPU_DISP) { MSG mess = message(ID_NULL, ANI_REFRESH, Ani.GetCurWin()); Kernel.SendMsg(ID_ANIM, &mess); } OpCon.SetMode(TTY_Active | TTY_UConly | TTY_UseANSI | TTY_IBar); OpCon.ReFresh(); Mickey.ShowPointer(); while (bActive) { // // RCOS called here - each call to Kernel will do one of: // * Dispatch a message (thus running a device driver). // * Perform task switch if quantum expired. // * Execute a pcode, task switching if pcode calls "slow" operation. // // We start the clock before the kernel code runs and stops it // again after the Kernel has had its time slice. This allows // the Kernel to perform reasonably accurate time accounting. // Each emulated disk drive also get some time to spin it wheels // and see if any pending operation has completed... // if (bRun || bStep) { Clock.Start(); bStep = Kernel.Run(); Clock.Stop(); ADrive.Scheduler(); //BDrive.Scheduler(); } if (Rcos.AppGetMsg(msg, wParam, lParam)) { switch (msg) { case RC_Close: if (Rcos.AppCBstate(CB_CONF, bState) == FALSE) bActive = FALSE; else bActive = (bState ? (BOOL)(ID_CANCEL == MessageBox("Information!", pszExit, MB_YESCANCEL)) : FALSE); break; case RC_Click: switch (wParam) { case PB_RUN: bRun = TRUE; Rcos.AppTitle("Running.."); if (bFirst) { Kernel.Startup(); bFirst = FALSE; } break; case PB_PAUSE: bRun = FALSE; bStep = FALSE; Rcos.AppTitle("Paused.."); break; case PB_STEP: bStep= TRUE; bRun = FALSE; Rcos.AppTitle("Step Mode Active."); break; case PB_ABOUT: MessageBox("About the Author", pszRcos, MB_OK); break; default: if ((wParam >= RB_PM) && (wParam <= RB_TTY_BASE + nTerms - 1)) nRbLast = wParam; if ( ((wParam - RB_PM) != (UINT16)Ani.GetCurWin()) && ((wParam >= RB_PM) && (wParam <= RB_DM)) ) { Ani.SetCurWin((wParam - RB_PM), bReTitle); MSG mess = message(ID_NULL, ANI_REFRESH, Ani.GetCurWin()); Kernel.SendMsg(ID_ANIM, &mess); } } bReTitle = ((wParam <= PB_STEP) ? TRUE : FALSE); break; case RC_Paint: PaintFixed(); Ani.SetCurWin(Ani.GetCurWin(), bReTitle); OpCon.ReFresh(); Rcos.pMain->Refresh(); break; case RC_HelpKey: Rcos.AppTitle(pszTitle); MessageBox("Help", pszHelp, MB_OK); break; } } // // Dispatch any user keystrokes to one of the tty devices based on // the current radio button setting. Note that unless the TTY's // are visible, they can't get input (reasonable). Changing the // display from the "Devices" automatically resets input to the // operator's console, as does the "Devices" button at all times.. // if (KbdIn.KeyHit(_ASC)) { MSG mess(ID_Kernel, KM_KeyPress, (UINT16)KbdIn.KeyGet(_ASC)); UINT16 wDest = (nRbLast >= RB_TTY_BASE) ? ID_TTY_BASE + (nRbLast - RB_TTY_BASE) : ID_TTY0; Kernel.PostMsg(wDest, &mess); } } DestroyCtrls((UINT16)Ani.GetCurWin()); }}/////////////////////////////////// EOF ////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -