{ File name: Raven.mc Description: Raven LSEP (Low Speed Electronic Printer) microcode Author: Pitts Jarvis, Created: March 14, 1980, Last Edited: Jarvis, November 25, 1980 2:14 PM Olmstead, March 23, 1981 5:25 PM: Remove some unneeded CANCELBR's Garner, July 30, 1981 11:51 PM: added ClrDPRq & PCtl_ after endBand so that hardware fix to allow slower LSEP's works. (Note that the click at endBand can be eliminated if the click before uses nibCarry.) BJackson, 16-Nov-85 19:10:07: Cleanup tabs, etc. } { Printer Control register on X-Bus ~ClearLineActive 8 Inhibits data wakeups and forces video to all white until next line sync ForceRequest 4 forces printer wakeups every round VideoWhite 2 forces video to white EnablePrinter 1 enables printer and memory refresh task wakeups } Set[EndActiveScanCtl, 1]; Set[EndBandScanCtl, 5]; Set[StartScanCtl, 9]; Set[StartActiveCtl, 0B]; { Raven CSB (read once per page, immediately after code detects run#0) run non-zero=> index of 1st band record (displayBase0 relative), read then zeroed overrun non-zero=> over ran band buffer interruptMask Mesa process stuff bandSize number of lines in a band active scan number of words in line buffer actually sent to printer line size number of words in line buffer tab number of words skipped from line sync before sending image to printer scans number of blank lines sent to printer at start of page } { Raven band record pointer real address of band (displayBase1 relative) next index of next band record (displayBase0 relative) status 0=> empty, #0=> full, <0=> last band } SetTask[1]; StartAddress[PrinterInit]; PrinterInit: displayBase1 _ 0 {band buffer in first 64K}, CancelDisp[$] ,c1; PrinterInitC2: displayBase0 _ rD0 _ uIOPage ,c2; Noop ,c3; pageGap: MAR_ [displayBase0, rD0 + PrinterRunOffset] ,c1; {wait for non-zero run} MDR_ 0, CancelPgCross[$, 0], LOOPHOLE[wok] ,c2; {. . . clear it immediately} rD1_ MD ,c3; uThis_ rD1, ZeroBr ,c1; rD1_ 0A, BRANCH[startPage, $] ,c2; {rD1_ AltUaddr index} PCtl_ EndActiveScanCtl, GOTO[pageGap] ,c3; startPage: Noop ,c3; rD0 _ MAR _ [displayBase0, rD0 + PrinterOverrunOffsetM1 + 1] ,c1; {clear overrun} MDR _ 0, CancelPgCross[$, 0], LOOPHOLE[wok] ,c2; Noop ,c3; loadParam: MAR_ [displayBase0, rD0+1], rD0_ rD0+1 ,c1; {load parameters} uScans_ rD0, CancelPgCross[$] ,c2; rD0_ MD ,c3; Ybus_ rD1, rD1_ rD1+1, NibCarryBr, AltUaddr ,c1; uyParamBase_ rD0, BRANCH[$, skipLines] ,c2; rD0_ uScans, GOTO[loadParam] ,c3; skipLines: rD0_ rD0-1, ZeroBr ,c3; {loaded uScans last} BRANCH[$, firstBand] ,c1; PCtl_ EndActiveScanCtl, GOTO[skipLines] ,c2; firstBand: rD0_ uThis ,c2; rD1_ 1 ,c3; {not last band} advanceBand: MAR_ [displayBase0, rD0], rD0_ rD0+1, ClrDPRq ,c1; []_ rD1, NegBr, CancelPgCross[$] ,c2; {test for last band} rD1_ MD, BRANCH[$, lastBandDone] ,c3; {pointer to band} MAR_ [displayBase0, rD0], rD0_ rD0+1, ClrDPRq ,c1; uLineAddress_ rD1, CancelPgCross[$] ,c2; rD1_ MD ,c3; {next band} MAR_ [displayBase0, rD0], uBandStatus_ rD0, ClrDPRq ,c1; {save address for later} uThis_ rD1, CancelPgCross[$] ,c2; rD1_ MD ,c3; {status of this band} []_ rD1, ZeroBr ,c1; rD1_ uLineAddress, BRANCH[$, RavenOverrun], ClrDPRq ,c2; rD0_ uBandSize ,c3; uLineCount_ rD0, ClrDPRq ,c1; rD0_ uTabCnt ,c2; rD0_ rD0-4, GOTO[startLine1] ,c3; {4 click band overhead} startLine: PCtl_ EndActiveScanCtl ,c1; rD0_ uLineSize, ClrDPRq ,c2; rD1_ uLineAddress ,c3; rD1_ rD1+rD0, ClrDPRq ,c1; {line sync wakeup} PCtl_ StartScanCtl ,c2; rD0_ uTabCnt ,c3; {Enter from advanceBand or startLine. At this point rD0 has uTabCnt, rD1 has uLineAddress} startLine1: uLineAddress_ rD1, ClrDPRq ,c1; Noop ,c2; Noop ,c3; idle: rD0_ rD0-1, ZeroBr ,c1; {tab over to active area} BRANCH[$, startActive], ClrDPRq ,c2; GOTO[idle] ,c3; startActive: PCtl_ StartActiveCtl ,c3; scan: MAR_ [displayBase1, rD1+0], ClrDPRq ,c1; MDR_ rD0{= zero}, rD1_ rD1+1, PgCarryBr ,c2; POData_ MD, BRANCH[scan, endLine] ,c3; endLine: rD1_ uLineCount, ClrDPRq ,c1; {play out last word} rD1_ rD1-1, ZeroBr ,c2; uLineCount_ rD1, BRANCH[startLine, endBand] ,c3; endBand: ClrDPRq ,c1; PCtl_ EndBandScanCtl ,c2; rD0_ uBandStatus ,c3; MAR_ [displayBase0, rD0+0] ,c1; {mark band empty} MDR_ rD1 ,c2; {. . . and get next band} rD1_ MD ,c3; {negative=> last band} {initiate band complete interrupt} rD0_ uWP ,c1; rD0_ uInterruptMask or rD0, MesaIntRq ,c2; uWP_ rD0 ,c3; rD0_ uThis ,c1; endBand1: Noop ,c2; PCtl_ EndActiveScanCtl, GOTO[advanceBand] ,c3; {save old status for test} lastBandDone: PCtl_ EndActiveScanCtl, GOTO[PrinterInitC2] ,c1; RavenOverrun: rD0 _ uIOPage ,c3; MAR_ [displayBase0, rD0 + PrinterOverrunOffsetM1 + 1] ,c1; {set overrun} rD1 _ MDR _ 1, CancelPgCross[$, 0], LOOPHOLE[wok] ,c2; {. . . and not last band} rD0_ uBandStatus ,c3; rD0_ rD0-2, GOTO[endBand1] ,c1; {retry this band again} {Memory Refresh Task} SetTask[3]; StartAddress[RefreshGo]; Set[WakeupMaskOffset, 0EA] ; {added to uIOPage=(1)4001} Set[HalfFieldSize, 0E0] ; RefreshGo: uClockBits _ 0, CancelDisp[$] ,c1; Noop ,c2; RefreshField: displayBase2 _ rD2 _ uIOPage ,c3; MAR _ [displayBase2, rD2 + WakeupMaskOffset] ,c1; Noop, CancelPgCross[$, 0] ,c2; rD2 _ MD ,c3; uPWakeup _ rD2 ,c1; Noop ,c2; Noop ,c3; {This code looks this way because uWP must be updated within one click.} rD2 _ uWP ,c1; rD2 _ uPWakeup or rD2, MesaIntRq ,c2; uWP _ rD2 ,c3; rD2 _ LShift1 HalfFieldSize ,c1; uRefreshLine _ rD2 ,c2; ClrRefRq ,c3; Refresh: rD2 _ uClockLow, Refresh ,c1; rD2 _ rD2 + 1, CarryBr ,c2; uRefreshTemp _ rD2, BRANCH[$, RefreshCarry] ,c3; Refresh ,c1; Noop ,c2; Refresh1: uClockLow _ rD2 ,c3; rD2 _ uRefreshLine, ZeroBr ,c1; rD2 _ rD2 - 1, BRANCH[$, RefreshField] ,c2; uRefreshLine _ rD2, ClrRefRq, GOTO[Refresh] ,c3; RefreshCarry: rD2 _ uClockHigh, Refresh ,c1; rD2 _ rD2 + 1 ,c2; Noop ,c3; uClockHigh _ rD2 ,c1; rD2 _ uRefreshTemp, GOTO[Refresh1] ,c2;