// midas.bcpl // midas main program get "sysdefs.d" //Needed for def of levDirectory get "altofilesys.d" get "streams.d" external [ // OS CallSwat; Junta; MoveBlock; lvUserFinishProc; DoubleAdd Resets; OpenFile; Timer // MASM ErrorProtect // MDISP FinishDisplay; SetDisplay // MRGN DriverLoop; UpdateDisplay // MMPRGN DoubleNeg // MMENU ExecuteTextCmdStream // MTXTBUF TxtBNewChar // STATE Storage; EndStorage GetStorage; StorageLeft; SaveState; RestoreState // MINIT0 Init0; mdsInitFP; StateStream // MINIT1 Init1 // MINIT2 Init2; DInit0 // MINIT3 Init3 // MCMD CmdDoRC; PrintComputeTime; CFOutStream // MOVERLAY KillOverlays // Machine dependent InitHardware; FinishHardware // Defined here Nmidas; CopyTemplate; PutField; GetField; StartTimer; ElapsedTime MidasFinish; StateBlockSize; Restoring; lvFinishProc MidasCFA; FirstStatic; LastStatic; Switch; Initialized; HaveHardware TimeStart; TimeJunta; TimeLoadRam; TimeLookup; TimeOvScan TimeQFiles; TimeFont; TimeMRGN; TimeMAP; TimeMSYM; TimeMMPRGN TimeLoad; TimeInit3; TimeFinish ] static [ Initialized = false; HaveHardware = true; Restoring lvFinishProc MidasCFA // To save CFA for Midas.run across Junta StateBlockSize = 140B // Number of saved page zero statics * 2 FirstStatic // Address of first program static from Layout vector LastStatic // Last static in program from Layout vector Switch // Command line switch to program // statistics TimeStart // - Timer() at start TimeJunta // Runtime after Junta TimeLoadRam // Runtime after LoadRam TimeLookup // Runtime after building FP's for Midas files TimeOvScan // Runtime after OverlayScan TimeQFiles // Runtime after building FP's for programs TimeFont // Runtime after reading gacha10.al TimeMRGN // Runtime after MRGN init TimeMAP // Runtime after InitFmap TimeMSYM // Runtime after MSYM init TimeMMPRGN // Runtime after MMPRGN init TimeInit1 // Runtime after Display initialization TimeLoad // Runtime after LOAD in command file TimeCFile // Runtime after command file init TimeInit3 // Runtime after Init3 TimeFinish // Runtime at call to DriverLoop ] let Nmidas(Layout,userParams,CFA) be [ FirstStatic = Layout!26 LastStatic = Layout!27 Switch = userParams!1 TimeStart = table [ 0; 0 ] ; StartTimer() //Since all statics are preserved by SaveState/RestoreState need to make //some storage which is safe. Restoring!0 is true if //MidasFinish should boot regular Alto microcode, else false. //Restoring!1 is a pointer to the command file name or 0 if Com.CM //should be read. Restoring = table [ 0; 0; 0; 0 ] //Save Midas.run CFA across Junta for OverlayScan MidasCFA = table [ 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0 ] MoveBlock(MidasCFA,CFA,lCFA) Junta(levDirectory,InitMidas) ] and InitMidas() be [ // Init0 returns true if full initialization should be done. The // stream for save or restore is left in StateStream test Init0(MidasCFA,Switch) ifso [ Storage = Init0 //Add Init0 code to free storage Init1(); ElapsedTime(lv TimeInit1) Storage = DInit0 //Add Init1 code to free storage let EndSave = EndStorage Init2() //First display Init just to make OverlayZone ErrorProtect(lv ExecuteTextCmdStream, OpenFile(0,ksTypeReadOnly,charItem,0,mdsInitFP)) TxtBNewChar(177B) KillOverlays(); EndStorage = EndSave ElapsedTime(lv TimeCFile) SaveState(StateStream,Resume) ] ifnot RestoreState(StateStream,false) Resume: InitHardware() //It is safe to postpone display initialization because no screen //painting occurs until SetDisplay turns on the display below Init2() //Repeat display init (avoid saving all the bit //buffers by doing this twice) if Init3(Restoring!1) then [ KillOverlays(); CFOutStream = Restoring!3 ErrorProtect(lv CmdDoRC) ] KillOverlays(); PrintComputeTime(); UpdateDisplay() if Restoring!2 ne 0 then ExecuteTextCmdStream(Restoring!2) SetDisplay(false); DriverLoop(); finish ] and MidasFinish() be [ FinishDisplay(); if Restoring!0 eq 0 then FinishHardware() @lvUserFinishProc = lvFinishProc; Restoring!0 = 0 ] and CopyTemplate() be return // needed by levStreams and StartTimer() be [ Timer(TimeStart); DoubleNeg(TimeStart) ] and ElapsedTime(lvStatic) = valof [ let X = GetStorage(2); Timer(X); DoubleAdd(X,TimeStart) rv lvStatic = X; resultis X ] and PutField(Bit1, NBits, DVec, Field) be [ if (NBits le 0) % (NBits > 16) then CallSwat() let Wx = Bit1 rshift 4 // Bit1 starts at 0 let LBx = (Bit1 & 17B) + NBits let Mask = #177777 rshift (16-NBits) let Shift = 16 - LBx if LBx le 16 then // fits in one word [ DVec!Wx = ( (DVec!Wx) & not(Mask lshift Shift)) logor ((Field & Mask) lshift Shift) return ] Shift = -Shift DVec!Wx = ((DVec!Wx) & not(Mask rshift Shift)) logor ((Field & Mask) rshift Shift) Shift = 32-LBx DVec!(Wx+1) = ((DVec!(Wx+1)) & not(Mask lshift Shift)) logor ((Field & Mask) lshift Shift) ] and GetField(Bit1, NBits, DVec) = valof [ if (NBits le 0) % (NBits > 16) then CallSwat() let Wx = Bit1 rshift 4 let LBx = (Bit1 & 17B) + NBits if LBx le 16 then // field fits in one word resultis ((DVec!Wx) rshift (16-LBx)) logand ( #177777 rshift (16-NBits) ) let Part1 = (DVec!Wx) & (#177777 rshift (LBx - NBits)) let Part2 = ((DVec!(Wx+1)) rshift (32-LBx)) resultis ( Part1 lshift (LBx-16)) logor Part2 ]