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,) .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,) ;DEVSER SETWRD (DEVMOD,>) ;DEVMOD SETWRD (DEVTYP,<<.TYLPT*.TYEST>!.SPLPT!DEPLEN,,0>) ;DEVTYP SETWRD (DEVCPU,) ;DEVCPU SETWRD (LPTCHF,<+LPTCHN##>) ;PI CHANNEL FLAGS (ERR+INT) SETWRD (LPTDNO,) ;SKIP IF ERROR SETWRD (LPTDNZ,) ;SKIP IF ERROR SETWRD (LPTCSZ,) ;LINE CONTROL SETWRD (LPTCNI,) ;CONI SETWRD (LPTCNO,) ;CONO SETWRD (LPTDTO,) ;DATAO SETWRD (LPTBKO,) ;BLKO SETWRD (LPTSTS,) ;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,) EQUATE (LOCAL,0,) LPXDSP: DRVDSP (LPT,LPTCHN##,LPTDDB,LPTLEN,URDDIA##) ;DEFAULT MONGEN'ED DEVICE TABLE DEFMDT: MDKL10 (7,124,0,0,) ;DEVICE CODE 124 MDKL10 (7,234,0,0,) ;DEVICE CODE 234 MDKL10 (7,230,0,0,) ;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,- ;-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 ; 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