Trailing-Edge
-
PDP-10 Archives
-
BB-X140B-BB_1986
-
10,7/703mon/dlpser.mac
There are 10 other files named dlpser.mac in the archive. Click here to see a list.
TITLE DLPSER - LINEPRINTER SERVICE FOR MULTIPLE RSX-20F LINEPRINTERS - V024
SUBTTL A. WILSON 19 FEB 86
SEARCH F,S,DTEPRM
PRMMIN==017 ;DTEPRM MUST BE AT LEAST THIS RECENT
IFL VDTPRM-PRMMIN,<PRINTX ?PLEASE USE LATEST VERSION OF DTEPRM
PASS2
END>
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
.CPYRT<1977,1986>
;COPYRIGHT (C) 1977,1978,1979,1980,1982,1984,1986
;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
;ALL RIGHTS RESERVED.
;
XP VDLPSR,024 ;DEFINE GLOBAL VERSION NUMBER FOR LOADER MAP
ENTRY DLPSER
DLPSER:
SUBTTL SYMBOL DEFINITIONS
MAXLPT==1 ;MAX LINE NUMBER (LPTS/CFE)
;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
DLPRDS==Z(1B8) ;REQUESTING DEVICE STATUS FROM FRONT-END
;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 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
CPOPJ## ;(-1)INTERNAL FUNCTION FOR TO-10 MESSAGE RUINED
DLPDSP::EATMSG## ;(0)
EATMSG## ;(1)
EATMSG## ;(2)
EATMSG## ;(3)
EATMSG## ;(4)
EATMSG## ;(5)
EATMSG## ;(6)
DLPTKS ;(7)TAKE DEVICE STATUS
EATMSG## ;(10)
EATMSG## ;(11)
EATMSG## ;(12)
EATMSG## ;(13)
EATMSG## ;(14)
EATMSG## ;(15)
EATMSG## ;(16)
DLPACK ;(17)ACK
EATMSG## ;(20)
EATMSG## ;(21)
EATMSG## ;(22)
DLPHLA ;(23)HERE ARE LINE ALLOCATIONS
EATMSG## ;(24)
DLPAAL ;(25)ACK ALL
EATMSG## ;(26)
EATMSG## ;(27)
EATMSG## ;(30)
EATMSG## ;(31)
EATMSG## ;(32)
EATMSG## ;(33)
EATMSG## ;(34)
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
DLPHNG: ;HUNG DEVICE IS SAME AS RELEASE
DLPREL: MOVEI T1,.HCULP ;LP05 CLASS PRINTER
DPB T1,[POINT 3,DEVHCW(F),14] ;SAVE IN DDB
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 T1,P4 ;GET UNIT NUMBER
IBP P4 ;MOVE PAST UNUSED BYTE
CAILE T1,MAXLPT ;OUT OF RANGE?
JRST DLPACK ;YES, IGNORE IT
HLRZ F,P1 ;GET CPU NUMBER
MOVEI F,@LPDTDV##(F) ;GET DDB ADDRESS
JUMPE F,DLPACK ;FAILED--LOOP FOR NEXT ARGUMENT
PUSHJ P,DLPDON ;TREAT THIS AS DONE INTERRUPT
JRST DLPACK ;LOOP FOR MORE ARGUMENTS
;HERE FROM DTESER ON ACK ALL FOR LPT
DLPAAL: MOVEI F,FL0DDB## ;GET ADDRESS OF FIRST DLPT DDB
MOVEI P4,DLPTN## ;GET NUMBER OF DLPT'S
DLPAA1: HRRZ T1,DLPDUX##(F) ;GET THE DTE INDEX
CAMN P1,LPCPDT##(T1) ;THIS LPT ON THIS DTE?
PUSHJ P,DLPDON ;YES--TREAT THIS AS DONE INTERRUPT
HLRZ F,DEVSER(F) ;ON TO THE NEXT DDB
SOJG P4,DLPAA1 ;LOOP IF MORE UNITS TO DO
POPJ P, ;RETURN
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 T1,P4 ;GET LINE NUMBER
CAILE T1,MAXLPT ;OUR OF RANGE?
JRST DLPHLA ;YES, IGNORE THIS LINE
HLRZ F,P1 ;GET CPU NUMBER
MOVEI F,@LPDTDV##(F) ;GET DDB ADDRESS
JUMPE F,DLPHLA ;FAILED -- LOOP FOR NEXT ARGUMENT
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,LPCPDT##(P3) ;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,SETALL ;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
IFN FTPI,<
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
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
;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,^D40 ;GET 160 WORDS OF MONITOR FREE CORE
PUSHJ P,GET4WD## ; IN 4-WORD BLOCKS
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,LPCPDT##(P3) ;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,^D40 ;RETURN THE 160 WORDS WE USED
HRRZ T2,S ;GET ADDRESS OF CORE AREA
PJRST GIV4WD## ;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,LPCPDT##(P3) ;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
;ROUTINE TO SET UP ALL ACS FOR DLP ROUTINES
;ARGS: P1/CPU #,,DTE # (AS SUPPLIED BY DTESER)
; LH(P3)/UNIT NUMBER
;CALL: PUSHJ P,SETALL
; RETURN HERE IF FAILED FOR SOME REASON
; RETURN HERE IF SUCCESSFUL
SETALL: HLRZ F,P1 ;GET CPU NUMBER
HLRZ T1,P3 ;GET UNIT NUMBER
MOVEI F,@LPDTDV##(F) ;GET DDB ADDRESS
JUMPE F,CPOPJ## ;NON-SKIP IF NONE
AOS (P) ;SKIP IF GOOD
PJRST IOSET## ;GO SET UP THE REST OF THE REGS
END