// PDInit.bcpl -- PDPrint initialization // derived from PressInit.bcpl 2/7/83 // errors 200 get "PDInternals.d" get "Streams.d" // outgoing procedures external [ PDInit ] // incoming procedures external [ //PDPrint PDPrint PDUserFinishProc PDError PDTrap DblShift //PDINSTALL, PDINSTALLUTILS PDInstall IndexFile //METER MeterInit //Used for initialization of files, etc. -- removed by Junta OpenFile Closes Gets Endofs ReadBlock Junta MyFrame CallersFrame GotoLabel //PDML MulDiv; Ugt DoubleAdd; DoubleSub; DoubleCop //SCANSTRINGS TypeForm ReadComInit ReadCom ReadNumber //ALLOC InitializeZone Allocate //OS MoveBlock Zero lvUserFinishProc StartIO //LOADRAM LoadRam SetBLV //TFS TFSInit TFSSetDisk TFSCreateDDMgr //FLOAT FLDI; FML; FTR //PrintOrbitInit OrbitInit //WINDOW and misc. WindowInit;WindowRead;WindowClose;WindowSetPosition WindowReadBlock FileStuff ] // incoming statics external [ BitsFile PDFile tridentVec tridentUsed FileName Directive UserCopies UserPageStart UserPageEnd XOffset YOffset printerDevice ResolutionS ResolutionB PaperDimensionS PaperDimensionB nScans nBitsPerScan DPzero DoMeter DoFileMeter Debug Verbose mirrorX invertMode PDVersion Report UseRam PDZone PermanentBottom OverlayTable OverlayReloc OverlayBottom OverlayTop RamImage PDSavedUFP AltoVersion ] // internal statics static [ tridentDiskBase ] // File-wide structure and manifest declarations. //manifests copied from AltoFileSys.d and SysDefs.d because Bcpl // dictionary was getting too big: manifest [ lFP=5 levBFSbase=5 levDirectory=9 lTFSDSK=100 ] structure STR[ length byte char↑1,255 byte ] // Procedures let PDInit(userParams, cfa) = valof [ TypeForm("PDPrint ", 10, PDVersion/256, $., 10, PDVersionŹ, 0) //Following hint for "PDPrint.State" is overwritten at PDInstall time by fiddling with // the .Run file. This is the primary mechanism for getting at the installed state // reasonably quickly. In addition to the FP, there is a "magic" number that is // written as the first word on the state file. This is to try to guard against un- // installed systems running wild. let hintState=table [ 0;0;0;0;0;0 ] compileif lFP+1 ne 6 then [ foo=nil ] //See if we are installing PDPrint. let doInstall=false ReadComInit() let str=vec 20 let sw=vec 5 ReadCom(str,sw) //Bypass "PDPRINT" command for i=1 to sw!0 do switchon sw!i into [ case $I: doInstall=true; endcase default: endcase ] //Very first thing to do is load the RAM: UseRam=(AltoVersion rshift 12) le 3 if UseRam then [ let errs=LoadRam(RamImage, true) unless errs eq 0 then PDError(210) SetBLV(#177776) //Prepare for a silent boot when finishing. PDSavedUFP=@lvUserFinishProc @lvUserFinishProc=PDUserFinishProc //Will boot to restore tasks to ROM ] if doInstall then PDInstall(cfa, hintState) //Now set up a temporary zone to hold things that will ultimately // reside in "permanent" storage at the top of memory. let rpb=@#335 //Get bottom of stack. let cpb=rpb+100 //That many statics. let rp=rpb let cp=cpb //Now initialize state vectors and scalars. For the vectors, remember // a relocation table so that things can be moved to high memory after // the Junta. let s=OpenFile("PDPrint.State",ksTypeReadOnly,0,0,hintState) if s eq 0 % Gets(s) ne hintState!lFP then PDInstall(cfa, hintState) //Not installed! let passCount=Gets(s); ReadBlock(s, cp, passCount) //Default settings [ let adr=Gets(s) if adr eq 0 then break let len=Gets(s) test len eq 0 ifso @adr=Gets(s) ifnot [ ReadBlock(s, cp, len) @adr=cp cp=cp+len @rp=adr rp=rp+1 ] ] repeat Closes(s) //Now finish global switch processing. This is done after the statics are restored in case // some things want to be reset. for i=1 to sw!0 do switchon sw!i into [ case $D: Debug= not Debug; endcase case $M: DoMeter= not DoMeter; endcase case $V: Verbose= not Verbose; endcase case $R: mirrorX=not mirrorX;endcase case $N: invertMode=not invertMode;endcase default: endcase ] //Look for other command modifiers: UserCopies=1 UserPageStart=1; UserPageEnd=2000 let p=vec 3000 //For indexing file let pz=InitializeZone(p, 3000) //Just to set up Allocate,Free to Call0,Call1 //Init the trident disk, if it is there. //there are Trident drive nos 0-7, each with up to 3 file systems //allow user to grab any or all tridentVec=cp;cp=cp+NTridentDrives*NPartitions Zero(tridentVec,NTridentDrives*NPartitions) @rp=lv tridentVec rp=rp+1 if tridentUsed then [ let ddmgr=TFSCreateDDMgr(pz) tridentDiskBase=cp //save to put in permanent area @rp=lv tridentDiskBase rp=rp+1 for t=0 to NTridentDrives*NPartitions-1 do [ tridentVec!t=TFSInit(pz,true,(NPartitions-1-(t rem NPartitions))*#400 + (NTridentDrives-1-(t/NPartitions)),ddmgr) if tridentVec!t eq 0 then loop MoveBlock(cp, tridentVec!t, lTFSDSK) cp=cp+lTFSDSK ] if tridentDiskBase eq cp then //no trident drives working [ TypeForm("Trident drive is not on-line. Check it out!") finish ] ] //Finish processing the command line: let rpPDFile = nil; Directive=0 while ReadCom(str,sw) do [ let j=Disambiguate(str) unless j then PDError(201, str) let num=0 if j ls 20 then [ unless ReadCom(str,sw) then PDError(202) num=ReadNumber(str) //Leaves fp result in ac1 ] switchon j into [ case 1: UserCopies=num; endcase //Copies case 2: [ ResolutionB = num; //Resolution ResolutionS=ResolutionB ] ; endcase case 3: XOffset=num; endcase //Xoffset case 4: YOffset=num; endcase //Yoffset case 5: UserPageStart=num; UserPageEnd=num; endcase //Page case 6: UserPageEnd=num; endcase //To case 20: // Print -- Find and index the PD file: [ Directive=dirPrint%dirPDScan let p = vec 3000; unless ReadCom(str,sw) then PDError(207) //Salt away the file name: FileName=cp let plen=(str!0 rshift 9)+1 MoveBlock(cp, str, plen) cp=cp+plen @rp=lv FileName rp=rp+1 plen=IndexFile(p, FILEPD, str) if plen eq 0 then PDError(200, str) //Salt away the indexed file: PDFile=cp MoveBlock(cp, p, plen) cp=cp+plen @rp=lv PDFile rpPDFile = rp; rp=rp+1 ] ; endcase case 21: Directive=dirPrint ; endcase //Reprint case 22: Directive=dirPatterns%dirPrint ; endcase //Patterns case 23: Directive=Directive&(not dirPrint) ; endcase //NoPrint case 24: Directive=(Directive&(not dirPrint))%dirDisplay ; endcase //Display ] ] if Debug then DoFileMeter=true if PDFile eq 0 & Directive eq 0 then PDError(203) nScans = MulDiv(ResolutionS, PaperDimensionS, 10); nBitsPerScan = MulDiv(ResolutionB, PaperDimensionB, 10); //Init the Orbit, if necessary if printerDevice le printerOrbitLast then OrbitInit() //Save length of "permanent" area: cpb!-1=cp-cpb if Ugt(rp, cpb-1) then PDError(204) @rp=0 //Terminate relocation list //Get rid of the operating system: Junta(levBFSbase, PDInitAux) ] and PDInitAux() be [ //Move "permanent" things up from where we saved them temporarily. let rp=@#335 let cp=rp+100 let len=cp!-1 let PermanentTop=MyFrame()-3000 //3000 words of stack space @#335=PermanentTop PermanentBottom=PermanentTop-len MoveBlock(PermanentBottom, cp, len) while @rp ne 0 do [ @@rp=@@rp+PermanentBottom-cp rp=rp+1 ] //fix up the trident disk table if tridentUsed then [ for t=0 to NTridentDrives*NPartitions-1 do if tridentVec!t ne 0 then [ tridentVec!t=tridentDiskBase tridentDiskBase=tridentDiskBase+lTFSDSK ] ] //Now allocate any more permanent things you can think of.... let z=vec 2 z>>ZN.Allocate=PermanentAllocate z>>ZN.Free=PDTrap PDZone=z compileif MeterSw then [ if DoMeter then MeterInit() ] OverlayTop=PDInit OverlayBottom=PDInit PDPrint(0) //And run PDPrint! ] and PermanentAllocate(zone, siz) = valof [ PermanentBottom=PermanentBottom-siz resultis PermanentBottom ] and Disambiguate(str) = valof [ let len=str>>STR.length let matchNo=nil let matchCnt=0 for i=1 to 100 do [ let s=selecton i into [ case 1: "Copies" case 2: "Resolution" case 3: "XOffset" case 4: "YOffset" case 5: "Page" case 6: "To" case 20: "Print" case 21: "Reprint" case 22: "Patterns" case 23: "NoPrint" case 24: "Display" default: 0 ] if s eq 0 % len gr s>>STR.length then loop let match=true for j=1 to len do if ((str>>STR.char↑j xor s>>STR.char↑j)&(not #40)) ne 0 then match=false if match then [ matchCnt=matchCnt+1 matchNo=i ] ] if matchCnt eq 1 then resultis matchNo resultis false ]