1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-03-01 17:26:38 +00:00
Files
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

735 lines
24 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TITLE DLPSER - LINEPRINTER SERVICE FOR MULTIPLE RSX-20F LINEPRINTERS - V040
SUBTTL A. WILSON 23-AUG-88
SEARCH F,S,DEVPRM,DTEPRM
$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
; 1977,1978,1979,1980,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.
.CPYRT<1977,1988>
XP VDLPSR,040 ;DEFINE GLOBAL VERSION NUMBER FOR LOADER MAP
PRMMIN==063 ;DTEPRM MUST BE AT LEAST THIS RECENT
IFL VDTPRM-PRMMIN,<PRINTX ?PLEASE USE LATEST VERSION OF DTEPRM
PASS2
END>
DLPSER::ENTRY DLPSER
SUBTTL SYMBOL DEFINITIONS
;DEVICE DEPENDENT BITS IN LH OF DEVIOS
DLPSYN==Z(1B11) ;CRFF AFTER CLOSE HAS BEEN SENT
DLPEND==Z(1B10) ;CLOSE UUO HAS BEEN DONE
DLPOPB==Z(1B9) ;PARTIAL BUFFER ALREADY OUTPUT
;DEVICE DEPENDENT BITS IN RH OF DEVIOS
DLPNFF==100 ;SUPPRESS FREE CRFF
;LPT SPECIFIC STATUS BITS FROM RSX-20F
DL.PGZ==1B35 ;PAGE COUNTER PASSED ZERO
DL.RCI==1B34 ;CHARACTER INTERRUPT (FROM RAM)
DL.VFE==1B33 ;VFU ERROR--PAPER REALIGNMENT REQUIRED
DL.LER==1B32 ;ERROR FINDING/READING VFU/RAM FILE
DL.OVF==1B31 ;PRINTER HAS OPTICAL (NOT DA) VFU
DL.RPE==1B30 ;RAM PARITY ERROR--RELOAD REQUIRED
SUBTTL AUTOCONFIGURE
;DRIVER CHARARCTERISTICS
; DLP = DLPCNF
; 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 (DLP,LPT,7,0,0,0,MDSEC0,MDSEC0,<DR.GCC!DR.NET>)
.ORG DEVLSD
DLPDUX:! BLOCK 1 ;UNIT # ON FRONT-END,,DTE INDEX
DLPCDN:! BLOCK 1 ;CPU,,DTE NUMBERS
DLPMLA:! BLOCK 1 ;MAXIMUM LINE ALLOCATION
DLPRLA:! BLOCK 1 ;REMAINING LINE ALLOCATION
DLPSNT:! BLOCK 1 ;NUMBER OF WORDS ALREADY SENT
DLPFRM:! BLOCK 1 ;FORMS TYPE NAME (SIXBIT)
DLPLEN:! ;LENGTH OF DTE PRINTER DDB
.ORG
$LOW
DLPDDB: DDBBEG (DLP,DLPLEN)
SETWRD (DEVCHR,<6*HUNGST+DVLPTL,,LPTSIZ##>) ;DEVCHR
SETWRD (DEVSER,<MCSEC0+RLPDSP>) ;DEVSER
SETWRD (DEVMOD,<DVOUT!DVLPT,,<1_A+1_AL+1_BYTMOD+1_I>>) ;DEVMOD
SETWRD (DEVTYP,<<.TYLPT*.TYEST>!.SPLPT!DEPLEN,,0>) ;DEVTYP
DDBEND
$HIGH
EQUATE (LOCAL,0,<DLPCKT,DLPICD,DLPICL,DLPINT,DLPKDB,DLPKLN,DLPUDB,DLPULN>)
EQUATE (LOCAL,0,<DLPULB,DLPULP>)
DLPDSX: DRVDSP (DLP,0,DLPDDB,DLPLEN,URDDIA##)
;DEFAULT MONGEN'ED DEVICE TABLE
DEFMDT: MDKL10 (7,200,0,0,<MD.KON>) ;DEVICE CODE 200
MDKL10 (7,204,0,0,<MD.KON>) ;DEVICE CODE 204
MDKL10 (7,210,0,0,<MD.KON>) ;DEVICE CODE 210
MDKL10 (7,214,0,0,<MD.KON>) ;DEVICE CODE 214
MDTERM
;BITS FOR MDT ENTRIES ARE ASSIGNED HERE
LPT.UC==:1 ;UPPER-CASE ONLY PRINTER
DLPCFG: XMOVEI T1,DLPMDT## ;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
MOVE T1,.CPCPN## ;OUR CPU NUMBER
HRRZ F,DTEMAS##(T1) ;FETCH MASTER DTE
LDB T1,[POINT 7,ETDCNI(F),9] ;GET DTE NUMBER
HRRZ T2,.CPDVC## ;AND DEVICE BEING CONFIGURED
CAIE T1,(T2) ;DOING THE MASTER DTE?
JRST CPOPJ1## ;NO
MOVSI T1,(ED.PPC) ;BIT TO TEST
TDNE T1,ETDSTS(F) ;PRIMARY PROTOCOL RUNNING?
PJRST DLPRDS ;YES--CAN REQUEST DEVICE STATUS DIRECTLY
XMOVEI T1,DLPRDS ;ROUTINE TO REQUEST DEVICE STATUS
MOVEI T2,1 ;WAIT FOR PRIMARY PROTOCOL TO START
PUSHJ P,AUTCLK## ;QUEUE UP A CLOCK REQUEST
JRST CPOPJ1## ;MAYBE OTHER DTE-BASED DEVICES EXIST
;HERE WHILE PRIMARY PROTOCOL IS RUNNING TO REQUEST DEVICE STATUS
DLPRDS: PUSHJ P,SAVE4## ;SAVE SOME ACS
MOVE T1,.CPCPN## ;OUR CPU NUMBER
HRRZ F,DTEMAS##(T1) ;FETCH MASTER DTE
LOAD. P1,ED.DTN,(F) ;GET MASTER DTE NUMBER
HRL P1,.CPCPN## ;INCLUDE OUR CPU NUMBER
MOVE P2,[.EMLPT,,.EMRDS] ;FE DEVICE CODE,,FUNCTION CODE
SETZ P3, ;START WITH UNIT ZERO
DLPRD1: HRRI P3,2 ;TWO BYTES
MOVE P4,[POINT 8,P3,9] ;BYTE POINTER TO UNIT NUMBER
SETZ S, ;NO POST ADDRESS
S0PSHJ DTEQUE## ;QUEUE UP REQUEST FOR DEVICE STATUS
JFCL ;SHOULDN'T FAIL
AOBJN P3,.+1 ;ADVANCE UNIT NUMBER
TLNN P3,-1-DLPMAX##+1 ;OVERFLOW?
JRST DLPRD1 ;LOOP BACK FOR MORE
JRST CPOPJ1## ;MAYBE OTHER DTE-BASED DEVICES EXIST
;HERE WHILE PROCESSING A DEVICE STATUS MESSAGE FOR A PREVIOUSLY
;UNKNOWN DTE-BASED DEVICE TO ACTUALLY BUILD THE DTE DEVICE DATA BASE
;P1 - P4 SETUP WITH DEVICE STATUS MESSAGE POINTERS
DLPDTS: SE1ENT ;ENTER SECTION ONE
PUSHJ P,AUTLOK## ;INTERLOCK THE DATA BASE
JRST [PUSHJ P,DLPRDS ;BUSY & INTERRUPT LEVEL--TRY AGAIN LATER
JFCL ;WILL MOST LIKELY SKIP
POPJ P,] ;CALL THIS A FAILURE
PUSH P,F ;SAVE DDB ADDRESS OR ZERO
MOVE T1,.CPCPN## ;OUR CPU NUMBER
HRRZ F,DTEMAS##(T1) ;AND THE MASTER ETD FOR THIS CPU
LDB T1,[POINT 7,ETDCNI(F),9] ;DEVICE CODE
XMOVEI T2,DLPDSX ;DRIVER DISPATCH
SETZ T3, ;NO CHANNEL
PUSHJ P,AUTSET## ;SET UP AUTCON CALLS
POP P,F ;GET FLAG BACK
JUMPN F,DLPDT1 ;JUMP IF A KNOWN DEVICE
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 [PUSHJ P,AUTULK## ;NO CORE
PJRST AUTDDN##] ;DEALLOCATE DEVICE NUMBER
DLPDT1: MOVEM P1,DLPCDN(F) ;SAVE CPU,,DTE NUMBER
HRLM P3,DLPDUX(F) ;SAVE FE UNIT (LINE) NUMBER
HRRM P1,DLPDUX(F) ;SAVE DTE NUMBER (HISTORICAL)
XMOVEI T1,DLPMDT## ;POINT TO MONGEN'ED DEVICE TABLE
XMOVEI T2,DEFMDT ;GET DEVICE CODES FROM THE DEFAULT TABLE
HRLO T3,P3 ;USE FE UNIT FOR UNIT NUMBER
SETZ T4, ;IGNORE FLAGS
PUSHJ P,AUTMDT## ;SEE IF WE HAVE DATA
JRST DLPDT2 ;THERE IS NONE
MOVSI T2,DVLPTL ;GET LOWER-CASE PRINTER BIT
TRNE T1,LPT.UC ;IF UPPER-CASE ONLY PRINTER
ANDCAM T2,DEVCHR(F) ;THEN CLEAR THE LOWER-CASE BIT
;ADD FUTURE MDT VALUE TESTS HERE
DLPDT2: PUSHJ P,AUTULK## ;RELEASE INTERLOCK
JRST CPOPJ1## ;RETURN
SUBTTL DISPATCH TABLES
;UUOCON DISPATCH TABLE FOR RSX-20F LINEPRINTER(S)
JRST DLPONL ;SEE IF LPT ON-LINE NOW
JRST DLPDVP ;DEVOP. UUO
JRST REGSIZ## ;GET BUFFER SIZE FROM DDB
JRST DLPINI ;INITIALIZATION
JRST DLPHNG ;HUNG DEVICE ERROR
RLPDSP::JRST DLPREL ;RELEASE
JRST DLPCLS ;CLOSE
JRST DLPOUT ;OUT/OUTPUT
JRST ILLINP## ;IN/INPUT
;DTESER DISPATCH TABLE FOR LPT
IFIW CPOPJ## ;(-1) LOST TO-10 INDIRECT MESSAGE
DLPDSP::DTEFNC ;(??) GENERATE DUMMY TABLE ENTRIES
DTEFNC (HDS,DLPTKS) ;(07) TAKE DEVICE STATUS
DTEFNC (ACK,DLPACK) ;(17) ACK
DTEFNC (HLA,DLPHLA) ;(23) LINE ALLOCATIONS
DTEFNC (AKA,DLPAAL) ;(25) ACK ALL
SUBTTL MONITOR-LOAD DEVICE INITIALIZATION
;DLPINI IS CALLED AT SYSTEM INITIALIZATION TIME FROM IOGO IN SYSINI WITH
; THE DDB ADDRESS IN F. DLPINI FORCES IOGO TO INVOKE DLPINI FOR EACH RSX-20F
; LINEPRINTER 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 DLPINI IS DEPENDENT ON THE IOGO CODE WHICH SHOULD BE:
;
; PUSHJ P,DINI(P3)
; HRRZM P3,SAVITM
DLPINI: PUSHJ P,DLPREL ;GO THROUGH RELEASE CODE
PJRST CPOPJ1## ;SKIP RETURN TO FORCE CALL FOR EACH LPT
SUBTTL OUT/OUTPUT UUO
;HERE FROM UUOCON ON OUT OR OUTPUT UUO
DLPOUT: TLO S,IO ;INDICATE OUTPUT
PUSHJ P,DLPOFL ;IF TROUBLE, GET IT FIXED
TLZE S,IOBEG ;FIRST OUTPUT?
PUSHJ P,DLPSFF ;YES, SEE ABOUT SENDING FREE CRFF
JFCL
TLZE S,DLPOPB ;PARTIAL BUFFER ALREADY OUTPUT?
DLPOU0: JRST [SKIPLE DEVCTR(F) ;YES, BUT WERE WE DONE WITH IT
JRST DLPOU1 ;NO, MORE TO PRINT
PUSHJ P,ADVBFE## ;GET NEXT BUFFER HERE
PJRST DLPSTP ;NO MORE, SHUT DOWN PRINTER
JRST .+1] ;RETURN INLINE FOR NEW BUFFER
MOVE T1,DEVOAD(F) ;PICK UP BUFFER ADDRESS
HRRZ T1,1(T1) ;PICK UP WORD COUNT
MOVEM T1,DEVCTR(F) ;SET DEVCTR UP WITH WORD COUNT
SETZM DLPSNT(F) ;NO DATA FROM THIS BUFFER YET
JUMPE T1,DLPOU0 ;GET NEXT IF NO DATA
DLPOU1: PUSHJ P,DLPSND ;START DATA TRANSFER
PJRST SETACT## ;SET IOACT, STORE S, SET HUNG COUNT, RETURN
;HERE DURING OUTPUT UUO TO SEE IF LPT ON-LINE
;ARGS: F/DDB ADDRESS
; S/DEVIOS WORD FROM DDB
;CALL: PUSHJ P,DLPOFL
; RETURN HERE WHEN ON-LINE (BOTHERING USER IF NECESSARY TO GET IT ON-LINE)
DLPOFL: PUSHJ P,DLPONL ;SEE IF LPT ON-LINE
JRST DLPOF1 ;IT'S NOT--TELL THE USER
POPJ P, ;IT IS--RETURN
DLPOF1: MOVEM S,DEVIOS(F) ;SAVE S
MOVSI T1,DEPADV
IORM T1,DEVADV(F) ;LEAVE BUFFERS ALONE
MOVSI T1,DVOFLN
IORM T1,DEVCHR(F) ;MARK DDB OFF-LINE
PUSHJ P,HNGSTP## ;HALT JOB AND COMPLAIN
MOVSI T1,DEPADV
ANDCAM T1,DEVADV(F) ;CLEAR BIT ON RETRY
JRST DLPOFL ;TRY AGAIN
;ROUTINE TO SEE IF LPT ON-LINE
;ARGS: F/DDB ADDRESS
;CALL: PUSHJ P,DLPONL
; RETURN HERE IF OFF-LINE
; RETURN HERE IF ON-LINE
DLPONL: MOVEI T1,EM.OFL+EM.NXD ;GET RSX-20F OFF-LINE BITS
TDNN T1,DEVSTS(F) ;OFF-LINE?
AOS (P) ;NO--SKIP RETURN FOR ON-LINE
POPJ P, ;YES--NON-SKIP RETURN
;HERE TO SEND INITIAL/FINAL CRFF IF NECESSARY
;ARGS: F/DDB ADDRESS
; S/DEVIOS WORD FROM DDB
;CALL: PUSHJ P,DLPSFF
; RETURN HERE IF CRFF NOT SENT
; RETURN HERE IF SENT
DLPSFF: TRNE S,DLPNFF ;NEED TO SEND CRFF?
POPJ P, ;NO--NON-SKIP RETURN
PUSHJ P,SAVE4## ;SAVE P1-P4
MOVE P4,[POINT 7,LPCRFF] ;POINT TO CRFF
MOVEI T1,1 ;ONLY 1 WORD
PUSHJ P,DLPSOU ;SEND THIS STRING
PJRST CPOPJ1## ;SKIP RETURN
LPCRFF: BYTE (7) 15,14,0 ;CR,FF,0
SUBTTL CLOSE AND RELEASE UUO'S
;HERE FROM UUOCON ON CLOSE UUO
DLPCLS: TLO S,DLPEND ;SET "CLOSE DONE"
TLZ S,DLPOPB+DLPSYN ;CLEAR TROUBLE AND SYNC BITS
MOVEM S,DEVIOS(F) ;STORE S
JRST OUT## ;TAKE CARE OF LAST BUFFER
;HERE FROM UUOCON ON RELEASE UUO
;SET UP SOME REASONABLE DEFAULTS FOR LP20-BASED LPT'S
;VARIABLE RAM, LP20/LP05, DAVFU
DLPHCW==INSVL.(.HCT20,HC.TYP)!INSVL.(.HCVTD,HC.VFT)!
INSVL.(.HCCVR,HC.CST)!INSVL.(.HCULP,HC.TYU)
DLPHNG: ;HUNG DEVICE IS SAME AS RELEASE
DLPREL: MOVSI T1,(DLPHCW) ;GET INITIAL HCW WORD
MOVSI T2,DVLPTL ;LPT LOWERCASE BIT
TDNE T2,DEVCHR(F) ;IF SET,
TLO T1,(HC.LCP) ;THEN PROPAGATE TO HCW BITS
MOVSI T2,DL.OVF ;BIT FOR OPTICAL VFU
TDNE T2,DEVSTS(F) ;DID -20F SET IT?
TLC T1,(INSVL.(.HCVTD^!.HCVTO,HC.VFT)) ;YES--CHANGE TO OPTICAL
HLLM T1,DEVHCW(F) ;SET FOR PRYING EYES
MOVSI T1,DEPADV ;GET "DON'T ADVANCE BUFFER" BIT
ANDCAM T1,DEVADV(F) ;TURN IT OFF IN DDB
TLZ S,DLPOPB ;CLEAR PARTIAL BUFFER BIT
PJRST DLPSTP ;CLEAR ACTIVE I/O
SUBTTL ACK MESSAGE ("OUTPUT DONE") PROCESSING
;HERE FROM DTESER ON ACK FOR LPT
DLPACK: SUBI P3,2 ;ACCOUNT FOR TWO BYTES/ARGUMENT
JUMPL P3,CPOPJ## ;RETURN WHEN ARGUMENT COUNT EXHAUSTED
ILDB T3,P4 ;GET UNIT NUMBER
IBP P4 ;MOVE PAST UNUSED BYTE
PUSHJ P,FNDDLP ;FIND CORRECT DLP DDB
PUSHJ P,DLPDON ;TREAT THIS AS DONE INTERRUPT
JRST DLPACK ;LOOP FOR MORE ARGUMENTS
;HERE FROM DTESER ON ACK ALL FOR LPT
DLPAAL: SKIPE F,DDBTAB##+.TYLPT ;POINT TO FIRST LPT IN SYSTEM
DLPAA1: HLRZ F,DEVSER(F) ;LINK TO NEXT
JUMPE F,CPOPJ## ;RETURN IF RUN OUT OF DDBS
LDB T1,PDVTYP## ;GET DEVICE TYPE
CAIE T1,.TYLPT ;CHECKED ALL LPTS?
POPJ P, ;ALL DONE
HRRZ T1,DEVSER(F) ;GET DISPATCH
CAIE T1,RLPDSP ;OWNED BY US?
JRST DLPAA1 ;TRY ANOTHER
CAMN P1,DLPCDN(F) ;CPU#,,DTE# MATCH?
PUSHJ P,DLPDON ;YES--TREAT THIS AS DONE INTERRUPT
JRST DLPAA1 ;GO CHECK OUT THE NEXT LPT
SUBTTL HERE ARE LINE ALLOCATIONS PROCESSING
;HERE FROM DTESER ON HERE ARE LINE ALLOCATIONS FOR LPT
DLPHLA: SUBI P3,2 ;ACCOUNT FOR TWO BYTES/ARGUMENT
JUMPL P3,CPOPJ## ;RETURN WHEN ARGUMENT COUNT EXHAUSTED
ILDB T2,P4 ;GET ALLOCATION
ILDB T3,P4 ;GET LINE NUMBER
PUSHJ P,FNDDLP ;FIND SPECIFIED DDB
MOVEM T2,DLPMLA(F) ;SAVE LINE ALLOCATION
JRST DLPHLA ;LOOP FOR MORE
SUBTTL OUTPUT DONE PROCESSING
;HERE IF RSX-20F ACKNOWLEDGED AN ACTIVE LINEPRINTER
;ARGS: F/DDB ADDRESS
; S/LPT STATUS WORD (DDB DEVIOS)
;CALL: PUSHJ P,DLPDON
; RETURN HERE
DLPDON: PUSHJ P,IOSET## ;SET UP THE REST OF THE REGS
MOVE T1,DLPMLA(F) ;PICK UP MAX ALLOCATION
MOVEM T1,DLPRLA(F) ;THIS IS CURRENT ALLOCATION
TRNN S,IOACT ;OUTPUT ACTIVE?
POPJ P, ;NO, RETURN
SKIPLE DEVCTR(F) ;OUTPUT REMAINING FROM PREVIOUS BUFFER?
JRST DLPDN1 ;YES--WORK ON THAT BUFFER SOME MORE
TLZE S,DLPEND ;CLOSE DONE?
JRST DLPDN2 ;YES--SEE ABOUT FINAL CRFF
TLZN S,DLPSYN ;NO--CRFF JUST OUTPUT?
DLPDN0: PUSHJ P,ADVBFE## ;NO--ADVANCE TO NEXT BUFFER
PJRST DLPSTP ;CAN'T--SHUT DOWN LPT
PUSHJ P,SETIOD## ;ARRANGE FOR JOB TO RUN AGAIN
MOVE T1,DEVOAD(F) ;PICK UP BUFFER ADDRESS
HRRZ T1,1(T1) ;PICK UP WORD COUNT
MOVEM T1,DEVCTR(F) ;SET DEVCTR UP WITH WORD COUNT
SETZM DLPSNT(F) ;NO, THIS BUFFER IS DONE
JUMPE T1,DLPDN0 ;IGNORE EMPTY BUFFERS
DLPDN1: PUSHJ P,DLPSND ;START UP NEXT OUTPUT
PJRST STOIOS## ;SAVE S, SET HUNG COUNT, RETURN
DLPDN2: PUSHJ P,DLPSFF ;SEE ABOUT SENDING CRFF
PJRST DLPSTP ;NOT SENT--SHUT DOWN LPT
TLO S,DLPSYN ;REMEMBER CRFF SENT SO DON'T ADVANCE BUFFERS
PJRST STOIOS## ;SAVE S, SET HUNG COUNT, RETURN
;HERE TO STOP LPT AND START USER
DLPSTP: TRZ S,IOACT ;CLEAR IOACT
MOVEM S,DEVIOS(F) ;SAVE DEVIOS
PUSHJ P,SETIOD## ;START UP THE USER
PJRST RTEVMO## ;RETURN ANY EVM
SUBTTL SEND LPT DATA TO FRONT-END
;HERE TO SEND OUTPUT DATA TO RSX-20F LPT FROM USER BUFFER
;ARGS: F/DDB ADDRESS
;CALL: PUSHJ P,DLPSND
; RETURN HERE
DLPSND: PUSHJ P,SAVE4## ;SAVE P1-P4
MOVE P4,DEVPTR(F) ;PICK UP DATA ADDRESS
ADDI P4,2 ;POINT TO FIRST DATA WORD
ADD P4,DLPSNT(F) ;OFFSET POINTER TO REMAINING DATA
HRLI P4,440700 ;ASSUME 7 BIT BYTES
LDB T1,PIOMOD## ;PICK UP I/O MODE
CAIN T1,BYTMOD ;REALLY BYTE MODE?
HRLI P4,441000 ;YES, 8 BIT BYTES
HRRZ T1,DEVCTR(F) ;PICK UP REMAINING WORD COUNT
PUSHJ P,DLPSOU ;SEND THIS STRING
ADDM T1,DLPSNT(F) ;ACCUMULATE WORD COUNT
MOVNS T1 ;NEED NEGATIVE OF COUNT
ADDM T1,DEVCTR(F) ;DECREMENT REMAINING COUNT
POPJ P, ;DONE
;HERE TO SEND STRING OUTPUT DATA TO RSX-20F LPT
;ARGS: F/DDB ADDRESS
; T1/WORD COUNT
; P4/BYTE POINTER
;CALL: PUSHJ P,DLPSOU
; RETURN HERE WITH WORDS SENT IN T1
DLPSOU: LDB T3,[POINT 6,P4,11] ;PICK UP BYTE SIZE
MOVEI T2,44 ;36 BITS/WORD
IDIVI T2,(T3) ;NOW GOT BYTES/WORD
MOVE T3,DLPRLA(F) ;PICK UP REMAINING ALLOCATION
IDIVI T3,(T2) ;CONVERT TO WORDS
CAMLE T1,T3 ;SMALLER THAN STRING LENGTH?
MOVE T1,T3 ;YES, USE ALLOCATION
JUMPLE T1,CPOPJ## ;RETURN IF NO ALLOCATION LEFT
MOVE P3,DLPDUX(F) ;P3 IS UNIT #,,DLP DTE INDEX
MOVE P1,DLPCDN(F) ;P1 IS CPU#,,DTE#
MOVE P2,[.EMLPT,,EM.IND+.EMSTR] ;OUTPUT INDIRECT STRING TO LPT
IMULI T2,(T1) ;GET STRING LENGTH IN BYTES
HRR P3,T2 ;PUT INTO ARG LIST
MOVNS T2 ;NEGATE
ADDM T2,DLPRLA(F) ;UPDATE REMAINING ALLOCATION
PUSH P,S ;SAVE S
PUSH P,T1 ;SAVE WORD COUNT
MOVEI S,0 ;NO POST ADDRESS
PUSHJ P,DTEQUE## ;QUEUE THE REQUEST
JFCL ;FAILED--WAIT FOR HUNG TIME-OUT OR ACK ALL
POP P,T1 ;RESTORE WORD COUNT
POP P,S ;RESTORE S
POPJ P, ;DONE
SUBTTL TAKE DEVICE STATUS FROM FRONT-END
;HERE FROM DTESER TO TAKE LPT STATUS FROM FRONT-END (DTESER ALREADY RECEIVED IT)
DLPTKS: PUSHJ P,SETRGS ;SET UP NECESSARY ACS
PJRST EATMSG## ;COULDN'T--IGNORE THIS MESSAGE
ILDB T1,P4 ;GET FIRST STATUS (GENERAL) BYTE
ILDB T2,P4 ;GET SECOND (LPT) BYTE
HRL T1,T2 ;PUT THEM TOGETHER
MOVEM T1,DEVSTS(F) ;SAVE COMBINED STATUS BITS
MOVEI T2,.HCVTO ;CODE FOR OPTICAL VFU
TLNE T1,DL.OVF ;IS IT OPTICAL TYPE
DPB T2,[POINT 3,DEVHCW(F),5] ;YES, SAVE IN CHARACTERISTICS WORD
MOVEI T2,IOPAR% ;CODE FOR RAM ERROR
TLNE T1,DL.RCI+DL.RPE ;ANY RAM PROBLEMS?
JRST DLPIOE ;YES
MOVEI T2,IOVFE% ;NO, CODE FOR VFU PROBLEM
TLNE T1,DL.VFE ;VFU PROBLEM?
JRST DLPIOE ;YES
MOVEI T2,IODER% ;CODE FOR DEVICE ERROR
TRNN T1,EM.FER ;FATAL ERROR (ALL RETRIES FAILED)
JRST DLPTK2 ;NO, GO CHECK FOR OFFLINE
DLPIOE: DPB T2,PDVESE## ;STORE THE CODE
TRO S,740000 ;SET ALL ERROR FLAGS IN S
TRO T1,EM.OFL ;DECLARE PRINTER OFF-LINE
PUSH P,S ;SAVE STATUS
PUSH P,T1 ;SAVE STATUS FOR A MOMENT
PUSHJ P,[PUSHJ P,SAVE4 ;SAVE SOME REGS
HRRI P2,.EMFLO ;FLUSH ANY REMAINING OUTPUT
HRRI P3,0 ;NO DATA
SETZB P4,S ;NO POST ROUTINE
PJRST DTEQUE##] ;SEND MESSAGE TO CFE
JFCL ;IGNORE FAILURE
POP P,T1 ;GET BACK STATUS
POP P,S ;RESTORE S
;HERE TO DEAL WITH OFF-LINE OR ON-LINE
DLPTK2: MOVE T2,DEVCHR(F) ;PICK UP OLD STATUS
MOVSI T3,DVOFLN ;OFF-LINE BIT
TRNE T1,EM.OFL!EM.NXD ;DEVICE THERE?
JRST DLPTK3 ;NO
ANDCAM T3,DEVCHR(F) ;ASSUME ON-LINE
TLNE T2,DVOFLN ;WAS IT OFF-LINE?
PUSHJ P,PSIONL## ;YES, TELL USER IT IS BACK AGAIN
PJRST EATMSG## ;DONE WITH THIS MESSAGE
DLPTK3: MOVEM S,DEVIOS(F) ;MAKE SURE ERROR BITS ARE SAVED
TRNN S,IOACT ;PRINTER ACTIVE NOW?
PJRST EATMSG## ;NO, DONE WITH THIS MESSAGE
IORM T3,DEVCHR(F) ;NOTE DEVICE OFF-LINE
TLNN T1,DL.RCI+DL.RPE+DL.VFE ;ANY ERRORS IN LPT?
TLO S,DLPOPB ;NO, INDICATE MINOR TROUBLE NOTICED
PUSHJ P,DLPSTP ;STOP LPT AND START USER
PUSHJ P,DEVERR## ;CAUSE UUOCON TO RETRY ON UUO LEVEL
PJRST EATMSG## ;DONE
SUBTTL DEVOP. UUO INTERFACE
;HERE FROM UUOCON ON DEVOP. UUO
;ARGS: F/DDB ADDRESS
; T1/FUNCTION
;CALL: PUSHJ P,DLPDVP
; RETURN HERE ON ERROR OR INVALID FUNCTION
; RETURN HERE ON SUCCESS, T1 CONTAINING ANY ARGUMENT RETURNED
DLPDVP: MOVSI T2,-DLPDVL ;MAKE AOBJN POINTER WITH TABLE LENGTH
DLPDV1: HLRZ T3,DLPDVT(T2) ;GET THE FUNCTION CODE
HRRZ T4,DLPDVT(T2) ;GET DISPATCH ADDRESS
CAMN T1,T3 ;CODES MATCH?
JRST (T4) ;YES--DISPATCH
AOBJN T2,DLPDV1 ;NO--TRY NEXT ONE
PJRST ECOD2## ;NO MATCH--ERROR
DLPDVT: 11,,DVPRAM ;LOAD LPT RAM
12,,DVPVFU ;LOAD LPT VFU
1004,,DVPSTS ;READ DEVICE STATUS
1005,,DVPFTR ;READ FORMS TYPE
2005,,DVPFTS ;SET FORMS TYPE
DLPDVL==.-DLPDVT ;DISPATCH TABLE LENGTH
;HERE TO READ LPT STATUS
DVPSTS: MOVEI T1,0 ;ZERO INITIAL STATUS
MOVE T2,DEVSTS(F) ;GET STATUS BITS SENT FROM FRONT-END
TRNE T2,EM.OFL+EM.NXD ;OFF-LINE?
TLO T1,(DV.OFL) ;YES
TLNE T2,DL.VFE ;VFU ERROR?
TRO T1,DV.VFE ;YES
PJRST STOTC1## ;STORE STATUS, SKIP RETURN
;HERE TO READ/SET FORMS TYPE NAME
DVPFTR: MOVE T1,DLPFRM(F) ;GET FORMS NAME
JRST STOTC1## ;RETURN IT TO THE USER
DVPFTS: PUSHJ P,GETWR1## ;FETCH USER'S ARGUMENT
JRST RTM1## ;ADDRESS CHECK ERROR
MOVEM T1,DLPFRM(F) ;SET FOR POSTERITY
JRST CPOPJ1## ;SUCCESS RETURN
;ROUTINE TO LOAD LPT RAM/VFU
;ARGS: F/DDB ADDRESS
; M/USER ARGUMENT AREA ADDRESS
;CALL: SAVE P1-P4
; PUSHJ P,DVPXXX WHERE XXX IS RAM OR VFU
; RETURN HERE IF UNSUCCESSFUL
; RETURN HERE IF SUCCESSFUL
DVPRAM: TDZA P2,P2 ;REMEMBER LOADING RAM
DVPVFU: MOVEI P2,1 ;REMEMBER LOADING VFU
PUSHJ P,DLPOFL ;MUST BE ON-LINE
PUSHJ P,GETWR1## ;GET RAM/VFU BYTE-COUNT ARG FROM USER
PJRST ECOD3## ;ERROR
JUMPLE T1,ECOD3## ;ERROR IF BYTE COUNT NOT GREATER THAN ZERO
MOVE P3,T1 ;REMEMBER BYTE COUNT
ADDI T1,3(P2) ;FUDGE REMAINDER
IDIVI T1,4(P2) ;MAKE T1 A WORD-COUNT
CAILE T1,^D128 ;WITHIN REASON?
PJRST ECOD3## ;NO--OUT-OF-RANGE ERROR
MOVN P1,T1 ;YES--GET -WC
HRLZS P1 ;MAKE LH OF AOBJN POINTER
PUSHJ P,GETWR1## ;GET ADDRESS OF RAM/VFU DATA BLOCK
PJRST RTM1## ;COULDN'T--GIVE ADDRESS-ERROR RETURN
HRRI M,-1(T1) ;PREPARE FOR CALL TO GETWR1
MOVEI T2,^D160 ;WORDS OF MONITOR FREE CORE
PUSHJ P,GETWDS## ;ALLOCATE CORE
PJRST ECOD3## ;NOT REALLY OUT OF RANGE, BUT ...
MOVE P4,T1 ;REMEMBER ADDRESS OF FREE CORE
HRR P1,T1 ;FINISH BUILDING AOBJN POINTER
JUMPN P2,DVPVF1 ;GO GET VFU DATA
DVPMOV: PUSHJ P,GETWR1## ;GET WORD FROM USER
PJRST [PUSHJ P,DVPGIV ;ERROR--GIVE BACK FREE CORE
PJRST RTM1##] ;GIVE ADDRESS-ERROR RETURN
MOVEM T1,(P1) ;SAVE WORD IN OUR BUFFER AREA
AOBJN P1,DVPMOV ;LOOP IF MORE DATA TO MOVE
HRLI P4,(POINT 18,) ;P4 IS BYTE POINTER
MOVE P2,[.EMLPT,,EM.16B+EM.IND+.EMLDR] ;FUNCTION WORD
PUSH P,P3 ;SET UP THE BYTE COUNT
JRST DVPCMN ;GO TO COMMON PART
DVPVF1: HRLI P1,(POINT 8,0) ;MAKE OUTPUT BYTE POINTER
MOVE P2,P3 ;PICK UP BYTE COUNT
PUSHJ P,DVPVB1 ;GET A VFU BYTE
CAIN T2,25 ;STANDARD START CODE?
MOVEI T2,356 ;YES
CAIN T2,26 ;6 LPT?
MOVEI T2,354 ;YES
CAIN T2,27 ;8 LPT?
MOVEI T2,355 ;YES
SKIPA ;ALREADY HAVE FIRST BYTE
DVPVF2: PUSHJ P,DVPVFB ;GET ANOTHER BYTE
PUSH P,T2 ;BYTES NEED TO SWAP
SOJG P2,DVPVF3 ;COUNT IT
SETZ T2, ;PUT A ZERO BYTE FOR LAST
JRST DVPVF4 ;GO STORE IT
DVPVF3: PUSHJ P,DVPVFB ;GET NEXT BYTE
CAIN T2,126 ;STOP CODE?
MOVEI T2,357 ;YES
DVPVF4: IDPB T2,P1 ;PUT BYTE INTO OUTPUT
POP P,T2 ;GET SWAPPED BYTE
IDPB T2,P1 ;PUT IT INTO OUTPUT ALSO
SOJG P2,DVPVF2 ;LOOP THRU WHOLE VFU
HRLI P4,(POINT 16,) ;SET UP BYTE POINTER FOR DTESER
MOVE P2,[.EMLPT,,EM.16B+EM.IND+.EMLDV] ;SET UP FUNCTION WORD
PUSH P,P3 ;SAVE ON STACK NOW
DVPCMN: MOVE P3,DLPDUX(F) ;P3 IS UNIT #,,DLP DTE INDEX
MOVE P1,DLPCDN(F) ;GET CPU#,,DTE#
PUSH P,S ;SAVE S
HRRZ S,P4 ;SET S TO BUFFER ADDR
DVPPRT: MOVEI T1,300 ;DO MAX OF 300 BYTE TRANSFERS
CAML T1,-1(P) ;FEWER BYTES REMAINING?
MOVE T1,-1(P) ;YEP, USE SMALLER NUMBER
HRR P3,T1 ;PUT COUNT INTO MESSAGE
MOVNS T1 ;CALCULATE REMAINING DATA
ADDM T1,-1(P)
SKIPG -1(P) ;LAST MESSAGE?
HRLI S,DVPGIV ;YES, GIVE BACK CORE ON THIS ONE
PUSHJ P,DTEQUE## ;YES--QUEUE THE REQUEST
PJRST DLPERR ;ERROR--SAY DEVICE OFF-LINE
ADDI P4,300/4 ;POINT TO NEXT PART OF STRING
SKIPE -1(P) ;DONE?
JRST DVPPRT ;NO, GO DO THE NEXT PART
PUSHJ P,DLPEOF ;SEND EOF TO TERMINATE LOAD FUNCTION
PJRST DLPER1 ;ERROR--SAY DEVICE OFF-LINE
POP P,S ;RESTORE S
POP P,(P) ;THROW AWAY COUNT
PJRST CPOPJ1## ;SKIP RETURN
DVPVFB: TLNE T3,760000 ;MORE DATA STILL IN WORD?
JRST DVPVB2 ;YES, GO GET IT
DVPVB1: PUSHJ P,GETWR1## ;NO, GET NEXT WORD
PJRST [POP P,(P) ;POP OFF RETURN
PUSHJ P,DVPGIV ;GIVE BACK CORE
PJRST RTM1##] ;GIVE ADDRESS-ERROR RETURN
MOVE T3,[POINT 7,T1] ;RESET BYTE POINTER
DVPVB2: ILDB T2,T3 ;GET A BYTE
POPJ P, ;RETURN
DLPERR: PUSHJ P,DVPGIV ;GIVE BACK FREE CORE
DLPER1: POP P,S ;RESTORE S
POP P,(P) ;THROW AWAY COUNT
PJRST ECOD7## ;SAY DEVICE OFF-LINE
;ROUTINE TO GIVE BACK MONITOR FREE CORE
;ARGS: RH(S)/ADDRESS OF FREE CORE AREA
;CALL: PUSHJ P,DVPGIV
; RETURN HERE
DVPGIV: MOVEI T1,^D160 ;RETURN THE WORDS WE USED
HRRZ T2,S ;GET ADDRESS OF CORE AREA
PJRST GIVWDS## ;GIVE IT BACK
;ROUTINE TO SET EOF STATUS FOR FRONT-END LPT
;ARGS: F/DDB ADDRESS
;CALL: SAVE P1-P4,S
; PUSHJ P,DLPEOF
; RETURN HERE IF UNSUCCESSFUL
; RETURN HERE IF EOF SENT SUCCESSFULLY
DLPEOF: MOVE P3,DLPDUX(F) ;P3 IS UNIT #,,DLP DTE INDEX
MOVE P1,DLPCDN(F) ;GET CPU#,,DTE#
MOVE P2,[.EMLPT,,EM.16B+EM.IND+.EMHDS] ;SET DEVICE STATUS FOR LPT
HRRI P3,2 ;TWO 8-BIT BYTES OF STATUS
MOVE P4,[POINT 16,[BYTE (16) EM.EOF]]
MOVEI S,0 ;NO POST ROUTINE OR VALUE TO SAVE
PUSHJ P,DTEQUE## ;QUEUE THE REQUEST
POPJ P, ;ERROR--NON-SKIP RETURN
PJRST CPOPJ1## ;SUCCESS--SKIP RETURN
SUBTTL GENERAL SUBROUTINES
;INTERRUPT REGISTER SETUP
;CALL WITH:
; P1=CPU #,,DTE #
; P3=LINE,,DATA COUNT
; P4=BYTE POINTER TO MESSAGE
SETRGS: MOVE T1,P4 ;COPY BYTE POINTER
ILDB T1,T1 ;GET GENERAL STATUS BYTE
TRNE T1,EM.NXD ;NON-EXISTANT DEVICE?
POPJ P, ;THEN WE CERTAINLY DON'T KNOW ABOUT IT
MOVE F,DDBTAB##+.TYLPT ;POINT TO PROTOTYPE DDB
SETRG1: HLRZ F,DEVSER(F) ;LINK TO NEXT
JUMPE F,SETRG2 ;GO CONFIGURE IF END OF CHAIN
LDB T1,PDVTYP## ;GET DEVICE TYPE
CAIE T1,.TYLPT ;STILL LOOKING AT RIGHT TYPE?
JRST SETRG2 ;NO--MUST CONFIGURE
HRRZ T1,DEVSER(F) ;GET DISPATCH
CAIN T1,RLPDSP ;OWNED BY US?
CAME P1,DLPCDN(F) ;AND CPU,,DTE NUMBERS MATCH?
JRST SETRG1 ;TRY NEXT DDB
HLRZ T1,DLPDUX(F) ;GET FE UNIT (LINE) NUMBER
HLRZ T2,P3 ;AND THE ONE FROM THE MESSAGE
CAIE T1,(T2) ;MATCH?
JRST SETRG1 ;TRY ANOTHER
AOS (P) ;GIVE SKIP RETURN
PJRST IOSET## ;GET THE REST OF THE AC'S
SETRG2: SETZ F, ;UNKNOWN DEVICE
PUSHJ P,DLPDTS ;AUTOCONFIGURE A LINE PRINTER
POPJ P, ;FAILED
AOS (P) ;GIVE SKIP RETURN
PJRST IOSET## ;GET THE REST OF THE AC'S
FNDDLP: MOVE F,DDBTAB##+.TYLPT ;POINT TO PROTOTYPE DDB
FNDDL1: HLRZ F,DEVSER(F) ;LINK TO NEXT
JUMPE F,CPOPJ1## ;NO LPTS??
LDB T1,PDVTYP## ;GET DEVICE TYPE
CAIE T1,.TYLPT ;STILL LOOKING AT RIGHT TYPE?
JRST CPOPJ1## ;GIVE UP
HRRZ T1,DEVSER(F) ;GET DISPATCH
CAIN T1,RLPDSP ;OWNED BY US?
CAME P1,DLPCDN(F) ;AND CPU,,DTE NUMBERS MATCH?
JRST FNDDL1 ;TRY NEXT DDB
HLRZ T1,DLPDUX(F) ;GET FE UNIT (LINE) NUMBER
CAIE T1,(T3) ;MATCH?
JRST FNDDL1 ;TRY ANOTHER
POPJ P, ;RETURN WITH DDB IN AC 'F'
SUBTTL END
END