// P R I N T // errors 5000 // get "SprucePrinters.d" get "SpruceDoc.d" get "SpruceFont.d" get "SpruceBand.d" get "spruceMisc.d" get "SpruceFiles.d" get "Orbit.d" // outgoing procedures external [ DrivePrinter ] // incoming procedures external [ SpruceError Max; Min CallSwat InitRam ChooseMailboxBin //SprucePrint AddToBin Announce AwaitPageSync IncBinSerial PrintNext ReadBands ReadClock ReadFont //CURSOR CursorChar; CursorDigit // SprucePrintRes DoFunc; ROSStatus // Timer (debug only) SetTimer; TimerHasExpired ] // incoming statics external [ BandFile bandRecordSize BinCounters breakPage breakPageCopy Capabilities Debug DebugSystem debugTrail FAvalue Func knockResult logBandRecordSize LowAdr Measure; CloseMeasure; TickMeasure; InitMeasure; measureTable nBands nPagesPrinted nRecs numMustPrint numPrinted printerForward ros12 ros13 scanTicks // # of 38 usec. ticks in 4 printer scan lines. stopsPrinting xmFonts // Font data will be read into Bank 1 via Bank 0, if set BinSerials ] // internal statics static [ imageTimeout rosCount = 0 // Pimlico/puffin/penguin command count printSeq twosided curBin; nextBin curHandling; nextHandling switchBin = false // for delayed bin switch if intermediate break page needed nextCopy debDelay = 0 // debugging: delay per page to simulate printing. ] // File-wide structure and manifest declarations. manifest [ AuxCount = 19 //keep count of sheets in Aux tray in BinCounters!19 AuxRecoveryCount = 20 //number of first sides to be replaced in BinCounters!20 sigband = 100 RTC=#430 eTicks = 4 //time to spend checking scanning fITO = 15*27 //15 seconds to get first sheet thru rITO = 2*27 //2 seconds to get subsequent sheets thru. timeOut=15*27 //time to wait for standby status to appear printHysteresis = 30 // print this many before allowing suspension, each time in debugTrailSize = 10*3 minDocumentError = 300 // Document inherently hard to print // commands to Penguin pResetCount = #60000 // 6000x- reset your count of commands received from me pNewLED = #62400 // 65nmx- last 2 nibbles contain decimal digits pSetLED = #63002 // 6602x- display last value sent with pNewLED pPrint = #63001 // 6601x- print a page pSSMain = #63040 // 6620x- page is singlesided from main tray pSSAux = #63041 // 6621x- page is singlesided from auxtray pTSFirst = #63042 // 6622x- page is first side of duplex (goes from main to aux) pTSSecond = #63043 // 6623x- page is second side of duplex (aux to some output bin) pSetBin = #63100 // 6640x- position bins (to bin indicated in last five bits) pClearMalf = #63050 // 6628x- move malf indication to status pIgTSCErr = #63004 // 6004x- ignore tsc error indication // printSeq values: warmup = 1 standby = 2 preprint = 3 printing = 4 cycledown = 5 malfClear = 6 mainSeqErr = 107 subSeqErr = 106 abnormal = 113 powerOn = 123 ] // ----------------------------------------------------------- // 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 if (DebugSystem & #4000) ne 0 then CallSwat("DrivePrinter") unless nPagesAlreadyPrinted then BinCounters!AuxCount = 0 // if no pages printed, shouldn't be paper in aux tray let CommTab=vec 8 CommTab=(CommTab+1)&(-2) let knockKnock = false // time to let somebody in if true twosided = pDoc>>DocG.duplex ne 0 curBin = 0 let overflowBin = 0 // usually is . . . test (Capabilities & mMailbox) ne 0 ifso [ unless BinCounters!0 > 50 do // can't move trays [ //find the bin we would like it to go in let mtray = ChooseMailboxBin((lv pDoc>>DocG.CreatStr)>>STR.char↑1) if BinCounters!mtray <50 do curBin = mtray // if there is room ] breakPageCopy=curBin?1001,1002 ] ifnot [ if (Capabilities & mMultiBin) ne 0 do //filling bins from bottom up - find 1st nonfull [ until (BinCounters!(curBin) < 50) % (curBin eq 18) do [ curBin = curBin + 1 ] overflowBin = 18 ] ] let binMax = (curBin eq overflowBin)? 200, 50 InitializeHardware() InitMeasure(measureTable, 2000, measureVec) let backup = 0 let xportModel = 0 @lvFailureCode = (ROSCommand(pResetCount) % ROSCommand(pIgTSCErr))? 121, 0 @lvFailureCode = ROSCheck() if @lvFailureCode resultis SetupRecovery(pDoc, lvFailureCode, lv xportModel, nPagesAlreadyPrinted) let needFonts, needInit =true, true let FontTable, nfRecs, LeftOver, LeftOverGuard = nil, nil, nil, nil let buf = nil let tim = nil imageTimeout = fITO //allow penguin to get ready if BinCounters!AuxRecoveryCount do nPagesPrinted = BinCounters!AuxCount let nextPage=NextSheet(pDoc, nPagesPrinted) // Print (cont.) Loop [PrintLoop // Find out which page to print next: let page=nextPage if page eq 0 then [ knockKnock = false; IncBinSerial(BinSerials+curBin); break ] // Finished! if knockKnock then break // go let somebody in if needFonts do // Read in font and relocate the pointers to characters: [ let font=page>>PageG.fontLoad*(size FontG/16)+pDoc>>DocG.Fonts FontTable = ReadFont(font, LowAdr, nRecs) // call returns location of ICC table 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 // Figure out where buffers are. let nRecords= xmFonts? (pDoc>>DocG.ICCtotal+bandRecordSize-1) rshift logBandRecordSize, font>>FontG.nRecords nfRecs=nRecs-nRecords // max allowable band list size LeftOver=LowAdr+(font>>FontG.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 ] // Now read in the bands for this page ReadBands(page, buf, nfRecs, nBands) if needInit do // if this is the first time thru or paper handling changed [ if stopsPrinting eq binFull then [ @lvFailureCode = 130; break ] // Initialize the Orbit, etc. InitializeHardware() // wait for ready or some serious condition or for long enough tim = @RTC unless Debug do [ let x = ROSCheck(standby) unless x then break // ready if x > 0 then resultis SetupRecovery(pDoc, lvFailureCode, lv xportModel, nPagesPrinted, x) //result was -1: not ready yet, but may be soon. Have we waited long enough? if (@RTC - tim) > timeOut resultis SetupRecovery(pDoc, lvFailureCode, lv xportModel, nPagesPrinted, 120) ] repeat xportModel = 0 // paper cleared from transport mechanism // tell penguin to print a page and how to handle the paper curHandling = nextHandling let bin = nextBin test (nextBin eq overflowBin) & (curBin ne overflowBin) then // switching to overflow bin: do break page [ nPagesPrinted = nPagesPrinted - 1; binMax = 200; bin = curBin;switchBin = true ] or [ switchBin = false ] if ROSCommand(pSetBin + 2+bin) % ROSCommand(curHandling) % ROSCommand(pPrint) do [ @lvFailureCode = 122; break ] curBin = nextBin // 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) needInit = false ] // ----------------------------------------------------------- // Print real printing function // ----------------------------------------------------------- // first, set up to display page number we're printing on penguin's led nPagesPrinted=nPagesPrinted+1 let m,n = nil, nil m, n, m = nPagesPrinted rem 100, m rem 10, (m/10) lshift 4 //and build table so orbit will send them thru during page imaging CommTab!0 = 180 CommTab!1 = #62400 + m +n //set up leds and CommTab!2 = 150 CommTab!3 = #63002 //display'em CommTab!4 = -1 // this will be set to an appropriate band number if there is another page CommTab!5 = #63001 //command to print another page CommTab!6 = -1 // 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 tim=@RTC // Start the microcode!!!! DoFunc(fSlot, CommTab, 20000, nBands-1, FAvalue, LeftOver, FontTable, buf-1, nil, nil, (nextCopy lshift 5)+4) if Debug then [ while (@RTC-tim) < debDelay loop; tim = @RTC ] // ~~delay // Assume the page we are printing will be OK and prepare for whatever comes next: rosCount = rosCount + 2 // for the led setting commands CursorDigit(nPagesPrinted) // See who's (maybe) knocking at my door: 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 // Find next page to work on: nextPage=NextSheet(pDoc, nPagesPrinted) needInit = true if (not knockKnock) & nextPage & //if nobody waiting and there is more to do (nextBin eq curBin ) & (nextHandling eq curHandling ) & // and penguin doesn't need a pause (not switchBin) & (stopsPrinting eq false) then // and no forced bin switch then continue printing. // enable interband communication with penguin to set up the next revolution // keep track of what I've sent so we don't get out of sync [ needInit = false CommTab!4 = sigband rosCount = rosCount + 1 ] needFonts = (nextPage>>PageG.fontLoad ne page>>PageG.fontLoad) & (nextPage ne 1) // Now see if we actually printed this properly. Wait for Orbit to announce it is finished. while @#720 ne 0 do if (@RTC-tim) gr imageTimeout then [ InitializeHardware() // clear hardware, #720 // Machine dead or Orbit got behind and it wasn't detected // Will generally be overriden by more specific analysis @lvFailureCode = 103 // 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<<STATUS.invalidBandEntry then [ InitializeHardware(true); if LeftOverGuard!1 eq -1 then SpruceError(1010, @1, @2) //else, assume that //bad band entry is simply result of leftover overflow ] test stat<<STATUS.prematurePageAbort then [ Announce(16); nonF = 301 ] or if stat<<STATUS.behind then [ Announce(16); nonF = 300 ] if stat<<STATUS.timeout then [ Announce(17); @lvFailureCode = 102 ] if LeftOverGuard!1 ne -1 then [ Announce(18); nonF = 310 ] // then check possible next page data enclobberment if nonF then @lvFailureCode = nonF // Now try for more specific engine status check let running = needInit?cycledown, printing let printingSecondSide = (running eq printing) & (curHandling eq pTSSecond) tim = @RTC unless Debug do [ let x = ROSCheck( running, printingSecondSide) unless x then break // that's what we expected if x > 0 do [@lvFailureCode = x ; break ] //result was -1: ok if cycledown expected and still printing if (running eq printing) % ((@RTC - tim) > 27) do [ @lvFailureCode = 114; break ] ] repeat // Now wait for page sync to go off unless AwaitPageSync(0) then @lvFailureCode = 101 //Now decide what to do: if (@lvFailureCode > 0) & (@lvFailureCode < minDocumentError) do [ backup = 1; break ] imageTimeout = rITO +(needInit?11*27,0) // next image should be out in less than 2 seconds xportModel = ((xportModel & 3) lshift 1) + 1 test curHandling eq pTSFirst then [ BinCounters!AuxCount = (BinCounters!AuxCount) +1 if BinCounters!AuxRecoveryCount do [ BinCounters!AuxRecoveryCount = BinCounters!AuxRecoveryCount -1 unless BinCounters!AuxRecoveryCount do nPagesPrinted = nPagesAlreadyPrinted ] ] or // note that bin counters not incremented if filling aux tray [ AddToBin(binMax, curBin); if (curHandling eq pTSSecond) do [ BinCounters!AuxCount = (BinCounters!AuxCount) - 1 ] ] ]PrintLoop repeat InitializeHardware() CloseMeasure() resultis (knockKnock % @lvFailureCode)? SetupRecovery(pDoc,lvFailureCode,lv xportModel, nPagesPrinted-backup), -1 ] // -------------------------------------------------------------------------- // code = ROSCheck(expectedPrintSeq) // -------------------------------------------------------------------------- // analyze ROS status // code = 0 if there are no malfunctions, ROS is ready to print // -1 if the only thing wrong is that penguin needs to cycle round to the expected state // otherwise, a code for the error detected // // expectedPrintSeq where caller thinks penguin should be(printing, cycling down, standing by, don't care) // ROSCheck first screens the current status for any malfunction indications, and // returns right away if there are none. Otherwise, it applies the current status // against a printer-dependent table of possible conditions, yielding a failure // code. // A check verifies that the laser is on and the polygon is // scanning (SOS/EOS are seeing things), by making sure that the low four bits of the line // count (indicated in status word) are changing. The code reads the line count, waits // approximately the time needed for four scan lines (generous margin), then reads the // count again, reporting a problem if the values are equal. This test happens only when // the running parameter is false. The wait time (scanTicks) is computed in PrintInit, as: // ResolutionS is scaled by 10 as stored, PaperSpeedInches by 100. The (fast 10 bits of) // the RTC ticks at 38 usec. intervals. Thus the # ticks wanted for four lines is: // ( 4 lines x 10↑6 usec/sec x 1/38 tick/usec.) / ((PaperSpeedInches/100 x ResolutionS/10) lines/sec) // or about (106 x 10↑3) / (PaperSpeedInches/100 x ResolutionS/10) ticks -- about 30 for Dover. // This is only approximate because ROSStatus time, about 10 ticks for Dover, is not included. // Part of the reason for waiting four line times is to account for possible delays in obtaining // the correct line count status. Later, this method can be used to check for correct polygon speed. // The scanTicks static is shifted left by 6 to match the clock reading function's results and ROSCheck(expected, printingSecondSide; numargs na) = valof [ if na < 2 then printingSecondSide = false ros12 = ROSStatus(12) ros13 = ROSStatus(13) let scanning, auxTrayProblem = true, false let malFnStatus = ros13M let auxTrayEmpty = (ros13 & #100) ne 0 let mainTrayEmpty = (ros13 & #200) ne 0 let subSeq = (ros13 rshift 8)&7 let mainSeq = (ros13 rshift 11)&7 let mode = ros13 rshift 14 let printSeq = selecton mainSeq into [ case 1: powerOn case 2: warmup case 3: standby case 4: 0 case 5: malfClear default: mainSeqErr //Mainseq error ] unless na do expected = printSeq // printing not valid state if nothing expected unless printSeq do [ printSeq = selecton subSeq into [ case 0: printing case 1: preprint case 2: cycledown case 4: abnormal default: subSeqErr // subSeq error ] ] let ready = (printSeq eq expected) & // penguin is where we think it should be (malFnStatus eq 0) & (not mainTrayEmpty) & ((ros12 & #12377) eq (rosCount & #377)) & //no malf and no queue problems mode eq 1 // and printer is in remote print mode if ready & (printSeq ne printing) then [ let lineCount = ROSStatus(7) & #170000 let rtc = ReadClock() until (ReadClock()-rtc) ge scanTicks loop scanning = (ROSStatus(7)𩠐) ne lineCount if expected ne cycledown do // can't check while paper may be moving [ if (BinCounters!AuxCount eq 0) & (not auxTrayEmpty) then auxTrayProblem = 72 ] ] if printingSecondSide & auxTrayEmpty then auxTrayProblem = 70 if ready & scanning & (auxTrayProblem eq false) % Debug resultis 0 // identify the problem or condition preventing ready let malf = selecton malFnStatus into [ case 1: 81 // processor interlock open case 2: 82 // zone IIA jam case 3: 83 // zone IIB jam case 4: 84 // zone III jam case 5: 85 // sorter interlock open // case 6: 86 // stop print push button pressed: not used in remote print. case 7: 71 // aux tray empty case 8: 115 // main tray empty - shouldn't happen with mainTrayProblem being watched. case 9: 108 // ink low case 10: 109 // trays don't match case 11: 110 // fuser not ready case 12: 111 // main tray paper misfeed case 13: 80 // aux tray paper misfeed case 14: 112 // cycle control state error case 15: 124 // paperexit jam case 16: 125 // (output) bin enter jam case 0: 0 default : -1 ] let noResponse = EngineCommErr(ros12) //check status of spruce communication with penguin let code = 0 test mode ne 1 then code = 100 // local mode - Penguin not listening or test ros12 < 0 then code = 104 // wait state - Penguin not listening or test malf > 0 then [ let x = ROSCommand(pClearMalf) unless (auxTrayProblem eq 70) do code = malf // good malfunction code ] or test noResponse then code = 116 // penguin not talking or test printSeq > malfClear then code =printSeq // State error or test malf then code = 117 // unknown malfunction code or test not scanning then code = 118 // laser appears to be off or test auxTrayProblem then code = auxTrayProblem or test mainTrayEmpty then code = 132 or test printSeq ne expected then code = -1 or code = 119 // can't figure out what's wrong resultis code ] // NextSheet(pDoc, afterPage) // ----------------------------------------------------------------------------------- // Setup paper handling info, copy number and pointer to PageG structure that describe the next image. // It is assumed that the PageG entities represent consecutively numbered pages. whichSide identifies a // page as 'odd' or 'even'; 'odd' pages face the same way the break page does --up, in the normal penguin mode [down, if "printerForward"]. // All pages are paired except: the break page, the first page if it is "even", the last page if it is "odd" // NextSheet makes two passes thru the document: // ** on the first pass all images that will be facing down are printed and stored in the aux tray in reverse order. // **on the second pass the pages that will be face up in the output bin are printed. This pass is complicated // by the fact that there may be face-down sheets for which there is no corresponding face-up image // -- these sheets must be passed thru at the appropriate time -- and by the fact that there may be face-up sheets for which // there is no corresponding face-down sheet -- these sheets must be fed from the main tray instead of the aux. and let NextSheet(pDoc, afterPage) = valof [ nextBin = SelectBin(curBin) if (nextBin eq 0) & (curBin ne 0) & breakPage & (afterPage < pDoc>>DocG.nPages) do // switching to overflow bin - leave break page in mailbox [ nextHandling = pSSMain; nextCopy = 1011; breakPageCopy = 1012 IncBinSerial(BinSerials+curBin) resultis ((pDoc>>DocG.nPages)-1)*(size PageG/16)+pDoc>>DocG.Pages ] let nPages, nBreaks = pDoc>>DocG.nPages, breakPage unless twosided & ((nPages - nBreaks) gr 0) do [ nextHandling = pSSMain; resultis PrintNext(pDoc, lv nextCopy, afterPage) ] nPages = nPages - nBreaks let bkPage = nPages*(size PageG/16)+pDoc>>DocG.Pages // if there is one let nCopies = pDoc>>DocG.nCopies let page = pDoc>>DocG.Pages // pointer to first page let firstPageEven = (page>>PageG.whichSide eq 0)? 1,0 page = (nPages-1) * (size PageG/16) + page // pointer to last page let lastPageOdd = (page>>PageG.whichSide ne 0)? 1,0 let nDoubles = (nPages - firstPageEven - lastPageOdd)/2 let nSheets = nDoubles + firstPageEven + lastPageOdd let nAuxSides, auxIncr, nAuxBreaks, incr, relImageIndex, copy = nil, nil, nil, nil, nil, 0 test printerForward ifso [ nAuxSides, auxIncr, nAuxBreaks, incr, nBreaks = nDoubles + lastPageOdd, lastPageOdd, nBreaks, firstPageEven, 0 ] ifnot [ nAuxSides, auxIncr, nAuxBreaks, incr = nDoubles + firstPageEven, firstPageEven, 0, lastPageOdd ] let totAuxSides = nAuxSides * nCopies + nAuxBreaks page = 0 test afterPage ls totAuxSides ifso // then need to fill Aux tray [ nextHandling = pTSFirst copy = afterPage / nAuxSides test copy eq nCopies then page = bkPage or [ nextCopy = printerForward? nCopies-copy, copy+1 relImageIndex = (afterPage rem nAuxSides)*2 + 1 - auxIncr if printerForward do relImageIndex = nPages -1- relImageIndex page = relImageIndex * (size PageG/16) + pDoc>>DocG.Pages ] ] ifnot // then put paper out - from aux tray or as single sheets from main tray [ afterPage = afterPage - totAuxSides nextHandling = pTSSecond test afterPage < nAuxBreaks then page = 1 or // no image -- just feed breakpage thru [ afterPage = afterPage - nAuxBreaks test afterPage < nSheets*nCopies ifso // if there are more data pages . . . [ copy = afterPage/nSheets nextCopy = printerForward? copy+1, nCopies - copy relImageIndex = afterPage rem nSheets test (relImageIndex +auxIncr) eq nSheets then page = 1 // no image -- just feed page thru or // there is an image to do [ if relImageIndex < incr do nextHandling = pSSMain // single sheet let pageIndex = (afterPage rem (nSheets - auxIncr))*2 + 1 - incr unless printerForward do pageIndex = nPages - 1 - pageIndex page = pageIndex*(size PageG/16) + pDoc>>DocG.Pages ] ] ifnot // no more data pages [ if afterPage <nSheets*nCopies + nBreaks do [ nextHandling = pSSMain; page = bkPage ] ] ] ] if page eq bkPage then nextCopy = breakPageCopy resultis page ] // ----------------------------------------------------------------------------------- // SetupRecovery(pDoc, lvFailureCode, lvXportModel, restartPage, code; numargs na) // ----------------------------------------------------------------------------------- //This is truly serious - Spruce aborts the file and restarts from the beginning. // $$5070 070: starting over - Aux tray empty too soon // Aux tray should have had a sheet with a first side - got lost somewhere // $$5071 071: Aux tray empty malfunction // May be spurious // $$5072 072: Aux tray has trash in it - please empty it //These represent external problems - Spruce needs user intervention to recover nicely //if the Aux tray is involved. // $$5080 080: Aux tray misfeed // $$5081 081: Processor interlock open // $$5082 082: Zone IIA jam // $$5083 083: Zone IIB jam // $$5084 084: Zone III jam // $$5085 085: Jam - Remove 1 sheet from paper path/aux tray. // $$5086 086: Jam - Remove 2 sheets from paper path/aux tray. // $$5087 087: Jam - Remove 3 sheets from paper path/aux tray. //Even if these were detected while printing, assume Penguin did not start feeding paper //(last page must be reprinted, but nothing in the paper transport mechanism was damaged) // $$5090 090: Main tray misfeed //these assume last page was printed successfully if detected while printing first side //If we are wrong, error 70 will occur // $$5100 100: Printer is in local mode. Remove Auditron key. // $$5101 101: ROS malfunction - Page sync never went off. // $$5102 102: ROS or printing malfunction - Orbit timed out // -- page sync never arrived, or engine died, or Orbit got behind. // $$5103 103: ROS or printing malfunction - Alto program timed out // waiting for Orbit microcode; page sync never arrived, or engine died, or Orbit got behind. // $$5104 104: Not ready - controller is in wait state. // $$5105 105: Sorter interlock open // $$5106 106: bad 6800 subsequence code // $$5107 107: bad 6800 main sequence code // $$5108 108: Ink low // $$5109 109: Trays don't match // $$5110 110: Fuser not ready // $$5111 111: Main tray misfeed // $$5112 112: Cycle control state error in 6800 // $$5113 113: 6800 reports abnormal condition, but did not specify what it is // $$5114 114 Unexpectedly lost Printing state or didn't reach expected Cycledown state //( Penguin Print [printloop]) // $$5115 115: Main paper tray empty // $$5116 116: Penguin not communicating - please check it(ROSCheck) // $$5117 117: Penguin returned unknown malfunction code // $$5118 118: Laser appears to be off // $$5119 119: Something is wrong, but don't know what //These assume the last page was imaged correctly // $$5120 120: Timeout waiting for Standby - ready Penguin, please. // $$5121 121 Penguin not communicating - please check it // (Print startup) // $$5122 122: Penguin in standby, but won't accept print command // $$5123 123: Printer in power-on mode: Push StartPrint button // $$5124 124: Paper exit jam: Please clear // $$5125 125: Output bin-entry jam: Please clear //these are precautionary stops - spruce proceeds after user intervention // $$5130 130: Output bin full: empty it then type P // $$5132 132: Main tray empty - add paper //these don't stop printing // $$5300 300: Some pages too complicated, but all were printed // Orbit got behind ROS, but page terminated normally. // $$5301 301: Some pages too complicated, but printing continued // Orbit got behind ROS, quit early when SendVideo went away. // $$5310 310: Internal problem; please inform Spruce mainenance personnel // Left over table is not big enough. // ----------------------------------------------------------------------------------- // SetupRecovery(pDoc, lvFailureCode, lvXportModel, restartPage, code; numargs na) // ----------------------------------------------------------------------------------- and let SetupRecovery(pDoc, lvFailureCode, lvXportModel, restartPage, code; numargs na ) = valof [ test na eq 5 then [ @lvFailureCode = code ] or [ code = @lvFailureCode ] unless code resultis restartPage if code < 75 resultis 0 //paper in aux tray didn't come out even with 2nd side images let backup = 0 if code < 85 then [ let xpm =@lvXportModel while xpm ne 0 do [ backup = backup + (xpm & 1); xpm = xpm rshift 1 ] if backup do [ stopsPrinting = (backup lshift 8) + jam; if twosided do @lvFailureCode = backup + 84 ] ] backup = backup + nPagesPrinted - restartPage let nFirstSides, nSecondSides, nSingleSheets = 0, 0, 0 if (nPagesPrinted ge backup) & (restartPage ge (nPagesPrinted - backup)) do //for each destroyed sheet [ let x = NextSheet(pDoc, restartPage-1) test nextHandling eq pTSFirst then nFirstSides = nFirstSides + 1 or test nextHandling eq pTSSecond then nSecondSides = nSecondSides + 1 or nSingleSheets = nSingleSheets + 1 if restartPage eq (nPagesPrinted - backup) then break restartPage = restartPage - 1 ] repeat test BinCounters!AuxRecoveryCount then BinCounters!AuxRecoveryCount = BinCounters!AuxRecoveryCount+ backup or BinCounters!AuxRecoveryCount = Max(nSecondSides - nFirstSides, 0) resultis restartPage ] // ----------------------------------------- // InitializeHardware, ROSCommand, EngineCommErr, SelectBin. // ----------------------------------------- and InitializeHardware() be [ if Debug return InitRam(0) //Reset all RAM tasks, restart Trident if necessary DoFunc(fControl, 1) //Reset Orbit ] and ROSCommand(command) = valof [ rosCount = (command eq pResetCount)? 0, rosCount + 1 DoFunc(fROSCommand, command) if Debug resultis 0 let tim = @RTC until (@RTC - tim) ge eTicks do [ ros12 = ROSStatus(12) if (rosCount & #377) eq (ros12 & #377) then break ] resultis EngineCommErr(ros12) ] and let EngineCommErr(x) = valof // returns // 1 - if count kept by penguin does not agree with rosCount // 2 - if a command was rejected because penguin didn't recognize it // 3 - if penguin didn't accept a command because its buffers were full (of other commands) [ if (x & #377) ne (rosCount & #377) resultis 1 if (x & #10000) eq #10000 resultis 2+ (xߐ eq 0?0,1) resultis 0 ] and SelectBin(bin) = valof [ let tray = 0 if ((Capabilities & mMailbox) ne 0) & (BinCounters!bin le 50) & (BinCounters!0 le 50) then tray = bin if ((Capabilities & mMultiBin) ne 0) then [ test (BinCounters!bin < 50) then tray = bin or tray = Min(bin+1, 18) ] resultis tray ] // December 15, 1978 10:04 AM first cut - derived from puffinprint, sort of. // January 2, 1979 4:40 PM more work on ROSCheck // January 4, 1979 3:12 PM first cut at xportModel, more work on ROSCheck // January 15, 1979 3:53 PM fix ROSCommand // January 19, 1979 3:04 PM cleanup and beautification // January 30, 1979 11:08 AM change order of tests in EngineCommErr // February 14, 1979 9:47 AM turn on led control -- release 2 // February 28, 1979 3:19 PM increase printHysteresis to 30 // March 1, 1979 12:26 PM be tougher on unexpected printing state from 6800 // April 10, 1979 12:45 PM first cut - twosided printing // April 17, 1979 10:01 PM cleanup // May 22, 1979 11:24 AM upgrade to os16 // May 23, 1979 2:19 PM, fix measure interface // June 28, 1979 4:40 PM, allow for spurious 'auxtray empty' msg and primitive error recovery // August 6, 1979 10:49 AM, use SetupPrint in SprucePrint; handle simplex, overflow protection, output modes // August 10, 1979 4:14 PM, first cut new error handling // August 14, 1979 5:06 PM, more cleanup work // August 21, 1979 10:20 AM, put out break page if changing bins, cleanup // August 29, 1979 2:03 PM, multibin doesn't use same overflow bin as mailbox // September 13, 1979 9:48 AM, force user interaction for jam on two sided print // September 13, 1979 4:45 PM, fix handling of jam on 4th sheet // September 20, 1979 9:55 AM, work on error messages // September 28, 1979 9:58 AM, if file is just a break page, treat as single side // October 3, 1979 4:24 PM, use new PageG structure // October 17, 1979 3:19 PM, enable bin-positioning commands // October 26, 1979 12:16 PM, put 'MORE IN OVERFLOW BIN' breakpage in mailbox // October 26, 1979 3:59 PM, increase timeout to 11 seconds to allow bin movement to complete // January 15, 1980 10:12 PM, remove kludge for spurious aux tray empty msg on switch to 2nd side // " add errors 124 & 125 for exit jams // February 27, 1980, 4:27 PM, try to get intermediate break pages in right bin // March 3, 1980 12:06 PM, try some more // July 16, 1980, 4:38 PM, if there is a break page breakPage value is 1 (instead of true) // July 23, 1980, 4:07 PM, cycledown gracefully if bin full // February 2, 1981 4:21 PM, don't swat if bad band entry probably due to leftover overflow // February 5, 1981 10:49 AM, remove bin choosing code, put into sprintUtils // February 5, 1981 4:57 PM, add first cut at BinSerials code