// ScavInit -- once only initialization // Copyright Xerox Corporation 1979, 1980, 1981, 1982 // Last modified April 30, 1982 8:58 PM by Boggs get "AltoDefs.d" get "AltoFileSys.d" get "Streams.d" get "Disks.d" get "BFS.d" external [ // outgoing procedures InitScavenger // incoming procedures EditDisk; TryDisk; DiskToCursor; Ws; Confirm StartLog; SplitPuts; SysErr; FindDShape ScavAssignDiskPage; ScavReleaseDiskPage CreateSimpleDspStream; CreateKeyboardStream SimpleDspEraseBits; SimpleDspCharWidth; SimpleDspDCB InitializeZone; Allocate; Endofs; Gets; Puts BFSInit; BFSCreateFile; BFSDeletePages MoveBlock; Zero; MyFrame; Idle PutTemplate // outgoing statics sysZone; sysDisk; dsp maxVDA; alterFlag; label; data // incoming statics gacha10; keys; log ] static [ sysZone; sysDisk; dsp maxVDA; alterFlag; label; data ] manifest [ dspHeight = 100 //scan lines dspWidth = 36 //words ] //----------------------------------------------------------------------------------------- let InitScavenger() be //----------------------------------------------------------------------------------------- [ // create cursor MoveBlock(cursorBitMap, table [ 177700b; 77600b; 37400b; 17700b; 7360b; 3074b; 1017b; 3; 0; 0; 0; 167112b; 105252b; 44252b; 25352b; 167244b ], 16) Idle = DiskToCursor // create sysZone manifest stackLimit = 335b let freeBegin = @stackLimit let freeEnd = MyFrame() -1500 @stackLimit = freeEnd if freeEnd-freeBegin ls 0 then freeBegin = freeEnd-77777b sysZone = InitializeZone(freeBegin, freeEnd-freeBegin) // create keyboard, display, and log streams log = StartLog() keys = CreateKeyboardStream() dsp = CreateSimpleDspStream(Allocate(sysZone, dspHeight*dspWidth, false, true), dspWidth, dspHeight, gacha10) dsp>>ST.puts = SplitPuts let dspDCB = SimpleDspDCB(dsp) dspDCB>>DCB.indentation = 3 let spaceDCB = Allocate(sysZone, lDCB, false, true); Zero(spaceDCB, lDCB) spaceDCB>>DCB.height = 20 spaceDCB>>DCB.next = dspDCB @displayListHead = spaceDCB Ws("Alto File System Scavenger of September 29, 1982") // default label and data buffers -- used by everyone label = Allocate(sysZone, lDL) data = Allocate(sysZone, 256) // give user a chance to change disks let eng = (table [ 61014b; 1401b ])()<>DSK.AssignDiskPage = ScavAssignDiskPage sysDisk>>DSK.ReleaseDiskPage = ScavReleaseDiskPage sysDisk>>DSK.CreateDiskFile = BFSCreateFile sysDisk>>DSK.DeleteDiskPages = BFSDeletePages // InitScavenger (cont'd) let res = valof //dummy control structure to break two loops [ let status = TryDisk(0, 0, 0, 1) & DSTgoodStatusMask let ds = data + FindDShape(data) +1 test status eq DSTgoodStatus & ds>>DSHAPE.nHeads eq 2 & (ds>>DSHAPE.nDisks eq 1 % ds>>DSHAPE.nDisks eq 2) & (ds>>DSHAPE.nTracks eq 203 % ds>>DSHAPE.nTracks eq 406) & (ds>>DSHAPE.nSectors eq 12 % ds>>DSHAPE.nSectors eq 14) ifso [ sysDisk>>BFSDSK.nDisks = ds>>DSHAPE.nDisks sysDisk>>BFSDSK.nTracks = ds>>DSHAPE.nTracks sysDisk>>BFSDSK.nSectors = ds>>DSHAPE.nSectors ] ifnot [ if sysDisk>>BFSDSK.nDisks eq 2 then if TryDisk(1, 0, 0, 0)<>BFSDSK.nDisks = 1 if sysDisk>>BFSDSK.nTracks eq 406 then if TryDisk(0, 203, 0, 0)<>BFSDSK.nTracks = 203 if sysDisk>>BFSDSK.nSectors eq 14 then if TryDisk(0, 0, 0, 13)<>BFSDSK.nSectors = 12 ] [ let curPart = eng gr 3? (table [ 61037b; 1401b ])(0), nil Puts(dsp, $*N); if eng gr 3 then PutTemplate(dsp, "Partition: $D, ", curPart) PutTemplate(dsp, "Disks: $D, Cylinders: $D, Heads: 2, Sectors: $D", sysDisk>>BFSDSK.nDisks, sysDisk>>BFSDSK.nTracks, sysDisk>>BFSDSK.nSectors) PutTemplate(dsp, "*NReady to scavenge a $S model-$S $Sfile system", (sysDisk>>BFSDSK.nDisks eq 1? "single", "dual"), (sysDisk>>BFSDSK.nTracks eq 203? "31", "44"), (eng gr 3? (sysDisk>>BFSDSK.nSectors eq 12? "12-sector ", "14-sector "), "")) if Confirm(" [confirm]") test (kbdAd!2 & 4000b) eq 0 ifso [ EditDisk(); break ] ifnot resultis 0 if eng gr 3 then [ let newPart = GetNumber("*NPartition number ", curPart) if newPart ne curPart & newPart ne 0 then [ (table [ 61037b; 1401b ])(newPart); break ] ] unless TryDisk(1, 0, 0, 0)<>BFSDSK.nDisks = Confirm("*NUse both disks?")? 2, 1 unless TryDisk(0, 203, 0, 0)<>BFSDSK.nTracks = Confirm("*NUse all 406 cylinders?")? 406, 203 unless TryDisk(0, 0, 0, 13)<>BFSDSK.nSectors = Confirm("*NUse all 14 sectors?")? 14, 12 ] repeat ] repeat // also valof if sysDisk>>BFSDSK.nDisks eq 2 then WaitForDisk(1) maxVDA = sysDisk>>BFSDSK.nDisks * sysDisk>>BFSDSK.nTracks * 2 * sysDisk>>BFSDSK.nSectors -1 sysDisk>>BFSDSK.diskBTsize = maxVDA/16 +1 alterFlag = Confirm("*NMay I alter your disk to correct errors?") Ws("*NProceeding with scavenge...") ] //----------------------------------------------------------------------------------------- and GetNumber(prompt, number) = valof //----------------------------------------------------------------------------------------- [ Ws(prompt) PutTemplate(dsp, "$UO", number) let digitTyped = false [ let char = Gets(keys) switchon char into [ case $*N: case $*S: case $*033: resultis number case $*177: Ws(" XXX"); resultis 0 case $0 to $7: [ unless digitTyped while number ne 0 do [ SimpleDspEraseBits(dsp, -SimpleDspCharWidth(dsp, (number&7)+$0)) number = number rshift 3 ] number = number lshift 3 + char-$0 Puts(dsp, char) digitTyped = true endcase ] case $*001: case $*010: [ if number ne 0 then SimpleDspEraseBits(dsp, -SimpleDspCharWidth(dsp, (number&7)+$0)) number = number lshift 3 endcase ] ] ] repeat ] //----------------------------------------------------------------------------------------- and WaitForDisk(dsk) be //----------------------------------------------------------------------------------------- [ if TryDisk(dsk, 0, 0, 0)<>DST.notReady eq 0 loop Ws("Ready!") ] ]