// PressInit.bcpl // last modified by GWilliams, 14 March 1983 4:43 pm PST (Monday) // - added Geronimo switch. // last modified by Ramshaw, January 19, 1982 4:08 PM // - added FontPickyMatch static // last modified by Ramshaw, March 30, 1981 5:23 PM // - add LocalFidelity static - 3/30/81 // - substituted an rshift for a divide @ (nScanLines+BANDWidth-1) rshift... 3/20/81 // - PressInit, let the print command "print" Press.bits files - 10/22 // - PressInit, have IndexFile set nPressRecs - 10/22 // - PressInit, let ReadCom loop use the Tridents - 10/20 // - ResolutionB, ResolutionS, 1X instead of 10X - 10/14 // - Add InvertMode for /N (negative) invert global switch - 7/11/80 // errors 200 // // PRESS INITIALIZATION // // get "PressInternals.df" get "PressParams.df" get "PressFile.df" get "Streams.d" // outgoing procedures external [ PressInit ] // outgoing statics external [ ExternalFileList //name,indexlen,index, ... Transparent TShirtMode InvertMode LocalFidelity FontPickyMatch nPressRecs Geronimo //Do everything but print the page, see below. ] static [ ExternalFileList Transparent=false TShirtMode=false InvertMode=false LocalFidelity=false FontPickyMatch=false //if true, Swat for any font request that //can't be "perfectly" matched nPressRecs = 0; Geronimo = false //Converts to limit of Press.bits then exits. ] // incoming procedures external [ //PRESS Press PressUserFinishProc PressError PressTrap DblShift //PRESSINSTALL PressInstall IndexFile //METER MeterInit //Used for initialization of files, etc. -- removed by Junta OpenFile Closes Gets Endofs ReadBlock Junta MyFrame CallersFrame GotoLabel //PRESSML MulDiv; Ugt DoubleAdd; DoubleSub; DoubleCop //SCAN 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 SetPartBounds;SetPositioninPart ] // incoming statics external [ BitsFile PressFile tridentVec tridentUsed FileName Directive UserCopies UserPageStart UserPageEnd ResolutionS ResolutionB PaperDimensionS PaperDimensionB nScanLines nBitsPerScan nBands printerMaxBitsPerScan printerDevice XOffset YOffset ScaleOffset ScreenModulus ScreenMagnitude ScreenAngle DPzero BESizes DoFileMeter DoMeter Debug SoftScan Verbose UseMicroCode DoEtherReport PressVersion Report PressZone PermanentBottom OverlayTable OverlayReloc OverlayBottom OverlayTop RamImage PressSavedUFP ] // 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 PressInit(userParams, cfa) = valof [ TypeForm("Press ", 10, PressVersion/256, $., 10, PressVersionŹ, 0) //Following hint for "Press.State" is overwritten at PressInstall 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 Press. let dDirective=0 let doInstall=false ReadComInit() let str=vec 20 let sw=vec 5 ReadCom(str,sw) //Bypass "PRESS" command for i=1 to sw!0 do switchon sw!i into [ case $I: doInstall=true; endcase case $S: dDirective=dDirective%#040000 case $C: dDirective=dDirective%#020000 case $P: dDirective=dDirective%#010000; endcase default: endcase ] Directive=#170000 if dDirective then Directive=dDirective //Very first thing to do is load the RAM: let errs=LoadRam(RamImage, true) unless errs eq 0 then PressError(210) SetBLV(#177776) //Prepare for a silent boot when finishing. PressSavedUFP=@lvUserFinishProc @lvUserFinishProc=PressUserFinishProc //Will boot to restore tasks to ROM if doInstall then PressInstall(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("Press.State",ksTypeReadOnly,0,0,hintState) if s eq 0 % Gets(s) ne hintState!lFP then PressInstall(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 $O: SoftScan=not SoftScan;endcase //flip ORbit flag case $T: Transparent=not Transparent;endcase case $M: DoMeter= not DoMeter; endcase case $U: UseMicroCode= not UseMicroCode; endcase case $V: Verbose= not Verbose; endcase case $F: FontPickyMatch=not FontPickyMatch;endcase case $R: TShirtMode=not TShirtMode;endcase case $N: InvertMode=not InvertMode;endcase case $L: LocalFidelity=not LocalFidelity;endcase case $G: Geronimo = true; endcase default: endcase ] if Debug%TShirtMode%InvertMode then SoftScan=true //Look for other command modifiers: UserCopies=0 UserPageStart=1 UserPageEnd=1000 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+8*3 Zero(tridentVec,8*3) @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 8*3-1 do [ tridentVec!t=TFSInit(pz,true,(2-(t rem 3))*#400 + (7-(t/3)),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 rpPressFile = nil; while ReadCom(str,sw) do [ let j=Disambiguate(str) unless j then PressError(201, str) let num=0 if j ls 20 then [ unless ReadCom(str,sw) then PressError(202) num=ReadNumber(str) //Leaves fp result in ac1 ] switchon j into [ case 1: UserCopies=num; endcase case 2: UserPageStart=num; //No endcase!! case 3: UserPageEnd=num; endcase case 4: [ ResolutionB = num; ResolutionS=ResolutionB ] ; endcase case 5: ScreenModulus=num;endcase case 6: ScreenMagnitude=num;endcase case 7: ScreenAngle=num rem 90;endcase case 8: XOffset=Inches(); endcase case 9: YOffset=Inches(); endcase case 10: ScaleOffset=num; endcase case 20: // Find and index the PRESS file: [ let p = vec 3000; unless ReadCom(str,sw) then PressError(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, FILEPress, str) if plen eq 0 then PressError(200, str) //Salt away the indexed file: PressFile=cp MoveBlock(cp, p, plen) cp=cp+plen @rp=lv PressFile rpPressFile = rp; rp=rp+1 ] ; endcase case 21: Directive=#010000 ; endcase //Reprint case 22: Directive=#1 ; endcase //Patterns case 23: Directive=#2 ; endcase //Test ] ] if Debug then [ DoFileMeter=true DoEtherReport=false ] if PressFile eq 0 & (Directive𧄀) ne 0 then PressError(203) if UserPageStart ls 1 then UserPageStart=1 if UserPageEnd ls UserPageStart then UserPageEnd=UserPageStart nScanLines = MulDiv(ResolutionS, PaperDimensionS, 10); nBands=(nScanLines+BANDWidth-1) rshift LogBANDWidth;//divide by power of 2 nBitsPerScan = MulDiv(ResolutionB, PaperDimensionB, 10); if nBitsPerScan gr printerMaxBitsPerScan then [ PressError(205) //Warning only -- he may be using non-standard nBitsPerScan=printerMaxBitsPerScan //resolution ] //Init the ORbit, if necessary switchon printerDevice into [ case printerDover: case printerSequoia: case printerPimlicoAlt: case printerPimlico: case printerDurango: case printerPuffin: case printerPenguin: OrbitInit() default: ] //check for file directory part (referencing external files as in GetDotsFromFile) if PressFile ne 0 then [PR let PressSpace=vec 2000 PressZone=InitializeZone(PressSpace,2000) let PressLength=vec 1 // FileStuff(PressFile, PressLength); // can't use since can be on Trident PressLength!0 = 0; PressLength!1 = nPressRecs; DblShift(PressLength, -LogPressRecordSize); DoubleSub(PressLength,table [ 0;PressRecordSize ]) if PressLength!0 ls 0 then PressError(100) let EL=WindowInit(PressFile) WindowSetPosition(EL,PressLength) //Get to doc dir. let DocDir=vec PressRecordSize WindowReadBlock(EL,DocDir,PressRecordSize) DblShift(PressLength,LogPressRecordSize) // let nPressRecs=PressLength!1+1 test PressLength!0 eq 0 & DocDir>>DDV.Passwd eq PressPasswd ifnot [ WindowSetPosition(EL, table [ 0; 3; ]); unless WindowRead(EL) eq PressPasswd then // not a Press.bits file [ if PressLength!0 then PressError(101); PressError(102); ] BitsFile = PressFile; PressFile = 0; Directive = #010000; // just print @rpPressFile = rpPressFile; ] ifso [ unless DocDir>>DDV.nRecs eq nPressRecs then PressError(103) unless DocDir>>DDV.nParts*(size PE/16) le DocDir>>DDV.pdRecs*PressRecordSize then PressError(104) //old code, commented out by Lyle Ramshaw //if (DocDir>>DDV.SoftScan eq 0)%(DocDir>>DDV.SoftScan eq -1) then //DocDir>>DDV.SoftScan = DocDir!10;// assume old ddv, used to be here if (DocDir>>DDV.SoftScan eq $n)%(DocDir>>DDV.SoftScan eq $N) then InvertMode=true if (DocDir>>DDV.SoftScan eq $r)%(DocDir>>DDV.SoftScan eq $R) then TShirtMode=true if (DocDir>>DDV.SoftScan eq $s)%(DocDir>>DDV.SoftScan eq $S) then SoftScan=true if (DocDir>>DDV.SoftScan eq $t)%(DocDir>>DDV.SoftScan eq $T) then Transparent=true //Find the file part (if it exists) SetPartBounds(EL,DocDir>>DDV.pdStart,DocDir>>DDV.pdRecs) SetPositioninPart(EL,table [ 0;0]) //Start reading parts here let filefound=false let FilePart=vec size PE/16 for i=1 to DocDir>>DDV.nParts do [ WindowReadBlock(EL,FilePart,size PE/16) if FilePart>>PE.Type eq PETypeFile then //File part [ filefound=true;break ] ] ExternalFileList=0 @rp=lv ExternalFileList rp=rp+1 if filefound then //do indexing operations [ ExternalFileList=cp SetPartBounds(EL,FilePart>>PE.pStart,FilePart>>PE.pRecs) SetPositioninPart(EL,table [ 0;0]) [ //repeat loop for all files mentioned let fName=vec 40 fName!0=WindowRead(EL) if fName!0 eq 0 then break //no more for i=1 to (fName!0 rshift 9) do fName!i=WindowRead(EL) //Strip off "[server]subdir>" if necessary StripServerDir(fName) // Added by EMV //Salt away the file name: let plen=(fName!0 rshift 9)+1 MoveBlock(cp, fName, plen) cp=cp+plen let p=vec 3000 plen=IndexFile(p, FILEExternal, fName) if plen eq 0 then PressError(200, fName) //Salt away the indexed file: cp!0=plen MoveBlock(cp+1, p, plen) cp=cp+plen+1 ] repeat //for all files ] //end of if filefound ] // end of ifso ]PR //Save length of "permanent" area: cpb!-1=cp-cpb if Ugt(rp, cpb-1) then PressError(204) @rp=0 //Terminate relocation list //Get rid of the operating system: Junta(levBFSbase, PressInitAux) ] and PressInitAux() 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 8*3-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=PressTrap PressZone=z //Set up vector for reporting things in: compileif ReportSw then [ Report=Allocate(PressZone, size REP/16) Zero(Report, size REP/16) Report>>REP.Version=PressVersion Report>>REP.Directive=Directive ] //Re-Initialize Trident disk because it contains addresses ... // No longer needed -- don't reference the addresses // if tridentDisk then TFSSetDisk(tridentDisk, 0, tridentDrive) compileif MeterSw then [ if DoMeter then MeterInit() ] OverlayTop=PressInit OverlayBottom=PressInit Press(0) //And run Press! ] 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: "Pages" case 3: "To" case 4: "Resolution" case 5: "Screen" case 6: "Amplitude" case 7: "Angle" case 8: "XOffset" case 9: "YOffset" case 10: "Scale" case 20: "Print" case 21: "Reprint" case 22: "Patterns" case 23: "Test" 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 ] // Floating AC1 has a value in inches -- convert to micas: and Inches() = valof [ FLDI(0, 2540) FML(1, 0) resultis FTR(1) ] // Routine added by Evelyn Van Orden on 10 January 1980: // Changed by Evelyn Van Orden on 21 January 1980: and StripServerDir(name) be [ // Change "[server]subdir>filename" to "filename" let sptr = name>>STR.length while (name>>STR.char^sptr ne $> & name>>STR.char^sptr ne $] & sptr ge 1) do sptr = sptr - 1 let diff = name>>STR.length - sptr for i = 1 to diff do name>>STR.char^i = name>>STR.char^(i+sptr) name>>STR.length = diff ](1800)