// 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