// P R I N T // errors 1000 // get "Spruce.d" get "SpruceFiles.d" get "Orbit.d" // outgoing procedures external [ DrivePrinter ] // incoming procedures external [ SpruceError Max Min InitRam //SprucePrint AddToBin Announce AwaitPageSync PrintNext ReadBands ReadClock ReadFont //CURSOR CursorChar CursorDigit // SprucePrintRes DoFunc ROSStatus // Timer (debug only) SetTimer TimerHasExpired //OS Zero DisableInterrupts EnableInterrupts ] // incoming statics external [ scanTicks // # of 38 usec. ticks in 4 printer scan lines. logBandRecordSize nPagesPrinted bandRecordSize ros12 ros13 Debug DebugSystem Func debugTrail knockResult numPrinted numMustPrint InitMeasure // engine control monitoring stuff CloseMeasure TickMeasure Measure measureTable xmFonts // Font data will be read into Bank 1 via Bank 0, if set nRecs LowAdr FAvalue nBands stopsPrinting ] // internal statics static [ rosCount = 0 // Pimlico/puffin command count rosSyncError = false // Pimlico/puffin -- sync problem startRun = true // delay ~~~~ debugging: delay per page to simulate printing debDelay = 0 // delay no delay std. // delay ~~~~ ] // File-wide structure and manifest declarations. manifest [ eTicks = 4 timeOut=15*27 printHysteresis = 15 // print this many before allowing suspension, each time in // ~~ above number may want to increase for large runs, or something? RTC=#430 debugTrailSize = 10*3 // Failure Code ranges -- see ROSCheck maxNotReady = 9 // not ready, but probably will be soon maxManual = 19 // Manual intervention required maxJam = 99 // Error during operation minDocumentError = 300 // Document inherently hard to print ] // ----------------------------------------------------------- // Print Initialization // ----------------------------------------------------------- // Returns -1 if printing is successfully completed, else // nPagesPrinted, so can pick up where we left off. let DrivePrinter(pDoc, nPagesAlreadyPrinted, lvFailureCode) = valof [ let measureVec = vec 5 let CommTab=vec 3 CommTab=(CommTab+1)&(-2) CommTab!0=-1 InitializeHardware(true) InitMeasure(measureTable, 2000, measureVec) let knockKnock = false // time to let somebody in if true let needInit, needFonts = true, true let copy, nfRecs, LeftOver, LeftOverGuard, FontTable, buf = nil, nil, nil, nil, nil, nil let np = nil let nextPage = PrintNext(pDoc, lv copy, nPagesPrinted) //-------------------------------- // Printloop //---------------------------------- [Printloop let page=nextPage // Find out which page to print next: if page eq 0 then [ knockKnock = false; break ] if knockKnock then break // go let somebody in if stopsPrinting eq binFull then [ @lvFailureCode = 130; break ] if needFonts do [ // Read in font and relocate the pointers to characters: let font=page>>PageG.fontLoad*(size FontG/16)+pDoc>>DocG.Fonts // Next call returns location of ICC table, FontTable = ReadFont(font, LowAdr, nRecs) unless xmFonts do for i=0 to pDoc>>DocG.ICCtotal-1 do // if rasters are in bank 1, they start at 0 FontTable!i=FontTable!i + LowAdr FontTable=FontTable-100000b let nRecords= xmFonts? (pDoc>>DocG.ICCtotal+bandRecordSize-1) rshift logBandRecordSize, font>>FontG.nRecords nfRecs=(nRecs-nRecords) LeftOver=LowAdr+(nRecords lshift logBandRecordSize) LeftOverGuard = LeftOver+(loSize&(-4))-4 buf = (LeftOver+loSize+8)&(-2) // ~~ all the 4's, 8's and 10's in here are cowardly slack needFonts = false ] ReadBands(page, buf, nfRecs) // Now read in the bands for this page if needInit do [ InitializeHardware(false) // Initialize the Orbit, etc. let tim = @RTC unless Debug do // wait for ready or some serious condition or for long enough [ np = ROSCheck(lvFailureCode, nPagesAlreadyPrinted, false) if np eq -1 break // ready if @lvFailureCode > maxNotReady % (@RTC-tim) > timeOut resultis np ] repeat // Try to empty Orbit buffers to clear them. This is to minimize toner dumping on first (blank) page. compileif loSize ls 256 then [ foo=nil ] for i=0 to 31 do DoFunc(fReadBlock, 256, LeftOver) DoFunc(fControl, 21b) // Turn off adCommandBeamOn, if on, revert to normal modulation-- // ~~ causes glitch AdCommand(AdapterScales) DoFunc(fROSCommand, adBufferReset) ROSCommand(#63346) // Start, using std. 3 color video queue AwaitPageSync(0) needInit = false ] let nC = nil nextPage = PrintNext(pDoc, lv nC, nPagesPrinted+1) unless nextPage do ROSCommand(#63030) // Stop Print (at end of copy) // Start Orbit working on the present page. DoFunc(fControl, #21) //Reset, clear behind DoFunc(fROSCommand, adBufferReset) LeftOver!0=0 //Initialize LeftOver table LeftOverGuard!1=-1 let tim=@RTC // Start the microcode!!!! DoFunc(fSlot, CommTab, 20000, nBands-1, FAvalue, LeftOver, FontTable, buf-1, nil, nil, (copy lshift 5)+4) if Debug then // ~~delay [ // ~~delay while (@RTC-tim) < debDelay loop // ~~delay tim = @RTC // ~~delay don't invoke timeout code below ] // ~~delay // Assume the page we are printing will be OK: nPagesPrinted=nPagesPrinted+1 CursorDigit(nPagesPrinted) copy = nC // See who's (maybe) knocking at my door // This logic is copied from SpruceUtilsRes: if we are not planning to defer to spooler, // don't trouble to shut down here, just to find that out there. Would be too expensive if (DebugSystem) eq 0 & numPrinted ge numMustPrint & knockResult & (nPagesPrinted-nPagesAlreadyPrinted) > printHysteresis then knockKnock = true if (nextPage>>PageG.fontLoad ne page>>PageG.fontLoad) do needFonts = true // Now see if we actually printed this page properly. First, wait for Orbit to announce it is finished. let imageTimeout = 10*27 while @#720 ne 0 do if (@RTC-tim) gr imageTimeout then [ Blast() // clear hardware, #720 // Machine dead or Orbit got behind and it wasn't detected // Will generally be overriden by more specific analysis @lvFailureCode = 19 // Manual intervention required break ] // Check Orbit status let nonF = 0 let stat=Func!9 //Orbit printing status. // Fatal error detected by microcode -- invalid Band entry -- possibly broken processor if stat<