// Midas.bcpl -- Main program // Last edited: 16 November 1979 get "altofilesys.d" get "streams.d" get "mdecl.d" get "mcommon.d" external [ // OS Resets; TruncateDiskStream; Closes; Puts; GetCompleteFa; JumpToFa CreateDiskStream; lvUserFinishProc; DoubleAdd; Timer; MyFrame GotoLabel // MASM Wss; @MBlock; ErrorProtect; DoubleNeg; DoubleDiv // MDATA LastTimer; TimeStart // MSYM StreamFromTextName // MTXTBUF TxtBNewChar; InputTextBuffer // MIOC DWns; Wns // MOVERLAY KillOverlays // MDISP FinishDisplay; SetDisplay // MRGN DriverLoop // MMENU ExecuteTextCmdStream; EscAction; CFileStream // MCMD CmdDoRC; DisplayError; RunProgMenu; StartCmdOverlay // MCMDOV TextCmdOutStream // MGO StartSetup; HaltWait // MINIT0 Init0; TimeStream; MStatus // MINIT1 Init1 // MINIT2 Init2 // ACTIONS NoopAction // Machine dependent FinishHardware // Defined here Nmidas; InitRes; StartTimer; ElapsedTime; PrintTime; MidasFinish MidasSwat TopFrame; Resume; BegCF; @NestedCFiles; lvFinishProc; Initialized TimerGoing; SysZoneSize; StackSize; StateFileSize TimeJunta; TimeLoadRam; TimeJunkInit; TimeLookup1; TimeCreateFiles TimeOvScan; TimeLookup2; TimeQFiles; TimeMSYM; TimeInit1 TimeLoad; TimeSwapInit2; TimeScreenInit; TimeRCActions TimeInitHardware; TimeCmdMenu1; TimePaintRegions; TimeInit2Menu TimeCmdMenu2; TimeLoadOvl; TimeComCM; TimeFinish CodeOS; StorageSize; BBblockSize; AvailBlockSize; FinalStorage ] static [ Initialized = false; TimerGoing = false; TopFrame; lvFinishProc @NestedCFiles = 0 // Initialization statistics for DoradoMidas on 27 October 79 TimeJunta //(0.011) Runtime after Junta TimeJunkInit //(0.020) Assorted GetStorage calls TimeLoadRam //(0.178) After InitHardware1 (LoadRam primarily) TimeLookup1 //(0.637) After building FP's for Midas files //**Midas/I only** TimeOvScan // (2.385) After OverlayScan TimeCreateFiles //(.002,4.613) After creating auxiliary files TimeLookup2 // (0.565) After 2nd LookupEntries call TimeQFiles // (1.130) Build FP's from Midas.Programs & // Midas.UserPrograms TimeMSYM // (0.198) MSYM init, swap in Load overlay TimeInit1 // (0.155) Make MPD, MDFS, RGN structures TimeLoad // (0.992) Open Midas.Midas + Ld in command file // (.13 slower if LOADER.MB not dumped) TimeRestoreState //(4.707) Rest of Midas.Midas on Midas/I -or- //(3.143) Rest of Midas.Midas if temp files exist -or- //(0.387) RestoreState TimeSwapInit2 //(0.166) Loading Init2 overlay TimeScreenInit //(0.008) Init ScreenTV, ControlV, and display TimeRCActions //(0.003) Create RdCmds and RunProg actions TimeComCM //(0.181) Reading Com.CM TimeInitHardware //(1.399) InitHardware() TimeCmdMenu1 //(0.042) Forming regular command menu TimePaintRegions //(0.057) Paint non-MPD lines //**Init2 menu only (select Dorado)** TimeInit2Menu // (indeterminate) TimeCmdMenu2 // (0.044) Forming regular command menu TimeLoadOvl //(0.495) Loading overlays into space avilable TimeFinish //(18.131) Midas/i and create temporary files -or- //(11.293) Midas/i, temp files already exist -or- //( 3.799) Total time when not Midas/i TimeUpdate //(0.172) Runtime at call to DriverLoop //Screen update times determined manually // (0.106) in ClearAndScanConvert // (0.097) in FormMPDMenu & below // (0.071) in MarkMenus & below // (0.069) in DatatoStream & below // (0.037) in MPDEveryTime // (0.012) in MGetxx // Storage statistics CodeOS // (21130) OS after Junta to levStreams // (was 25600 when Junta'd to levKeyboard) //StackSize large enough for SimGo action to be called from a command file. StackSize = #4400 StorageSize //(54271) Original size excluding stack and init code //SysZoneSize = #6400 is enough for #5100 words of SimGo overlay and open //command and output files. Other worst case is two open files during //Ld, plus open command and output files. SysZoneSize = #6400 BBblockSize //(26330) Bit buffers AvailBlockSize //(20010) OverlayZone (part of bit buffers) //(1065 words/line at ScreenWidth eq 76) FinalStorage //(14315) Free storage available for additional FP's in //Midas.Programs and Midas.UserPrograms & Midas additions; //used meanwhile for overlays made resident and symbols. StateFileSize //(15236) Words on Midas.RunProg or Midas.Dtach // TimeFont (0.261) Reading gacha10.al **no longer do this** // BBWait (in MDATA) is the loop count waiting for bit buffers (~ 562) ] manifest [ MaxNestedCFiles = 8 ] let Nmidas(Layout,userParams,CFA) be [ StartTimer() Init0(Layout,userParams,CFA) //Never returns ] //Enter with GotoLabel from Init0A--never returns and InitRes(nil) be [ TopFrame = MyFrame() let CFileStack = vec lCFA*MaxNestedCFiles //Init1 returns only on Midas/I; otherwise, does RestoreState(..) to //"Resume". CFileStack is used to return the FP for MIDAS.MIDAS //and as TempStorage for Init0B(..). Init1(CFileStack) //Execute MIDAS.MIDAS comfile which must leave display off and not activate //hardware interface. MIDAS.MIDAS must write two state files: //MIDAS.DTACH for starting Midas from the Exec or from a Dtach; //MIDAS.RUNPROG for reinitializing on RunProg. ErrorProtect(lv ExecuteTextCmdStream, CreateDiskStream(CFileStack+(offset DV.fp/16), ksTypeReadOnly,charItem)) Resume: ElapsedTime(lv TimeRestoreState) //Display is off here, returns non-0 if com-file on input line. let CFS = Init2(); KillOverlays() //If the machine is running at this time, wait for halt, abort, or Dtach. if MStatus>>MStatus.MachRunning ne 0 do [ SetDisplay(false) //Display on StartCmdOverlay(lv StartSetup,HaltWait) SetDisplay(true) //Display off ] //On initialization, execute command file from Exec's command line; on //RunProg, execute command file named on input text line or in menu. if CFS then ErrorProtect(lv CmdDoRC,lv RunProgMenu) //CmdDoRC jumps here with GotoLabel, ensuring that the stack won't get too //deep during nested command files. An open stream exists for only one //command file at-a-time; its callers are remembered on CFileStack. BegCF: test InputTextBuffer!0 ne 0 //Start comfile ifso [ test CFileStream eq 0 ifso SetDisplay(true) //Display off for first comfile ifnot //Push previous comfile [ test NestedCFiles ge MaxNestedCFiles ifso [ ErrorProtect(lv DisplayError,"Comfile nesting > 8 levels") CFS = CFileStream; goto(RetCF) ] ifnot [ GetCompleteFa(CFileStream,CFileStack+(NestedCFiles*lCFA)) NestedCFiles = NestedCFiles+1 Closes(CFileStream) ] ] CFileStream = -1 //StreamFromTextName will ErrorExit(..) with the display on if any error //occurs, resulting in a call on DisplayError because CFileStream is ne 0 CFS = ErrorProtect(lv StreamFromTextName,InputTextBuffer, ".MIDAS",ksTypeReadOnly,charItem) ] ifnot CFS = CFileStream //Aborted RunProg or RdCmds RetCF: CFileStream = 0 if CFS ne 0 then ExecuteTextCmdStream(CFS) TxtBNewChar(#177) if NestedCFiles > 0 do //Pop comfile from stack & continue [ NestedCFiles = NestedCFiles-1 let CFA = CFileStack+(NestedCFiles*lCFA) CFS = CreateDiskStream(lv CFA>>CFA.fp,ksTypeReadOnly,charItem) JumpToFa(CFS,lv CFA>>CFA.fa) goto(RetCF) ] PrintComputeTime() SetDisplay(false); ElapsedTime(lv TimeUpdate) EscAction = NoopAction DriverLoop(); finish ] and MidasFinish() be [ if TextCmdOutStream ne 0 do [ TruncateDiskStream(TextCmdOutStream); Closes(TextCmdOutStream) ] FinishDisplay(); FinishHardware() @lvUserFinishProc = lvFinishProc ] //Puts Timer in TimeStart and LastTimer vectors and StartTimer() be [ Timer(TimeStart) //Don't use MBlock here because not initialized at first call LastTimer!0,LastTimer!1 = TimeStart!0,TimeStart!1 TimerGoing = true ] //TimeV!0←low-order word of Timer-LastTimer, high-order word returned. //LastTimer←Timer. and ElapsedTime(TimeV) = valof [ let X = vec 1; MBlock(X,LastTimer,2); DoubleNeg(X) Timer(LastTimer); DoubleAdd(X,LastTimer) TimeV!0 = X!1; resultis X!0 ] //Timer covers about 1200 hours and PrintComputeTime() be [ MBlock(LastTimer,TimeStart,2) let Y = vec 1; Y!0 = ElapsedTime(Y+1) TimeFinish = Y!1 //Single-precision result in TimeFinish PrintTime(Y) TimerGoing = false ] //Prints the elapsed time in double-precision V on TimeStream and PrintTime(V) be [ let TimeParse = vec 3 DoubleAdd(V,table [ 0; 5 ] ) //For rounding to 100ths TimeParse!3 = DoubleDiv(V,1000)/10 //Y←seconds, excess 100ths TimeParse!2 = DoubleDiv(V,60) //Y←minutes, excess sec TimeParse!1 = DoubleDiv(V,60) //Y←hours, excess min TimeParse!0 = DoubleDiv(V,24) //Y←days, excess hrs Resets(TimeStream); Wss(TimeStream,"Time: ") let Printing = false if V!1 ne 0 do [ Wns(TimeStream,V!1,0,10); Wss(TimeStream," days ") Printing = true ] for I = 0 to 3 do [ if (TimeParse!I ne 0) % (I eq 2) then Printing = true if Printing do [ DWns(TimeStream,TimeParse+I,16,0,10,2,$0) let Char = table [ $:; $:; $.; 0 ] !I if Char ne 0 then Puts(TimeStream,Char) ] ] ] and MidasSwat(ErrNo,P1,P2,P3,P4,P5) be [ (table [ #77403; #1401 ] )("Midas.Errors",lv ErrNo) ]