// SaveState.bcpl // Copyright Xerox Corporation 1979 // Last modified March 5, 1979 1:50 PM by Boggs get "Streams.d" get "AltoFileSys.d" get "AltoDefs.d" get "Disks.d" external [ // outgoing procedures SaveState // incoming procedures OpenFile; Closes; CreateDiskStream WriteBlock; PositionPage; SetFilePos; GetCompleteFa OutLd; RealDiskDA; EnumerateFp ReadDiskDescriptor; WriteDiskDescriptor MoveBlock; Zero; BitBlt; SetBlock; InitializeZone MyFrame; ReadCalendar; CallSwat; StartIO DisableInterrupts; EnableInterrupts // incoming statics sysDisk; sysZone; UserName; UserPassword; OsVersion AltoVersion; SerialNumber; fpSysDir; fpDiskDescriptor ] //---------------------------------------------------------------------------- let SaveState(filename, flags; numargs na) = valof //---------------------------------------------------------------------------- // Saves the present core image on an S0 boot file. // See the BuildBoot documentation for more on boot files. // This code is is mostly pieces of BootInit.bcpl -- OS initialzation. // If (flags & 1) ne 0 then flush disk state after creating file. // If (flags & 2) ne 0 then read disk state after booting. // Returns: // 0 if we OutLded // 1 if we InLded // 2 if we DiskBooted // 3 if we EtherBooted [ if OsVersion ls 16 then CallSwat("OsVersion must be ge 16") if na eq 1 then flags = 0 Zero(UserName, UserName!-1) Zero(UserPassword, UserPassword!-1) let fp, fprd = vec lFP, vec lFP GetFP(filename, ksTypeWriteOnly, fp, fprd) if (flags & 1) ne 0 then WriteDiskDescriptor() // Save page 1 in a vector in our stack. // Cold starting does not restore it, so we must. let page1 = vec 256; MoveBlock(page1, 400b, 256) // If we are started by InLd or BootFrom, we will 'return' from OutLd with: // outLdResult = 0 if we OutLded ourself onto the disk // outLdResult = 1 if we InLded fro the disk (InLd) // outLdResult = 2 if we booted from the disk (hardware Boot or BootFrom) // If we are started cold, we will 'materialize' at ColdStart with: // outLdResult = 3 if we cold started (EtherBoot) let outLdResult = 0 @0 = 3 // jmp @0 to cold start @1 = MyFrame() // stack frame for cold starting @2 = ColdStart // -> cold start initialization @3 = 030001b // lda 2 1 @4 = 002002b // jmp @2 ColdStart: test outLdResult eq 3 ifso for p = 0 to 6 by 2 do [ //restore locations 400b-427b, etc let ta = table [ 400b; 427b; 431b; 520b; 524b; 567b; 600b; 777b ] for i = ta!p to ta!(p+1) do @i = page1!(i-400b) ] ifnot [ outLdResult = 3 //this is the value saved on the file DisableInterrupts() outLdResult = OutLd(fprd, 0) ] if outLdResult ne 0 then [ SerialNumber = StartIO(0) & 377b AltoVersion = (table [ 61014b; 1401b ])() @613b = AltoVersion<>BBT.dBank = 1 bbt>>BBT.sBank = 1 //127 "scan lines" of 512 words each. //skip I/O area in high memory. bbt>>BBT.dbmr = 512 bbt>>BBT.sbmr = 512 bbt>>BBT.dw = 512 * 16 bbt>>BBT.dh = 127 BitBlt(bbt) ] ] ] let temp = @activeInterrupts @activeInterrupts = 0 EnableInterrupts() @wakeupsWaiting = 0 @activeInterrupts = temp @diskAddress = -1 //invalidate disk arm position. @MESR = 0 @MECR = 177773b //correction on, report double errors SetBlock(0, 77400b, 16) if (flags & 2) ne 0 then [ ReadDiskDescriptor() EnumerateFp(ZapFP) MoveBlock(fpSysDir, sysDisk>>DSK.fpSysDir, lFP) MoveBlock(fpDiskDescriptor, sysDisk>>DSK.fpDiskDescriptor, lFP) GetFP("Swatee", ksTypeReadOnly, 0, trapVector!37b+4) GetFP("Swat", ksTypeReadOnly, 0, trapVector!37b+9) ] if outLdResult eq 0 then [ let stream = CreateDiskStream(fp) SetFilePos(stream, 0, 6) let dv = vec 1; ReadCalendar(dv) WriteBlock(stream, dv, 2) Closes(stream) ] resultis outLdResult ] //---------------------------------------------------------------------------- and ZapFP(fp) be Zero(fp, lFP) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and GetFP(filename, type, fp, fprd) be //---------------------------------------------------------------------------- [ let stream = OpenFile(filename, type, 0, 0, fp) test stream ifso [ if fprd ne 0 then [ let cfa = vec lCFA; GetCompleteFa(stream, cfa) MoveBlock(fprd, lv cfa>>CFA.fp, lFP) RealDiskDA(sysDisk, cfa>>CFA.fa.da, lv fprd>>FP.leaderVirtualDa) ] if type eq ksTypeWriteOnly then PositionPage(stream, 256) Closes(stream) ] ifnot SetBlock(fp, -1, lFP) ]