// Sprint.Bcpl - last modified: February 5, 1981 9:31 PM // SPRUCE MAIN PRINTING PROCEDURE // errors 2600, 5000 (Print reports) //get "Spruce.d" made too big dictionary get "SpruceInLdOutLd.d" // InLd/OutLd messages for spooler <-> service communication get "Sprucedoc.d" get "spruceMisc.d" get "sprucePrinters.d" //Just for maxBins value get "SpruceFiles.d" get "PressFile.d" get "Altofilesys.d" // outgoing procedures external [ Sprint DoBreakPage ] // incoming statics external [ //Files, disks BandFile; MeterFile; FontFile; RunFile CheckFp FontWindow logBandRecordSize sprintFPRD; spruceFPRD inMsg; outMsg DPzero //Double precision zero UseMicroCode //Flag to use microcode facilities Debug //On if debugging DebugSystem Which SprintSavedUFP SprintVersion //Version number =a.b = a*256+b DoEtherReport //True if log errors on MAXC What??? Report //Pointer to REP structure for Ether reporting breakPage printDateString printerDevice NumBins //Free storage stuff SpruceZone //Zone to use for all free storage PermanentBottom //Bottom of "permanent" free storage OverlayTop //Place where last word of overlay is // Info from spooler numFilesSpooled; numMustPrint SpoolVec printDoc // Print Count numPrinted errorPending drive1Disk statusOf31s tridentUsed tridentDisk tridentDrive earMask tickMask BinSerials // defined here stopsPrinting; breakPageCopy ] // incoming procedures external [ //Main procedures for the various passes. SprintInstall Interpret Print PrintInit PrintSetParameters ForceBreakPage // ValidateFonts // Checks all of Spruce.fonts, if validate routines loaded //Spruce streams WindowGetPosition WindowSetBounds WindowReadBlock WindowReadByte WindowRead WindowWrite InitSpruceFile // Checkpoints CheckPoint RestoreFromCheckPoint ReleaseCheckLevel InitCheckZone ActOnEntry // Spruce Utilities CursorChar FSGetX; FSInit; FSPut Reclaim InitRam EarOn Max Overlay; LoadBase; IsOverlayPresent SpruceError; SpruceCondition DisableComments SetupDrive LoadOrbitMC; LoadShowMC //METER MeterBlock; MeterClose //OS MoveBlock StartIO SysErr MyFrame OutLd InLd Zero CallSwat GotoLabel Allocate //Alloc InitializeZone //Time package CONVUDT //SPRUCEML DoubleAdd; DoubleSub; DoubleCop; MulDiv // Other DisableInterrupts; EnableInterrupts PageData PollEther SwapOnSpoolRequest; SwapSystem // TFS TFSSetDisk TFSTryDisk restartFrame didContinue ] static [ breakPageCopy; stopsPrinting ] let Sprint(layout, userParams, runCfa; numargs n) be [Sprint DPzero= table [ 0;0 ] CheckFp = table [ 0; 0; 0; 0; 0; 0 ] // FP for CheckPointFile. MoveBlock(CheckFp, layout, lFP) // First, call initialization routine. It will call Sprint() when it is finished. if n then SprintInstall(layout, runCfa) didContinue = true // force OutLd first time restartFrame = MyFrame() BinSerials = 0 // cause allocation of table the first time //|| Overlay state: no overlays present // Main Loop [Print external RestartSprint //|| No Overlays || LoadBase() //|| OVBase, OVInit || FSInit() unless BinSerials do // allocate BinSerials the first time through [ BinSerials=FSGetX(maxBins, SpruceZone, 50) NumBins=maxBins //this is wrong, but future checkpoints will correct it ] CheckPoint(LEVRun,LEVRun) //save away the BinSerials table SwapSystem(false) RestartSprint: CursorChar($I) //|| Overlay state: practically any configuration is possible here || LoadBase() //||(OVT80), OVBase, OVInit || Zero(outMsg, 18) // assumes 18 = lInLdMessage numPrinted = 0 spruceFPRD = inMsg // as it were DisableComments() // no break page comments exist ReleaseCheckLevel(LEVSharedInitStatics) // Throw out almost everything! RestoreFromCheckPoint(LEVSharedVersions, LEVSharedVersions) // Up-to-date versions RestoreFromCheckPoint(LEVSharedInitStatics, LEVRun) // Retrieve basic info RestoreFromCheckPoint(LEVEternalStatics, LEVEternalStatics) stopsPrinting = false breakPageCopy = 1 if (DebugSystem&1) ne 0 then CallSwat("Sprint: Return from InLd") //|| (OVT80), OVBase, OVInit; may not match tridentUsed requirements || tridentDisk = 0; if tridentUsed then [ LoadBase() let cpZone = InitCheckZone() SetupDrive(DISKT80, cpZone) if tridentDisk eq 0 % TFSTryDisk(tridentDrive) ne 1 then SpruceError(2600) ] drive1Disk = 0; if statusOf31s eq 1 then [ let cpZone = InitCheckZone() SetupDrive(DISK31B, cpZone) ] // SpruceZone is NOT set up // SpruceZone must be set up! SpruceZone = InitializeZone(OverlayTop+1, 3000) let cpZone = InitCheckZone() printDateString=Allocate(cpZone,15) CONVUDT(printDateString,0,true) //|| (OVT80), OVBase, OVInit || PrintInit(0) // Start printer, initialize nLeading, nTrailingBands logBandRecordSize = BandFile>>SPruceFile.lnPageSize // Print up to numFilesSpooled documents // for numPrinted = 0 to numFilesSpooled-1 do -- loop controlled from within [PrintOne if numPrinted ge numFilesSpooled break breakPageCopy = 1 //|| (OVT80), either (OVBase&(OVInterpet or OVInit)) or OVPrint || LoadBase() //|| (OVT80), OVBase, OVInit || // printDoc _ DocG from checkpoint ReleaseCheckLevel(LEVRunDocs) // Release if there is any // RestoreFromCheckPoint(LEVRunDocs, LEVRunDocs, numPrinted+1) Reclaim() ActOnEntry(SpoolVec!(numPrinted+1), true) // get entry into core SwapOnSpoolRequest() // ~~ remove when interrupts restored // If user has specified a copy count, will be needed for reprinting, perhaps (even though document directory is not re-read) let overRideCopies=printDoc>>DocG.nCopies // Parameters set up at this point fall into two classes: // CONSTANT: relate to printer or installation requirements (ResolutionS, ResolutionB, PaperDimensionX, FA) // FILE: relate to the particular Press file: all are contained in the DocG structure pointed to by pDoc // PressFile: a file structure for the file to be printed (or -1 for reprinting) // nCopies (Stand-alone only -- no way for user to specify via EFTP/Press) // XOffset,YOffset,ScaleOffset: perturb page placement // UserPageStart,UserPageEnd: page ranges compileif ReportSw then [ GetTime(lv Report>>REP.totalTime) ] // Supply defaults for printing parameters not supplied by user let pDoc = printDoc // ~~ historical nomenclature pDoc>>DocG.UserPageStart = Max(1, pDoc>>DocG.UserPageStart) unless pDoc>>DocG.UserPageEnd do pDoc>>DocG.UserPageEnd = 1000 pDoc>>DocG.UserPageEnd = Max(pDoc>>DocG.UserPageStart, pDoc>>DocG.UserPageEnd) let reprint, overRideDuplex, overRidePageStart, overRidePageEnd = false, false, 0, 0 if (DebugSystem&2) eq 0 then // Inhibit processing if DebugSystem's 2 bit is o [DoPrint // Obtain Band Processing Code //|| (OVT80), OVBase, OVInit || let baseLevP1 = IsOverlayPresent(OVBase)+1 let reprint = false test pDoc>>DocG.PressFile ne -1 then // else reprint, power on, or power off [ Overlay(OVInterpret, baseLevP1, lv LoadShowMC) Ov0: if (DebugSystemd) ne 0 then CallSwat("Sprint: Ov0") FSInit() Interpret(pDoc) ] or [ let directive = pDoc>>DocG.printerDirective switchon directive into // See SpruceInit for Spruce commands leading to directives [ case 0: case 100: Overlay(OVInterpret, baseLevP1, lv LoadShowMC) FSInit(); docase directive+1000 case 1000: // case 0, extended InitSpruceFile(BandFile, 0, 0); overRidePageStart = pDoc>>DocG.UserPageStart overRidePageEnd = pDoc>>DocG.UserPageEnd overRideDuplex = pDoc>>DocG.duplex reprint = true; endcase // prepare for reprint // removed call to ValidateFonts() case 1100: docase -1 // case 100, extended default: // Power on or off PrintInit(directive); // docase -1 case -1: outMsg>>TOSpoolerMsg.numPrinted = 1; break ] ] // P R I N T //|| (OVT80), OVBase, OVInterpret || pDoc=PageData(0) //Read in the goodies -- destroys SpruceZone Overlay(OVPrint, IsOverlayPresent(OVT80)+1, lv LoadOrbitMC) //|| (OVT80), OVPrint || Ov1: if (DebugSystemÈ) ne 0 then CallSwat("Sprint: Ov1") if overRideCopies then pDoc>>DocG.nCopies=overRideCopies let nPrinted=0 if reprint do [ if overRidePageStart > pDoc>>DocG.UserPageStart do [ nPrinted = overRidePageStart - pDoc>>DocG.UserPageStart -1 pDoc>>DocG.UserPageStart = overRidePageStart ] if overRidePageEnd < pDoc>>DocG.UserPageEnd do pDoc>>DocG.UserPageEnd = overRidePageEnd pDoc>>DocG.nPages = pDoc>>DocG.UserPageEnd -pDoc>>DocG.UserPageStart + breakPage +1 pDoc>>DocG.duplex = overRideDuplex ] [ let report = nil EarOn(2) // duty cycle limited; rcvr turned on only by "tick" code let oldPermBot = PermanentBottom // ~~ outrageous nPrinted = Print(pDoc, nPrinted, lv report) PermanentBottom = oldPermBot // ~~ outrageous // if someone knocked and we are deferring to the spooler, nPrinted ge 0 and report = 0 // else if nPrinted ge 0, report tells of a major bug that stopped things or a minor one // that we're reporting now that all is done. In the last case, nPrinted is such // that printing will terminate immediately on closing the loop ~~~~~! if nPrinted<0 % (report & Debug) then [ EarOn(1); break ] //good, or error but debugging test report then SpruceCondition(5000+report,ECEngineTerminate) or SwapOnSpoolRequest() // of which we know there is one PrintSetParameters(0) // Returning after perhaps a long time ] repeat // will loop after return from InLd //And finish statistics: compileif ReportSw then [ Report>>REP.Success=true ] compileif ReportSw & MeterSw then [ MeterBlock(METERRep, Report, size REP/16) ] compileif MeterSw then [ MeterClose() ] ]DoPrint numPrinted = numPrinted + 1 outMsg>>TOSpoolerMsg.numPrinted = numPrinted outMsg>>TOSpoolerMsg.lastPrintedCode = pDoc>>DocG.PressFile>>SPruceFile.fileCode ]PrintOne repeat // loop numPrinted to numFilesSpooled outMsg>>TOSpoolerMsg.completionCode = CCFinished ]Print repeat ]Sprint // This is here because ForceBreakPage is in the other overlay from Print and DoBreakPage() be [ ForceBreakPage(printDoc) // ~~ dirty pDoc conventions let pDoc=PageData(0) //Read in the goodies -- destroys SpruceZone //|| (OVT80), OVBase, OVInterpret Overlay(OVPrint, IsOverlayPresent(OVT80)+1, lv LoadOrbitMC) //|| (OVT80), OVPrint || Ov1Err: printDoc = pDoc // ~~ just in case let nPrinted=0 [ let report = nil EarOn(2) // duty cycle limited; rcvr turned on only by "tick" code let oldPermBot = PermanentBottom // ~~ outrageous nPrinted = Print (pDoc, nPrinted, lv report) EarOn(1) PermanentBottom = oldPermBot // ~~ outrageous if nPrinted < 0 % Debug return SpruceCondition(5000+report,ECEngineTerminate) ] repeat ] // DCS, July 27, 1977 10:00 PM, derived (loosely) from "Press" version of Spruce // July 28, 1977 10:24 AM, spruce up enough to run initial test // July 29, 1977 3:04 PM, don't change finish proc until Ram is loaded // July 30, 1977 10:12 PM, repair random bugs to first working Spooled printer! // August 2, 1977 12:10 AM, add reprint, power on, power off // August 7, 1977 12:40 PM, put in approx. to final error management. // August 22, 1977 5:23 PM, DebugSystem takes on bit by bit meaning // (see SharedStatics) // August 28, 1977 7:35 AM, Spruce -> Sprint, Sprouller->Spruce // September 2, 1977 4:26 PM, add ether "ear" // September 5, 1977 9:38 AM, add SwapOnSpoolRequest // September 23, 1977 9:57 PM, accommodate new printer status reporting // November 3, 1977 7:44 AM, pick up LEVSharedRun stuff in inMsg after full swap, v4.(2,7) // December 20, 1977 3:19 PM, mods for Trident disk version // January 20, 1978 1:56 PM, accommodate improved overlay structure // January 21, 1978 12:50 AM, remove SwapSystem, ...OnSpoolReq..., finish procedure // January 23, 1978 9:57 AM, move PageData to SpruceBand, call it before print overlay // January 23, 1978 5:42 PM, bring in Interpret overlay to process reprint, etc. (PageData) ~~ // March 10, 1978 9:24 AM, add OVInit // May 11, 1978 6:46 PM, accommodate interrupt level Ether Ear // May 12, 1978 5:55 PM, suspension during printing! // August 28, 1978 8:37 PM, change EarOn parameter conventions // September 15, 1978 3:31 PM, accommodate new installation, checkpoint stuff // September 18, 1978 9:29 AM, CheckCfa -> CheckFp // September 22, 1978 2:22 PM, get up-to-date Spruce versions after Spooler call // October 16, 1978 8:50 AM, mods for fast files // December 6, 1978 10:31 AM add printer specific overlay structure // April 25, 1979 1:39 PM respond to Spruce ValidateFonts -- see SpruceInit, SpruceValidate // August 29, 1979 1:31 PM, use LEVReport to pass BinCounters back and forth // January 29, 1980 4:33 PM, add LoadOrbitMC and LoadShowMC to overlay calls // July 16, 1980, 1:11 PM allow override of duplex, page-start and -end on reprint // July 22, 1980, 4:14 PM, restore LevSharedVersions first // January 26, 1981, 5:00PM, create printDateString for use on break page // February 4, 1981 8:53 PM, add BinSerials hacking, hence more CheckPointing // October 6, 1982 11:24 AM removed refs to ValidateFonts() (635)\876b7B338b10B359b2B288b13B55b9B269b25B1675b61B519b79B666b2B62b79B2302b35B