Trailing-Edge
-
PDP-10 Archives
-
BB-JR93N-BB_1990
-
10,7/galaxy/lptspl/lptser.mac
There are 16 other files named lptser.mac in the archive. Click here to see a list.
TITLE LPTSER - LINE PRINTER SERVICE ROUTINE FOR MULTIPLE LINE PRINTERS - V531
SUBTTL T. N. MCMANUS /TNM/CHW/RCC/LSS TS 25-OCTOBER-88
SEARCH F,S,DEVPRM
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
;1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.
.CPYRT<1973,1988>
XP VLPTSR,531 ;DEFINE GLOBAL VERSION NUMBER FOR LOADER MAP
LPTSER::ENTRY LPTSER
SUBTTL CONI/CONO DEFINITIONS
;LINE PRINTER CONI BITS AND MASKS FOR LP100 AND BA10
CI.VFU==3B1 ;VFU TYPE
VFUPT==0 ;OPTICAL
VFUDA==1 ;DIRECT ACCESS
VFUNO==2 ;NONE
CI.FEN==1B2 ;FEATURES ENABLED
CI.ENV==1B3 ;EVEN PARITY
CI.CTR==7777B17 ;PAGE COUNTER
CI.INT==1B18 ;INTERRUPT IF CI.FEN
CI.NRY==1B19 ;LPT NOT READY
CI.PZR==1B20 ;PAGE COUNTER ZERO
CI.PAR==1B21 ;LPT PARITY ERROR
CI.VFE==1B22 ;VFU ERROR
CI.NLD==1B23 ;VFU LOAD INHIBIT
CI.CHR==3B25 ;CHARACTER SET (BA10 ALSO)
CHR64==0 ;64 CHARACTERS
CHR96==1 ;96 CHARACTERS
CHR128==2 ;128 CHARACTERS
CHRVAR==3 ;VARIABLE (NOT BA10)
CI.LOV==1B26 ;LINE OVERFLOW (646 ONLY)
CI.OFL==1B27 ;OFF-LINE (BA10 ALSO)
CI.BSY==1B28 ;BUSY (BA10 ALSO)
CI.DON==1B29 ;DONE (BA10 ALSO)
CI.PIB==7B32 ;ERROR INTERRUPT CHN (BA10 ALSO)
CI.PIA==7B35 ;DONE INTERRUPT CHN (BA10 ALSO)
;LINE PRINTER CONO BITS AND MASKS FOR LP100 AND BA10
CO.CIN==1B18 ;CLEAR INTERRUPT
CO.FEN==1B20 ;FEATURES ENABLED
CO.CPE==1B21 ;CLEAR PARITY ERROR
CO.SEP==1B22 ;SEND EVEN PARITY
CO.NLD==1B23 ;INHIBIT VFU LOAD
CO.PRI==1B25 ;PRINTER INIT (BA10 ALSO)
CO.LSV==1B26 ;LOAD STANDARD VFU
CO.SPC==1B27 ;NEXT DATAO SETS PAGE COUNTER
CO.SBY==1B28 ;SET BUSY (BA10 ALSO)
CO.SDN==1B29 ;SET DONE (BA10 ALSO)
CO.PIB==7B32 ;ERROR INTERRUPT CHN (BA10 ALSO)
CO.PIA==7B35 ;DONE INTERRUPT CHAN (BA10 ALSO)
;SPECIAL CONI/CONO COMBOS
CI%SKP==CI.INT+CI.LOV+CI.OFL+CI.DON ;CONSO SKIP CHAIN MASK
CI%SKF==CI.INT ;CONSO MASK WHEN LPT IF OFF
CI%SKE==CI%SKP-CI.DON ;CONSO/Z SKIP IF ERROR
CO%OFF==CO.CIN+CO.FEN+CO.CPE ;CONO TO TURN LPT OFF
CO%ON==CO%OFF+CO.SDN ;CONO TO TURN LPT ON
SUBTTL SYMBOL DEFINITIONS
;DEVICE DEPENDENT BITS IN LH OF DEVIOS
LPTSYN==Z(1B11) ;CRFF AFTER CLOSE HAS BEEN SENT
LPTEND==Z(1B10) ;CLOSE UUO HAS BEEN DONE
LPTRBL==Z(1B9) ;LPT TROUBLE DETECTED AT INTERRUPT LEVEL
LPTOPB==Z(1B8) ;PARTIAL BUFFER ALREADY OUTPUT
;DEVICE DEPENDENT BITS IN RH OF DEVIOS
LPTNFF==100 ;SUPPRESS FREE FORM FEEDS
SUBTTL LPT ERROR REPORTING
;EIGHT WORDS ARE IN EACH LINEPRINTER DDB FOR DAEMON ERROR REPORTING.
;; !=======================================================!
;; LPTDAP: ! AOBJN POINTER TO DAEMON ERROR BLOCK !
;; !=======================================================!
;;
;;
;;
;; !=======================================================!
;; LPTDAE: ! SIXBIT DEVICE NAME !
;; !-------------------------------------------------------!
;; !CTR TYPE!DEV TYPE! !N ! RETRY COUNT !
;; !-------------------------------------------------------!
;; ! PPN !
;; !-------------------------------------------------------!
;; ! PROGRAM NAME !
;; !-------------------------------------------------------!
;; ! # WORDS IN SUB-BLOCK ! SUB-BLOCK OFFSET !
;; !-------------------------------------------------------!
;; ! CONI WORD AT ERROR !
;; !-------------------------------------------------------!
;; ! LAST DATA WORD SENT TO LPT !
;; !=======================================================!
.LENAM==0 ;SIXBIT DEVICE NAME
.LETYP==1 ;CONTROLLER/DEVICE TYPE
LE.CTR==77B5 ;CONTROLLER TYPE
.LECIL==.HCTUK ;ILLEGAL
.LECBX==.HCTBX ;BA-10
.LECLC==.HCTLC ;LP-100
LE.DTP==77B11 ;DEVICE TYPE
.LEDLP==1 ;LPT
LE.NRC==1B17 ;NON-RECOVERABLE ERROR
LE.RTY==777777B35 ;RETRY COUNT
.LEPPN==2 ;PPN
.LEPGM==3 ;PROGRAM NAME
.LEPTR==4 ;NUMBER WORDS FOLLOWING,,OFFSET TO FIRST
.LECNI==5 ;CONI AT ERROR
.LEDAT==6 ;LAST DATA WORD SENT TO LPT
.LESIZ==7 ;SIZE OF THE BLOCK
SUBTTL AUTOCONFIGURE
;DRIVER CHARARCTERISTICS
; LPT = LPTCNF
; LPT = LINE PRINTER
; 7 = MAXIMUM DEVICES IN SYSTEM
; 0 = KONTROLLER TYPE
; 0 = MAXIMUM DRIVES PER KONTROLLER
; 0 = HIGHEST DRIVE NUMBER ON KONTROLLER
; MDSEC0 = SECTION FOR KDB/UDB
; MDSEC0 = SECTION FOR DDB
DRVCHR (LPT,LPT,7,0,0,0,MDSEC0,MDSEC0,<DR.GCC!DR.NET>)
.ORG DEVLEN
LPTCHF:! BLOCK 1 ;PI CHANNEL FLAGS
LPTCSO:! BLOCK 1 ;ADDRESS OF INTERRUPT CODE
LPTSVE:! BLOCK 1 ;ADDRESS OF ALTERNATE ENTRY TO INTERRUPT CODE
LPTRET:! BLOCK 1 ;ADDRESS OF ALTERNATE EXIT FROM INTERRUPT
LPTPAG:! BLOCK 1 ;PAGE COUNTER
LPTPTR:! BLOCK 1 ;BLKO POINTER
LPTDAP:! BLOCK 1 ;AOBJN POINTER TO ERROR BLOCK
LPTDAE:! BLOCK 7 ;DAEMON ERROR BLOCK
LPTIOB:! ;START OF I/O INSTRUCTIONS
LPTCNI:! BLOCK 1 ;CONI
LPTCNO:! BLOCK 1 ;CONO
LPTDTO:! BLOCK 1 ;DATAO
LPTBKO:! BLOCK 1 ;BLKO
LPTSTS:! BLOCK 1 ;DEVICE STATUS WORD CONI
LPTDNO:! BLOCK 1 ;CONSZ SKIP IF ERROR
LPTDNZ:! BLOCK 1 ;CONSO SKIP IF ERROR
LPTCSZ:! BLOCK 1 ;CONSO FOR LINE CONTROL
LPTIOE:! ;END OF I/O INSTRUCTIONS
LPTFRM:! BLOCK 1 ;FORMS TYPE NAME (SIXBIT)
LPTLEN:! ;LENGTH OF LPT DDB
.ORG
$LOW
LPTDDB: DDBBEG (LPT,LPTLEN)
SETWRD (DEVCHR,<6*HUNGST+DVLPTL,,LPTSIZ##>) ;DEVCHR
SETWRD (DEVSER,<MCSEC0+LPTDSP>) ;DEVSER
SETWRD (DEVMOD,<DVOUT!DVLPT,,<1_A+1_AL+1_I>>) ;DEVMOD
SETWRD (DEVTYP,<<.TYLPT*.TYEST>!.SPLPT!DEPLEN,,0>) ;DEVTYP
SETWRD (DEVCPU,<LPTCHN##>) ;DEVCPU
SETWRD (LPTCHF,<<LPTCHN##*10>+LPTCHN##>) ;PI CHANNEL FLAGS (ERR+INT)
SETWRD (LPTDNO,<CONSZ 000,CI%SKE>) ;SKIP IF ERROR
SETWRD (LPTDNZ,<CONSO 000,CI%SKE>) ;SKIP IF ERROR
SETWRD (LPTCSZ,<CONSZ 000,(U)>) ;LINE CONTROL
SETWRD (LPTCNI,<CONI 000,U>) ;CONI
SETWRD (LPTCNO,<CONO 000,(U)>) ;CONO
SETWRD (LPTDTO,<DATAO 000,(U)>) ;DATAO
SETWRD (LPTBKO,<BLKO 000,LPTPTR>) ;BLKO
SETWRD (LPTSTS,<CONI 000,DEVSTS>) ;DEVICE STATUS WORD CONI
DDBEND
$HIGH
;CONSO SKIP CHAIN CODE (AUTCON WILL FILL IN THE BLANKS)
LPTICD: PHASE 0
CONSO 000,0 ;(00) SKIP IF INTERRUPT FOR THIS LPT
JRST .-1 ;(01) GO TO NEXT SKIP CHAIN ELEMENT
MOVEM F,LPTSAV ;(02) SAVE AC F
SKIPA F,.+1 ;(03) SET UP DDB ADDRESS
EXP 0 ;(04) DDB ADDRESS
XJRST .+1 ;(05) CALL INTERRUPT HANDLER
EXP 0 ;(06) INTERRUPT HANDLER ADDRESS
LPTINX:!MOVE F,LPTSAV ;(07) RESTORE AC F
JSR PIERR## ;(10) SAVE ACS AND SETUP PDL
SKIPA F,.+1 ;(11) SET UP DDB ADDRESS
EXP 0 ;(12) DDB ADDRESS
XJRST .+1 ;(13) CALL INTERRUPT HANDLER
LPTICN:!EXP 0 ;(14) INTERRUPT HANDLER ADDRESS
LPTEXT:!MOVE F,LPTSAV ;(15) RESTORE AC F
XJEN -1 ;(16) DONE
LPTSAV:!EXP -1 ;(17) STORAGE FOR AC F
DEPHASE
LPTICL==.-LPTICD ;LENGTH OF CONSO SKIP CHAIN CODE
EQUATE (LOCAL,0,<LPTCKT,LPTKDB,LPTKLN,LPTUDB,LPTULN>)
EQUATE (LOCAL,0,<LPTULB,LPTULP>)
LPXDSP: DRVDSP (LPT,LPTCHN##,LPTDDB,LPTLEN,URDDIA##)
;DEFAULT MONGEN'ED DEVICE TABLE
DEFMDT: MDKL10 (7,124,0,0,<MD.KON>) ;DEVICE CODE 124
MDKL10 (7,234,0,0,<MD.KON>) ;DEVICE CODE 234
MDKL10 (7,230,0,0,<MD.KON>) ;DEVICE CODE 230
MDTERM
;BITS FOR MDT ENTRIES ARE ASSIGNED HERE
LPT.UC==:1 ;UPPER-CASE ONLY PRINTER
LPTCFG: XMOVEI T1,LPTMDT## ;MONGEN'ED DEVICE TABLE
XMOVEI T2,DEFMDT ;DEFAULT TABLE
MOVNI T3,1 ;NO MASSBUS UNIT OR DRIVE INFORMATION
MOVEI T4,MD.KON ;MATCH ON KONTROLLER DEFINITION
PUSHJ P,AUTMDT## ;SCAN THE TABLES
JRST CPOPJ1## ;NO MATCHES
PUSH P,T1 ;SAVE MDT DATA
MOVEI T1,LPTIOB ;WORD CONTAINING AN I/O INSTRUCTION
PUSHJ P,AUTFND## ;SEE IF THERE'S ALREADY A DDB
JRST LPTCF1 ;JUST MAKE SURE THE NUMBERS ARE OK
PUSHJ P,AUTADN## ;ALLOCATE A DEVICE NUMBER
HRLI T1,'LPT' ;INCLUDE GENERIC DEVICE NAME
SETZ T2, ;LOCAL DEVICE
PUSHJ P,AUTDDB## ;CREATE A DDB
JRST [POP P,T1 ;NO CORE
PJRST AUTDDN##] ;DEALLOCATE DEVICE NUMBER
LPTCF1: MOVSI T1,-<LPTIOE-LPTIOB> ;-LENGTH
XMOVEI T2,LPTIOB(F) ;STARTING ADDRESS
HRRZ T3,.CPDVC## ;DEVICE CODE
PUSHJ P,AUTDVC## ;FILL IN DEVICE CODES
SKIPE LPTCSO(F) ;BEEN HERE BEFORE?
JRST LPTCF3 ;THEN DON'T MESS WITH THE SKIP CHAIN
ADDM F,LPTSTS(F) ;RELOCATE CONI TO LOAD UP DEVSTS
ADDM F,LPTBKO(F) ;RELOCATE BLKO INSTRUCTION
MOVE T1,F ;DATA BLOCK ADDRESS
XMOVEI T2,LPTINT ;INTERRUPT SERVICE
PUSHJ P,AUTICD## ;GENERATE INTERRUPT ROUTINES
SKIPA T2,F ;NO CORE
JRST LPTCF2 ;ONWARD
MOVEI T1,LPTLEN ;DDB ADDRESS
PUSHJ P,AUTKIL## ;DELETE THE DDB
PUSHJ P,AUTDDN## ;DEALLOCATE DEVICE NUMBER
JRST TPOPJ## ;PHASE STACK AND RETURN
LPTCF2: MOVEM T1,LPTCSO(F) ;SAVE ADDRESS
MOVEI T2,LPTNXT ;ALTERNATE INTERRUPT ENTRY POINT
HRRM T2,LPTICN(T1) ;SET UP DISPATCH
MOVEI T2,LPTINX(T1) ;ALTERNATE INTERRUPT ENTRY ADDRESS
MOVEM T2,LPTSVE(F) ;SAVE
MOVEI T2,LPTEXT(T1) ;ALTERNATE INTERRUPT EXIT ADDRESS
MOVEM T2,LPTRET(F) ;SAVE
MOVEI T2,LPTCHN## ;PI CHANNEL
PUSHJ P,AUTCSO## ;LINK INTO CONSO SKIP CHAIN
LPTCF3: POP P,T4 ;RESTORE MDT DATA
MOVSI T1,DVLPTL ;LOWERCASE LPT BIT
TRNE T4,LPT.UC ;IF THIS IS AN UPPER-CASE ONLY PRINTER,
ANDCAM T1,DEVCHR(F) ;CLEAR IT FOR LPTTYP
;ADD FUTURE MDT VALUE TESTS HERE
POPJ P, ;ALL DONE
;LINE PRINTER SERVICE DISPATCH TABLE
JRST LPTONL ;SEE IF LPT IS ON LINE NOW
JRST LPTDVP ;DEVOP. UUO
JRST REGSIZ## ;GET BUFFER SIZE FROM DDB
JRST LPTINI ;INITIALIZE
JRST LPTHNG ;HUNG DEVICE ERROR
LPTDSP: JRST LPTREL ;RELEASE
JRST LPTCLS ;CLOSE
JRST LPTOUT ;OUTPUT
JRST ILLINP## ;INPUT
SUBTTL MONITOR-LOAD DEVICE INITIALIZATION
;LPTINI IS CALLED AT SYSTEM INITIALIZATION TIME FROM
; IOGO IN SYSINI WITH THE DDB ADDRESS IN F
; 1. CLEAR THE SPECIFIED LINE PRINTER
; 2. DEASSIGN BOTH THE ERROR AND DONE INTERRUPT
; CHANNELS FOR THAT LINE PRINTER
; 3. CLEAR THE SKIP CHAIN INTERRUPT MASK FLAGS
; FOR THAT LINE PRINTER
;NOTE: THE LPTINI CODE FORCES IOGO IN SYSINI TO INVOKE
; LPTINI FOR EACH LINE PRINTER ON THE SYSTEM RATHER
; THAN FOR THE NORMAL CASE WHERE IT INVOKES THE
; INITIALIZATION CODE ONCE FOR EACH DISPATCH TABLE.
;
; THEREFORE, THE CORRECT OPERATION OF THE LPTINI CODE
; IS DEPENDANT UPON THE IOGO CODE WHICH SHOULD BE:
; PUSHJ P,DINI(P3)
; HRRZM P3,SAVITM
LPTINI: CAIN F,LPTDDB ;PROTOTYPE DDB?
JRST CPOPJ1## ;IOGO WILL CALL US AGAIN
PUSHJ P,LPTREL ;GO THRU RELEASE CODE
MOVSI T1,-.LESIZ ;LOAD LENGTH OF ERROR BLOCK
HRRI T1,LPTDAE(F) ;MAKE AN AOBJN POINTER
MOVEM T1,LPTDAP(F) ;AND STORE IT
MOVE T1,DEVNAM(F) ;GET DEVICE NAME
MOVEM T1,LPTDAE+.LENAM(F) ;SAVE TIME AT INTERRUPT LEVEL
MOVEI T1,.LEDLP ;DEVICE TYPE IS LPT
DPB T1,[POINT 6,LPTDAE+.LETYP(F),11] ;STORE IN TYPE WORD
MOVE T1,[.LESIZ-.LEPTR-1,,.LECNI] ;GET SUB-BLOCK POINTER
MOVEM T1,LPTDAE+.LEPTR(F) ;SAVE IN POINTER WORD
PJRST CPOPJ1## ;SKIP RETURN TO FORCE CALL FOR EACH LPT
SUBTTL OUT/OUTPUT UUO
LPTOUT: TLO S,IO ;NO, INDICATE OUTPUT
PUSHJ P,LPTOFL ;IF TROUBLE, GET IT FIXED
XCT LPTCNI(F) ;DO A CONI
ANDI U,CI.NLD ;GET STATE OF NO LOAD BIT
IOR U,LPTCHF(F) ;GET CHANNEL ASSIGNMENT FROM DDB
TRO U,CO%ON ;SET LPT "ON"
TRNE S,LPTNFF ;SUPPRESS FORM FEED?
TLZA S,IOBEG ;YES, CLEAR IOBEG AND OUTPUT FIRST BUFFER
TLNN S,IOBEG ;1ST OUTPUT?
JRST LPTGO ;NO, CONTINUE ON NORMALLY
;HERE IF THIS IS THE FIRST OUTPUT AFTER INIT
PUSHJ P,LPTSTI ;SETUP INITIAL BLKO POINTER
CAIA
;HERE TO START THE PRINTER GOING
LPTGO: PUSHJ P,LPTSET ;SET UP BLKO POINTER
PUSHJ P,SETACT## ;SET IOACT, STORE S, SET HNG CNT
HLL U,LPTCHF(F) ;GET SKIP CHAIN MASK FLAGS
PIOFF ;TURN OFF PI TO PREVENT IMM. INT.
XCT LPTCNO(F) ;SEND CONDITIONS OUT TO LPT
HLRM U,@LPTCSO(F) ;SAVE SKIP CHAIN MASK FLAGS
XCT LPTCSZ(F) ;FIND OUT IF DEVICE EXISTS
JRST ONPOPD## ;DEVICE RECEIVED CONO, OK
PION ;REENABLE ALL INTERRUPTS
PUSHJ P,CLRACT## ;DEVICE NON-EXISTANT OR OFF, CLEAR IOACT
PUSHJ P,LPTSTP ;DON'T LEAVE THE CONSO MASK SETUP
PUSHJ P,LPTOF1 ;CLEAR HUNG COUNTER AND PRINT A MESSAGE
JRST LPTOUT ;TRY AGAIN WHEN WE GET BACK
;HERE DURING OUTPUT UUO TO SEE IF DEVICE EXISTS
LPTOFL: PUSHJ P,LPTONL ;SEE IF LPT IS ON-LINE
SKIPA ;IT'S NOT, TELL THE USER
POPJ P, ;IT IS, JUST RETURN
LPTOF1: MOVEM S,DEVIOS(F) ;YES, SAVE S (LPTRBL OFF)
MOVSI T4,DEPADV ;WANT BUFFER LEFT ALONE
IORM T4,DEVADV(F) ;
MOVSI T4,DVOFLN ;MARK LPT OFF LINE
IORM T4,DEVCHR(F)
PUSHJ P,HNGSTP## ;HALT JOB & PRINT REMINDER
MOVSI T4,DEPADV ;LOAD "DONT ADV BUFFERS"
ANDCAM T4,DEVADV(F) ;AND CLEAR IT IN THE DDB
JRST LPTOFL ;BACK HERE ON CONT, TRY AGAIN
SUBTTL CLOSE UUO - RELEASE UUO
;CLOSE UUO - WHEN A CLOSE UUO IS EXECUTED (OR CLOSE COMMAND)
; LPTCLS IS CALLED. LPTCLS RESETS SOME STATUS FLAGS AND
; LIGHTS LPTEND SO THE FINAL CRFF CAN BE SETUP NEXT TIME
; LPTOUT IS CALLED. LPTCLS RETURNS BY BRANCHING TO "OUT"
; SO THE LAST PARTIAL BUFFER IS OUTPUT.
LPTCLS: TLO S,LPTEND ;SET "CLOSE DONE"
TLZ S,LPTOPB+LPTSYN ;CLEAR TROUBLE BITS
MOVEM S,DEVIOS(F) ;STORE S
JRST OUT## ;AND CALL OUT FOR LAST BUFFER
;RELEASE UUO - WHEN A "RESET" IS DONE ON THE LPT, LPTREL IS
; CALLED. THE LINEPRINTER IS "TURNED-OFF" (SEE LPTOFF)
; THE PAGE COUNTER IS TURNED OFF AND THE DDB IS CLEANED UP.
LPTREL: PUSHJ P,LPTTYP ;SETUP LINEPRINTER TYPE
CAIE T2,.LECLC ;AN LP100?
JRST LPTRE1 ;NO, BA10
MOVEI U,CO%OFF+CO.NLD ;TURN OFF THE LPT AND DISABLE LOADING THE VFU
MOVEI T1,CI%SKP-CI.OFL ;CONSO MASK
HRLI T1,CI%SKF ;SKIP ON ERRORS
JRST LPTRE2 ;GO DO THE INITIALIZATION
LPTRE1: MOVEI U,CO.PRI ;ZAP THE PRINTER
MOVEI T1,CI%SKP ;CONSO MASK
HRLI T1,CI%SKE ;SKIP ON ERRORS
LPTRE2: XCT LPTCNO(F) ;TURN THE LPT OFF
HRLM T1,LPTCHF(F) ;STORE THE CONSO MASK
HLRM T1,LPTDNZ(F) ;SKIP ON ERRORS
HLRM T1,LPTDNO(F) ;SKIP ON DONE
HLLZS @LPTCSO(F) ;AND TAKE IT OFF CONSO CHAIN
MOVSI T1,DEPADV ;GET "DONT ADV BUFFER" BIT
ANDCAM T1,DEVADV(F) ;TURN IT OFF
TLZ S,LPTOPB ;CLEAR THE TROUBLE BITS
SETOM LPTPAG(F) ;TURN OFF PAGE COUNTER
TRZ S,IOACT ;CLEAR ACTIVE I/O
PJRST STOIOS## ;SAVE S AND RETURN
LPTHNG==LPTREL ;HUNG DEVICE IS SAME AS RELEASE
SUBTTL INTERRUPT ENTRY & DATA INTERRUPT ROUTINE
;ENTER HERE ON ALL INTERRUPTS
LPTINT: XCT LPTSTS(F) ;STORE CONI STATUS IN DDB
HRL F,DEVIOS(F) ;GET RH FLAGS
TLNN F,IOACT ;JOB DOING I/O
XJRST LPTSVE(F) ;NO, RANDOM DONE INTERRUPT
XCT LPTDNZ(F) ;SKIP IF DONE FLAG IS OFF
SKIPL LPTPTR(F) ;BLKO COUNT TO 0 ON LAST INT?
XJRST LPTSVE(F) ;YES, SAVE AC'S, RETURNS AT LPTNXT
XCT LPTBKO(F) ;NO, SEND NEXT WORD FOR PRINTING
XJRST LPTRET(F) ;LAST WORD SENT BUT INT PENDING
XJRST LPTRET(F) ;GO RESTORE F AND RETURN
;LAST BLKO POINTER RAN OUT. NEED TO ADVANCE BUFFER-RING AND SETUP BLKO
LPTNXT: PUSHJ P,IOSET## ;SETUP ACS R AND S
XCT LPTDNO(F) ;SKIP IF DONE IS UP
JRST LPTERR ;ELSE HANDLE ERROR INTERRUPT
TRNN S,IOACT ;RANDOM DONE INT?
JRST LPTSTP ;YES, STOP PRINTER
TLZE S,IOBEG ;NO BUFFER ADVANCE ON 1ST OUTPUT
JRST LPTNX1 ;YES, SETUP NEXT BLKO AND RETURN
TLZE S,LPTEND ;CLOSE DONE?
JRST LPTNX2 ;YES, OUTPUT CRFF
TLZN S,LPTSYN ;WAS CRFF JUST OUTPUT?
PUSHJ P,ADVBFE## ;NO, ADVANCE TO NEXT BUFFER
PJRST LPTSTP ;CANT ADVANCE, BUFFER UNAVAIL
PUSHJ P,SETIOD## ;ARRANGE FOR JOB TO RUN AGAIN
LPTNX1: PUSHJ P,LPTSET ;SET UP NEW BLKO POINTER
PJRST STOIOS## ;SAVE S, SET HUNG COUNT, AND JEN
LPTNX2: PUSHJ P,RTNEVM##
TLO S,LPTSYN ;REMEMBER CRFF SENT SO DON'T ADVANCE BUFFERS
PUSHJ P,LPTSTI ;SET BLKO POINTER FOR CRFF
JRST STOIOS## ;STORE S AND JEN
SUBTTL ERROR INTERRUPT ROUTINE
LPTERR: XCT LPTCNI(F) ;DO A CONI TO READ LPT STATUS
TRNE U,CI.PZR ;PAGE-ZERO?
JRST LPTPZR ;YES, HANDLE ZERO PAGE COUNTER
TRNE U,CI.VFE ;VFU ERROR?
JRST LPTVFE ;YES HANDLE VFU ERROR
TRNE U,CI.PAR ;LINE-PRINTER PARITY?
JRST LPTPAR ;YES, HANDLE PARITY ERROR
TRNE U,CI.LOV ;LINE OVERFLOW (PDP6 PRINTER)
JRST LPTLOV ;YES, DO IT
TRNE U,CI.OFL+CI.NRY ;OFF-LINE?
JRST LPTNOL ;YES, HANDLE IT
;HERE IF ON-LINE OR VFU ERROR CLEARED
MOVSI T1,DVOFLN ;OFF-LINE BIT
TDNN T1,DEVCHR(F) ;IS THE LPT OFF-LINE?
JRST LPTRTI ;NO, MUST HAVE BEEN VFU ERROR CLEARING
ANDCAM T1,DEVCHR(F) ;CLEAR OFF-LINE BIT
PUSHJ P,PSIONL## ;TELL USER LPT IS NOW ON-LINE
JRST LPTRTI ;CLEAR INTERRUPT AND DISMISS
;HERE ON PAGE-COUNTER ZERO INTERRUPT ON LP100
LPTPZR: MOVE T2,LPTPAG(F) ;GET THE PAGE COUNTER
MOVEI T1,IOPLE% ;LOAD THE ERROR CODE
PJUMPE T2,LPTOER ;EMPTY, GIVE I/O ERROR
PUSHJ P,LPTSPC ;ELSE, SET IT
JRST LPTRTI ;CLEAR CONDITION AND RETURN
;HERE ON LINE-PRINTER PARITY ERROR ON LP100
LPTPAR: PUSHJ P,LPTSYR ;DO SYSERR REPORTING
MOVEI T1,IOPAR% ;LOAD PARITY ERROR
PJRST LPTOER ;GIVE USER ERROR AND RETURN
;HERE ON LINE-PRINTER VFU ERROR ON LP100
LPTVFE: TRNN U,CI.NLD ;LOADING THE VFU?
JRST LPTRTI ;YES, IGNORE VFU ERROR
PUSHJ P,LPTSYR ;TELL SYSERR
PUSHJ P,LPTNOL
MOVEI T1,IOVFE% ;VFU ERROR
JRST LPTOER ;TELL THE USER ABOUT IT
;HERE TO HANDLE LINE-OVERFLOW INTERRUPT ON PDP6 PRINTER
LPTLOV: MOVN U,[EXP 1000001] ;DECREMENT BLKO POINTER
ADDM U,LPTPTR(F) ;BACKUP THE POINTER
MOVEI U,[EXP 15B6+12B13] ;LOAD A CRLF
XCT LPTDTO(F) ;AND PRINT IT
POPJ P, ;RETURN
;HERE WHEN LINE PRINTER IS OFF-LINE
LPTNOL: TRNN S,IOACT ;OFF-LINE WHILE PRINTING
JRST LPTSTP ;NO, CATCH IT LATER
MOVSI T1,DVOFLN ;MARK LPT OFF-LINE
IORM T1,DEVCHR(F) ;FOR ON-LINE INTERRUPT
TLO S,LPTOPB ;INDICATE TROUBLE NOTICED ON INTERRUPT
PUSHJ P,LPTSTP ;TURN OFF LPT, CLEAR IOACT
JRST DEVERR## ;CAUSE UUOCON TO RETRY ON UUO LEVEL
SUBTTL SETUP NEXT BLKO POINTER
LPTSET: MOVEI T1,@DEVOAD(F) ;GET ABS. ADDR. OF CURRENT BUFFER
MOVN T2,1(T1) ;GET NEGATIVE WORD COUNT
HRL T1,T2 ;COMBINE NEG. WORD COUNT AND ADDR.
TLZN S,LPTOPB ;TROUBLE ON LAST IO?
AOJA T1,LPTS1 ;NO
SKIPL T2,LPTPTR(F) ;YES PARTIAL BUFFER LEFT?
JRST [TLNE S,IOBEG!LPTSYN ;NO, TROUBLE ON FREE FORM FEED
AOJA T1,LPTS1 ;YES, PROCEED WITH USERS BUFFER
PUSHJ P,ADVBFE## ;GET NEXT SINCE WE REALLY FINSHED LAST ONE
JRST LPTSTP ;WAS THE LAST, SHUT DOWN THE PRINTER
JRST LPTSET] ;SET UP FOR NEW BUFFER
HRRI T2,-1 ;YES. SET RH(T2) FOR SUB
SUB T2,T1 ;LH(T2)=NO OF WORDS ALREADY OUT
HLRS T2
ADD T1,T2 ;UPDATE POINTER BY NO OF WORDS DONE
ADDI T1,1 ;+1 FOR IOWD TO FORM
LPTS1: MOVEM T1,LPTPTR(F) ; LPTPTR:= -(WORD COUNT),(BUFF. ADDR. +1)
POPJ P, ; AND RETURN
;HERE TO SETUP BLKO POINTER FOR CRFF ON OPEN AND CLOSE
; SETS BLKO POINTER FOR CRFF UNLESS THE USER HAS REQUESTED
; SUPPRESSION. SETS LPTDAB SINCE NEXT BLKO WILL NOT PROCESS
; "CURRENT" BUFFER.
LPTSTI: SETZM LPTPTR(F) ;CLEAR THE POINTER
HRROI T1,LPCRFF-1 ;MAKE BLKO POINTER TO CRFF
TRNN S,LPTNFF ;DOES HE WANT THEM?
MOVEM T1,LPTPTR(F) ;YES, GIVE THEM TO HIM
POPJ P, ;AND RETURN
LPCRFF: BYTE (7) 15,14,0 ;<CR><FF>
SUBTTL DEVOP UUO INTERFACE
;HERE ON DISPATCH FROM UUOCON
; F=DDB
; T1=FUNCTION
LPTDVP: MOVSI T2,-LPTDVL ;GET TABLE LENGTH SETUP AOBJN PTR
LPTDV1: HLRZ T3,LPTDVT(T2) ;GET THE FUNCTION CODE
HRRZ T4,LPTDVT(T2) ;GET THE DISPATCH ADDRESS
CAMN T1,T3 ;DO CODES MATCH?
JRST (T4) ;YES, DISPATCH
AOBJN T2,LPTDV1 ;NO, LOOP
PJRST ECOD2## ;NO MATCH, GIVE AN ERROR
LPTDVT: XWD 1,DVLLV ;LOAD HARDWARE VFU
XWD 2,DVENV ;ENABLE PROGRAM VFU LOAD
XWD 3,DVDEV ;DISABLE PROGRAM VFU LOAD
XWD 1000,DVPC ;READ PAGE COUNTER
XWD 2000,DVPC ;SET PAGE COUNTER
XWD 1004,DVDCS ;READ DEVICE STATUS
XWD 1005,DVFRMR ;READ FORMS TYPE
XWD 2005,DVFRMS ;SET FORMS TYPE
LPTDVL==.-LPTDVT ;DISPATCH TABLE LENGTH
;ROUTINE TO LOAD STANDARD HARDWARE VFU
DVLLV: PUSHJ P,LPTSCO ;SETUP FOR CONO
TRO U,CO.LSV ;SET
JRST DVLLV1 ;ENTER COMMON CODE
;DISABLE PROGRAM LOADING OF VFU
DVDEV: PUSHJ P,LPTSCO
TRO U,CO.NLD
JRST DVLLV1
;ENABLE FOR PROGRAM LOADING OF VFU
DVENV: PUSHJ P,LPTSCO
TRZ U,CO.NLD ;SET
DVLLV1: LDB T2,[POINT 2,U,1] ;GET VFU TYPE
CAIE T2,VFUDA
PJRST ECOD5##
XCT LPTCNO(F) ;OK
PJRST CPOPJ1## ;SKIP RETURN
;HERE TO READ OR SET THE PAGE COUNTER
DVPC: MOVE T3,DEVHCW(F) ;GET CHARACTERISTICS
TLNN T3,(HC.PGC) ;DEVICE HAVE PAGE COUNTER?
PJRST ECOD11## ;NO, ERROR
TRNE T1,1000 ;READ?
JRST DVPC1 ;YES
PUSHJ P,GETWR1## ;NO, SET T1=PAGE ARG
PJRST RTM1## ;ERROR
SETOM LPTPAG(F) ;ASSUME -1
JUMPE T1,CPOPJ1## ;RETURN
MOVEM T1,LPTPAG(F) ;STORE NEW PAGE COUNTER WORD
PUSHJ P,LPTSPC ;SET PAGE COUNTER
JRST CPOPJ1##
DVPC1: SKIPGE LPTPAG(F) ;ATTEMPT TO READ WHEN
PJRST ECOD10## ; NOT SET
XCT LPTCNI(F) ;GET STATUS
LDB T1,[POINT 12,U,17] ;ISOLATE PAGE COUNTER
ADD T1,LPTPAG(F) ;ADD IN REMAINING AMOUNT
PJRST STOTC1## ;RETURN WITH PAGE COUNT IN T1
;HERE TO READ LPT STATUS
DVDCS: MOVEI T1,0 ;INITIALIZE
PUSHJ P,LPTONL ;READ STATUS/CHECK OFFLINE
TLO T1,(DV.OFL) ;OFF LINE
TRNE U,CI.VFE ;VFU ERROR?
TRO T1,DV.VFE ;YES
TRNN U,CI.NLD ;CAN PROGRAM LOAD THE VFU?
TRO T1,DV.VLE ;YES
PJRST STOTC1## ;STORE STATUS/GOOD RETURN
;HERE TO READ/SET FORMS TYPE NAME
DVFRMR: MOVE T1,LPTFRM(F) ;GET FORMS NAME
JRST STOTC1## ;RETURN IT TO THE USER
DVFRMS: PUSHJ P,GETWR1## ;FETCH USER'S ARGUMENT
JRST RTM1## ;ADDRESS CHECK ERROR
MOVEM T1,LPTFRM(F) ;SET IT
JRST CPOPJ1## ;RETURN SUCCESS
SUBTTL VARIOUS UTILITY ROUTINES
;SUBROUTINE TO SET THE HARDWARE PAGE COUNTER
; IF SOFTWARE PAGE COUNTER WORD (SPCW) IS .EQ. 0, JUST RETURN
; ELSE SET HARDWARE PAGE COUNTER TO MAX(SPCW,7777) I IF THE
; SPCW IS NOT-NEGATIVE, DECREMENT IT BY THE AMOUNT SET.
LPTSPC: SKIPN LPTPAG(F) ;IS THERE ANYTHING TO SET?
POPJ P, ;NO, JUST RETURN
PUSHJ P,LPTSCO ;SETUP FOR CONO
TRO U,CO.SPC ;SET THE FLAG
XCT LPTCNO(F) ;DO THE CONO
SKIPL U,LPTPAG(F) ;GET THE SPCW
CAILE U,7777 ;WITHIN RANGE OF HARDWARE?
MOVEI U,7777 ;NO, PUT WITHIN RANGE
XCT LPTDTO(F) ;SET THE PAGE COUNTER
MOVNS U ;NEGATE THE AC
SKIPL LPTPAG(F) ;DONT DECREMENT IF NOT SET
ADDM U,LPTPAG(F) ;DECREMENT THE SPCW
POPJ P, ;AND RETURN
;SUBROUTINE TO SETUP TO DO A CONO
; DOES A CONI, PRESERVES BUSY, DONE, PIA, PIB, FEATURES ENABLE,
; AND VFU-NOLOAD. RETURNS WORD IN U.
LPTSCO: XCT LPTCNI(F) ;DO THE CONI
TRZ U,-1-CI.BSY-CI.DON-CI.NLD-CI.PIA-CI.PIB
IORI U,CO.FEN ;PRESERVE FEA-EN AND NOLOAD
POPJ P, ;AND RETURN
;SUBROUTINE TO SEE IF THE LPT IS ON LINE
LPTONL: XCT LPTCNI(F) ;GET THE CONI WORD
JUMPE U,[PIOFF ;NO CONI BITS, TURN OFF PI
MOVEI U,1 ;"FAKE" PI CHANNEL
XCT LPTCNO(F) ;GIVE IT ONE (1)
XCT LPTCSZ(F) ;SEE IF SOMETHING TOOK IT
AOS (P) ;ITS THERE AND ON-LINE
SETZ U, ;CLEAR PI ASSIGNMENT
XCT LPTCNO(F) ;ZAP
JRST ONPOPD##] ;RESTORE PI SYS AND RETURN
TRNE U,CI.NRY!CI.OFL!CI.BSY ;IS IT OFF-LINE?
POPJ P,
TLNE U,(CI.FEN)
TRNE U,CI.NLD
TRNN U,CI.VFE
AOS (P) ;SKIP IF NOT "OFF"
POPJ P, ;EITHER OFF-LINE OR OFF
;HERE TO GIVE THE USER AN I/O ERROR AND DISMISS THE INTERRUPT
; ERROR CODE IN T1.
LPTOER: DPB T1,PDVESE## ;STORE THE ERROR CODE
PUSHJ P,RTNEVM## ;RETURN ANY EVM
TRO S,740000 ;SET ALL ERROR FLAGS IN S
;FALL INTO DISMISS ROUTINE
;HERE TO STOP THE LPT AND START THE USER.
LPTSTP: PUSHJ P,LPTSCO ;SETUP TO DO CONO
TLNN U,(CI.FEN) ;DID FEATURES ENABLED SET?
JRST LPTOFF ;NO, OLD LPT
HRLI U,CI%SKP-CI.OFL ;CONSO MASK FOR PRINT WHEN OFF
TRO U,CO%OFF ;SET TO TURN LPT OFF
TRZA U,CI.DON+CI.NRY+CI.CHR
LPTOFF: MOVEI U,0 ;CONO LPT, 0, NO CONSO MASK
XCT LPTCNO(F) ;TURN LPT OFF
HLRM U,@LPTCSO(F) ;SET CONSO MASK
TRZE S,IOACT ;CLEAR IOACT
PUSHJ P,SETIOD## ;START UP THE USER
PJRST STOIOS## ;STORE S AND RETURN
;HERE TO CLEAR ALL INTERRUPT CONDITIONS AND DISMISS THE INTERRUPT
LPTRTI: PUSHJ P,LPTSCO ;SETUP THE CONO WORD
TRO U,CO%OFF ;CLEAR THE CONDITIONS
XCT LPTCNO(F) ;DO THE CONO
PJRST STOIOS## ;STORE S AND RETURN
;HERE TO DO DAEMON ERROR REPORTING FOR SYSERR
LPTSYR: LDB J,PJOBN## ;GET JOB NUMBER FROM DDB
MOVE T1,JBTPPN##(J) ;GET PPN OF USER
MOVEM T1,LPTDAE+.LEPPN(F) ;SAVE IN ERROR REPORTING BLOCK
MOVE T1,JBTNAM##(J) ;GET NAME OF RUNNING JOB
MOVEM T1,LPTDAE+.LEPGM(F) ;SAVE IN ERROR REPORTING BLOCK
XCT LPTCNI(F) ;GET THE CONI
MOVEM U,LPTDAE+.LECNI(F) ;SAVE IT
HRRZ T1,LPTPTR(F) ;GET BLKO POINTER
MOVE T1,(T1) ;GET THE DATA WORD
MOVEM T1,LPTDAE+.LEDAT(F) ;SAVE IT
MOVEI T1,.ERHCC ;LOAD SYSERR TYPE
HRLI T1,LPTDAP(F) ;POINTER TO AOBJN POINTER
PJRST DAEERR## ;CALL DAEMON
;HERE TO SETUP HARDWARE CHARACTERISTICS WORD AND DETERMINE CONTROLLER TYPE
LPTTYP: PUSHJ P,LPTSCO ;SETUP UP CONO WORD
XCT LPTCNO(F) ;DO THE CONO
XCT LPTCNI(F) ;DO A CONI
SETZ T1, ;ASSUME UPPER CASE PRINTER
LDB T2,[POINTR (U,CI.CHR)] ;GET CHARACTER SET TYPE
MOVSI T3,DVLPTL ;GET LOWER CASE PRINTER BIT
TLNE U,(CI.FEN) ;FEATURES ENABLED (LPT100)?
CAIG T2,CHR64 ;AND AN LOWER CASE PRINTER?
TDNE T3,DEVCHR(F) ;A LOWER CASE PRINTER?
MOVSI T1,(HC.LCP) ;YES, NOTE THAT
DPB T2,[POINTR (T1,HC.CST)] ;STORE CHARACTER SET TYPE
LDB T2,[POINTR (U,CI.VFU)] ;VFU TYPE
DPB T2,[POINTR (T1,HC.VFT)] ;BA10/LP100 CODES MATCH HC.VFT CODES
ANDCAM T3,DEVCHR(F) ;ASSUME AN UPPER CASE PRINTER
TLNE T1,(HC.LCP) ;LOWER CASE PRINTER?
IORM T3,DEVCHR(F) ;PROPAGATE BIT FOR UUOCON
MOVEI T2,.HCTBX ;ASSUME A BA10
TLNN U,(CI.FEN) ;LP100?
JRST LPTTY1 ;BA10
TLO T1,(HC.PGC) ;LP100 HAS A HARDWARE PAGE COUNTER
MOVEI T2,.HCTLC ;INDICATE LP100
LPTTY1: TLO T1,(<.HCULP>B14) ;LP05 CLASS PRINTER
HLLM T1,DEVHCW(F) ;STORE HARDWARE CHARACTERISTICS
DPB T2,[POINT 3,DEVHCW(F),11] ;STORE CONTROLLER TYPE IN DEVHCW
DPB T2,[POINT 6,LPTDAE+.LETYP(F),5] ;AND CONTROLLER TYPE
POPJ P, ;RETURN
$LIT
END