// PrintOrbit.bcpl // errors 3400,3500 get "PDInternals.d" get "Orbit.d" // outgoing procedures external [ POrbit POrbitInit ] // incoming procedures external [ //PrintOrbitHdwFns InitializeHardware DoFunc ROSCommand AdCommand SetupAdapter AddQEntry FeedASheet AwaitPageSync ROSCheck //PRINT PrintError //PDPRINT Min PDError //CURSOR CursorChar CursorDigit CursorToggle //OS Zero MoveBlock StartIO //PrintDisk PrintDiskInit PrintDiskRead PrintDiskCheck PrintDiskStop ] // incoming statics external [ nPrinterColors printerDevice useStandardQueue SLOTTimeOut Debug //PRINTORBITINIT nVisibleBands nLeadingBands nTrailingBands FA orbitSignalBand //PRINTORBITHDWFNS Func ] //outgoing statics external [ debugTrail ] static [ debugTrail ] // internal statics static [ coldStart orbitStat readyTimeOut=3*27 ] // File-wide structure and manifest declarations. manifest [ OrbitBandWidth=16 RTC=#430 loSize=30 //Enough for one character, end, slop debugTrailSize=40*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 = 150 // Document inherently hard to print ] manifest [ //P commands PResetRemoteQueue=#63010 PStartRemoteQueue=#63006 PStart3ColorVideo=#63346 PStart3ColorScan=#63246 PStart4ColorVideo=#63306 PStart4ColorScan=#63206 PAppendQueueEntry=#63020 PSetVideo=#63204 PNoPaperAction=#63003 PFeedPaper=#63203 PReleasePaper=#63103 PSinglePass=#63303 PNoColor=#63001 PSetColor6=#63201 //usually black PSetColor7=#63101 //usually cyan PSetColor9=#63041 //usually magenta PSetColor11=#63021 //usually yellow ] // ----------------------------------------------------------- // Print Initialization // ----------------------------------------------------------- let POrbitInit(pg, nPages, nCopies; numargs na) be [ coldStart=true let debugTrailVec=vec debugTrailSize compileif DebugSw then [ debugTrail=debugTrailVec; debugTrail!0=1; debugTrail!1=debugTrailSize-4 ] [ SetupAdapter() InitializeHardware(true) let FailureCode=ROSCheck(false) if FailureCode eq 0 then break PrintError(3400+FailureCode) ] repeat if na eq 0 then return // If using a standard queue, check to be sure it's consistent if useStandardQueue then [ if nPages rem nPrinterColors ne 0 then PDError(3589) for i=0 to nPages-1 do [ let toner=pg>>PageG.ColorPass let expToner=selecton (i rem nPrinterColors) into [ case 0: 2; case 1: 3; case 2: 1; case 3: 0 ] if toner ne expToner then PDError(3588) let f,s=0,0 if (i rem nPrinterColors) eq 0 then f=1 if (i rem nPrinterColors) eq (nPrinterColors-1) then s=1 if pg>>PageG.strip ne s % pg>>PageG.feed ne f then PDError(3587) pg=pg+lPageG ] return ] // Do P machine queue creation (Pimlico, Puffin) // establish queue entries: first, a null entry, and then the real entries ROSCommand(PResetRemoteQueue) ROSCommand(PAppendQueueEntry) //null rev if nCopies*nPages gr 40 then PDError(3590) //Too many entries for i=1 to nCopies do [ let p=pg for j=1 to nPages do [ let paperAction=PNoPaperAction if p>>PageG.feed then paperAction=PFeedPaper if p>>PageG.strip then [ test p>>PageG.feed then paperAction=PSinglePass or paperAction=PReleasePaper ] if (nPrinterColors eq 3)&(p>>PageG.ColorPass eq 0) then PDError(3591) let tonerColor=selecton p>>PageG.ColorPass into [ case 0: PSetColor6; //Black case 1: PSetColor7; //Cyan case 2: PSetColor9; //Magenta case 3: PSetColor11 ] //Yellow AddQEntry(tonerColor, paperAction) p=p+lPageG ] //for all pages ] //for all copies ROSCommand(PStartRemoteQueue) //Start printer turning coldStart=false ] // POrbit -- main routine to print a single page with the Orbit and POrbit(pg, lowAdr, highAdr, last) = valof [ let FailureCode=0 let debugTrailVec=vec debugTrailSize compileif DebugSw then [ debugTrail=debugTrailVec; debugTrail!0=1; debugTrail!1=debugTrailSize-4 ] let nBands=nLeadingBands+nVisibleBands+nTrailingBands let nImageBands=pg>>PageG.LastBand-pg>>PageG.FirstBand+1 lowAdr=(lowAdr+1)&(-2) //Make it even let BandCommands=lowAdr lowAdr=lowAdr+(nBands+nImageBands)*2 let FontTable=lowAdr //it's even lowAdr=lowAdr+nImageBands //never need more than nImageBands chars let LeftOver=vec loSize+1 LeftOver=(LeftOver+1)&(-2) let LeftOverGuard=LeftOver+(loSize&(-4))-4 LeftOver!0=0 //Initialize LeftOver table LeftOverGuard!1=-1 let FirstBuffer=nil let nBuffers=PrintDiskInit(pg, lowAdr, highAdr, lv FirstBuffer) //Now build font table: char i points to buffer i let p=FirstBuffer for i=0 to Min(nImageBands,nBuffers)-1 do [ FontTable!i=p p=p!-1 ] //Now build band command list let nextCharCode=0 let nextImageS=pg>>PageG.FirstBand*pg>>PageG.BandWidth let p=BandCommands for i=0 to nBands-1 do [ while nImageBands ne 0 & nextImageS ls (i-nLeadingBands+1)*OrbitBandWidth do [ nImageBands=nImageBands-1 p!0=#100000+nextCharCode nextCharCode=(nextCharCode+1) rem nBuffers p!1=((nextImageS&(OrbitBandWidth-1)) lshift 12)+ pg>>PageG.BitMargin+FA*16 nextImageS=nextImageS+pg>>PageG.BandWidth p=p+2 ] p!0=0; p!1=0; p=p+2 ] //Read first nBuffers worth of information into disk buffers let nR,nC=nil,nil for i=1 to nBuffers do nR=PrintDiskRead() nC=PrintDiskCheck() repeatuntil nC eq nR // Initialize the Orbit, printing engine, etc. InitializeHardware(false) // Now wait for the printer to indicate ready let tim = @RTC [ FailureCode=ROSCheck(not coldStart) if FailureCode eq 0 then break // ready if FailureCode > maxNotReady % (@RTC-tim) > readyTimeOut then [ InitializeHardware(true); resultis FailureCode ] ] repeat DoFunc(fControl, 21b) AdCommand(adBufferReset) // Feed a sheet (on those printers that require it) // If Dover is already running, this StartPrint may not do the right // thing, because it may be sent during the "dead" time near CS-5 FeedASheet() unless AwaitPageSync(0) do PrintError(3592) // Cold start for Dover requires an idle cycle if printerDevice eq printerDover & coldStart ne 0 then [ AwaitPageSync(1); FeedASheet(); AwaitPageSync(0) ] coldStart=false // Calculate a ROS command table for the device: let CommTabNoFeed=vec 3 CommTabNoFeed=(CommTabNoFeed+1)&(-2) CommTabNoFeed!0=-1 let CommTabFeed=vec 10 CommTabFeed=(CommTabFeed+1)&(-2) let CommTab=nil switchon printerDevice into [ case printerDover: CommTab=CommTabFeed CommTab!0=orbitSignalBand+2 CommTab!1=adExternalCommand1+(last? 0,1) CommTab!2=orbitSignalBand+1 CommTab!3=adExternalCommand1 CommTab!4=10000b+orbitSignalBand CommTab!5=32*256 //Status bits 0-3 of word 8 CommTab!6=-1 endcase case printerSequoia: [ CommTab!0=orbitSignalBand let stopPrint=#60005 if printerDevice eq printerSequoia then stopPrint=#60000 CommTab!1=last?stopPrint,#60001 //Stop unless proven otherwise (below) CommTab!2=-1 ] endcase case printerPuffin: case printerPimlico: [ CommTab = CommTabNoFeed if last ne 0 & useStandardQueue ne 0 do ROSCommand(#63030) // Stop Print (at end of copy) endcase ] ] // Start Orbit working on the present page. DoFunc(fControl, #21) //Reset, clear behind AdCommand(adBufferReset) // Start the microcode!!!! tim=@RTC OrbitStart: DoFunc(fSlot, CommTab, 20000, nBands-1, FA lshift 8, LeftOver, FontTable+#100000, BandCommands-1) // imageS is coordinate of first scan-line of the NEXT image band let imageS=(pg>>PageG.FirstBand+1)*pg>>PageG.BandWidth // Loop waiting for ORbit to finish. let imageTimeout = SLOTTimeOut*27 while @#720 ne 0 do [ if (@RTC-tim) gr imageTimeout then [ InitializeHardware(true) // clear hardware, stop printer // Machine dead or Orbit got behind and it wasn't detected // Will generally be overriden by more specific analysis FailureCode = 99 // Manual intervention required break ] // orbitS is coordinate of first scan-line in the band being composed // in a band buffer by Orbit microcode let orbitS=(nBands-nLeadingBands-1-Func!3)*OrbitBandWidth // If first scan-line in Orbit's current band is beyond first scan-line in // the NEXT disk buffer, the CURRENT disk buffer can be reused if orbitS gr imageS then [ let onR=nR nR=PrintDiskRead() if onR ne nR then imageS=imageS+pg>>PageG.BandWidth ] nC=PrintDiskCheck() if nC-nR ge nBuffers-1 then FailureCode=100 //disk behind ] // Check Orbit status orbitStat=Func!9 //Orbit printing status. if orbitStat<<STATUS.invalidBandEntry then FailureCode=98 test orbitStat<<STATUS.prematurePageAbort then [ FailureCode=102 ] or if orbitStat<<STATUS.behind then [ FailureCode=101 ] if orbitStat<<STATUS.timeout then [ FailureCode=18 ] if LeftOverGuard!1 ne -1 then [ FailureCode=103 ] // Now try for more specific engine status check if FailureCode eq 0 then FailureCode=ROSCheck(true) // Check COUNT-H signal, paper did not arrive -- else re-print page (Dover only). if printerDevice eq printerDover & ((CommTab!5)&1) eq 0 then FailureCode=97 resultis FailureCode ] //and Announce(n) be //[ // CursorChar((n ge 16? $K,$P)) // for i=0 to 3 do // [ // if (n&10b) ne 0 then CursorToggle(i) // n=n lshift 1 // ] //]