Trailing-Edge
-
PDP-10 Archives
-
BB-M081Z-SM
-
monitor-sources/linepr.mac
There are 52 other files named linepr.mac in the archive. Click here to see a list.
; UPD ID= 8541, RIP:<7.MONITOR>LINEPR.MAC.3, 9-Feb-88 17:04:01 by GSCOTT
;TCO 7.1218 - Update copyright date.
; *** Edit 7193 to LINEPR.MAC by WONG on 14-Nov-85
; Fix undefined symbol (LPTTIM) when LPTN=0
; UPD ID= 2098, SNARK:<6.1.MONITOR>LINEPR.MAC.11, 3-Jun-85 15:41:45 by MCCOLLUM
;TCO 6.1.1406 - Update copyright notice.
; UPD ID= 1439, SNARK:<6.1.MONITOR>LINEPR.MAC.10, 31-Jan-85 16:13:50 by MOSER
;TCO 6.1.1166 - *PERFORMANCE* - OFN MANAGEMENT - FIX ASNOFN CALLER
; UPD ID= 4521, SNARK:<6.MONITOR>LINEPR.MAC.9, 13-Jul-84 19:55:49 by PURRETTA
;Update copyright notice
; UPD ID= 4269, SNARK:<6.MONITOR>LINEPR.MAC.8, 30-May-84 21:19:53 by MOSER
;TCO 6.2060 - MAKE LPT MTOPR FASTER
; UPD ID= 4021, SNARK:<6.MONITOR>LINEPR.MAC.7, 31-Mar-84 16:20:51 by PAETZOLD
;TCO 6.2019 - Use ADJSPs
; UPD ID= 1460, SNARK:<6.MONITOR>LINEPR.MAC.6, 18-Nov-82 12:59:30 by MOSER
;TCO 6.1352 - PREVENT OKSKBG BUGHLT
; UPD ID= 1390, SNARK:<6.MONITOR>LINEPR.MAC.5, 28-Oct-82 17:01:11 by COBB
;TCO 6.1336 - Make STSWAT sched test notice hard errors from FE
; UPD ID= 1061, SNARK:<6.MONITOR>LINEPR.MAC.4, 9-Aug-82 15:53:04 by PAETZOLD
;TCO 6.1219 - Extend LPTDTB for RLJFD
; UPD ID= 596, SNARK:<6.MONITOR>LINEPR.MAC.3, 5-Apr-82 15:58:56 by MURPHY
;TCO 6.1074 - Revise build procedures
;<6.MONITOR>LINEPR.MAC.2, 16-Oct-81 18:05:10, EDIT BY MURPHY
;TCO 6.1030 - Node names in filespecs; etc.
;Revise DTB format; get rid of double skips on NLUKD, etc.
; UPD ID= 2071, SNARK:<5.MONITOR>LINEPR.MAC.4, 24-May-81 15:36:00 by ZIMA
;TCO 5.1345 - correct LPINI and MTOPR function .MOSTS for MO%LCP handling.
; UPD ID= 1562, SNARK:<5.MONITOR>LINEPR.MAC.3, 15-Feb-81 16:56:13 by ZIMA
;Move 5.1256 to not step on any allocation changes made by the -11.
; UPD ID= 1509, SNARK:<5.MONITOR>LINEPR.MAC.2, 31-Jan-81 18:35:20 by ZIMA
;TCO 5.1256 - Fix lost data on online/offline transitions.
; COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1976, 1988.
; ALL RIGHTS RESERVED.
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
; ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
; INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
; COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
; OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
; TRANSFERRED.
;
; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
; AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
; CORPORATION.
;
; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
; SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL.
SEARCH PROLOG
TTITLE LINEPRINTER
IFN KLFLG!SMFLG,<
SEARCH SERCOD
;LOCAL STORAGE DECLARED IN STG.MAC
EXTN <FELPTN,KSLPTN,LPFLSZ,LPTRLP,LPTTIM,LPTTYP,LPTICT>
EXTN <NLPBF,LPTSTS,LPTST1,LPTST2,LPTST3,LPTCNT,LPTBUF>
EXTN <LPTCLS,LPTCCW,LPTCKT,LPTLCK,LPTERR>
EXTN <LPTOFN,PGDATA>
MAXLPT==2 ;MAXIMUM NUMBER LPTS
MAXLPA==NLPBF*5 ;DEFAULT LINE ALLOCATION
INIPSI==77 ;PSI CHANNEL FIELD IF NO ENABLE HAS BEEN DONE
JSBITS==<FLD(.JSAOF,JS%DEV)+FLD(.JSAOF,JS%DIR)+FLD(.JSAOF,JS%GEN)+FLD(.JSAOF,JS%NAM)+FLD(.JSAOF,JS%TYP)+JS%PAF>
;SPECIAL AC DEFINITIONS USED HEREIN
DEFAC (U,Q1) ;UNIT NUMBER
DEFAC (STS,P1) ;SEE GTJFN FOR FUNCTIONS
DEFAC (JFN,P2)
DEFAC (DEV,P4)
; Externally defined symbols
; Entries to this part
INTERN LPTCHK ; Check routine
; Parameters and fixed core locations
;DEFINITIONS FOR DEVICE DEPENDENT DISPATCH TABLE
SNDFLO=0 ;SEND FLUSH
SNDLDP=1 ;SPECIAL DEVICE FUNCTION
SENACK=2 ;ACK
SNDDAT=3 ;SEND DATA
SNDEOF=4 ;SEND EOF
SNDSTD=5 ;SEND STRING DATA
GLPTST=6 ;LINPRINTER TEST
SNDRST=7 ;RESTART
SNDINI=10 ;INITILIZATION
FEIEN==11 ;INTERRUPT ENABLE CHECK
SNDOPN==12 ;OPEN PRINTER
FELPMX==13 ;MAX TABLE SIZE
;SYMBOLS AND DEFSTR'S FOR LPTSTS
DEFSTR (LPDEVT,LPTTYP,35,18)
LP%FE==7777B11 ;BYTES NOW IN THE FE
LP%MX==7777B23 ;MAX BYTES ALLOWED IN FE
LP%ALP==1B35 ;BUFFER POINTER
LP%ALI==1B34 ;INTERRUPT BUFFER POINTER
LP%OPN==1B33 ;LPT IS OPENED
LP%THN==1B32 ;LPT IS HUNG (LINE PR CONTROL FAILED)
LP%TWT==1B31 ;REQUEST ON QUEUE
LP%TBL==1B30 ;LPT IS BLOCKED (OVER LINE ALLOCATION)
LP%OL==1B29 ;LPT IS ON LINE
LP%ER==1B28 ;VFU HAD AN ERROR
LP%MWS==1B27 ;MTOPR WAITING FOR STATUS TO ARRIVE
LP%OBF==1B26 ;OUTPUT BEING FLUSHED (E.G., ON CLOSE OR .MONOP)
LP%HE==1B25 ;LPT HAS A HARD ERROR
LP%LHC==1B24 ;LOADING HAS COMPLETED FLAG
DEFSTR (LPTFE,LPTSTS,11,12) ;BYTES NOW IN THE FE
DEFSTR (LPTMX,LPTSTS,23,12) ;MAX BYTES ALLOWED IN FE
DEFSTR (ALTP,LPTSTS,35,1) ;BUFFER POINTER
DEFSTR (ALTI,LPTSTS,34,1) ;INTERRUPT BUFFER POINTER
DEFSTR (LPOPN,LPTSTS,33,1) ;LPT IS OPENED
DEFSTR (LPTHN,LPTSTS,32,1) ;LINE PR CONTROL FAILED
DEFSTR (LPTWT,LPTSTS,31,1) ;BIT INDICATING REQUEST ON Q
DEFSTR (LPTBL,LPTSTS,30,1) ;LPT IS OVER ALLOCATION
DEFSTR (LPTOL,LPTSTS,29,1) ;LPT ON-LINE BIT
DEFSTR (LPTER,LPTSTS,28,1) ;LPT HAD AN ERROR
DEFSTR (LPMWS,LPTSTS,27,1) ;MTOPR IS WAITING FOR A STATUS TO ARRIVE
DEFSTR (LPOBF,LPTSTS,26,1) ;OUTPUT IS BEING FLUSHED
DEFSTR (LPTHE,LPTSTS,25,1) ;HARD ERROR ON THIS LPT
DEFSTR (LPLHC,LPTSTS,24,1) ;LOADING-HAS-COMPLETED FLAG FOR RAM OR VFU LOADS
;SYMBOLS AND DEFSTRS FOR SECOND STATUS WORD
LP%SST==177777B35 ;SOFTWARE STATUS WORD
LP%LCP==1B18 ;LOWER CASE PRINTER
LP%SHA==1B19 ;STATUS HAS ARRIVED
LP%PAG==7777B17 ;PAGE COUNTER FIELD
LP%PSI==77B5 ;PSI CHANNEL FOR PAGE CTR & ON-LINE INTERRUPTS
DEFSTR (LPSST,LPTST1,35,16) ;SOFTWARE STATUS WORD
DEFSTR (LPLCP,LPTST1,18,1) ;LOWER-CASE PRINTER
MSKSTR (LPSHA,LPTST1,LP%SHA) ;STATUS HAS ARRIVED
DEFSTR (LPPAG,LPTST1,17,12) ;PAGE COUNTER
DEFSTR (LPPSI,LPTST1,5,6) ;CHANNEL NUMBER ON WHICH PSI'S ARE DESIRED
;DEFSTRS FOR LPTST2
DEFSTR (ARROWF,LPTST2,0,1) ;SAYS WE'RE CONVERTING CONTROL TO ARROW CHARACTER
DEFSTR (SAVBCT,LPTST2,12,12) ;SAVED BYTE COUNTER DURING ARROW HACK
DEFSTR (SAVBUS,LPTST2,28,16) ;SAVED BUS ADDRESS REGISTER
DEFSTR (LPTLOR,LPTST2,29,1) ;ON WHEN LOADING RAM
;DEFSTRS FOR LPTST3
DEFSTR (LPTCC,LPTST3,35,12) ;COUNT OF CHARACTERS SENT TO PRINTER
DEFSTR (SAVCHR,LPTST3,8,8) ;SAVED LP BUFFER CHARACTER WHILE SOING CONTROL HACK
DEFSTR (LPXBIT,LPTST3,0,1) ;ON IFF PRINTER EXISTS (AS DETERMINED DURING INITIALIZATION) CAUTION: ONLY FOR KS (10/10/77)
;DEFSTR FOR LPTERR WORD
LP%ERR==177777B35 ;HARDWARE STATUS FIELD
LP%FRK==777777B17 ;FORK ID OF OWNING PROCESS
LP%MSG==1B18 ;SUPPRESS STANDARD MESSAGE
LP%PCI==1B19 ;PAGE COUNTER HAS INTERRUPTED
DEFSTR (LPERR,LPTERR,35,16) ;LAST ERROR INDICATION
DEFSTR (LPFRK,LPTERR,17,18) ;FORK ID OF OWNING PSI PROCESS
DEFSTR (LPMSG,LPTERR,18,1) ;IF =1, SUPPRESS STANDARD MESSAGE
DEFSTR (LPPCI,LPTERR,19,1) ;PAGE COUNTER HAS INTERRUPTED
; DEFSTRS FOR LPTOFN WORD
DEFSTR (VFUOFN,LPTOFN,17,18) ;VFU OFN
DEFSTR (RAMOFN,LPTOFN,35,18) ;RAM OFN
.LRPAG==10 ;BYTE OFFSET TO PAGE COUNTER REGISTER
LP%IRP==1B32 ;INTERRUPT REQUEST PENDING
LP%RBR==1B33 ;RAM (OR VFU) BEING RELOADED
LP%LTR==1B34 ;RAM REQUIRES RELOADING
LP%LVF==1B35 ;VFU REQUIRES RELOADING
DEFSTR (PGFNC,PGDATA,15,16) ;FUNCTION CODE - LOAD PAGE COUNTER
DEFSTR (PGENB,PGDATA,16,1) ;ENABLE INTERRUPTS BIT
DEFSTR (PGCTR,PGDATA,31,15) ;PAGE COUNTER VALUE
DEFSTR (LPLVF,PGDATA,35,1) ;VFU REQUIRES RELOADING
DEFSTR (LPLTR,PGDATA,34,1) ;TRANSLATION RAM REQUIRES RELOADING
DEFSTR (LPRBR,PGDATA,33,1) ;RAM (OR VFU) BEING RELOADED
DEFSTR (LPIRP,PGDATA,32,1) ;INTERRUPT REQUEST PENDING
; DEFSTRS FOR LPTCLS WORD
LP%BSZ==77B5 ;BYTE SIZE OF OPENF
LP%NOE==1B17 ;NOTE OCCURRENCE OF END-OF-FILE
LP%RLD==1B16 ;FRONT END WAS RELOADED
MSKSTR (LPBSZ,LPTCLS,LP%BSZ) ;BYTE SIZE OF OPENF
MSKSTR (LPNOE,LPTCLS,LP%NOE) ;NOTE OCCURRENCE OF EOF
MSKSTR (LPRLD,LPTCLS,LP%RLD) ;FRONT END WAS RELOADED
SWAPCD ; IS SWAPPABLE
LPTDTB::LPTDTL ;LENGTH
DTBDSP LPTDIR ;SET DIRECTORY
DTBBAD (DESX9) ; Name lookup
DTBBAD (DESX9) ; Extension
DTBBAD (DESX9) ; Version
DTBBAD (DESX9) ;PROTECTION INSERTION
DTBBAD (DESX9) ;ACCOUNT INSERTION
DTBBAD (DESX9) ;STATUS INSERTION
DTBDSP (LPTOPN)
DTBBAD (DESX9)
DTBDSP (LPTSQO) ; Output
DTBDSP (LPTCLZ)
DTBBAD (DESX9) ; Rename
DTBBAD (DESX9) ; Delete
DTBBAD (DUMPX6) ; DUMPI
DTBBAD (DUMPX6) ; DUMPO
DTBBAD (DESX9) ; Mount
DTBBAD (DESX9) ; Dismount
DTBBAD (DESX9) ; Initialize directory
DTBDSP (LPTMTO) ; MTOPR
DTBDSP (LPDSTS) ; GET STATUS
DTBBAD (DESX9) ; Set status
DTBSKP ; RECORD OUT
DTBDSP (RFTADN) ; READ TAD
DTBDSP (SFTADN) ; SET TAD
DTBDSP (BIOINP) ;SET JFN FOR INPUT
DTBDSP (BIOOUT) ;SET JFN FOR OUTPUT
DTBBAD (GJFX49) ;CHECK ATTRIBUTE
DTBSKP ;RELEASE JFN
LPTDTL==:.-LPTDTB ;GLOBAL LENGTH OF DISPATCH TABLE
LPTDIR: TQO NNAMF ;NO NAME DEVICE
MOVEI A,DESX9
RET
; Initialize line printer
RESCD
LPTINI::
MOVEI U,FELPTN ;GET THE NUMBER OF FE LPT'S
MOVEI B,FELPVT ;GET VECTOR TABLE ADDRESSES
FELPLP: SOJL U,NXTLPT ;LEAVE LOOP IF NO MORE FE LPT'S
STOR B,LPDEVT,(U) ;UPDATE UNIT NUMBER
JRST FELPLP ;LOOP FOR REST OF FE LPT'S
NXTLPT: MOVEI U,KSLPTN ;GET NUMBER OF LP20'S ON KS
MOVEI B,FELPVT ;GET VECTOR TABLE NAME
KSLPIN: SOJL U,NXTLP1 ;LEAVE LOOP IF NO MORE
STOR B,LPDEVT,(U) ;STORE VECTOR TABLE ADDRESS
JRST KSLPIN ;LOOP FOR REST OF KS LP20'S
NXTLP1: MOVEI U,0
LOAD A,LPDEVT,(U)
CALL @SNDINI(A) ;DO SYSTEM-DEPENDENT LINEPRINTER INITIALIZATION
MOVSI U,-LPTN ;INIT ALL UNITS
LPI1: MOVEI A,^D60000 ;CHECK ALL UNITS ONCE A MINUTE
ADD A,TODCLK ;FROM NOW
MOVEM A,LPTCKT(U) ;LPTTIM INTERVAL
SETZM LPTSTS(U)
SETZM LPTST1(U) ;CLEAR SECOND STATUS WORD
SETZM LPTERR(U) ;NO ERROR YET
SETOM LPTOFN(U) ;INDICATE NO OFN'S FOR RAM, VFU FILES
SETOM LPTCNT(U)
SETOM LPTLCK(U)
MOVEI C,MAXLPA ;DEFAULT LINE ALLOCATION
STOR C,LPTMX,(U) ;DEFAULT LINE ALLOCATION
MOVX C,INIPSI ;GET CODE INDICATING PSI NOT ENABLED
STOR C,LPPSI,(U) ;MARK THAT PSI CHANNEL NOT DECLARED YET
LOAD A,LPDEVT,(U)
CALL @GLPTST(A) ;ASK FOR THE STATAS
AOBJN U,LPI1
RET
LPTRST::MOVSI U,-LPTN ;SET UP TO LOOP THRU LP'S
LPRST1: LOAD A,LPDEVT,(U) ;GET TABLE ENTRY ADDRESS
CALL @SNDRST(A) ;DO INIT
AOBJN U,LPRST1 ;LOOP UNTIL DONE
RET ;RETURN
SWAPCD
; Open line printer
LPTOPN: SKIPN PROFLG ;EVER GOING TO USE PRIMARY PROTOCOL ?
RETBAD (OPNX18) ;NO, DO NOT ALLOW ANY LPT OPEN'S
HLRZ U,DEV ;GET UNIT NUMBER
LOCK LPTLCK(U),<CALL LCKTST>
JN LPOPN,(U),[ UNLOCK LPTLCK(U)
MOVEI A,OPNX9
RET] ;FAIL
JE LPTOL,(U),[CALL CHKOFL ;SEE IF OPENF'S ALLOWED IF OFFLINE
SKIPA ;NO
JRST .+1 ;YES, LET THE OPENF PROCEDE
UNLOCK LPTLCK(U) ;LPT IS OFFLINE
MOVEI A,OPNX8 ;TELL PROGRAM
RET] ;AND DONE
TQNE <WRTF> ;WANT WRITE?
TQNE <READF> ;YES. AND NO READ?
JRST [ UNLOCK LPTLCK(U) ;NO. CAN'T DO IT THAT WAY
RETBAD (OPNX13)] ;BOMB IT
SETONE LPOPN,(U) ;LPT IS NOW OPENED
MOVE A,FORKX ;GET ID OF OPENER
STOR A,LPFRK,(U) ;REMEMBER FOR SYSERR
MOVX A,INIPSI ;GET FLAG INDICATING NO PSI ENABLED
STOR A,LPPSI,(U) ;MARK THAT NO PSI IS ENABLED
SETZB A,B ;SET TO 0, NO INTERRUPTS
CALL LODPAG ;GO INITIALIZE THE PAGE COUNTER
JFCL ;SHOULD NOT FAIL
SETZRO LPPCI,(U) ;INDICATE PAGE COUNTER HASN'T INTERRUPTED YET
SETZRO LPTHE,(U) ;CLEAR HARD ERROR
HRRZ A,LPTRLP(U) ;BUFFER ADDRESS
MOVES (A)
CALL FPTA ; Get ptn.pn for buffer
CALL MLKPG ; Lock the RLP(U) ;BUFFER ADDRESS
SETZRO LPNOE,(U) ;DO NOT NOTE OCCURRENCE OF EOF
LDB A,PBYTSZ ;GET BYTE SIZE SPECIFIED ON OPENF
STOR A,LPBSZ,(U) ;STORE BYTE SIZE OF OPENF
CALL INIFIL ;GO SET UP ALL POINTERS
SETZM FILBYN(JFN) ;INITIALIZE COUNT OF TOTAL BYTES OUTPUT
LOAD A,LPDEVT,(U) ;GET DEVICE TYPE
CALL @SNDOPN(A) ;DO DEVICE DEPENDENT OPEN FUNCTIONS
UNLOCK LPTLCK(U)
RETSKP
; ROUTINE TO INITIALIZE THE INTERRUPT COUNTS AND BUFFER FLAGS
INIFIL: NOSKED ;TURN OFF SCHEDULER
CHNOFF LPTCHN ;TURN OFF THE LP CHANNEL
SETZRO <LPOBF,ALTP,ALTI>,(U) ;INTIALZIE POINTERS
SETOM LPTCNT(U) ;YES MAKE STOP IMMEDIATELY
SETZM LPTICT(U) ;ZERO INTERRUPT COUNT
CHNON LPTCHN ;TURN ON LP CHANNEL
OKSKED ;AND THE SCHEDULER
; CALLRET SETBUF ;AND GO INIT BUFFERS AS WELL
; ROUTINE TO SET UP JFN BLOCK POINTERS AND COUNTS
SETBUF: HRRZ A,LPTRLP(U) ;GET BASE ADDRESS OF LPT BUFFERS
OPSTR <SKIPE>,ALTP,(U) ;USING SECOND BUFFER FOR THIS UNIT ?
ADDI A,NLPBF ;YES, GET ADDRESS OF SECOND BUFFER
HRLI A,(POINT 7,) ;GET POINTER FOR 7-BIT BYTES
LOAD B,LPBSZ,(U) ;GET BYTE SIZE FROM OPENF
CAIN B,^D8 ;USING 8-BIT BYTES ?
HRLI A,(POINT 8,) ;YES, GET POINTER FOR 8-BIT BYTES
MOVEM A,FILBYT(JFN) ;STORE POINTER TO CURRENT BUFFER
MOVEI A,^D36 ;GET NUMBER OF BITS PER WORD
LOAD B,LPBSZ,(U) ;GET BYTE SIZE FROM OPENF
CAIE B,^D8 ;USING 8-BIT BYTES ?
MOVEI B,7 ;NO, ASSUME 7-BIT BYTES
IDIV A,B ;COMPUTE # OF BYTES PER WORD
IMULI A,NLPBF ;COMPUTE # OF BYTES PER BUFFER
MOVEM A,FILCNT(JFN) ;STORE # OF BYTES PER BUFFER
RET ;RETURN
; Close line printer
LPTCLZ: HLRZ U,DEV ;GET UNIT NUMBER
JN LPOBF,(U),LPTCL2 ;IF BEING CLOSED, DON'T BLOCK
TXNN A,CZ%ABT ;DOING AN ABORT CLOSE ?
JRST [ CALL LPTEOF ;NO. SEND LAST BUFFER
TQNE <ERRF> ;SERVICE ROUTINE FOUND AN ERROR?
RET ;YES. RETURN NOW
LOAD A,LPDEVT,(U)
CALL @SNDEOF(A) ;GO ASK FOR EOF JUST IN CASE
MOVSI A,0(U) ;NO. SET UP SCHEDULER TEST
HRRI A,LPTDIS ;TO WAIT FOR BUFFERS AND ACK
RET] ;AND DONE
CALL FLUSH ;YES. GO DO FLUSH
JFCL ;WILL GO
JRST LPTCL3 ;GO FORCE THE CLOSE
;NORMAL CLOSE. CHECK FOR ERROR
LPTCL2: JN LPTHE,(U),[ SETZRO LPOBF,(U) ;NOT CLOSING ANYMORE
JRST GIVERR] ;AND GIVE AN ERROR
LPTCL3: LOCK LPTLCK(U),<CALL LCKTST> ;LOCK UP THIS LPT
SETZM LPTCLS(U) ;CLEAR BYTE SIZE FROM OPENF
SETOM LPTCNT(U) ;SET # OF BUFFERS TO ZERO
SETZM LPTICT(U) ;NO BYTES TO SEND
LOAD A,LPTOL,(U) ;GET ON-LINE INDICATION
LOAD B,LPTMX,(U) ;SAVE ALLOCATION
SETZM LPTSTS(U) ;CLEAR FLAGS
STOR A,LPTOL,(U) ;PRESERVE THIS INDICATION
STOR B,LPTMX,(U) ;RESTORE ALLOCATION
MOVX A,INIPSI ;GET FLAG SAYING NO PSI ENABLE WAS DONE
STOR A,LPPSI,(U) ;SAVE FLAG IN STATUS WORD
SETZRO LPMSG,(U) ;DO NOT SUPPRESS CTY MESSAGES ANY MORE
HRRZ A,LPTRLP(U) ;NOW UNLOCK BUFFER PAGE
CALL FPTA
CALL MULKPG
UNLOCK LPTLCK(U) ;RELEASE THE LPT LOCK
RETSKP
;SCHEDULER TEST FOR LPTCLZ
RESCD
LPTDIS: JN LPTHE,(A),1(4) ;IF FOUND ERROR, WAKE UP NOW
OPSTR <SKIPN>,LPTFE,(A) ;BYTES STILL IN FE?
SKIPL LPTCNT(A) ;NO. ALL BUFFERS CLEARED?
JRST 0(4) ;CAN'T WAKE UP YET
JRST 1(4) ;TEST SATISFIED
SWAPCD ;RETURN TO SWAPPABLE MONITOR
; ROUTINE TO FORCE OUT REMAINING DATA TO LPT
LPTEOF: MOVEI A,.CHNUL ;FILL REMAINDER OF BUFFER WITH NULLS
LPTEO1: JN LPTHE,(U),[ ;GOT AN ERROR?
CALL GIVERR ;GENERATE ERROR, FIX BUFFERS
RETBAD()] ;AND RETURN
SKIPN FILCNT(JFN) ;AT END OF BUFFER NOW?
JRST LPEOF1 ;YES, GO WAIT FOR ALL BUFFERS TO FINISH
CALL LPTSQO
TQNN <ERRF> ;SERVICE ROUTINE FIND AN ERROR?
TQNE <BLKF> ;SERVICE ROUTINE WANTS TO BLOCK?
RET ;YES, TELL CALLER THAT
JRST LPTEO1 ;NO. FILL UP ALL OF BUFFER
LPEOF1: SETONE LPOBF,(U) ;SET OUTPUT BEING FLUSHED
AOSN LPTCNT(U) ;TELL INTERRUPT LEVEL OF THIS BUFFER
CALL LPTSND ;START LPT IF WASNT GOING ALREADY
LPEOF2: MOVSI A,0(U) ;SAVE UNIT NO OF LPT
HRRI A,LPTDIS ;WAIT FOR END OF BUFFERS OR ERROR
TQO <BLKF> ;REQUEST CALLER TO BLOCK
RET ;AND RETURN
; Line printer sequential character output
LPTSQO: ASUBR <CHARIN> ;ALLOCATE SPACE AND REMEMBER THE BYTE
HLRZ U,DEV
LPSQO: JE LPLVF,(U),LPSQ05 ;VFU REQUIRE RELOADING ?
JE LPTOL,(U),[LOAD A,LPDEVT,(U)
CALL @SNDFLO(A) ;FLUSH REMAINING OUTPUT
JRST GIVERR] ;GIVE PROCESS ERROR AND RETURN
MOVEI B,VFUFIL ;GET BASE ADDRESS OF VFU FILENAME BUFFER
MOVEI C,.MOLVF ;GET FUNCTION TO PERFORM
CALL LPTLOD ;GO RE-LOAD THE VFU
RET ;ERROR OR BLOCK NEEDED, RETURN TO SOUT
LPSQ05: JE LPLTR,(U),LPSQ10 ;DOES THE RAM NEED RELOADING ?
MOVEI B,RAMFIL ;GET BASE ADDRESS OF RAM FILENAME BUFFER
MOVEI C,.MOLTR ;GET FUNCTION TO PERFORM
CALL LPTLOD ;GO RELOAD THE RAM
RET ;ERROR OR BLOCK NEEDED, RETURN TO SOUT
LPSQ10: JN LPTHE,(U),GIVERR ;HARD ERROR UP ON DEVICE
JN LPOBF,(U),[ CALL LPNOP2 ;IF WAITING FOR -11, CONTINUE
RET ;WANTS TO BLOCK, OR ERROR
JRST .+1] ;ALL DONE WAITING
SETZRO LPRLD,(U) ;FORGET RELOADED STATUS OF FRONT END
SKIPN FILCNT(JFN) ;IS BUFFER READY FOR PRINTING?
JRST [ AOSN LPTCNT(U) ;GIVE BUFFER TO INTERRUPT LEVEL
CALL LPTSND ;AND START IT IF NECESSARY
JRST .+1]
SOSGE FILCNT(JFN) ;ANY MORE ROOM IN BUFFER?
JRST [ CALL LPSQ20 ;NO. GET ANOTHER BUFFER
RET ;WANTS TO BLOCK
JRST LPSQO] ;GOT ONE. GO USE IT
MOVE A,CHARIN ;RECOVER THE BYTE
IDPB A,FILBYT(JFN) ;YES, STORE THE CHARACTER
AOS FILBYN(JFN) ;INCREMENT TOTAL # OF BYTES OUTPUT
RET ;THEN RETURN
;SUBROUTINE TO GET NEXT BUFFER FOR PRINTING.
;RETURNS: +1 NO BUFFER AVAILABLE. ARRANGE FOR BLOCK
; +2 BUFFER SET UP IN JFN BLOCK
LPSQ20: CALL BUFWAT ;GO SEE IF THERE IS A BUFFER FREE
RET ;NO. RETURN TO BLOCK
LOAD C,ALTP,(U) ;GET BUFFER POINTER
XORI C,1 ;TOGGLE IT
STOR C,ALTP,(U) ;NEW POINTER
CALL SETBUF ;GO SET UP JFN BLOCK COUNTS AND BUFFERS
RETSKP ;DONE
; HERE TO GIVE PROCESS AN ERROR
GIVERR: SETZRO LPTHE,(U) ;CLEAR ERROR BIT IN STATUS WORD
CALL INIFIL ;RESET BUFFER POINTERS AND COUNTS
TQO <ERRF> ;TELL PROCESS ABOUT ERROR
RETBAD (IOX5) ;RETURN ERROR
; ROUTINE TO RE-LOAD THE VFU OR RAM WITH LAST FILE USED FOR LOADING
;
; CALL: B/ RAMFIL OR VFUFIL
; C/ .MOLTR OR .MOLVF
; CALL LPTLOD
; RETURNS: +1 ERROR, COULD NOT LOAD
; +2 SUCCESS
LPTLOD: STKVAR <BASADR,CODE,CAPS> ;ALLOCATE SPACE FOR ADDRESS, CODE, CAPS
MOVEM B,BASADR ;SAVE BASE ADR OF FILENAME BUFFER AREA
MOVEM C,CODE ;SAVE FUNCTION TO PERFORM
JE LPTHE,(U),LPTLD1 ;WAS DATA POSSIBLY LOST ?
CALL LPTFLO ;YES, FLUSH BUFFERS, AND INIT LPT
JFCL ;IT BETTER WORK
LPTLD1: MOVE T1,CAPENB ;GET CURRENTLY ENABLE CAPABILITIES
MOVEM T1,CAPS ;SAVE CURRENT CAPABILITIES
MOVX T1,SC%WHL ;GET WHEEL CAPABILITY
MOVEM T1,CAPENB ;MAKE THIS PROCESS A WHEEL
MOVE B,BASADR ;GET BACK BASE ADDRESS OF FILENAME BUFFER
MOVEI A,LPFLSZ ;GET SIZE OF FILENAME BUFFERS
IMULI A,(U) ;GET OFFSET TO PROPER FILENAME BUFFER
ADDI B,(A) ;GET POINTER TO PROPER FILENAME BUFFER
MOVX A,177B6 ;SEE IF NAME ASSIGNED YET
TDNN A,0(B) ;IS IT
JRST GIVERR ;NO. SET ERRF AND RETURN
HRLI B,(POINT 7,) ;FORM POINTER TO FILENAME BUFFER
MOVX A,GJ%SHT!GJ%OLD ;SHORT CALL GTJFN, EXISTING FILE
GTJFN ;GET A JFN FOR FILE TO BE LOADED
JRST [ TQO <ERRF> ;SAY SOMETHING FAILED
JRST FIXCAP] ;AND GO GIVE UP
MOVE B,CODE ;GET FUNCTION TO BE PERFORMED
CALL LODLPT ;CALL ROUTINE TO DO THE WORK
SKIPA ;FAIL, DO NOT SKIP RETURN
AOS (P) ;SUCCESS, GIVE SKIP RETURN
; AND FALL THROUGH TO FIXCAP
; HERE ON AN ERROR TO RESTORE ORIGINAL CAPABILITIES
FIXCAP: MOVE T4,CAPS ;GET ORIGINAL CAPABILITIES
MOVEM T4,CAPENB ;RESTORE INITIAL CAPABILITIES
RET ;RETURN
; ROUTINE TO WAIT UNTIL A BUFFER IS FREE
BUFWAT: SKIPG LPTCNT(U) ;ANY FREE BUFFERS?
RETSKP ;YES, GIVE OK RETURN
HRLI A,LPTCNT(U) ;GET ADDRESS OF COUNT
HRRI A,DISLET ;WANT TO WAIT TILL ONE IS FREE
TQO <BLKF> ;TELL BOUT TO BLOCK
RET ;AND RETURN
;GET DEVICE DEPENDENT STATUS
LPDSTS: HLRZ U,DEV ;GET UNIT
LOAD A,LPPAG,(U) ;GET LAST PAGE COUNTER VALUE
UMOVEM A,3 ;STORE PAGE COUNTER IN USER'S AC 3
CALLRET GETSTS ;GO GET SOFTWARE,,HARDWARE STATUS AND RETURN
; ROUTINE TO RETURN SOFTWARE,,HARDWARE STATUS
;
; CALL: CALL GETSTS
; RETURNS: +1 ALWAYS, WITH
; A/ SOFTWARE,,HARDWARE STATUS + MO%LCP IF LPT IS LOWER CASE
GETSTS: LOAD A,LPERR,(U) ;GET LAST HARDWARE STATUS WORD
LOAD B,LPSST,(U) ;GET LAST SOFTWARE STATUS WORD
HRL A,B ;GET SOFTWARE,,HARDWARE STATUS
LOAD B,LPLCP,(U) ;GET "PRINTER IS LOWER CASE" FLAG
SKIPE B ;IS PRINTER LOWER CASE ?
TXO A,MO%LCP ;YES, INDICATE LOWER CASE LPT
JE LPRLD,(U),R ;DONE IF FRONT END HASN'T BEEN RELOADED,
TXO A,MO%RLD ; ELSE, MARK THAT FRONT-END WAS RELOADED
RET ;AND DONE
; JSYS TO INTITIALLY LOAD THE VFU AND RAM FILES
;
; ACCEPTS IN USER AC'S:
; A/ JFN OF FILE TO BE LOADED
; B/ MO%LCP IF LOWERCASE PRINTER + FUNCTION CODE
; (.MOLVF TO LOAD VFU; .MOLTR TO LOAD RAM)
; C/ UNIT NUMBER OF PRINTER
; LPINI
; RETURNS +1 ALWAYS
.LPINI::MCENT ;MONITOR CONTEXT ENTRANCE
MOVE A,CAPENB ;GET ENABLED CAPABILTIES
TXNN A,SC%WHL!SC%OPR ;IS THIS PROCESS CURRENTLY PRIVILEGED ?
ITERR (LPINX2) ;NO, ISSUE ERROR
SKIPN PROFLG ;DOING PRIMARY PROTOCOL?
ITERR (OPNX18) ;NO. DON'T LOAD IT THEN
UMOVE U,3 ;GET UNIT NUMBER TO BE LOADED
CAIL U,0 ;CHECK FOR VALID UNIT NUMBER,
CAILE U,LPTN ; BETWEEN 0 AND LPTN
ITERR (LPINX1) ;INVALID UNIT NUMBER
JN LPOPN,(U),[ITERR (LPINX3)] ;ERROR IF ALREADY OPENED
XCTU [HRRZ A,2] ;GET FUNCTION CODE
UMOVE B,1 ;GET JFN OF FILE TO BE LOADED
CALL SAVNAM ;SAVE AWAY NAME OF FILE, EVEN IF LOADING ERROR
UMOVE A,1 ;GET JFN OF FILE TO BE LOADED
UMOVE B,2 ;GET FUNCTION CODE AND FLAG (.MOLVF OR .MOLTR)
SETZRO LPLCP,(U) ;ASSUME PRINTER NOT LOWERCASE
TXZE B,MO%LCP ;IS PRINTER SUPPOSED TO BE LOWERCASE ?
JRST [ SETONE LPLCP,(U) ;YES, INDICATE PRINTER IS LOWERCASE
JRST .+1] ;CONTINUE
CALL LODLPT ;GO LOAD THE VFU OR RAM
JFCL ;IGNORE ERRORS
JRST MRETN ;RETURN TO USER
;ROUTINE TO IMPLEMENT THE MTOPR FUNCTIONS
LPTMTO: TQNN <OPNF> ;CHECK TO SEE IF OPENED
RETBAD (CLSX1) ;ILLEGAL IF NOT OPENED
HLRZ U,DEV ;GET UNIT NUMBER
CAIL T2,.MOPSI ;CHECK FOR LEGAL VALUE, TOO SMALL?
CAILE T2,.MOFLO ;OR TOO BIG?
LPMT10: RETBAD (MTOX1) ;RETURN INVALID FUNCTION ERROR
CALLRET @LPMTAB-.MOPSI(T2) ;DO FUNCTION
; DISPATCH TABLE FOR LPT MTOPR FUNCTIONS - UNUSED CODES GO TO LPMT10
; FIRST DISPATCH IS .MOPSI
LPMTAB: DTBDSP (LPTPSI) ;27 - .MOPSI - ENABLE PSI
DTBDSP (LPMT10) ;30 - UNUSED - GENERATE ERROR
DTBDSP (LPTNOP) ;31 - .MONOP - WAIT FOR ACTIVITY TO FINISH
DTBDSP (LPTLVF) ;32 - .MOLVF - LOAD VFU
DTBDSP (LPTRVF) ;33 - .MORVF - READ VFU NAME
DTBDSP (LPTLTR) ;34 - .MOLTR - LOAD TRANSLATION RAM
DTBDSP (LPTRTR) ;35 - .MORTR - READ TRANSLATION RAM NAME
DTBDSP (LPSTAT) ;36 - .MOSTS - SET STATUS
DTBDSP (LPRSTS) ;37 - .MORST - READ STATUS
DTBDSP (LPTFLO) ;40 - .MOFLO - FLUSH OUTPUT
; .MOLVF - LOAD VFU FUNCTION
LPTLVF: JN LPRBR,(U),LODCMP ;JUMP IF RAM ALREADY BEING RELOADED
MOVEI T1,1 ;GET OFFSET TO JFN IN ARGUMENT BLOCK
CALL GETWRD ;GET JFN FROM USER
RETBAD (MTOX13) ;RETURN ARGUMENT BLOCK TOO SMALL
MOVE A,B ;GET JFN OF VFU FILE
MOVEI B,.MOLVF ;GET FUNCTION FOR "LOAD VFU"
CALL LODLPT ;GO LOAD THE VFU
JRST LODBLK ;GO SEE IF BLOCK WANTED
RETSKP ;SUCCESS, RETURN
; .MOLTR - LOAD TRANSLATION RAM
LPTLTR: JN LPRBR,(U),LODCMP ;JUMP IF RAM ALREADY BEING RELOADED
MOVEI A,1 ;GET OFFSET TO JFN IN ARGUMENT BLOCK
CALL GETWRD ;GET JFN FROM USER
RETBAD (MTOX13) ;RETURN ARGUMENT BLOCK TOO SMALL
MOVE A,B ;GET JFN FOR RAM FILE
MOVEI B,.MOLTR ;GET CORRECT FUNCTION CODE
CALL LODLPT ;GO LOAD RAM
JRST LODBLK ;GO SEE IF BLOCK WANTED
RETSKP ;RETURN
;HERE ON RETURN FROM LODLPT TO SEE IF BLOCK NEEDED
LODBLK: TQNN <BLKF> ;BLOCK REQUESTED?
RET ;NO. GIVE UP
SETONE LPRBR,(U) ;YES. REMEBER ONCE HERE
RET ;AND GO BLOCK
; HERE WHEN RAM ALREADY BEING RELOADED, INDICATE LOADING COMPLETE
LODCMP: SETZRO LPRBR,(U) ;MARK THAT RAM NO LONGER BEING RELOADED
RETSKP ;SUCCESS RETURN
; .MOPSI - ENABLE FOR PSI INTERRUPTS ON OPERATOR-ATTENTION CONDITIONS
LPTPSI: MOVEI A,1 ;GET OFFSET TO PSI CHANNEL IN ARG BLOCK
CALL GETWRD ;GET PSI CHANNEL TO ENABLE
RETBAD (MTOX13) ;ARGUMENT BLOCK TOO SMALL
CAIL B,0 ;CHECK THAT GIVEN PSI CHANNEL IS A VALID
CAILE B,5 ; ASSIGNABLE CHANNEL
JRST [ CAIL B,^D24 ;CHECK THAT GIVEN PSI CHANNEL IS A VALID
CAILE B,^D35 ; ASSIGNABLE CHANNEL
RETBAD (MTOX14) ;BAD PSI CHANNEL NUMBER GIVEN
JRST .+1 ] ;PSI CHANNEL OK, RETURN
STOR B,LPPSI,(U) ;SAVE PSI CHANNEL TO INTERRUPT ON
MOVEI A,2 ;GET OFFSET TO FLAG WORD
CALL GETWRD ;GET FLAGS FROM USER
RETSKP ;NO FLAG WORD, RETURN
TXNN B,MO%MSG ;USER WANT TO SUPPRESS MESSAGES ?
RETSKP ;NO, RETURN
SETONE LPMSG,(U) ;YES, MARK THAT "PROBLEM ON DEVICE" ISN'T WANTED
RETSKP ;RETURN TO USER
; SCHEDULER TEST ROUTINE TO WAIT FOR COMPLETION OF RAM OR VFU LOADING
RESCD
LODWAT: JE LP%LHC,(1),0(4) ;RETURN IF LOADING-HAS-COMPLETED FLAG IS OFF
JRST 1(4) ;LOADING-HAS-COMPLETED FLAG ON, RETURN SUCCESS
SWAPCD
; .MOFLO - FLUSH OUTPUT TO LPT
LPTFLO: CALL INIFIL ;GO INITIALIZE BUFFER FLAGS AND INTERRUPT COUNT
JN LPMWS,(U),[ SETZRO LPMWS,(U) ;NOT WAITING FOR STATUS
JRST RSKP] ;RETURN
LOAD A,LPDEVT,(U)
CALL @SNDFLO(A) ;NOW SEND A FLUSH TO THE -11
LOAD A,LPDEVT,(U)
CALL @GLPTST(A) ;ASK FOR STATUS IN CASE ITS NEEDED
; JRST LPRSTS
; FLUSH - INTERNAL FLUSH ROUTINE
FLUSH: CALL INIFIL ;GO INITIALIZE BUFFER FLAGS AND INTERRUPT COUNT
LOAD A,LPDEVT,(U)
CALL @SNDFLO(A) ;NOW SEND A FLUSH TO THE -11
LOAD A,LPDEVT,(U)
CALL @GLPTST(A) ;ASK FOR STATUS IN CASE ITS NEEDED
RET ;DONE, RETURN
; .MORST - READ LINE PRINTER STATUS
LPRSTS: JN LPMWS,(U),HAVSTS ;JUMP IF MTOPR WAITING FOR STATUS ALREADY
SETZRO LPSHA,(U) ;INITIALIZE STATUS HAS ARRIVED FLAG
LOAD A,LPDEVT,(U)
CALL @GLPTST(A) ;GO ASK -11 FOR LPT STATUS
SETONE LPMWS,(U) ;REMEBER WAITING FOR STATUS
HRL A,U ;GET UNIT #
HRRI A,STSWAT ;GET ADR OF ROUTINE TO CHECK FOR STATUS ARRIVAL
TQO <BLKF> ;TELL MTOPR TO BLOCK
RET ;RETURN
; HERE WHEN STATUS REQUESTED BY .MORST HAS ARRIVED
HAVSTS: SETZRO LPMWS,(U) ;MARK THAT MTOPR NOT WAITING FOR STATUS ANY MORE
CALL GETSTS ;GET SOFTWARE,,HARDWARE STATUS IN A
MOVE B,A ;COPY STATUS FOR PUTWRD ROUTINE
MOVEI A,1 ;GET OFFSET INTO USER'S ARGUMENT BLOCK
CALL PUTWRD ;STORE STATUS IN USER ARGUMENT BLOCK
RETBAD (MTOX13) ;ARGUMENT BLOCK TOO SMALL
MOVEI A,2 ;GET OFFSET INTO USER'S ARGUMENT BLOCK
LOAD B,LPPAG,(U) ;GET LPT PAGE COUNTER REGISTER
CALL PUTWRD ;STORE PAGE COUNTER IN USER'S ARG BLOCK
RETBAD (MTOX13) ;ARGUMENT BLOCK TOO SMALL
RETSKP ;RETURN TO USER
RESCD
; ROUTINE TO TEST FOR STATUS ARRIVAL
; CALLED FROM SCHEDULER
STSWAT: JN LPSHA,(1),1(4) ;RETURN SKIP IF STATUS HERE
JN LPTHE,(1),1(4) ;OR IF WE NOTICED A HARD ERROR
JRST 0(4) ;NO SKIP, STATUS HAS NOT ARRIVED
SWAPCD
; .MOSTS - SET LPT STATUS
LPSTAT: MOVEI A,1 ;GET OFFSET INTO USER'S ARGUMENT BLOCK
CALL GETWRD ;GET USER'S FLAGS
RETSKP ;RAN OUT OF ARGUMENTS, RETURN
TXNE B,MO%SER ;CLEAR SOFTWARE ERROR ?
CALL SNDACK ;YES, GO SEND AN ACK TO THE -11
MOVEI A,1 ;GET OFFSET INTO USER'S ARGUMENT BLOCK
CALL GETWRD ;GET USER'S FLAGS
RETSKP ;RAN OUT OF ARGUMENTS, RETURN
LOAD A,LPDEVT,(U) ;ASSUME CALL TO SNDEOF
TXNE B,MO%EOF ;SEND AN EOF TO THE -11 ?
CALL @SNDEOF(A) ;YES GO SEND AN EOF TO THE -11
MOVEI T1,1 ;GET OFFSET INTO USER'S ARGUMENT BLOCK
CALL GETWRD ;GET USER'S FLAGS
RETSKP ;RAN OUT OF ARGUMENTS, RETURN
LOAD T2,MO%LCP,T2 ;GET THE LOWERCASE SETTING DESIRED
STOR T2,LPLCP,(U) ; AND SET IT FOR THE PRINTER
MOVEI A,2 ;GET OFFSET TO PAGE COUNTER IN ARG BLOCK
CALL GETWRD ;GET PAGE COUNTER FROM USER ARGUMENT BLOCK
RETSKP ;RETURN, PAGE COUNTER NOT GIVEN
CAMN B,[-1] ;DID USER WANT TO IGNORE PAGE COUNTER ?
RETSKP ;YES, RETURN
MOVE A,B ;NO, GET VALUE TO SET INTO PAGE COUNTER
SKIPE B ;DID USER WANT TO ENABLE PSI INTERRUPTS ?
SETOM B ;YES, INDICATE INTERRUPTS SHOULD BE ENABLED
CALL LODPAG ;GO LOAD THE PAGE COUNTER
JFCL ;SHOULD NOT FAIL
RETSKP ;RETURN TO THE USER
; ROUTINE TO LOAD THE PAGE COUNTER
;
; CALL: A/ VALUE TO BE LOADED INTO THE PAGE COUNTER
; B/ 0 - DO NOT ENABLE FOR INTERRUPTS ON PAGE COUNTER OVERFLOW
; 1 - ENABLE FOR INTERRUPTS ON PAGE COUNTER OVERFLOW
; CALL LODPAG
; RETURNS: +1 FAILURE, CALL TO LINE PR CONTROL FAILED
; +2 SUCCESS
LODPAG: SETZRO LPPCI,(U) ;CLEAR PAGE COUNTER INTERRUPTED FLAG
STOR A,PGCTR,(U) ;STORE VALUE TO BE LOADED INTO PAGE COUNTER
STOR B,PGENB,(U) ;STORE ENABLE/DISABLE INTERRUPTS BIT
MOVX A,.DFLPC ;GET SPECIAL DEVICE OPERATION: LOAD PAGE COUNTER
STOR A,PGFNC,(U) ;STORE SPECIAL DEVICE OPERATION
LOAD A,LPDEVT,(U) ;FIND CORRECT ROUTINE
CALLRET @SNDLDP(A)
; ROUTINE TO SEND AN ACK TO THE FRONT-END
SNDACK: SETZRO LPPCI,(U) ;CLEAR PAGE-COUNTER-INTERRUPTED FLAG
LOAD A,LPDEVT,(U) ;FIND CORRECT ROUTINE
CALL @SENACK(A) ;SEND ACK
JFCL ;IGNORE ERROR
RET ;RETURN
; .MORVF - READ FILENAME OF LAST VFU FILE LOADED
; .MORTR - READ FILENAME OF LAST RAM FILE LOADED
LPTRVF: SKIPA C,[VFUFIL] ;GET BASE ADDRESS OF VFU FILENAME BUFFER
LPTRTR: MOVEI C,RAMFIL ;GET BASE ADDRESS OF RAM FILENAME BUFFER
STKVAR <REDCNT,REDIPT,REDOPT> ;ALLOCATE SPACE FOR COUNT AND POINTERS
MOVEI D,LPFLSZ ;GET SIZE OF FILENAME BUFFERS
IMULI D,(U) ;COMPUTE OFFSET TO PROPER BUFFER
ADDI C,(D) ;GET ADDRESS OF PROPER FILENAME BUFFER
HRLI C,(POINT 7,) ;FORM POINTER TO LAST FILENAME LOADED
MOVEM C,REDIPT ;SAVE INPUT POINTER
MOVEI A,1 ;GET OFFSET TO POINTER IN USER ARG BLOCK
CALL GETWRD ;GET POINTER TO USER BUFFER
RETBAD (MTOX13) ;ARG BLOCK TOO SMALL
CAML B,[777777,,0] ;-1,,ADR GIVEN ?
HRLI B,(POINT 7,) ;YES, CHANGE TO STANDARD POINTER
MOVEM B,REDOPT ;SAVE POINTER TO USER BUFFER
MOVEI A,2 ;GET OFFSET TO COUNT IN USER ARG BLOCK
CALL GETWRD ;GET COUNT FROM USER ARG BLOCK
RETBAD (MTOX13) ;USER ARG BLOCK TOO SMALL
MOVEM B,REDCNT ;SAVE COUNT
; LOOP TO RETURN FILENAME STRING TO USER
LPTR10: SOSGE REDCNT ;DECREMENT COUNT, SKIP IF A CHARACTER LEFT
RETSKP ;DONE, RETURN
ILDB A,REDIPT ;GET A CHARACTER FROM FILENAME
XCTBU [IDPB A,REDOPT] ;STORE CHARACTER IN USER BUFFER
JUMPN A,LPTR10 ;IF NOT A NULL, GO CHECK NEXT CHARACTER
MOVEI A,1 ;GET OFFSET TO POINTER IN USER ARG BLOCK
MOVE B,REDOPT ;GET FINAL POINTER TO USER SPACE
CALL PUTWRD ;STORE POINTER IN USER ARG BLOCK
JFCL ;IGNORE FAILURE
MOVEI A,2 ;GET OFFSET TO COUNT IN USER ARGUMENT BLOCK
MOVE B,REDCNT ;GET FINAL BYTE COUNT
CALL PUTWRD ;STORE FINAL BYTE COUNT IN USER ARGUMENT BLOCK
JFCL ;IGNORE ERRORS
RETSKP ;NULL SEEN, RETURN
; .MONOP - WAIT FOR I/O TO STOP
;
; THIS FUNCTION IS ACCOMPLISHED BY SENDING AN END-OF-FILE TO THE -11. THIS
; TELLS THE -11 TO RETURN AN EOF BACK WHEN ALL DATA RECIEVED PRIOR TO THE
; EOF HAS BEEN OUTPUT.
LPTNOP: JN LPOBF,(U),LPNOP2 ;ALREADY BEEN HERE?
SETZRO LPSHA,(U) ;CLEAR STATUS ARRIVED
CALL LPTEOF ;NO. GO SEND SOME DATA
TQNE <ERRF> ;MADE AN ERROR?
RETBAD() ;YES. RETURN ERROR INFORMATION
SETONE LPNOE,(U) ;NOTE OCCURRENCE OF EOF
RET ;AND GO WAIT FOR BUFFERS TO CLEAR -10
LPNOP2: JN LPTHE,(U),[ CALL GIVERR ;IF HARD ERROR, REPORT IT
RETBAD()] ;AND REPORT ERROR UP
SKIPE FILCNT(JFN) ;HAVE A BUFFER SET UP NOW?
JRST LPNOP4 ;YES. DON'T ALLOCATE A NEW ONE
CALL LPSQ20 ;NO. GO GET ONE
JRST [ JE LPTHE,(U),R ;IF WAITING, KEEP WAITING
TQZ <BLKF> ;NOT BLOCKED
RETBAD (IOX5)] ;REPORT THE ERROR
LPNOP4: JE LPSHA,(U),LPNOP3 ;HAS STATUS ARRIVED YET?
SETZRO LPSHA,(U) ;SAY HAVE NO STATUS
CALL GETSTS ;YES. GET IT
TXNE A,MO%EOF ;EOF UP?
JRST [ SETZRO <LPNOE,LPOBF>,(U) ;YES
RETSKP] ;ALL DONE
LPNOP3: HRL A,U ;GET UNIT # FOR STATUS CHECK
HRRI A,STSWAT ;WAIT FOR NEXT STATUS
TQO <BLKF> ;SAY BLOCK
RET ;AND RETURN
;ROUTINE TO LOAD THE VFU OR TRANSLATION RAM
;
; THE FILE TO BE LOADED IS EFFECTIVELY OPENED FOR WRITING BY ACQUIRING AN
; OFN ON IT, SO THAT NO OTHER PROCESS MAY ALTER THE FILE DURING THE TIME
; THAT IT MAY BE USED TO RELOAD THE VFU OR RAM.
;
; CALL: A/ JFN OF FILE CONTAINING DATA TO LOAD
; B/ FUNCTION CODE: .MOLVF OR .MOLTR TO LOAD VFU OR RAM
; CALL LODLPT
; RETURNS: +1 ERROR, CODE IN A
; +2 SUCCESS
LODLPT: STKVAR <LODFCN,LODJFN,SVFDB> ;ALLOCATE STORAGE FOR FUNCTION CODE AND JFN
MOVEM A,LODJFN ;SAVE JFN OF FILE
MOVEM B,LODFCN ;SAVE FUNCTION CODE
; CHECK THAT THE FILE TO BE LOADED IS ON DISK
IMULI A,MLJFN ;GET INDEXABLE VALUE
HRRZ A,FILDEV(A) ;GET DISPATCH
CAIE A,DSKDTB ;IS THIS A DISK?
RETBAD (MTOX16,<TQO ERRF>) ;NO, RETURN ERROR
; CHECK THAT THE DEVICE HAS A DAVFU
MOVE A,LODFCN ;GET FUNCTION TO PERFORM
CAIE A,.MOLVF ;LOADING THE VFU ?
JRST LPLD03 ;NO, GO SEE IF THERE IS OUTPUT PENDING
LOAD A,LPERR,(U) ;YES, GET LAST HARDWARE STATUS FROM -11
TXNE A,MO%LVU ;DOES DEVICE HAVE AN OPTICAL VFU ?
RETBAD (MTOX15,<TQO ERRF>) ;YES, RETURN ERROR
; CHECK THAT NO OUTPUT IS PENDING
LPLD03: SKIPLE LPTICT(U) ;STILL DATA IN OUR BUFFER ?
RETBAD (MTOX9,<TQO ERRF>) ;YES, RETURN ERROR
;..
;..
; GET OFN ON FILE TO BE LOADED
LOAD A,VFUOFN,(U) ;GET PREVIOUS VFU FILE OFN
MOVE B,LODFCN ;GET FUNCTION CODE
CAIE B,.MOLVF ;LOADING THE VFU ?
JRST [ LOAD A,RAMOFN,(U) ;NO, GET OFN FOR RAM FILE
JRST .+1 ] ;CONTINUE IN MAIN-LINE CODE
CAIE A,-1 ;ANY OFN YET ?
CALL RELOFN ;YES, RELEASE PREVIOUS OFN
MOVE A,LODJFN ;GET JFN OF FILE TO BE LOADED
MOVE B,[1,,.FBADR] ;GET ONE WORD, INDEX BLOCK ADDRESS
MOVEI C,A ;PUT THE INDEX BLOCK ADDRESS IN AC A
GTFDB ;GET THE INDEX BLOCK ADDRESS OF FILE TO LOAD
TXO A,FILWB ;TURN ON FILE WRITE BIT (SO NO OTHER OPENS)
MOVEM A,SVFDB ;SAVE IDX BLOCK
MOVE B,LODJFN ;GET JFN AGAIN
IMULI B,MLJFN ;GET INTERNAL INDEX
HRRZ A,FILDDN(B) ;GET DIR NUMBER
LOAD B,FLUC,(B) ;GET UNIQUE STR CODE
HRL A,B ;BUILD 36-BIT DIR NUMBER
CALL IGTDAL ;GET CURRENT ALLOCATION
TDZA A,A ;GIVE HIM ZERO
SUB A,B ;CORRECT FORM FOR ASOFN
MOVE D,A ;MOVE TO CORRECT PLACE
MOVE A,LODJFN ;GET JFN AGAIN
IMULI A,MLJFN ;CONVERT TO INTERNAL INDEX
LOAD B,STR,(A) ;GET STR #
HRRZ C,FILDDN(A) ;GET DIR #
MOVE A,SVFDB ;RESTORE FDB ADDRS
BLCAL. ASNOFN,<T1,T2,T3,T4,[0]>
SETOM A ;ALREADY A WRITER, INDICATE NO OFN FOR FILE
MOVE B,LODFCN ;GET FUNCTION CODE
CAIE B,.MOLVF ;LOADING VFU ?
JRST LPLD05 ;NO, SAVE OFN FOR RAM FILE
STOR A,VFUOFN,(U) ;YES, SAVE OFN FOR VFU FILE
JRST LPLD10 ;GO ON TO READ DATA TO BE LOADED
LPLD05: STOR A,RAMOFN,(U) ;SAVE OFN FOR RAM FILE
; STORE NAME OF FILE USED FOR LOADING
LPLD10: MOVE T1,LODFCN ;GET FUNCTION CODE
MOVE T2,LODJFN ;GET JFN OF FILE THAT WAS LOADED
CALL SAVNAM ;GO SAVE AWAY NAME OF FILE THAT WAS JUST LOADED
; OPEN THE FILE TO BE LOADED FOR INPUT
MOVE A,LODJFN ;GET JFN OF FILE TO BE LOADED
MOVE B,[1,,.FBBYV] ;GET WORD WITH BYTE SIZE
MOVEI C,C ;STORE IT HERE
GTFDB ;GET FDB DATUM
ERJMP OPNFAI ;FAILED
MOVX B,OF%RD ;GET ACCESS
LOAD C,FB%BSZ,C ;EXTRACT BYTE SIZE OF FILE
STOR C,OF%BSZ,B ;STASH IT AWAY
OPENF ;OPEN THE FILE
OPNFAI: RETBAD (MTOX10,<TQO ERRF>) ;CANNOT OPEN VFU OR RAM FILE
; CHECK THAT PRINTER IS REALLY ON-LINE, DO NOT LOAD IF OFF-LINE
JE LPTOL,(U),[ MOVX D,MTOX17 ;GET ERROR CODE
JRST LODERR ] ;GO GIVE PROCESS AN ERROR
;..
;..
; READ THE DATA TO BE LOADED
MOVE A,LODJFN ;GET JFN OF FILE CONTAINING DATA
MOVE B,LPTRLP(U) ;GET BASE ADDRESS OF LPT BUFFER
OPSTR <SKIPN>,ALTP,(U) ;USING ALTERNATE BUFFER ?
ADDI B,NLPBF ;NO, USE ALTERNATE BUFFER FOR RAM OR VFU DATA
HRLI B,(POINT ^D16,) ;FORM BYTE POINTER TO BUFFER
MOVNI C,2*NLPBF ;GET -<MAX # OF WORDS TO INPUT>
SIN ;READ DATA TO BE LOADED
ERJMP LPLD15 ;JUMP ON EOF
JRST [ MOVX D,MTOX11 ;DATA TOO LARGE FOR BUFFERS. GET ERROR CODE
JRST LODERR ] ;GO CLOSE FILE AND GIVE PROCESS AN ERROR
LPLD15: GTSTS ;GET CURRENT FILE STATUS
TXNN B,GS%ERR ;FILE ERROR?
TXNN B,GS%EOF ;NO. NOW AT EOF?
JRST [ MOVX D,MTOX12 ;NOT ALL DATA READ OR I/O ERROR
JRST LODERR ] ;GO CLOSE FILE AND GIVE PROCESS AN ERROR
MOVEI D,2*NLPBF(C) ;ALL OK, GET # OF BYTES READ
ASH D,1 ;COMPUTE # OF 8-BIT BYTES
; SEND DATA TO LPT VIA DTE REQUEST QUEUER
MOVE C,LODFCN ;GET FUNCTION
CAIN C,.MOLVF ;WANT TO LOAD THE VFU?
JRST [ SETZRO LPLVF,(U) ;YES. CLEAR FLAG TO LOAD IT
MOVSI B,.DFLVF ;GET PROPER FUNCTION
JRST .+1] ;AND PROCEED
CAIN C,.MOLTR ;WANT TO LOAD TRNASLATION RAM?
JRST [ SETZRO LPLTR,(U) ;YES. CLEAR FLAG
MOVSI B,.DFLTR ;GET PROPER FUNCTION
JRST .+1] ;AND PROCEED
SETZRO LPLHC,(U) ;SAY LOADING NOW IN PROGRESS
LOAD A,LPDEVT,(U)
CALL @SNDDAT(A) ;SEND DATA
JFCL
LOAD A,LPDEVT,(U)
CALL @SNDEOF(A) ;GO SEND AN EOF TO THE -11
;..
;..
; CLOSE THE FILE THAT WAS JUST LOADED
MOVE A,LODJFN ;GET JFN OF FILE THAT WAS LOADED
CLOSF ;CLOSE THE FILE
JFCL ;IGNORE ERRORS
MOVSI A,LPTSTS(U) ;GET UNIT NUMBER
HRRI A,LODWAT ;GET SCHEDULER TEST FOR LOADING DATA SENT
TQO <BLKF> ;MARK THAT PROCESS SHOULD BLOCK
RET ;RETURN
; ROUTINE TO CLOSE RAM OR VFU FILE AND RETURN AN ERROR TO THE PROCESS
;
; ACCEPTS IN D/ ERROR CODE
LODERR: MOVE A,LODJFN ;GET JFN OF FILE TO BE LOADED
CLOSF ;CLOSE THE FILE AND RELEASE THE JFN
JFCL ;IGNORE ERRORS HERE
LDERR1: TQO <ERRF> ;MARK ERROR
MOVE A,D ;GET ERROR CODE
RET ;RETURN
; ROUTINE TO MARK THAT DATA TO BE LOADED HAS BEEN SENT TO -11
RESCD
LODDON: SETONE LPLHC,(B) ;MARK THAT LOADING HAS COMPLETED
RET ;RETURN
SWAPCD
; ROUTINE TO SAVE AWAY NAME OF FILE TO BE LOADED
SAVNAM: STKVAR <SVNAMJ> ;ALLOCATE SPACE FOR FUNCTION CODE AND JFN
MOVEM B,SVNAMJ ;SAVE JFN
MOVE D,A ;GET FUNCTION TO PERFORM
MOVEI A,VFUFIL ;GET NAME OF VFU FILE BUFFER
CAIE D,.MOLVF ;LOADING VFU ?
MOVEI A,RAMFIL ;NO, GET RAM FILE NAME BUFFER
MOVEI B,LPFLSZ ;GET SIZE OF FILENAME BUFFERS
IMULI B,(U) ;COMPUTE OFFSET TO PROPER BUFFER
ADDI A,(B) ;COMPUTE ADDRESS OF FILENAME BUFFER TO USE
HRLI A,(POINT 7,) ;FORM POINTER TO FILENAME BUFFER
MOVE B,SVNAMJ ;GET JFN USED FOR LOADING
MOVX C,JSBITS ;GET FLAGS SAYING WHICH FIELDS TO OUTPUT
JFNS ;STORE NAME OF FILE USED FOR LOADING
ERJMP .+1 ;IGNORE ERRORS
RET ;RETURN
RESCD
; Line printer interrupt
LPTINT: JSP CX,CHKLPT ;MAKE SURE IS A VALID LPT
PUSH P,U ;SAVE UNIT INICATOR
MOVEI U,0(B) ;MOVE UNIT NUMBER
;NOW UPDATE COUNTS FOR THIS BUFFER
LOAD B,LPTFE,(U) ;BYTES IN FE
ADDI B,0(A) ;INCREASE IT
STOR B,LPTFE,(U) ;UPDATE IT
MOVEI B,0(A) ;SAVE COUNT OF LAST TRANSFER
SUB A,LPTICT(U) ;UPDATE THE COUNT
MOVNM A,LPTICT(U) ;THE NEW COUNT
ADJBP B,LPTCCW(U) ;UPDATE BYTE POINTER
MOVEM B,LPTCCW(U) ;SAVE NEW BYTE POINTER
;BUFFER COMPLETE, SEE IF MORE TO DO
LPTNXT: SKIPLE LPTICT(U) ;THIS BUFFER DONE?
JRST LPTN11 ;NO. GO FINISH IT
FSKED ;FLAG SCHED FOR POSSIBLE FORK UNBLOCK
LOAD C,ALTI,(U) ;GET INTERRUPT BUFFER
XORI C,1 ;TOGGLE IT
STOR C,ALTI,(U) ;AND PUT IT BACK
SOSL LPTCNT(U) ;ANOTHER BUFFER READY?
JRST [ CALL LPTSND ;YES, SET IT UP
JRST LPTN10] ;GO RETURN
JE LPNOE,(U),LPTN10 ;NOTING OCCURRANCE OF EOF ?
LOAD A,LPDEVT,(U)
CALL @SNDEOF(A) ;YES, TELL -11 TO ADVISE US WHEN DONE
LPTN10: POP P,U ;RESTORE U
RET ;RETURN
LPTN11: CONSZ PI,1B<LPTCHN+^D20>;AT PI?
JRST LPTN12 ;YES. GO ON THEN
NOSKD1 ;TURN OFF SCHEDULING
CHNOFF LPTCHN ;AND PREVENT INTERRUPTS
LPTN12: CALL LPTSN5 ;GO FINISH IT
JRST LPTN10 ;AND DONE
;SETUP BUFFER POINTER AND OUTPUT THE BUFFER
LPTSND: JN <LPTBL,LPTHN>,(U),R ;IF BLOCKED OR HUNG, RETURN NOW
CONSZ PI,1B<LPTCHN+^D20> ;AT PI?
JRST LPTSN1 ;YES. GO ON THEN
NOSKD1 ;TURN OFF SCHEDULING
CHNOFF LPTCHN ;AND PREVENT INTERRUPTS
LPTSN1: SKIPLE LPTICT(U) ;HAVE A BUFFER YET?
JRST LPTSN5 ;YES. GO WORK ON IT
MOVE A,LPTRLP(U) ;GET BUFFER BASE
OPSTR <SKIPE>,ALTI,(U) ;USING SECOND BUFFER?
ADDI A,NLPBF ;YES. GET TO IT
HRLI A,(<POINT 7,0>) ;MAKE A 7-BIT BYTE POINTER
LOAD B,LPBSZ,(U) ;GET BYTE SIZE OF OPENF
CAIN B,^D8 ;USING 8 BIT BYTES ?
HRLI A,(POINT 8,) ;YES, USE 8-BIT BYTE POINTER
MOVEM A,LPTCCW(U) ;SAVE POINTER IN THE POINTER WORD
MOVEI A,^D36 ;GET BITS PER WORD
LOAD B,LPBSZ,(U) ;GET BYTESIZE OF OPENF
CAIE B,^D8 ;USING 8-BIT BYTES ?
MOVEI B,7 ;NO, ASSUME 7-BIT BYTES
IDIV A,B ;COMPUTE # OF BYTES PER WORD
IMULI A,NLPBF ;COMPUTE # OF BYTES PER BUFFER
MOVEM A,LPTICT(U) ;TO COUNT WORD
;..
LPTSN5: JN <LPLTR,LPLVF>,(U),NOSEND ;IF A RAM NEEDS LOADING, BLOCK
LOAD A,LPTFE,(U) ;GET COUNT OF BYTES IN FE
LOAD B,LPTMX,(U) ;GET CURRENT LIMIT
CAIL A,0(B) ;ROOM FOR MORE BYTES?
JRST NOSEND ;NO, GO INDICATE PROCESS BLOCKED AND RETURN
SUBI B,0(A) ;GET ROOM LEFT
MOVE A,LPTICT(U) ;BYTES IN BUFFER
CAILE A,0(B) ;ROOM FOR WHOLE THING?
MOVEI A,0(B) ;NO. FILL QUOTA THEN
PUSH P,F ;SAVE FLAGS
MOVEI F,0(A) ;COUNT IS UNIQUE CODE
LOAD A,LPDEVT,(U) ;FIND CORRECT ROUTINE
CALL @SNDSTD(A)
JRST [ SETONE LPTHN,(U) ;SAY WE ARE HUNG
MOVEI A,^D1000 ;TIME FOR SCHEDULER CHECK
CAMGE A,LPTTIM ;EARLIER THAN CURRENT?
MOVEM A,LPTTIM ;YES. THIS ONE IS FIRST
ADD A,TODCLK ;TIME FOR THIS CHECK
MOVEM A,LPTCKT(U) ;SET IT UP
POP P,F ;RESTORE FLAGS
JRST INTOK] ;GO FIX UP INTS
POP P,F ;RESTORE FLAGS
INTOK: CONSZ PI,1B<LPTCHN+^D20>;AT PI?
RET ;YES. ALL DONE
CHNON LPTCHN ;TURN ON CHANNEL
OKSKD1 ;AND ENABLE SCHEDULER
RET ;AND DONE
; HERE TO BLOCK PROCESS AND RETURN
NOSEND: SETONE LPTBL,(U) ;SAY WE BLOCKED
JRST INTOK ;AND GO AWAY
;ROUTINE TO TAKE THE STATUS OF A LPT
; B/ UNIT
; D/POINTER TO BYTES
; C/COUNT OF BYTES
LPTTLS::JUMPLE C,R ;MAKE SURE A BYTE IS THERE
JSP CX,CHKLPT ;GO VERIFY ARGS
STKVAR <TLSPSI,TLSCNT,TLSSST,TLSMSG> ;ALLOCATE STORAGE
MOVEM C,TLSCNT ;SAVE COUNT OF BYTES IN STATUS MESSAGE
SETZM TLSPSI ;ASSUME NO PSI INTERRUPT REQUIRED
; GET SOFTWARE STATUS WORD AND SAVE FOR PROCESS EXAMINATION
ILDB A,D ;GET HIGH ORDER STANDARD STATUS BITS
ILDB C,D ;GET LOW ORDER STATUS BITS
LSH A,8 ;PLACE HIGH ORDER BITS IN PROPER POSITION
IOR A,C ;FORM COMPLETE STATUS
STOR A,LPSST,(B) ;STORE SOFTWARE STATUS WORD FOR PROCESS USE
MOVEM A,TLSSST ;SAVE SOFTWARE STATUS WORD
LOAD C,LPTER,(B) ;GET PREVIOUS ERROR BIT
LOAD A,LPTOL,(B) ;AND PREVIOUS ON-LINE BIT
IORI C,-1(A) ;FORM EQV
MOVE A,TLSSST ;RESTORE SOFTWARE STATUS WORD
; SEE IF PSI INTERRUPT NEEDED BECAUSE OF ON-LINE/OFF-LINE TRANSITION
JE LPTOL,(B),LPTS05 ;JUMP IF LPT WAS OFF-LINE
TXNE A,.DVFOL!.DVFNX ;LPT WAS ON-LINE. IS IT OFF-LINE NOW ?
SETOM TLSPSI ;YES, REQUEST PSI CAUSE LPT WENT OFF-LINE
JRST LPTS10 ;GO ON TO SAVE NEW STATUS
LPTS05: TXNN A,.DVFOL!.DVFNX ;LPT WAS OFF-LINE. IS IT ON-LINE NOW ?
SETOM TLSPSI ;YES, REQUEST PSI CAUSE LPT WENT ON-LINE
LPTS10: SETONE LPTOL,(B) ;ASSUME IS ON-LINE
SETZRO LPTER,(B) ;AND THAT NO ERRORS NOW EXIST
TXNN A,.DVFOL!.DVFNX ;OFF LINE?
JRST LPTS20 ;NO
SETZRO LPTOL,(B) ;YES. SAY SO
LPTS20: TXNE A,.DVFFE ;FATAL ERROR ON LPT?
CALL SETER2 ;YES, FREE BUFFERS, MARK ERROR, AND ZERO COUNTS
;..
;..
; HERE TO SAVE HARDWARE STATUS, PAGE COUNTER, AND TO SEE IF MESSAGE NEEDED
LPTS30: MOVEM C,TLSMSG ;SAVE MESSAGE-REQUIRED FLAG
ILDB A,D ;GET HIGH ORDER BITS OF PRINTER STATUS
ILDB C,D ;GET LOW EIGHT BITS
LSH A,8 ;POSITION HIGH ORDER BITS PROPERLY
IOR C,A ;FORM COMPLETE HARDWARE STATUS
STOR C,LPERR,(B) ;SAVE THE ERROR CODE FOR LATER
TXNE C,MO%LPC ;PAGE COUNTER OVERFLOWED ?
JRST [ JN LPPCI,(B),.+1 ;YES, BUT RETURN IF INTERRUPT ALREADY REQUESTED
SETONE LPPCI,(B) ;INDICATE INTERRUPT HAS BEEN REQUESTED
SETOM TLSPSI ;INDICATE PSI INTERRUPT NEEDED
JRST .+1 ] ;CONTINUE
TXNE C,MO%LCI!MO%RPE ;CHARACTER INTERRUPT OR RAM PARITY ERROR ?
JRST [SETONE LPLTR,(B) ;YES, MARK THAT RAM NEEDS RELOADING
CALL SETERR ;FREE UP BUFFERS, MARK ERROR, CLEAR COUNTS
JRST .+1] ;REJOIN MAIN-LINE CODE
TXNE C,MO%LVF ;VFU ERROR ?
JRST [ TXNE C,MO%LVU ;DOES THIS PRINTER HAVE A DAVFU?
JRST .+1 ;NO, IGNORE SPURIOUS ERRORS
SETONE LPLVF,(B) ;YES, MARK THAT VFU NEEDS RELOADING
SETONE LPLTR,(B) ;AND RELOAD THE RAM ALSO
CALL SETERR ;MARK ERROR, FREE BUFFERS, CLEAR COUNTS
JRST .+1] ;REJOIN MAIN-LINE CODE
ILDB A,D ;GET # OF BYTES OF DEVICE-DEPENDENT DATA
ADDI A,.LRPAG+1 ;ADD # OF BYTES TO PAGE COUNTER, + 1 FOR
; COUNT OF # OF BYTES OF DEVICE REGISTERS
CAMLE C,TLSCNT ;GOT ENOUGH BYTES FROM -11 ?
JRST LPTS50 ;NO, DO NOT TRY TO GET PAGE COUNTER
ADJBP A,D ;INCREMENT POINTER TO PAGE COUNTER REGISTER
MOVE D,A ;GET POINTER BACK
ILDB A,D ;GET HIGH ORDER BITS OF PAGE COUNTER
ILDB C,D ;GET LOW ORDER BITS OF PAGE COUNTER
LSH A,8 ;POSITION HIGH ORDER BITS PROPERLY
IOR A,C ;FORM COMPLETE PAGE COUNTER VALUE
STOR A,LPPAG,(B) ;STORE LATEST PAGE COUNTER VALUE
;..
;..
; HERE TO SEE IF PSI NEEDED
LPTS50: MOVE A,TLSSST ;RESTORE SOFTWARE STATUS
MOVE C,TLSMSG ;RESTORE MESSAGE-NEEDED FLAG
SETONE LPSHA,(B) ;MARK THAT A STATUS HAS ARRIVED
JE LPOPN,(B),R ;IF NOT OPENED, RETURN
SKIPE TLSPSI ;PSI REQUEST NEEDED ?
CALL REQPSI ;YES, GO REQUEST INTERRUPT IF FORK ENABLED
OPSTR <SKIPE>,LPTFE,(B) ;FE HAS NO BYTES?
TXNN A,.DVFHE!.DVFOL ;HARDWARE ERROR?
RET ;NO. ALL DONE
SETONE LPTER,(B) ;YES. SAY SO
SKIPE C ;NEED MESSAGE?
RET ;NO. DON'T DO ATTENTION
SNDPSI: MOVE A,TODCLK ;NOW
MOVEM A,LPTCKT(B) ;TIME TO CHECK THIS ONE
SETZM LPTTIM ;AND TO INTIATE SCHEDULER ACTION
RET ;ALL DONE
; ROUTINE TO MARK THAT A HARD ERROR HAS OCCURRED, FREE BUFFERS, AND
; CLEAR COUNTS
SETERR: OPSTR <SKIPN>,LPTFE,(B) ;DATA STILL IN FE ?
SKIPLE LPTICT(B) ;OR IN OUR BUFFER ?
SKIPA ;YES, SET HARD ERROR
JRST SETER1 ;NO, LEAVE HARD ERROR ALONE
SETER2: SETONE LPTHE,(B) ;MARK IT
SETER1: RET ;RETURN TO STATUS ROUTINE
; ROUTINE TO REQUEST A PSI INTERRUPT IF THE FORK OWNING THE LPT HAS
; ENABLED FOR INTERRUPTS
;
; CALL: B/ UNIT NUMBER
; CALL REQPSI
; RETURNS: +1 ALWAYS, TEMPORARY AC'S PRESERVED
REQPSI: SAVET ;SAVE TEMPS
LOAD A,LPPSI,(B) ;GET PSI CHANNEL FIELD
CAIN A,INIPSI ;HAS PROCESS ENABLED FOR INTERRUPTS ?
RET ;NO, RETURN
SETONE LPIRP,(B) ;MARK THAT AN INTERRUPT REQUEST IS PENDING
CALLRET SNDPSI ;ARRANGE FOR LPTCHK TO RUN TO GENERATE THE PSI
;ROUTINE CALLED FROM DTE SERVICE ROUTINES TO CHECK UNIT NUMBER
;OF LPT. CALLED BY
; JSP CX,CHKLPT
;WITH:
; B/ LPT UNIT
CHKLPT: CAIL B,LPTN ;A VALID LPT?
RET ;NO. GIVE IT UP THEN
JRST 0(CX) ;YES. RETURN IN-LINE
;PERIODIC CHECK FOR HUNG LPT
LPTCHK: MOVSI U,-LPTN ;CHECK ALL UNITS
JUMPE U,R ;RETURN IF NO UNITS
MOVSI A,(1B1) ;MAX TIME TO WAIT
MOVEM A,LPTTIM ;SET IT
LPTCK1: MOVE A,LPTCKT(U)
CAMLE A,TODCLK ;TIME TO DO THIS ONE?
JRST [ SUB A,TODCLK ;NO. GET RELATIVE TIME
CAMGE A,LPTTIM ;IS HE NEXT?
MOVEM A,LPTTIM ;YES. LET IT BE
JRST LPTCK3] ;AND MOVE ON
JN LPIRP,(U),[ SETZRO LPIRP,(U) ;IF PSI NEEDED, MARK THAT PSI REQUESTED
LOAD A,LPPSI,(U) ;GET PSI CHANNEL FOR INTERRUPT
LOAD B,LPFRK,(U) ;GET OWNING FORK FOR THIS LPT
CAIE A,INIPSI ;MAKE SURE INTERRUPT CHANNEL HAS BEEN SPECIFIED
CALL PSIRQ ;REQUEST A PSI INTERRUPT
JRST .+1 ] ;CONTINUE
JE LPTHN,(U),LPTCK2 ;NEED TO DO SOMETHING WITH THIS ONE
SETZRO LPTHN,(U) ;SAY NOT HUNG ANYMORE
CALL LPTSND ;TRY TO SEND IT OUT
LPTCK2: JE LPTER,(U),LPTCK4 ;NEED AN ERROR MESSAGE?
SETZRO LPTER,(U) ;YES. TURN OFF INDICATOR
JN LPMSG,(U),LPTCK4 ;NEED ERROR MESSAGE?
MOVE A,[ASCII /PLPT/] ;GET DEVICE TYPE
MOVEI B,"0"(U) ;THE UNIT NUMBER
DPB B,[POINT 7,A,34] ;PUT IN THE UNIT
PUSH P,A ;THE STRING
PUSH P,[0]
HRROI A,PRBDEV ;[7193] GET THE MESSAGE
CALL PMES ;(A)[7193] PRINT THE MESSAGE ON THE CTY
HRROI A,-1(P) ;[7193] THE ADDRESS
CALL PMES ;(A)[7193] PRINT THE MESSAGE ON THE CTY
HRROI A,CRLF ;[7193] ADD CRLF
CALL PMES ;(A)[7193] TO OUTPUT
ADJSP P,-2 ;FAST POP OF THE STACK
LPTCK4: MOVEI A,^D60000 ;WHEN TO CHECK AGAIN
CAMG A,LPTTIM ;LESS THAN CURRENT MINIMUM?
MOVEM A,LPTTIM ;YES
ADD A,TODCLK ;WHEN TO MAKE THE CHECK
MOVEM A,LPTCKT(U) ;TO THE CELL
LPTCK3: LOAD A,LPDEVT,(U) ;GET DEVICE TYPE
SKIPE A ;IF ZERO VECTORS NOT SETUP YET
CALL @FEIEN(A)
AOBJN U,LPTCK1 ;CHECK THEM ALL
RET
> ;END IFN KLFLG!SMFLG