Trailing-Edge
-
PDP-10 Archives
-
BB-J845A-SM
-
source/hdmc20.p11
There are no other files named hdmc20.p11 in the archive.
.REPT 0
COPYRIGHT (c) 1980, 1979
DIGITAL EQUIPMENT CORPORATION, maynard, mass.
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 WHICH IS NOT SUPPLIED BY DIGITAL.
.ENDR
;
.SBTTL HDMC20 - DMC11 SYNCHRONOUS INTERFACE TO 2020
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1977, 1978 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;Revision history
; 3(001) 17-April-79 Make DMC buffering more efficient
; 3(002) 18-Apr-79 Move some DMC11 definitions to other modules
; 3(003) 23-Apr-79 Fix number of bytes send to 2020.
; 3(004) 23-Apr-79 Unsuspend device when less than 2 msgs queued for 2020
; 3(005) 23-Apr-79 Prevent enabling of a non-existent line
; 3(006) 3-MAY-79 Fix restart code for case that -10 goes away
; 3(007) 3-may-79 Add some error counters in DMC line block
; 3(010) 3-may-79 Increase wait time for data part of DN60 message
; from 5 to 12 seconds
; 3(011) 7-MAY-79 Fix some bugs in restart code
; 3(012) 7-MAY-79 Change LB.ST1 to LB.STS for DMC lcb
; 3(013) 15-MAY-79 Add line command to set line signature
; 3(014) 27-JUNE-79 Include line flags in device status
; 3(015) 27-June-79 Do not clear activity bit on eof new input permission requested
; 3(016) 27-June-79 Clear device active bit when abort complete acked.
; 3(017) 27-June-79 Add second byte of line flags to line status
; Add line signature to device status
; 3(020) 27-June-79 Give reject for device status on disabled line
; 3(021) 27-June-79 Reject device command on disabled line
; 3(022) 27-June-79 Reject write data command on disabled line
; 3(023) 27-June-79 Do not delete lcb to prevent kmc11 confusion
; 3(024) 27-June-79 Give rejects for incorrect device numbers hasp/3780/2780
; 3(025) 27-June-79 Clean up line block statistics when line is disabled
; 3(026) 4-Aug-79 Fix RDDATA to do right thing when short of chunks
; Remove incorrrect register spec for LCB in DLTL01
; 3(027) 21-Sept-79 Fix places where carry not cleared on non-fatal errors.
; 3(030) 21-Sept-79 Remove redundant calls to DTCERR
; 3(031) 28-SEPT-79 Change MOV to ADD at DLGDTA + some.
; 3(032) 11-OCT-79 Make DMCTSK wait a real long time between header and
; data before assuming the world is dead
VDMC20=032 ;FILE EDIT NUMBER
VEDIT=VEDIT+VDMC20
J=R4 ;usually where line block held
.MACRO JTRACE ADDR
MOV ADDR,#0 ;!!;**DEBUG**;!!;
.ENDM
.MACRO TWIDDL
INC #0
.ENDM
; DMC initialization routine
MC.INI:
MOV #DM.SIZ,R0 ;SIZE OF LCB FOR THE DMC LINE
JSR PC,GETSTG ;GET THE STORAGE FOR THE LCB
BCS 99$ ;FATAL, NO STORAGE
MOV R0,DMCLCB ;SAVE ADDRESS OF LCB
MOV R0,J ;HERE TOO
MOV DMCSR,LB.SLA(J) ;STORE CSR ADDRESS IN LCB
MOV DMCVEC,LB.SLV(J) ;STORE THE INTERRUPT VECTOR ADDRESS TOO
MOV DMCVEC,R1 ;GET THE VECTOR ADDRESS
MOV #BR7,R0 ;INTERRUPT LEVEL
MOV #MCVA0,(R1)+ ;DMC INPUT INTERRUPT PC
MOV R0,(R1)+ ;THE PS
MOV #MCVB0,(R1)+ ;DMC OUTPUT INTERRUPT PC
MOV R0,(R1) ;THE PS
MOV #DMCIBF+DMCOBF,R3 ;get number of buffers for this DMC11
PIOFF ;prevent interrupts
10$: MOV CHLST,R0 ;
JSR PC,GETCHK ;GET A CHUNK
BCS 99$ ;FATAL
MOV #LB.FR,R2 ;QUEUE WHERE TO PUT FREE DMC BUFFERS
ADD J,R2 ;MAKE ABSOLUTE
MOV R0,R1 ;Put where DMCQUE wants it
JSR PC,DMCQUE ;QUEUE TO LIST OF FREE BUFFERS
SOB R3,10$ ;LOOP TIL ALL BUFFERS ASSIGNED
PION
BIC #LS2DMC,LB.STS(J) ;clear all DMC11 bits
MOV #LB.IUC,R2 ;displacement of start for zeroing
ADD J,R2 ;make into address
MOV #<<LB.FR-LB.IUC>/2>,R1 ;word count of section to zero
20$: ;loop to zero DMC11 specific part of line block
CLR (R2)+ ;clear next word
SOB R1,20$ ;till count exhausted
MOV #DMCBAS,LB.BAS(J) ;BASE ADDRESS FOR DMC
RTS PC
99$:
NOBUFS:
NOCHKS:
STOPCD DMA
MC.HDW: BIS #MC.MCL,@LB.SLA(J) ;MASTER CLEAR THE DMC
CLR LB.IUC(J) ;CLEAR BUFFER COUNT COUNTERS
CLR LB.OUC(J) ; ..
MOV LB.BAS(J),LB.POR(J) ;BASE TABLE FOR DMC
CLR LB.POR+2(J) ;clear RESUME bit
MOV #MC.BSI,R0 ;BASE IN COMMAND
JSR PC,DMCIN ;...
CLR LB.POR(J)
CLR LB.POR+2(J) ;FULL DUPLEX
MOV #MC.CTI,R0 ;CNTL I transaction
JSR PC,DMCIN ;START THE COMMAND
BIS #LS2INI,LB.STS(J) ;MARK DMC AS INITIALIZED
RTS PC
MCLDWN: ;HERE WHEN LINE TO 2020 GOES DOWN
MOV DMCLCB,J ;MAKE SURE THIS IS SET UP
MOV LB.OBF(J),R0 ;FLUSH TRANSMIT MSG QUEUE
BEQ 20$ ;NONE, SO DONE
MOV CHNXT(R0),LB.OBF(J) ;POINT TO NEXT MSG IN QUEUE
BNE 10$ ;THERE IS MORE
CLR LB.OBF+2(J) ;ZERO END POINTER IF NO MORE
10$:
MOV TCIDLE,R1 ;QUEUE TO IDLE TASK
JSR PC,QUECHK ;
BR MCLDWN ;LOOP UNTIL ALL DEQUE'D
20$:
CLR LB.OBF+4(J) ;message count must be zero
30$:
MOV #LB.IB,R2 ;NOW FLUSH ALL RECEIVE BUFFERS
ADD J,R2 ;MAKE ABSOLUTE
JSR PC,DMCDEQ ;REMOVE FROM QUEUE
BCS 34$ ;NO MORE
trace trcten,r1
JSR PC,DMCFRE ;PUT ON DMC FREE QUEUE
DEC LB.IUC(J) ;DECREMENT COUNT OF BUFFERS IN DMC
BR 30$ ;CONTINUE TIL ALL DEQUE'D
34$:
MOV #LB.IN,R2 ;GET BUFFERS STILL IN DMC
ADD J,R2 ;MAKE ABSOLUTE
JSR PC,DMCDEQ ;REMOVE FROM QUEUE
BCS 35$ ;NO MORE
trace trcten,r1
JSR PC,DMCFRE ;PUT ON DMC FREE QUEUE
DEC LB.IUC(J) ;DECREMENT COUNT OF BUFFERS IN DMC
BR 34$ ;CONTINUE TIL ALL DEQUE'D
35$:
BIC #LS2DMC,LB.STS(J) ;CLEAR ALL DMC BITS
BIS #MC.MCL,@LB.SLA(J) ;DO A MASTER RESET TO DMC
CLC ;[3(027)]CLEAR ANY ERROR CONDITIONS
RTS PC ;RETURN
;Interrupt Level Code
MCVA0: SAVE <J>
MOV DMCLCB,J ;POINT TO 2020'S LINE BLOCK
DMCAIN: ;RDYI interrupt
SAVE <R0,R1> ;SAVE SOME REGISTERS
MOV LB.SLA(J),R0 ;GET DMC HARDWARE ADDRESS
TRACE TRCDMC,<(R0)>
TRACE TRCDMC,<2(R0)>
ADD #4,R0 ;POINT TO SEL4 REGISTER
MOV #LB.POR,R1 ;ADDRESS OF DATA TO GIVE
ADD J,R1 ;TO THE DMC
TRACE TRCDMC,<(R1)>
TRACE TRCDMC,<2(R1)>
MOV (R1)+,(R0)+ ;COPY FIRST WORD INTO PORT
MOV (R1)+,(R0)+ ;AND ALSO 2ND
BIC #MC.RQI,@LB.SLA(J) ;CLEAR REQUEST
BIC #LS2IBY,LB.STS(J) ;CLEAR SOFTWARE INTERLOCK
RESTORE <R1,R0,J> ;RESTORE REGISTERS
RTI ;RETURN FOR INTERRUPT
MCVB0: SAVE <J>
MOV DMCLCB,J ;POINT TO 2020'S LINE BLOCK
DMCBIN: ;RDYO interrupt
SAVE <R0,R1,R2,R5> ;SAVE SOME REGISTERS
MOV LB.SLA(J),R0 ;DMC11 CSR ADDRESS
TRACE TRCDMC,<(R0)>
TRACE TRCDMC,<2(R0)>
TRACE TRCDMC,<4(R0)>
TRACE TRCDMC,<6(R0)>
TST (R0)+ ;POINT TO SEL2 REGISTER
MOV (R0)+,R1 ;GET ITS CONTENTS
BIT #1,R1 ;DID WE GET AN ERROR INTERRUPT?
BNE 50$ ;YES, GO HANDLE THAT CASE
BIT #MC.IOO,R1 ;HAVE WE RECEIVED INPUT?
BNE 20$ ;YES
;"XMIT DONE" INTERRUPT
MOV (R0)+,R1 ;GET BUFFER ADDRESS
SUB #CHDAT,R1 ;POINT TO BEGINNING OF BUFFER
TRACE TRCDMC,R1
JSR PC,DMCFRE ;JUST THROW AWAY
DEC LB.OUC(J) ;ONE LESS DMC XMIT BUFFER OUTSTANDING
CLR LB.SE5(J) ;[3(11)]INDICATE WE'VE HEARD FROM 2020
BR 40$ ;FINISH UP
;"RECEIVED DATA" INTERRUPT
20$:
CLR LB.SE5(J) ;[3(11)]INDICATE WE'VE HEARD FROM 2020
MOV (R0)+,R1 ;GET BUFFER ADDRESS
SUB #CHDAT,R1 ;POINT TO BEGINNING OF BUFFER
TRACE TRCDMC,R1
MOV #LB.IN,R2 ;POINT TO QUEUE OF BUFFERS IN DMC
ADD J,R2
JSR PC,DMCDEQ ;BUFFER NO LONGER IN DMC
BCC 27$ ;[3(027)]HAS TO WORK
STOPCD DMC ;[3(027)]OTHERWISE FATAL
27$:
MOV (R0)+,CHLEN(R1) ;DATA COUNT
BIC #40000,CHLEN(R1)
CMP CHLEN(R1),#MSGMAX ;MESSAGE TOO LONG?
BLE 33$
STOPCD DMC ;FATAL
33$:
MOV TCDMDR,R5 ;DMC TCB
BIT #EBINP,(R5) ;WAITING FOR INPUT?
BEQ 25$ ;NO
BIC #EBINP!EBWAIT,(R5) ;UNWAIT DMC TASK
25$: MOV #LB.IB,R2 ;QUEUE TO INPUT QUEUE
ADD J,R2 ;...
JSR PC,DMCQUE ;...
40$: MOV LB.SLA(J),R0 ;HERE TO RETURN FROM INTERRUPT
TST (R0)+ ;POINT TO SEL2
BIC #MC.RDO,@R0 ;INDICATE WE ARE DONE WITH PORT
RESTORE <R5,R2,R1,R0,J>
RTI
;
; HERE ON ERROR INTERRUPT
;
50$:
INC LB.SE1(J) ;INCREMENT # ERROR INTERRUPTS
MOV @R0,LB.SE2(J) ;SAVE SEL4 CSR FROM LAST INTERRUPT
TST (R0)+ ;SKIP TO SEL6 REGISTER
MOV @R0,R2 ;GET THE ERROR BITS
MOV R2,LB.SE3(J) ;SAVE SEL6 CSR FROM LAST INTERRUPT
TRACE TRCDMC,R2
BIT #MC.NXM!MC.ERR,R2 ;FATAL?
BEQ 60$ ;NO
STOPCD DMC
60$:
BIT #MC.RMA,R2 ;DID WE GET A MAINTENANCE MESSAGE?
BNE 93$ ;YES, TRY TO RESTART
77$: BIT #MC.RST,R2 ;RECEIVED A START MESSAGE?
BNE 93$ ;YES, TRY TO RESTART
80$: BIT #MC.TMO,R2 ;TIMEOUT?
BEQ 90$ ;NO
DEC LB.SE1(J) ;DON'T COUNT IN TOTAL ERROR STATISTICS
TST LB.OUC(J) ;ANY OUTSTANDING XMIT BUFFERS?
BEQ 40$ ;no, ignore it
TST LB.SE5(J) ;SECOND TIME-OUT IN A ROW?
BEQ 85$ ;NO. JUST COUNT IT FOR NOW
BR 93$ ;SECOND IN A ROW, LINE MUST BE DOWN
85$: INC LB.SE5(J) ;INCREMENT NUMBER OF TIMEOUTS
BR 40$ ;IGNORE UNLESS ANOTHER COMES
90$: ;check for buffer too small
BIT #MC.LOS,R2 ;lost data?
BEQ 40$ ;if not, we are done
STOPCD DMC
93$: ;ATTEMPT TO RESTART
;!!; BIS #LS2RST,LB.STS(J) ;TELL HIGHER LEVEL LINE IS DOWN
INC LB.SE6(J) ;INCREMENT # RESTARTS
BR 40$ ;RETURN FROM INTERRUPT
;
; ONCE-A-TIME-UNIT ROUTINES
;
DSPDLS:
DSPDLT:
RTS PC
;;!!;;;;;
INITDL:
STOPCD DMC ;THIS CAN'T HAPPEN YET
;CALL FROM TRPINT TO RELOAD US. NOT IMPLEMENTED
DLSTCS:
RTS PC
;
; GETS A BUFFER FROM THE DMC, COPIES TO A CHUNK, AND GIVES CHUNK
; ADDRESS TO CALLER IN R1
MC.INP:
MOV #LB.IB,R2 ;displacement of queue head
ADD J,R2 ;make absolute
JSR PC,DMCDEQ ;get a DMC buffer(put address in R1)
BCS 20$ ;but you promised there was one!
TRACE TRCTEN,R1 ;Trace the DMC buffer for the received data
JTRACE R1
10$: RTS PC ;return
20$: STOPCD DMC ;Tragic!
; THIS ROUTINE CHECKS THE QUEUE POINTER LB.OBF IN THE DMC LINE BLOCK FOR
; SOMETHING TO TRANSMIT. ANYTHING IN THIS QUEUE IS QUEUED UP TO THE DMC
; IMMEDIATELY FOR TRANSMISSION.
XMTCHK:
MOV LB.OBF(J),R0 ;IS THERE ANYTHING TO TRANSMIT TO 2020?
BEQ 30$ ;NO, JUST RETURN
CMP LB.OUC(J),#DMCOBF ;ENOUGH QUEUED TO DMC?
BLT 13$ ;
STOPCD DMC ;THIS SHOULD NEVER HAPPEN
13$: ;THERE IS DATA FOR THE 2020
PIOFF
MOV CHNXT(R0),LB.OBF(J) ;delink message
BNE 20$ ;if some more, branch
CLR LB.OBF+2(J) ;clear last pointer as well
20$: DEC LB.OBF+4(J) ;decrease count
CLR CHNXT(R0)
PION
MOV R0,LB.POR(J) ;BUFFER ADDRESS FOR DMC
ADD #CHDAT,LB.POR(J) ;POINT TO DATA PART
MOV CHLEN(R0),LB.POR+2(J) ;DATA BYTE COUNT
MOV #MC.BCI,R0 ;indicate BA/CC I
JSR PC,DMCIN ;do BA/CC I transaction
INC LB.OUC(J) ;INCREMENT NUMBER OF XMIT BUFFERS QUEUED
BR XMTCHK ;SEE IF MORE TO SEND
30$: RTS PC ;RETURN
DMCGIV:
CMP LB.IUC(J),#DMCIBF ;DOES DMC HAVE ENOUGH BUFFERS?
BGE 40$ ;YES, DON'T GIVE ANY MORE
JSR PC,DMCGET ;GET A DMC BUFFER
BCS 40$ ;CANNOT, HOPE DMC HAS ENUF
TRACE TRCDMC,R1
MOV #LB.IN,R2 ;REMEMBER THE BUFFERS WE GIVE TO THE
ADD J,R2 ;DMC IN CASE WE NEED THEM BACK.
JSR PC,DMCQUE ;(E.G. DDCMP LINE RESTART)
MOV R1,LB.POR(J) ;ADDRESS OF BUFFER TO GIVE DMC
ADD #CHDAT,LB.POR(J) ;POINT DMC TO DATA PART
MOV #MSGMAX,LB.POR+2(J) ;LENGTH OF DMC BUFFER
MOV #MC.IOI!MC.BCI,R0 ;DO A CONTROL IN COMMAND
JSR PC,DMCIN ;REQUEST THE DMC PORT
INC LB.IUC(J) ;INCREMENT NUMBER OF BUFFERS IN DMC
BR DMCGIV ;CAN WE GIVE MORE?
40$: CLC ;[3(027)]CLEAR ERROR CONDITION
RTS PC
;Subroutines
.REPT 0
The following subroutines assume that the link in the DMC11
buffer is the first word. If this is not the case, the conditional
below will give an error.
The standard register convention for these routines is:
R0 address of chunk chain containing message
R1 address of DMC11 buffer
R2 address of queue head and tail pointer entry in line block
.ENDR;.REPT 0
DMCFRE: ;free a DMC11 buffer
;Called with
; R1 containing buffer address
;Returns
; R2 pointing to Free queue
; all other registers unchanged
MOV #LB.FR,R2 ;displacement of free queue
ADD DMCLCB,R2 ;make into address
; BR DMCQUE ;queue it up
;...Falls into DMCQUE
DMCQUE: ;routine to queue DMC11 buffer
;Called with
; R2 pointing to queue
; R1 containing address of DMC11 buffer
TRACE TRCDMC,R1
TRACE TRCDMC,R2
SAVE R2 ;save queue address
PIOFF
CLR (R1) ;ensure link is 0
TST @R2 ;is anything already in queue?
BNE 10$ ;yes, must do it the hard way
MOV R1,(R2)+ ;no, copy buffer address to head
MOV R1,(R2)+ ;and tail
DMCRET=.
99$: PION ;re-enable interrupts
RESTORE R2 ;restore queue address
TRACE TRCDMC,R1
RTS PC ;return to caller
10$: ;here if something already on queue
MOV R1,@2(R2) ;make link of last buffer point to us
MOV R1,2(R2) ;and we are now last buffer
BR 99$ ;go exit
;THE DEQUEUE ROUTINE HAS TWO ENTRY POINTS. DMCDEQ IS THE GENERAL ENTRY POINT
;AND IS USED TO DEQUEUE A BUFFER FROM THE FRONT OF AN ARBITRARY LIST.
;DMCDEQ IS CALL WITH:
; R2/ ADDRESS OF THE QUEUE
; RETURN IS:
; R1/ ADDRESS OF BUFFER FROM TOP OF QUEUE
; CC SUCCESS
; CS QUEUE WAS EMPTY
;ENTRY DMCGET IS SPECIALIZED ENTRY POINT AND IS USED TO DEQUEUE A BUFFER
;FROM THE DMC QUEUE OF FREE DMC BUFFERS AT LB.FR. LIKE DMCDEQ , THE ADDRESS
;OF RETURNED BUFFER IS IN R1.
DMCGET:
SAVE R2 ;SAVE REGISTER
MOV #LB.FR,R2
ADD DMCLCB,R2 ;FALL THRU
BR DMCDQ0 ;JOINT NORMAL DEQUEUE CODE
DMCDEQ:
SAVE R2 ;SAVE R2
DMCDQ0: SEC ;ASSUME FAILURE
TRACE TRCDMC,<@R2>
TRACE TRCDMC,R2
PIOFF
MOV @R2,R1 ;GET NEXT ENTRY
BEQ DMCRET ;RETURN IF NONE
BIC #1,(SP) ;THERE IS ONE, CLEAR CARRY FOR RETURN
MOV @R1,(R2)+ ;SET NEW HEAD OF QUEUE
BNE DMCRET ;EXIT UNLESS QUEUE NOW EMPTY
CLR @R2 ;CLEAR TAIL IF SO
BR DMCRET ;RETURN
DMCIN: ;do an input transaction
;Called with
; R0 containing request type and IN/OUT bit
; LB.POR containing data to be copied to DMC11 port
BIS #MC.RUN!MC.RQI!MC.IEI,R0;ensure that request and
;interrupt enable are set
TRACE TRCDMC,<LB.POR(J)>
SAVE R0 ;save request on stack
MOV LB.SLA(J),R0 ;get hardware address
BIS #LS2IBY,LB.STS(J) ;indcate port in use
MOV (SP),(R0)+ ;do request
;when RDYI sets, it will cause
;an interrupt; the code at
;DMCAIN will copy data to port, and
;clear request
BIS #MC.IEO,@R0 ;also make sure RDYO interrupt enabled
20$: TSTB LB.STS(J) ;wait till done
BMI 20$
RESTORE R0
RTS PC
; ROUTINES TO COPY DATA BETWEEN CHUNKS AND DMC DATA BUFFERS
DMCBTC: ;copy DMC11 buffer to chunks
;if none, set carry, and requeue
;buffer to head of old queue
;Called with
; R1 buffer address
; R2 queue
;Returns
; R0 chunk address
; C bit set if not enough chunks, clear otherwise
SAVE <R1,R2,R3,R4,R5> ;we need a lot of registers
MOV CHLST,R0 ;get a chunk
JSR PC,GETCHK ;to receive data
BCS 99$ ;short on chunks
5$:
MOV CHLEN(R1),R5 ;length of data in buffer
trace trcspc,r5
MOV R5,CHLEN(R0) ;move to chunk
INC R5 ;to convert to number of words
ASR R5 ;divide by 2
MOV R1,R4 ;buffer address
ADD #CHDAT,R4 ;POINT TO FIRST DATUM
MOV R0,R1 ;CHUNK ADDRESS
ADD #CHDAT,R1 ;HERE TOO
25$: MOV (R4)+,(R1)+ ;TRANSFER FROM DMC BUFFER TO CHUNK
SOB R5,25$ ;LOOP TIL DONE
99$: RESTORE <R5,R4,R3,R2,R1>
RTS PC
DMCCTB: ;copy chunk to buffer
;Called with
; R1 buffer address
; R0 chunk address
; CN.LEN(R0) must have length
SAVE <R2,R3,R4,R5>
JTRACE R0
JTRACE R1
MOV CHLEN(R0),R5
MOV R5,CHLEN(R1) ;MOVE COUNT TO BUFFER
INC R5
ASR R5 ;make into word count
JTRACE R5
MOV R0,R2 ;point to chunk
ADD #CHDAT,R2 ;point to first datum
MOV R1,R3 ;point to DMC11 buffer
ADD #CHDAT,R3 ;point to first datum
21$: ;loop to copy one chunk
MOV (R2)+,(R3)+ ;copy a word
SOB R5,21$ ;for whole chunk
RESTORE <R5,R4,R3,R2>
RTS PC
;
.SBTTL DMC20 TASK
;
; THIS TASK INTERFACES TO THE PDP-10 THROUGH THE DMC
;
DMCTSK:
BCC 5$
STOPCD DMC ;SOMEONE FORGOT TO CLEAR CARRY
5$: MOV DMCLCB,J ;MAKE SURE THIS IS SET UP
BIT #LS2RST,LB.STS(J) ;HAS THE -10 GONE AWAY
BNE 97$ ;YES, GO TRY TO RESTART
MOV #EBINP!EBWAIT!EBTIME,(R5) ;WAIT CONDITIONS
MOV #<JIFSEC*74*10>,TCTIM(R5) ;WAIT MAXIMUM THIS LONG
MOV DMCLCB,J ;GET DMC'S LINE BLOCK
BIT #LS2INI,LB.STS(J) ;HAS THE DMC BEEN INITIALIZED YET?
BNE 13$ ;YES
JSR PC,MC.HDW ;NO, DO IT NOW
13$: JSR PC,DMCGIV ;CHECK IF DMC NEEDS INPUT BUFFERS
TST LB.IB(J) ;IS THERE INPUT?
BEQ 30$ ;NO, NO INPUT CURRENTLY
JSR PC,RDHDR ;GO READ IN THE HEADER BLOCK
BCS 97$ ;FATAL ERROR
TST DT10AK ;IS THERE DATA FROM -20 TO FOLLOW?
BEQ 25$ ;NO
MOV DMCLCB,J ;RDHDR DESTROYS J ALIAS R4
TST LB.IB(J) ;IS THE ADDITIONAL DATA HERE YET?
BNE 20$ ;YES
JSR PC,WAIT ;WAIT
MOV DMCLCB,J ;BE SURE J IS SET UP CORRECTLY
TST LB.IB(J) ;ANYTHING NOW?
BNE 20$ ;YES,OKAY
STOPCD DMC ;IF IT TAKES THIS LONG, THE 2020 IS DEAD
;FORCE A RELOAD
20$: JSR PC,RDDATA ;READ IN DATA PART FROM -20
BCS 97$ ;FATAL ERROR
25$: MOV DMCLCB,J ;RDDATA DESTROYS J ALIAS R4
JSR PC,DTSACK ;SEND BACK ACK AND/OR ANSWER
BCS 97$
30$: JSR PC,XMTCHK ;MAKE SURE ALL OUTPUT GETS OUT
MOV #JIFSEC,TCTIM(R5) ;WAIT MAXIMUM THIS LONG
JSR PC,WAIT ;WAIT A BIT BEFORE CHECKING AGAIN
BR DMCTSK ;LOOP
97$:
;
; HERE ON PDP-10 PROTOCOL ERROR.
; ABORT ALL STREAMS AND DISABLE ALL LINES.
;
BIT #LS2RST,LB.STS(J) ;IS OTHER END DEAD?
BEQ 21$ ;NO, DON'T RE-INIT DMC
JSR PC,MCLDWN ;YES, RE-INIT THE DMC
21$:
JSR PC,DTCERR ;TRY TO ABORT ALL BSC LINES
CLC ;[3(027)] RESUME WITH NO ERROR INDICATION
BR DMCTSK ; GO WAIT FOR ANOTHER COMMAND
;
;
; SUBROUTINE TO CALL A SUBROUTINE BASED ON AN INDEX.
; THIS IS USED AS A DISPATCHER.
;
; R0 = POINTER TO DISPATCH TABLE. THE FIRST ENTRY IS
; THE MAX INDEX, THE REMAINDER BEING POINTERS
; TO SUBROUTINES.
; R1 = INDEX, 0 BASED.
;
; RETURNS WITH C SET IF THE INDEX IS OUT OF RANGE OR IF THE
; TABLE ENTRY SELECTED CONTAINS A ZERO. OTHERWISE RETURNS
; WITH C AS SPECIFIED BY THE SUBROUTINE.
;
DLDISP:
CMP R1,(R0)+ ;IS INDEX IN RANGE?
BHI 11$ ;NO, FATAL ERROR.
ASL R1 ;YES, COMPUTE INDEX*2
ADD R1,R0 ;COMPUTE PLACE IN THE TABLE
MOV (R0),R1 ;PICK UP SUBROUTINE POINTER
BEQ 11$ ;0 = ERROR
TRACE trcspc,<R1>
JSR PC,(R1) ;NON-ZERO, CALL THE SUBROUTINE
RTS PC ;RETURN TO CALLER.
;
; HERE IF THE INDEX IS OUT OF RANGE OR IF THE SUBROUTINE POINTER
; IS ZERO.
;
11$: SEC ;FLAG ERROR
RTS PC ;RETURN.
;
;
; THIS SUBROUTINE HAS TWO ENTRY POINTS . DTSACK TO SEND
; AN ACK + FEH TO THE TEN AND DTSAK FOR SENDING THE
; ACK ALONE TO THE TEN TO ACKNOWLEDGE RECEIPT OF DATA.
;
DTSACK:
JSR PC,DMCGET ;GET A DMC BUFFER FOR DN60 HEADER
BCS 90$ ;SHOULD NEVER HAPPEN
JTRACE R1
MOV R1,R0 ;SAVE BUFFER ADDRESS
MOV #6,CHLEN(R0) ;HEADER SIZE
ADD #CHDAT,R0 ;POINT TO DATA PORTION
MOVB DT11DF(R5),DT10DF(R5) ;DN60 FCN CODE
MOV DT11AD(R5),DT10AD(R5) ;ADDRESS OF LINE #
SWAB DT10DF(R5) ;SWAP BYTES
SWAB DT10AD(R5) ;...
SWAB DT10DT(R5) ;...
MOV DT10DF(R5),(R0)+ ;PUT DATA IN BUFFER
MOV DT10AD(R5),(R0)+ ;...
MOV DT10DT(R5),(R0) ;...
MOV #LB.OBF,R2 ;POINT TO OUTPUT QUEUE
ADD J,R2 ;MAKE ABSOLUTE
JSR PC,DMCQUE ;QUEUE HEADER TO DMC LCB
JTRACE <TCXFR(R5)>
MOV DTXADR(R5),R1 ;ANY ADDITIONAL DATA?
BEQ 10$ ;NO
MOV TCXFR(R5),R0 ;GET ITS LENGTH
BNE 5$ ;BETTER NOT BE ZERO!
STOPCD DMC
5$: MOV R0,CHLEN(R1) ;MAKE SURE IN CHUNK
JTRACE R1
JSR PC,DMCQUE ;QUEUE THAT TOO
10$: RTS PC
90$: JSR P,NOBUFS
; ROUTINE TO READ IN THE HEADER BLOCK. IT IS ASSUMED THAT A CHECK HAS
; ALREADY BEEN MADE TO BE SURE THAT INPUT EXISTS.
RDHDR:
JSR PC,MC.INP ;GET A CHUNK OF DATA FROM THE DMC
TRACE TRCTEN,r1
MOV R1,R0 ;MAKE COPY OF CHUNK POINTER
CMP #6,CHLEN(R0) ;HEADER LENGTH IS 6
BEQ 10$ ;LENGTH OK
STOPCD DMC ;BAD HEADER LENGTH
10$: ADD #CHDAT,R0 ;POINT TO THE DATA PART
MOV (R0)+,DT11DF(R5) ;PUT HEADER DATA
MOV (R0)+,DT11AD(R5) ;WHERE OTHERS LIKE TO
MOV (R0)+,DT11DT(R5) ;HAVE IT
trace trcten,r1
JSR PC,DMCFRE ;FREE THE DMC BUFFER (ADDRESS IN R1)
DEC LB.IUC(J) ;DECREMENT # BUFFERS IN DMC
;
SWAB DT11DF(R5) ;SWAP BYTES
SWAB DT11AD(R5)
SWAB DT11DT(R5)
CLR DT10AK ;CLEAR "EXPECTING MORE DATA" FLAG
CLR TCXFR(R5) ;CLEAR BYTE COUNT FOR TO-TEN STATUS BUFFER
CLR DTXADR(R5) ;CLEAR ADDRESS OF ADDITIONAL DATA
CLR DT11GW(R5) ;CLEAR SHORT OF CHUNK FLAG
MOV DT11DT(R5),DLMBCT(R5) ;INITIALIZE MESSAGE BYTE COUNT
MOV DT11DT(R5),DLMCTL(R5) ;AND MESSAGE COUNT LEFT
MOVB DT11DF(R5),R1 ;GET DN60 FUNCTION-USED AS INDEX
MOV #15$,R0 ;POINT TO DISPATCH TABLE
JSR PC,DLDISP ;DISPATCH
;[3(030)] TWO LINES REMOVED FROM HERE...ERRORS HANDLED ON RETURN TO MAIN LOOP
RTS PC ;RETURN
;
; TABLE FOR PDP-10 INITIATED OPERATIONS
;
15$: .WORD <<16$-15$>/2>-2 ;MAXIMUM INDEX
.WORD 0 ;FUNCTION ZERO INVALID
.WORD DLTRDT ;1=READ DATA INTO THE PDP-10
.WORD DLTWDT ;2=WRITE DATA FROM THE PDP-10
.WORD DLTRDS ;3=READ DEVICE STATUS
.WORD DLTWDC ;4=WRITE DEVICE COMMAND
.WORD DLTRLS ;5=READ LINE STATUS
.WORD DLTWLC ;6=WRITE LINE COMMAND
.WORD DLTRES ;7=READ DN60 STATUS
.WORD DLTWEC ;8=WRITE DN60 COMMAND
.WORD DLTEXM ;9=EXAMINE 11 LOCATION
.WORD DLTDEP ;10=DEPOSIT IN 11 LOCATION
;
16$: ;END OF TABLE
;
;
RDDATA:
JSR PC,MC.INP ;GET FIRST BUFFER OF DATA FROM DMC
TRACE TRCTEN,R1
MOV R1,DT11Q(R5) ;PUT IT WHERE MOST EXPECT IT TO BE
TST DT11GW(R5) ;OPERATION DELAYED OR REJECTED??
BNE 21$ ;[3(026)]YES
CMPB #2,DT11DF(R5) ;IS IT A WRITE?
BEQ 16$ ;YES
CMPB #4,DT11DF(R5) ;WAS IT DATA FOR DEVICE STATUS?
BNE 12$ ;NO
JSR PC,DLTWD1 ;YES,SETUP DEVICE STATUS
BCS 15$ ;FATAL ERROR
BR 19$ ;UPDATE STATE
;
12$: CMPB #6,DT11DF(R5) ;IS IT FOR WRITE LINE STATUS?
BNE 13$ ;NO
JSR PC,DLTWL1 ;YES,SETUP LINE STATUS
BCS 15$ ;FATAL ERROR
BR 19$ ;UPDATE STATE AND RETURN
;
13$: CMPB #10,DT11DF(R5) ;NO,IS IT WRITE DN60 STATUS
BNE 14$ ;NO,
JSR PC,DLTWS1 ;YES,SETUP DN60 STATUS
BCS 15$ ;FATAL ERROR
BR 19$ ;UPDATE STATE AND RETURN
;
14$: STOPCD DTB20 ;GOOFY ELEVEN DONE INTP
;
;[3(030)] REMOVE ONE LINE HERE...ERRORS HANDLED ON RETURN TO MAIN LOOP
15$: RTS PC ;RETURN
;
;
; HERE IT HAS TO BE A PLAIN SIMPLE WRITE TO - ELEVEN DATA
;
16$: JSR PC,DLTEDN ;SETUP CHUNKS TO RECEIVE DATAIN
TST DT11GW(R5) ;SHORT OF CHUNKS??
BNE 21$ ;YES
TRACE TRCTEN,R0
JTRACE R0
TST R0 ;ANYTHING LEFT TO TRANSFER?
BEQ 18$ ;NOTHING LEFT TO XFER
17$: JSR PC,MC.INP ;MORE TO RECEIVE, GET NEXT MSG CHUNK
MOV R1,DT11Q(R5) ;PUT WHERE IT SHOULD BE
BR 16$
;
; HERE WHEN WE APPEAR TO HAVE RUN OUT OF DATA TO TRANSFER.
;
18$: TST DLMCTL(R5) ;ANY MORE TO XFER?
BGT 14$ ;BETTER NOT BE!!!
MOVB #1,DT10DF+1(R5) ;SUCCESS CODE TO TEN
19$: MOV DLMBCT(R5),DT10DT(R5) ;TELL -10/20 NUMBER OF BYTES WE GOT
TRACE TRCTEN,<DT10DT(R5)>
MOV DT11Q(R5),R1 ;IS THERE A DMC BUFFER TO RELEASE?
BEQ 20$ ;NO
MOV DMCLCB,J ;MAKE SURE J SET UP CORRECTLY
trace trcten,r1
JSR PC,DMCFRE ;RELEASE THE DMC BUFFER
DEC LB.IUC(J) ;DECREMENT # BUFFERS QUEUE TO DMC
20$: CLC ;SIGNAL SUCCESS
RTS PC ;RETURN.
21$: SUB DLMCTL(R5),DLMBCT(R5) ;ACTUALLY TRANSFERRED
MOV DT11Q(R5),R1 ;CHUNK ADDRESS
CLR DT11Q(R5) ;MAKE SURE CLEAR
22$:
TRACE TRCTEN,<DLMBCT(R5)>
SUB CHLEN(R1),DLMCTL(R5) ;DECREMENT # TO TRANSFER
MOV DMCLCB,J ;MAKE SURE J SET UP CORRECTLY
trace trcten,r1
JSR PC,DMCFRE ;FREE UP THE DMC BUFFER
DEC LB.IUC(J) ;DECREMENT # OF INPUT BUFFERS TIED UP
TST DLMCTL(R5) ;ANY MORE TO TRANSER?
BEQ 19$ ;NO
TST LB.IB(J) ;CHECK FOR REST
BEQ 14$ ;SHOULD BE SOMETHING THERE
JSR PC,MC.INP ;GET NEXT CHUNK
BR 22$ ;YES, CONTINUE TO FLUSH
; ROUTINE CALLED FROM TO-11 DONE ROUTINE TO ADD NEW CHUNK
; OR PROCESS END OF FRAGMENT
;
; CALL - NO REGISTERS NEEDED
; ON RETURN:
; R0/ LENGTH OF NEXT FRAGMENT TO TRANSFER
; R1/ ADDRESS TO STORE DATA
; PS/ Z BIT SET IF EVERYTHING IN
;
DLTEDN: JSR PC,DLNWCK ;CHECK ABNORMAL CONDITIONS
BCS 16$ ;THERE IS ONE
MOV DT11Q(R5),R1 ;GET BACK POINTER TO CHUNK
JSR PC,DMCBTC ;MOVE DATA FROM BUFFER TO CHUNKS
BCS 15$ ;NOT ENOUGH CHUNKS
MOV DMCLCB,J ;SET UP J
trace trcten,r1
JSR PC,DMCFRE ;FREE UP THE BUFFER
DEC LB.IUC(J) ;DECREMENT COUNT
CLR DT11Q(R5) ;INDICATE BUFFER NO LONGER TO BE FREED
SUB CHLEN(R0),DLMCTL(R5) ;DECREMENT # BYTES LEFT TO XFER
;
; IF THE COUNT IS -VE OR ZERO, THEN APPEND THE LAST CHUNK DONE
; TO THE MESSAGE FOR XLATE TASK
;
TRACE TRCTEN,<DLMCTL(R5)>
MOV TCXLT(R5),R1 ;POINT TO THE XLATE TASK
JSR PC,QUECHK ;SEND IT THE CHUNK
MOV DLMCTL(R5),R0 ;ANYTHING LEFT TO XFER?
BGT 11$ ;YES
CLR R0 ;NO,INDICATE NOTHING LEFT TO XFER
11$: TRACE TRCTEN,R0
CLC
RTS PC ;RETURN
15$: TWIDDL
16$:
TWIDDL
MOV TCXLT(R5),R1 ;POINT TO XLATE TASK
BIT #TCOAB,TCFG2(R1) ;ABORT OR DELAY?
BEQ DLSDLY ;JUST DELAYED
;
DLSERR: trace trcspc,r5
MOVB #3,DT10DF+1(R5) ;OPERATION REJECTED
MOV #-1,DT11GW(R5) ;SET FLAG TO INDICATE ERROR OR DELAYED
CLC ;NOT A FATAL ERROR
RTS PC ;RETURN
;
DLSDLY: trace trcspc,r5
MOVB #2,DT10DF+1(R5) ;OPERATION DELAYED
MOV #-1,DT11GW(R5) ;FLAG OPERATION DELAYED
CLC ;NOT A FATAL ERROR
RTS PC ;RETURN
;
; HERE ON PDP-10 PROTOCOL ERROR.
; ABORT ALL STREAMS AND DISABLE ALL LINES.
;
DTCERR: ;ERROR RETURN FOR SET DEV AND LINE
.IF NE,DEBUG
BIT #TRCTER,TRCHLT ;STOP ON PDP-10 ERRORS?
BEQ 11$ ;NO.
STOPCD TER ;YES, PDP-10 ERROR
11$:
.ENDC ;.IF NE,DEBUG
CLR R3 ;START WITH LINE NUMBER 0
12$: MOV DQLCB(R3),R0 ;GET LCB POINTER
BEQ 13$ ;NONE.
BIS #LF.DIS,LB.FGS(R0) ;DTE DISABLED THE LINE
MOV LB.TC1(R0),R1 ;POINT TO BSC TASK
CMP #TTHASP,LB.DVT(R0) ;HASP LINE?
BEQ 21$ ;YES.
BIS #TCOAB!TCIAB,TCFG2(R1) ;SIGNAL ABORT
MOV LB.TCD(R0),R1 ;POINT TO XLATE TASK
BIS #TCOAB!TCIAB,TCFG2(R1) ;SIGNAL ABORT
13$: ADD #2,R3 ;NEXT LINE NUMBER * 2
CMP #<NLINES*2>,R3 ;DONE ALL THE LINES?
BNE 12$ ;NO, DO THE REST.
SEC ;SIGNAL FAILURE
RTS PC ;RETURN
;
;
; HERE TO ABORT ALL DEVICES ON HASP-LINE
;
21$: BIT #LF.ENC,LB.FGS(R0) ;LINE ENABLE COMPLETE?
BEQ 13$ ;NO, CHECK NEXT LINE
MOV LB.NTC(R0),R2 ;GET # OF TCBS FOR HASP LINE
BNE 22$ ;IF IT HAS'NT BEEN SET, MAKE IT 5
MOV #5,R2 ;THATS MAX # OF TCBS HASP LINE
22$: MOV R0,R1 ;GET LCB PTR
ASL R2 ;DEV NO * 2
ADD R2,R1 ;ADD DEVICE #
ASR R2 ;GET BACK DEV NO
MOV LB.TCD(R1),R1 ;POINT TO XLATE TCB OF DEVICE
BEQ 24$ ;NO TCB FOR THE DEVICE
BIS #TCOAB!TCIAB,TCFG2(R1) ;SIGNAL ABORT
24$: SOB R2,22$ ;DO FOR ALL DEVICES ON HASP LINE
BR 13$ ;GO TO NEXT LINE
;
;
; HERE TO CHECK FOR DISABLED LINES
;
DLCKDL: CLR R1 ;START WITH LINE ZERO
11$: ASL R1 ;LINE # * 2
MOV DQLCB(R1),R0 ;POINT TO LCB
BEQ 12$ ;NONE THERE
BIT #LS.ENB,(R0) ;LINE DISABLED?
BNE 12$ ;NO.
BIT #LF.ABC,LB.FGS(R0) ;YES, CHECK IF ABORT COMPLETE
BEQ 12$ ;NOT YET
MOV R0,R4 ;LCB PTR IN R4
MOV LB.TC1(R4),R0 ;POINT TO BSC TCB
;3(023) BEQ 13$ ;ERROR, BSC TCB MISSING
BEQ 12$ ;;++BS-BSC TCB ALREADY DELETED 3(023)
MOV R1,-(SP) ;SAVE LINE # * 2
MOV TCBP1,R3 ;POINT TO START OF CHAIN
JSR PC,DLRLTC ;RELEASE THE BSC TCB
MOV R3,TCBP1 ;UPADTE THE BSC CHAIN PTR
CLR LB.TC1(R4) ;;++BS-CLEAR THE POINTER TO BSC TCB 3(023)
;3(023) MOV R4,R0 ;POINT TO LCB
;3(023) JSR PC,FRESTG ;FREE THE LCB ALSO
MOV (SP)+,R1 ;GET BACK THE LINE # * 2
;3(023) CLR DQLCB(R1) ;CLEAR LCB POINTER
JSR PC, HSSAVR ;;++BS-SAVE THE REGISTERS 3(025)
MOV DQLCB(R1), R2 ;;++BS-POINT R2 TO LCB 3(025)
MOV R2, R3 ;;++BS-POINT R3 TO LCB 3(025)
ADD #LB.ST1, R2 ;;++BS-POINT TO START OF LINE STATISTICS 3(025)
ADD #LB.ST2-2, R3 ;;++BS-DO ALL EXCEPT LINE DRIVER TYPE 3(025)
14$: CLR (R2)+ ;;++BS-CLEAR AN ENTRY 3(025)
CMP R2, R3 ;;++BS-HAVE WE REACHED THE END ? 3(025)
BNE 14$ ;;++BS-NO 3(025)
JSR PC, HSRESR ;;++BS-YES, ALL DONE, RESTORE REGISTERS 3(025)
12$: ASR R1 ;LINE # BACK
INC R1 ;FOR NEXT LINE
CMP R1,#NLINES ;IF LINE CONFIGURED
BLO 11$ ;LOOP FOR NEXT LINE
RTS PC ;RETURN
;
;3(023) 13$: STOPCD DTM ;TCB MISSING
;
;
; SUBROUTINE TO GET A BYTE OF DATA FROM THE PDP-10 THROUGH
; THE INDIRECT PORTION OF THE MESSAGE.
;
; R2 = POINTER TO CURRENT BYTE OF MESSAGE
; R4 = REMAINING COUNT IN THIS MESSAGE
;
; ON RETURN:
;
; C SET -- END OF DATA
; C CLEAR -- R1 = NEXT CHARACTER
;
DLGBYT: TST R4 ;ANY BYTES LEFT IN THIS POINTER?
BEQ 12$ ;NO, TRY NEXT PAIR
11$: DEC R4 ;YES, COUNT DOWN BYTE COUNTER
MOVB (R2)+,R1 ;PICK UP BYTE
INC TCXFR(R5) ;COUNT A BYTE TRANSFERED
CLC ;SUCCESS RETURN
RTS PC
;
; HERE IF THE COUNT IS DEPLETED.
;
12$:
SEC ;0 COUNT = EOF
RTS PC ;GIVE EOF RETURN.
;
;
; SUBROUTINE TO PUT A BYTE OF DATA INTO PDP-10 MEMORY
; BY APPENDING TO THE INDIRECT MESSAGE BEING BUILT.
;
; THIS SUBROUTINE MAY BE CALLED ONLY FROM DTE20 SUBROUTINES.
;
; R1 = BYTE TO STORE
; R2 = POINTER TO THE INDIRECT MESSAGE
; R4 = REMAINING COUNT IN THIS MESSAGE
;
; ON RETURN:
;
; C SET -- THERE IS NO ROOM FOR ANY MORE BYTES
; C CLEAR -- THERE IS ROOM FOR ANOTHER BYTE
;
DLPBYT: MOVB R1,(R2)+ ;STORE BYTE IN PDP-10 MEMORY
INC TCXFR(R5) ;COUNT A BYTE TRANSFERED
DEC R4 ;ANY ROOM LEFT IN THIS BYTE POINTER?
BEQ 12$ ;NO, CHECK FOR ANOTHER.
11$: CLC ;YES, INDICATE MORE ROOM
RTS PC ;RETURN.
;
; HERE WHEN THE COUNT RUNS OUT
;
12$: SEC ;NO MORE ROOM
RTS PC ;RETURN.
;
;
; SUBROUTINE TO PUT A WORD OF DATA INTO PDP-10 MEMORY,
; LOW BYTE FIRST.
;
; R1 = WORD TO STORE
; R2 = POINTER TO INDIRECT MESSAGE BEING BUILT
; R4 = REMAINING COUNT IN THIS MESSAGE
;
; ON RETURN:
;
; C SET -- THERE IS NO ROOM FOR ANY MORE BYTES
; (POSSIBLY HIGH BYTE WAS NOT STORED)
; C CLEAR -- THERE IS ROOM FOR ANOTHER BYTE
;
DLPWRD: JSR PC,DLPBYT ;STORE LOW BYTE IN PDP-10 MEMORY
BCS 11$ ;NO MORE ROOM
SWAB R1 ;GET HIGH BYTE
JSR PC,DLPBYT ;STORE HIGH BYTE
11$: RTS PC ;RETURN.
;
;
; SUBROUTINE TO COPY A STRING OF WORDS OUT THROUGH THE DTE20
;
; R0 = POINTER TO FIRST WORD
; R2 = POINTER TO INDIRECT MESSAGE BEING BUILT
; R3 = POINTER TO LAST WORD + 2
; R4 = REMAINING COUNT IN THE INDIRECT MESSAGE
;
; ON RETURN:
;
; C SET -- NO MORE ROOM FOR MORE BYTES
; (POSSIBLY NOT ALL OF THIS STRING WAS STORED)
; C CLEAR -- ROOM FOR MORE BYTES
;
DLPSTR: MOV (R0)+,R1 ;GET WORD TO STORE
JSR PC,DLPWRD ;STORE IT
BCS 11$ ;NO MORE ROOM
CMP R0,R3 ;DONE ALL WORDS YET?
BNE DLPSTR ;NO, DO ANOTHER.
CLC ;YES, ALL DONE.
11$: RTS PC ;RETURN.
;
.SBTTL DN60 FUNCTIONS INITIATED BY TEN
;
; DLTEXM SUBROUTINE TO DO THE EXAMINE FUNCTION
; DLTDEP SUBROUTINE TO DO THE DEPOSIT FUNCTION
;
DLTEXM:
DLTDEP: ;SAME ENTRY FOR DEPOSIT FUNCTION
MOV R5,R1 ;BUILD POINTER TO HEADER IN TCB
ADD #DT10HD,R1 ;POINT TO HEADER TO BE SENT TO TEN
.IIF NE,DEBUG,MOV R1,DTO10Q(R5) ;SAVE IT FOR REF
MOV NXMGO,-(SP) ;SAVE PREV NXMGO ADDRESS
MOV #14$,NXMGO ;SET CURRENT NXM PROCESSING ADR
CMPB DT11DF(R5),#12 ;IS IT A DEPOSIT FUNCTION?
BEQ 13$ ;YES,GO DO DEPOSIT
MOV @DT11AD(R5),DT10DT(R5) ;EXAMINE LOCATION PUT DATA IN 10 SIDE
11$: MOV (SP)+,NXMGO ;RESTORE XMGO
MOVB #1,DT10DF+1(R5) ;SET RESULT CODE =1;SUCCESS
12$:
CLR DTXADR(R5) ;NO DATA FOR IND XFER
RTS PC ;RETURN
;
13$: MOV DT11DT(R5),@DT11AD(R5) ;DEPOSIT THE DATA
BR 11$ ;SEND RESULT TO TEN
;
14$: MOV (SP)+,NXMGO ;RESTORE NXMGO
MOVB #3,DT10DF+1(R5) ;BAD ADR ;REJECT CODE
BR 12$
;
;
; DLTRES-SUBROUTINE TO PERFORM THE " READ DN60 STATUS "
;
DLTRES:
MOV DT11DT(R5),DT10DT(R5) ;SET COUNT TO BE SENT TO TEN
BEQ 11$ ;ZERO COUNT UNREASONABLE
MOV DT11DT(R5),R4 ;COUNT OF BYTES IN STATUS
JSR PC,DMCGET ;GET A DMC BUFFER TO GO TO 2020
BCS 90$ ;NONE, SHOULD NEVER HAPPEN
MOV R1,R2 ;SAVE BUFFER ADDRESS
MOV R2,DTXADR(R5) ;ADR OF INDIRECT DATA SET
MOV DT11DT(R5),CHLEN(R1) ;STORE LENGTH IN CHUNK
ADD #CHDAT,R2 ;POINT TO DATA PART
MOV #D60ST1,R0 ;POIN TO THE FIRST WORD OF STATUS
MOV #D60ST2+2,R3 ;POINT TO LAST WORD+2
JSR PC,DLPSTR ;MOVE A WORDS IN BUFFER
MOV TCXFR(R5),DT10DT(R5) ;NO OF BYTES TO XFER
BIS #B15,DT10FN(R5) ;INDICATE INDIRECT DATA
MOVB #1,DT10DF+1(R5) ;SUCCESS CODE TO TEN
CLC ;SUCCESS ALWAYS
9$: RTS PC ;RETURN
90$: JSR PC,NOBUFS
;
; HERE IF WE GET A ZERO COUNT ON 'READ DN60 STATUS'.
; THIS IS UNREASONABLE.
;
11$:
STOPCD TER ;ZERO LENGTH INVALID
;
;
; SUBROUTINE TO PERFORM THE "READ DATA" FUNCTION.
; MESSAGE QUE IS EXAMINED FOR A MESSAGE FROM THAT LINE
; AND IF ONE IS FOUND IT BECOMES CURRENT MESSAGE. THE
; USER MAY ASK FOR A MAXIMUM OF ONE CHUNK ONLY,HOWEVER
; IF ASKED FOR MORE THAN CHUNK HAS CURRENTLY, HE GETS
; WHATS LEFT IN THE CURRENT CHUNK.
;
DLTRDT:
MOV DT11DT(R5),DT10DT(R5) ;LENGTH OF INDIRECT DATA
BEQ 23$ ;ZERO LENGTH UNREASONABLE
MOVB DT11AD+1(R5),R0 ;GET LINE NUMBER
CMP R0,NDQ11S ;IS IT REASONABLE?
BHIS 23$ ;NO.
ASL R0 ;LINE NUMBER * 2
MOV DQLCB(R0),R4 ;POINT TO LCB
BEQ 23$ ;IT HAS NOT BEEN CREATED
BIT #LS.ENB,(R4) ;IS IT ENABLED?
BEQ 23$ ;NO, LOSE.
MOV R4,TCLCB(R5) ;AND REMEMBER LCB POINTER
MOVB DT11AD(R5),R1 ;GET DEVICE #
BIC #177770,R1 ;EXTRACT DEVICE # FROM RCB
;3(024).IF NE,DEBUG
;3(024) BNE 10$ ;TO TRACK -10 SCREW UPS
;3(024) CMP #TTHASP,LB.DVT(R4) ;CHECK DEV FOR HASP
;3(024) BNE 10$ ;
;3(024) STOPCD TER ;TEN ERROR
;3(024) 10$:
;3(024).ENDC ;.IF NE,DEBUG
JSR PC, DLMCHK ;;++BS- CHECK FOR LEGAL DEVICE NUMBER 3(024)
BCS 23$ ;;++BS- BAD DEVICE NUMBER, REJECT 3(024)
ASL R1 ;DEVICE * 2
MOV R1,R2 ;KEEP DEVICE # FOR LATER
ADD R4,R1 ;ADD DEVICE #
MOV LB.TCD(R1),TCXLT(R5) ; GET XLATE TASK POINTER
11$: JSR PC,DLGTCM ;GET CURRENT OR NEW MESSAGE
BCS 22$ ;NO MESSAGE FOR THIS DEVICE
12$: MOV MSGLCH(R0),R1 ;GET POINTER TO THE CHUNK
13$: MOV R1,R3 ;BUILD PONTER TO DATA
BEQ 21$ ;END OF MESSAGE FOUND
MOV (R3)+,DLPMST(R5) ;SAVE POINTER TO NEXT CHUNK
MOV (R3)+,R2 ;GET COUNT, POINT TO DATA
;
;
; THE FOLLOWING IS THE REGISTER ALLOCATION:
;
; R0 = POINTS TO THE CURRENT MESSAGE BEING PROCESSED
; R1 = POINTS TO CURRENT CHUNK
; R2 = AMOUNT OF BYTES IN THIS CHUNK
; R3 = POINTS TO DATA IN CURRENT CHUNK
; R5 = POINTER TO DTE20 DRIVER TCB
; MSGLCH(R0) = CURRENT CHUNK TO BE SENT
; MSGPTR(R0) = CURRENT BYTE TO BE SENT
;
14$: TST R2 ;ANY BYTES LEFT IN THIS CHUNK?
BEQ 20$ ;NO, LOOK FOR ANOTHER.
ADD R3,R2 ;POINT TO END OF THE CHUNK
CMP MSGPTR(R0),R2 ;DOES CHAR PTR LIE IN THIS RANGE
BLOS 15$ ;YES,IT DOES
STOPCD TER ;ERROR,CHAR PTR OUT OF RANGE
;
15$: MOV MSGPTR(R0),R3 ;SET UP INDIRECT DATA ADR
SUB MSGPTR(R0),R2 ;THIS IS MAX DATA WE HAVE IN CHUNK
CMP DT11DT(R5),R2 ;IS IT LESS THAN ASKED FOR?
BLT 19$ ;YES
MOV R2,DT10DT(R5) ;NO,GIVE HIM WHAT WE HAVE
MOV DLPMST(R5),R1 ;GET ADR OF NEXT CHUNK IN MESSAGE
MOV R1,MSGLCH(R0) ;SAVE IN MESSAGE HEADER
ADD #CHDAT,R1 ;BUILD DATA POINTER
MOV R1,MSGPTR(R0) ;SAVE NEW DATA POINTER
16$:
17$: MOVB #1,DT10DF+1(R5) ;SUCCESS CODE
JSR PC,DMCGET ;GET A DMC BUFFER FOR XMISSION TO 2020
BCC 6$
JSR PC,NOBUFS ;SHOULD ALWAYS HAVE A DMC BUFFER
6$:
MOV R1,R0 ;SAVE BUFFER ADDRESS
MOV DT10DT(R5),R2 ;[3(003)]GET AMOUNT TO XFER
MOV R2,CHLEN(R0) ;BYTE LENGTH FOR MSG TO 10/20
MOV R2,TCXFR(R5) ;PUT FOR DMC DRIVER
ADD #CHDAT,R0 ;POINT TO DATA PART OF BUFFER
7$: MOVB (R3)+,(R0)+
SOB R2,7$ ;TRANSFER DATA TO BUFFER
MOV R1,DTXADR(R5) ;REMEMBER WHERE DATA IS
18$: CLC ;NO FATAL ERRORS
RTS PC ;RETURN
;
19$: MOV DT11DT(R5),DT10DT(R5) ;SET AMOUNT TO BE XFERRED
ADD DT11DT(R5),MSGPTR(R0) ;UPDATE CHAR PTR
BR 16$ ;SEND TO TEN
;
;
; HERE WHEN THE CHUNK RUNS OUT. GO ON TO THE NEXT CHUNK.
;
20$: MOV DLPMST(R5),R1 ;POINT TO NEXT CHUNK
BNE 13$ ;PROCESS IT, IF ANY.
;
; HERE ON END OF MESSAGE
;
21$: ;R0 DOES POINT TO MESSAGE
MOV TCIDLE,R1 ;POINT TO IDLE TASK
JSR PC,QUEMSG ;SEND IT THE MSG TO FREE
CLR DT10DT(R5) ;ZERO BYTES SENT TO TEN
CMP #TTHASP,LB.DVT(R4) ;HASP LINE?
BNE 33$ ;NO.
CLR @TCPDM(R5) ;CLEAR DEVICE MESSAGE PTR
BR 11$ ;JOIN THE MAIN LOOP
33$:
MOV LB.LNU(R4),R1 ;GET LINE NUMBER
ASL R1 ;LINE NUMBER * 2
ADD R5,R1 ;POINT INTO TCB
CLR TCCMSG(R1) ;WE HAVE NO CURRENT MESSAGE
BR 11$ ;FIND NEXT MESSAGE AND SENT TO TEN
;
;
; HERE IF THERE IS NO MESSAGE FOR THAT LINE
;
22$: CLR DT10DT(R5) ;NO INDIRECT DATA TO SEND
MOV TCXLT(R5),R1 ;POINT TO XLATE TASK
BIT #TCIAB!TCIEC,TCFG2(R1) ;EOF OR ABORT?
BEQ 24$ ;NO. "DELAYED" RETURN.
23$: MOVB #3,DT10DF+1(R5) ;YES, GIVE "REJECT" RETURN
BIT #TCIAB, TCFG2(R1) ;;++BS- ABORT ? 3(015)
BNE 36$ ;;++BS- YES, CLEAR THE ACTIVE BIT 3(015)
BIT #TCIPR, TCFG2(R1) ;;++BS- INPUT PERMISSION REQUESTED ? 3(015)
BNE 18$ ;;++BS- YES, DO NOT CLEAR THE ACTIVE BIT 3(015)
;;++BS- NO, CLEAR THE ACTIVE BIT 3(015)
36$: ;;++BS-NEW LABEL 3(015)
JSR PC, DLRCAB ;CLEAR THE DEVICE ACTIVE BIT
BR 18$ ;SEND REJECT TO TEN
;
24$: MOVB #2,DT10DF+1(R5) ;INDICATE "DELAYED"
JSR PC, DLRCAB ;CLEAR DEVICE ACTIVE BIT
25$: BR 18$ ;SEND IT TO TEN
;;++BS-CODE TO CLEAR THE DEVICE ACTIVE BIT
DLRCAB: JSR PC, HSSAVR ;SAVE THE REGISTERS
MOVB DT11AD+1(R5), R0 ;GET LINE NUMBER
BIC #177770, R0 ;CLEAR JUNK
MOVB DT11AD(R5),R1 ;GET DEVICE NUMBER
BIC #177400, R1 ;CLEAR JUNK
TST R1 ;CHECK FOR ZERO DEVICE NUMBER
BNE 35$ ;NON ZERO, CONTINUE
MOV TCLCB(R5), R2 ;POINT TO LCB
BIT #LF.SIM, LB.FGS(R2) ;SIMULATION ?
BNE 34$ ;YES
MOV #3, R1 ;NO, SUPPORT, MUST BE CDR
BR 35$ ;CLEAR DEVICE ACTIVE BIT
34$: MOV #4, R1 ;SIMULATION, MUST BE LPT
35$: JSR PC, HSAMPC ;CLEAR DEVICE ACTIVE BIT
JSR PC, HSRESR ;RESTORE THE REGISTERS
RTS PC ;RETURN
;;++BS-END OF CODE TO CLEAR THE DEVICE ACTIVE BIT
;
; THIS SUBROUTINE LOOKS FOR A CURRENT MESSAGE AND IF
; NONE IS FOUND, GETS OLDEST MESSAGE WITH THE ID.
;
DLGTCM: MOV TCLCB(R5),R4 ;POINT TO LCB
MOV LB.LNU(R4),R1 ;GET LINE NUMBER
ASL R1 ;LINE NUMBER * 2
ADD R5,R1 ;POINT INTO TCB
CMP #TTHASP,LB.DVT(R4) ;HASP LINE?
BEQ 11$ ;YES
MOV TCCMSG(R1),R0 ;IS THERE A CURRENT MESSAGE?
BNE 16$ ;YES, CONTINUE WITH IT.
BR 13$ ;GO GET MESSAGE FOR THE LINE
11$: MOV TCCMSG(R1),R1 ;GET PTR TO DEV MSG
BNE 12$ ;THERE'S ONE
STOPCD HSB ;NONE EXISTS
;
12$: ADD R2,R1 ;GET DEVICE MSG PTR
MOV R1,TCPDM(R5) ;SAVE PTR TO DEV MSG
MOV (R1),R0 ;ANY DEVICE MESSAGE?
BNE 17$ ;YES.
MOV TCXLT(R5),R0 ;POINT TO DEVICE'S TCB
MOV TCCTP(R0),R1 ;GET THE RCB
MOV LB.LNU(R4),R0 ;GET LINE #
SWAB R0 ;PUT IN LEFT BYTE
ADD R0,R1 ;MAKE I.D. FOR THE MESSAGE
JSR PC,DEQMID ;GET OLDEST MSG WITH THAT ID
BCS 16$ ;THERE IS NONE.
;;++BS-CODE TO UNSUSPEND A DEVICE IF LESS THAN 2 MESSAGES QUEUED
MOV R3, -(SP) ;;++BS-SAVE R3
MOV TCXLT(R5), R3 ;;++BS-POINT TO XLATE TASK
DEC TCIMC(R3) ;;++BS-DECREMENT COUNT OF INPUT MESSAGES
CMP TCIMC(R3), #2 ;;++BS-LESS THAN 2 ?
BGE 31$ ;;++BS-NO, CONTINUE
MOV R1, -(SP) ;;++BS-YES, SAVE R1
MOV TCCTP(R3), R1 ;;++BS-GET DEVICE TYPE
BIC #177770, R1 ;;++BS-GET DEVICE NUMBER
JSR PC, HSUNSP ;;++BS-UNSUSPEND THE DEVICE
;;++BS-TCLCB(R5) POINTS TO XLATE LCB
MOV (SP)+, R1 ;;++BS-RESTORE R1
31$: MOV (SP)+, R3 ;;++BS-RESTORE R3
;;++BS-END OF CODE TO UNSUSPEND A DEVICE IF LESS THAN 2 MESSAGES QUEUED
MOV R0,@TCPDM(R5) ;SAVE DEVICE MSG PTR
17$: CLC ;SUCCESSFUL
RTS PC ;RETURN
;
13$: MOV LB.LNU(R4),R1 ;GET LINE # (I.D. FOR 2780/3780)
JSR PC,DEQMID ;GET MESSAGE FOR THE I.D.
BCS 16$ ;NO MESSAGE FOR THIS I.D.
MOV LB.LNU(R4),R1 ;GET LINE NUMBER
ASL R1 ;LINE NUMBER * 2
ADD R5,R1 ;POINT INTO TCB
MOV R0,TCCMSG(R1) ;REMEMBER CURRENT MESSAGE
CLC ;SUCCESS
16$: RTS PC ;EXIT
;
;
;
; SUBROUTINE TO PERFORM THE "WRITE DATA" FUNCTION. DATA IS
; FETCHED THROUGH THE DTE20 AND PLACED IN CHUNKS. THE CHUNKS
; ARE SENT TO THE XLATE TASK FOR TRANSLATION AND SUBSEQUENT
; QUEUEING TO THE DQ11.
;
; ON RETURN:
;
; C IS SET IF THE DTE20 FAILS OR THERE IS SOME INCONSISTENCY
; IN THE PDP-10 INFORMATION. OTHERWISE, R0 = RESULT CODE.
;
DLTWDT:
MOVB DT11AD+1(R5),R0 ;GET LINE NO
CMP R0,NDQ11S ;IS IT REASONABLE?
BHIS 14$ ;NO, PARM ERROR.
ASL R0 ;LINE NUMBER * 2
MOV DQLCB(R0),R4 ;POINT TO LCB
BEQ 14$ ;NOT INITIALIZED
BIT #LS.ENB,(R4) ;IS THE LINE ENABLED?
BEQ 14$ ;NO.
MOVB DT11AD(R5),R1 ;GET RCB OR DEVICE #
BIC #177770,R1 ;EXTRACT DEVICE # FROM RCB
;3(024).IF NE,DEBUG
;3(024) BNE 10$ ;
;3(024) CMP #TTHASP,LB.DVT(R4) ;CHECK FOR HASP
;3(024) BNE 10$ ;ONLY
;3(024) STOPCD TER ;TEN ERROR
;3(024) 10$:
;3(024).ENDC
JSR PC, DLMCHK ;;++BS- CHECK FOR LEGAL DEVICE NUMBER 3(024)
BCS 14$ ;;++BS- BAD DEVICE NUMBER, REJECT 3(024)
ASL R1 ;DEVICE * 2
ADD R4,R1 ;ADD DEVICE #
MOV LB.TCD(R1),R0 ;POINT TO XLATE TASK
MOV R0,TCXLT(R5) ;REMEMBER TCB OF XLATE TASK
MOV #-1,DT10AK ;NOTE THAT WE EXPECT ED DATA
TST TCCHK1(R0) ;INPUT WAITING FOR XLATE TASK??
BNE 12$ ;YES, WAKE UP PDP-10 WAIT A WHILE
;;;++BS-CODE TO SET DEVICE ACTIVE BIT FOR OUTPUT
; JSR PC, HSSAVR ;SAVR THE REGISTERS
; MOVB DT11AD+1(R5), R0 ;GET LINE NUMBER
; BIC #177770, R0 ;CLEAR JUNK
; MOVB DT11AD(R5), R1 ;GET DEVICE NUMBER-RCB
; BIC #177400, R1 ;CLEAR JUNK
; TST R1 ;CHECK FOR ZERO DEVICE NUMBER
; BNE 35$ ;NON ZERO, CONTINUE
; MOV TCLCB(R5), R2 ;POINT TO LCB
; BIT #LF.SIM, LB.FGS(R2) ;SIMULATION ?
; BNE 34$ ;YES
; MOV #4, R1 ;NO, SUPPORT, MUST BE LPT
; BR 35$ ;SET DEVICE ACTIVE BIT
;34$: MOV #3, R1 ;SIMULATION, MUST BE CDR
;35$: JSR PC, HSACMP ;SET THE DEVICE ACTIVE BIT
; JSR PC, HSRESR ;RESTORE THE REGISTERS
;;;++BS-END OF CODE TO SET THE DEVICE ACTIVE BIT
CLC ;INDICATE SUCCESSFUL RETURN
RTS PC ;RETURN
;
;
;;++BS-CODE TO CLEAR DEVICE ACTIVE BIT
12$:
JSR PC, HSSAVR ;SAVE THE REGISTERS
MOVB DT11AD+1(R5), R0 ;GET LINE NUMBER
BIC #177770, R0 ;CLEAR JUNK
MOVB DT11AD(R5), R1 ;GET DEVICE NUMBER-RCB
BIC #177400, R1 ;CLEAR JUNK
TST R1 ;CHECK FOR ZERO DEVICE NUMBER
BNE 37$ ;NON ZERO, CONTINUE
MOV TCLCB(R5), R2 ;POINT TO LCB
BIT #LF.SIM, LB.FGS(R2) ;SIMULATION ?
BNE 36$ ;YES
MOV #4, R1 ;NO, SUPPORT, MUST BE LPT
BR 37$ ;CLEAR DEVICE ACTIVE BIT
36$: MOV #3, R1 ;SIMULATION, MUST BE CDR
37$: JSR PC, HSAMPC ;CLEAR THE DEVICE ACTIVE BIT
JSR PC, HSRESR ;RESTORE THE REGISTERS
;;++BS-END OF CODE TO CLEAR THE DEVICE ACTIVE BIT
MOV TCXLT(R5),R1 ;POINT TO XLATE TASK
BIT #TCOAB,TCFG2(R1) ;HAS STREAM BEEN ABORTED?
BEQ 13$ ;NO,INDICATE DELAYED OPERATION
JMP DLSERR ;OPERATION REJECTED
;
13$:
TWIDDL
JMP DLSDLY ;OPERATION DELAYED
;
14$:
MOV #-1,DT10AK ;;++BS-NOTE THAT WE EXPECT ED DATA 3(022)
JMP DLSERR ;;++BS-REJECT THE REQUEST 3(022)
;3(022) SEC ;FATAL ERROR
;3(022) RTS PC ;RETURN
;
;
; SUBROUTINE TO PERFORM THE "READ DEVICE STATUS" FUNCTION.
; THE STATUS MESSAGE IS ASSEMBLED IN A BUFFER AND SENT TO-TEN
; AS INDIRECT DATA. NO EXCEPTIONAL CONDITIONS ARE POSSIBLE.
;
DLTRDS: TST DT11DT(R5) ;ASKING FOR ZERO?
BEQ 13$ ;YES, THROW HIM OFF.
MOVB DT11AD+1(R5),R0 ;GET LINE NO
CMP R0,NDQ11S ;IS IT REASONABLE?
BHIS 13$ ;NO, ERROR.
ASL R0 ;LINE NUMBER * 2
MOV DQLCB(R0),R4 ;POINT TO SPECIFIED LCB
BEQ 13$ ;NOT INITIALIZED.
BIT #LS.ENB,(R4) ;IS THE LINE ENABLED?
BEQ 13$ ;NO.
MOVB DT11AD(R5),R1 ;GET RCB OR DEVICE #
BIC #177770,R1 ;EXTRACT DEVICE # FROM RCB
;3(024).IF NE,DEBUG
;3(024) BNE 10$ ;TRACK 10 ERRORS
;3(024) CMP #TTHASP,LB.DVT(R4) ;CHECK HASP DEV #
;3(024) BNE 10$ ;ONLY
;3(024) STOPCD TER ;
;3(024) 10$:
;3(024).ENDC
JSR PC, DLMCHK ;;++BS-CHECK FOR LEGAL DEVICE NUMBER 3(024)
BCS 13$ ;;++BS-BAD DEVICE NUMBER, REJECT 3(024)
ASL R1 ;DEV NO * 2
ADD R4,R1 ;ADD DEVICE # TO
MOV LB.TCD(R1),TCXLT(R5) ; POINT TO XLATE TASK
MOV R4,TCLCB(R5) ;SAVE LCB IN CASE WE NEED IT LATER
JSR PC,DMCGET ;GET A DMC BUFFER TO SEND TO 2020
BCC 5$
JSR PC,NOBUFS ;SHOULD ALWAYS BE A DMC BUFFER FREE
5$:
MOV R1,R2 ;NEED ADDRESS HERE TOO
MOV R2,DTXADR(R5) ;SAVE IT FOR TO-TEN XFER
ADD #CHDAT,R2 ;START OF DATA
MOV DT11DT(R5),R4 ;SET COUNT PROVIDED BY TEN
MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
MOVB TCDVT(R0),R1 ;GET DEVICE TYPE
JSR PC,DLPBYT ;SEND TO PDP-10
BCS 13$ ;MUST BE MORE ROOM
MOV TCCTP(R0),R1 ;GET COMPONENT TYPE
JSR PC,DLPBYT ;SEND TO PDP-10
BCS 13$ ;MUST BE MORE ROOM
MOV TCPGC(R0),R1 ;GET PAGE COUNT REGISTER
JSR PC,DLPWRD ;SEND TO PDP-10
; BCS 11$ ;NO MORE ROOM
BCS 13$ ;;++BS-NO MORE ROOM 3(014)
MOV TCFG1(R0),R1 ;GET FLAGS WORD 1
JSR PC,DLPWRD ;SEND TO PDP-10
BCS 13$ ;MUST BE MORE ROOM
MOV TCFG2(R0),R1 ;GET FLAGS WORD 2
JSR PC,DLPWRD ;SEND TO PDP-10
BCS 13$ ;MUST BE MORE ROOM
MOV TCRSZ(R0),R1 ;GET RECORD SIZE FOR THE DEVICE
JSR PC,DLPWRD ;SEND TO PDP-10
; BCS 11$ ;NO MORE ROOM
BCS 13$ ;;++BS-NO MORE ROOM 3(014)
MOV TCLCB(R5), R1 ;;++BS-POINT TO LCB 3(014)
MOV LB.FGS(R1), R1 ;;++BS-GET THE LINE FLAGS 3(014)
JSR PC, DLPWRD ;;++BS-SEND TO PDP-10 3(014)
BCS 13$ ;;++BS-ERROR, NO MORE ROOM 3(017)
MOV TCLCB(R5), R1 ;;++BS-POINT TO LCB 3(017)
MOV LB.SIG(R1), R1 ;;++BS-GET THE LINE SIGNATURE 3(017)
JSR PC, DLPWRD ;;++BS-SEND TO PDP-10 3(017)
BCS 11$ ;;++BS-SEND THE INDIRECT MESSAGE 3(014)
;
; CONTINUED ON NEXT PAGE
;
;
;
; HERE WHEN THE INDIRECT MESSAGE HAS BEEN BUILT.
;
11$:
MOVB #1,DT10DF+1(R5) ;SEND SUCCESS CODE
MOV TCXFR(R5),DT10DT(R5) ;SETUP INDIRECT DATA LENGTH
CLC ;INDICATE SUCCESS
12$: RTS PC ;RETURN
;
; HERE IF THERE IS ANY ERROR
;
13$:
CLR DT10DT(R5) ;;++BS-ZERO DATA LENGTH 3(020)
BIS #B15, DT10FN(R5) ;;++BS-NO INDIRECT DATA 3(020)
;3(020) SEC ;FATAL ERROR
JSR PC, DLRJRQ ;;++BS-REJECT THE REQUEST 3(020)
RTS PC ;RETURN
;
;
; SUBROUTINE TO PERFORM THE "WRITE DEVICE COMMAND" FUNCTION.
; THE FIRST BYTE OF THE DATA IS THE FUNCTION CODE, IF OTHER
; DATA IS NEEDED IT FOLLOWS THE FUNCTION CODE.
;
; ON RETURN:
;
; C SET -- DTE20 FAILURE OR BADLY FORMED COMMAND
; C CLEAR -- R0 = 1 TO MEAN "SUCCESS", 2 TO MEAN "DELAYED"
;
DLTWDC:
MOVB DT11AD+1(R5),R0 ;GET LINE NUMBER
CMP R0,NDQ11S ;IN RANGE?
BHIS 12$ ;NO, ERROR.
ASL R0 ;YES, LINE NUMBER*2
MOV DQLCB(R0),R0 ;PICK UP LCB POINTER
BEQ 12$ ;NONE IS ERROR
BIT #LS.ENB,(R0) ;IS THE LINE ENABLED?
BEQ 12$ ;NO.
MOV R0, R4 ;;++BS-POINT R4 TO LCB 3(024)
MOVB DT11AD(R5),R1 ;GET RCB OR DEVICE #
BIC #177770,R1 ;EXTRACT DEVICE # FROM RCB
;3(024).IF NE,DEBUG
;3(024) BNE 10$ ;TRACK 10 ERRORS
;3(024) CMP #TTHASP,LB.DVT(R0) ;HASP DEV
;3(024) BNE 10$ ;ONLY
;3(024) STOPCD TER
;3(024) 10$:
;3(024).ENDC
JSR PC, DLMCHK ;;++BS-CHECK FOR LEGAL DEVICE NUMBER 3(024)
BCS 12$ ;;++BS-BAD DEVICE NUMBER, REJECT 3(024)
ASL R1 ;DEVICE * 2
ADD R0,R1 ;ADD DEVICE #
MOV LB.TCD(R1),TCXLT(R5) ;POINT TO XLATE TASK
13$: ;;++BS-NEW LABEL 3(021)
MOV #-1,DT10AK ;NOTE THAT WE EXPECT ED DATA
CLC ;INDICATE SUCCESS
RTS PC ;RETURN
;
12$:
CLR TCXLT(R5) ;;++BS-NO XLATE TASK FOR ERROR 3(021)
BR 13$ ;;++BS-REJECT HIS REQUEST ON ED DATA 3(021)
;3(021) SEC ;FATAL ERROR
;3(021) RTS PC ;RETURN
;
DLTWD1: MOV DT11Q(R5),R2 ;POINT TO WHERE STATUS IS
ADD #CHDAT,R2 ;POINT TO DATA PART OF CHUNK
MOV DT11DT(R5),R4 ;COUNT OF BYTES RECEIVED
JSR PC,DLGBYT ;GET COMMAND CODE BYTE INTO R1
BCS 11$ ;NONE, ERROR.
TST TCXLT(R5) ;;++BS-IS THERE A XLATE TASK ? 3(021)
BEQ 14$ ;;++BS-NO, REJECT THE REQUEST 3(021)
;;++BS-YES, CONTINUE 3(021)
MOV #12$,R0 ;POINT TO DISPATCH TABLE
MOVB #1,DT10DF+1(R5) ;SUCCESS CODE
JSR PC,DLDISP ;DISPATCH TO HANDLER
11$: RTS PC ;RETURN
14$: JSR PC, DLRJRQ ;;++BS-REJECT THE REQUEST 3(021)
BR 11$ ;;++BS-CONTINUE 3(021)
;
;
; DISPATCH TABLE
;
12$: .WORD <<13$-12$>/2>-2 ;MAX TABLE INDEX
.WORD 0 ;0 = INVALID
.WORD DLTD01 ;1 = SET CHARACTERISTICS
.WORD 0 ;2 = RESERVED
.WORD DLTD03 ;3 = DUMP OUTPUT [1(627)]
.WORD DLTD04 ;4 = CLEAR "INPUT PERMISSION WAS REQUESTED"
.WORD 0 ;5 = RESERVED
.WORD DLTD06 ;6 = INTERPRET CC ON INPUT
.WORD DLTD07 ;7 = DONT
.WORD DLTD08 ;8 = INTERPRET CC ON OUTPUT
.WORD DLTD09 ;9 = DONT
.WORD 0 ; RESERVED
.WORD 0 ; RESERVED
.WORD DLTD12 ;12 = DO COMPONENT SELECTION
.WORD DLTD13 ;13 = DONT
.WORD DLTD14 ;14 = ENABLE PAGE COUNTER
.WORD DLTD15 ;15 = DISABLE IT
.WORD 0 ;16 = RESERVED
.WORD DLTD17 ;17 = DO SPACE COMPRESSION
.WORD DLTD18 ;18 = DONT
.WORD DLTD19 ;19 = USE OLD BSC PROTOCOL
.WORD DLTD20 ;20 = DONT
.WORD DLTD21 ;21 = REQUEST OUTPUT PERMISSION
.WORD DLTD22 ;22 = GRANT INPUT PERMISSION
.WORD DLTD23 ;23 = SIGNAL OUTPUT EOF
.WORD DLTD24 ;24 = CLEAR OUTPUT EOF COMPLETE
.WORD DLTD25 ;25 = SIGNAL OUTPUT ABORT
.WORD DLTD26 ;26 = CLEAR OUTPUT ABORT COMPLETE
.WORD DLTD27 ;27 = CLEAR INPUT EOF COMPLETE
.WORD DLTD28 ;28 = SIGNAL INPUT ABORT
.WORD DLTD29 ;29 = CLEAR INPUT ABORT COMPLETE
.WORD DLTD30 ;30 = SUSPEND DEVICE (HASP)
.WORD DLTD31 ;31 = UNSUSPEND DEVICE (HASP)
.WORD DLTD32 ;32 = SET DEVICE RECORD SIZE
13$:
;
;
; SUBROUTINE TO PERFORM THE "READ LINE STATUS" FUNCTION.
; IF THE LINE IS NOT INITIALIZED, GIVE A 0-LENGTH REPLY
;
DLTRLS:
MOV DT11DT(R5),DT10DT(R5) ;SET LENGTH OF IDIRECT DATA
BEQ 14$ ;ZERO LENGTH UNREASONABLE
MOVB DT11AD+1(R5),R0 ;GET LINE NO
MOV R1,-(SP) ;;++BS-SAVE R1
MOVB NDQ11S, R1 ;;++BS-GET NUMBER OF DQ11S
DEC R1 ;;++BS-CONVERT TO LINE NUMBER
CMPB R1, R0 ;;++BS-EXCEED MAX NUMBER ?
BGE 31$ ;;++BS-NO, CONTINUE
MOV (SP)+, R1 ;;++BS-YES, RESTORE R1
BR 32$ ;;++BS-REJECT THE REQUEST
; CMP R0,NDQ11S ;IS IT REASONABLE?
; BHIS 14$ ;NO, ERROR.
31$: MOV (SP)+, R1 ;;++BS-RESTORE R1
ASL R0 ;LINE NUMBER * 2
MOV DQLCB(R0),R4 ;POINT TO SPECIFIED LCB
BEQ 11$ ;NOT INITIALIZED.
BIT #LS.ENB,(R4) ;IS THE LINE ENABLED?
BEQ 11$ ;NO.
MOV R4,TCLCB(R5) ;SAVE LCB IN CASE WE NEED IT LATER
MOV DT11DT(R5),R4 ;SET UP COUNT FOR DLPBYT
JSR PC,DMCGET ;GET A DMC BUFFER
BCC 5$
JSR PC,NOBUFS ;CANNOT HAPPEN
5$:
MOV R1,R2 ;NEED ADDRESS HERE TOO
MOV R2,DTXADR(R5) ;SAVE ADR OF INDIRECT DATA
ADD #CHDAT,R2 ;START OF DATA
MOV TCLCB(R5),R0 ;POINT TO LCB
MOVB LB.DVT(R0),R1 ;GET TERMINAL TYPE
JSR PC,DLPBYT ;STORE IN USER'S BUFFER
BCS 14$ ;ERROR IF NO MORE ROOM
;3(017) MOVB LB.FGS(R0),R1 ;GET LINE FLAGS
;3(017) JSR PC,DLPBYT ;STORE IN USER'S BUFFER
MOV LB.FGS(R0), R1 ;;++BS-GET LINE FLAGS 3(017)
JSR PC, DLPWRD ;;++BS-SEND TO PDP-10 3(017)
BCS 14$ ;ERROR IF NO MORE ROOM
MOV #B0,R1 ;INDICATE LINE IS ENABLED
BIT #LF.TSP,LB.FGS(R0) ;OUTPUT TRANSPARENT?
BEQ 21$ ;NO.
BIS #B3,R1 ;HOPE NOBODY ELSE USES BIT 3
21$: JSR PC,DQMDMS ;SET DTR AND DSR INTO R1
JSR PC,DLPBYT ;STORE STATUS BYTE IN USER'S BUFFER
;
; CONTINUED ON NEXT PAGE
;
;
; INCLUDE BSC STATISTICS IN LINE STATUS
;
BCS 14$ ;ERROR IF NO ROOM
;3(017) CLR R1 ;SEND RESERVE BYTE ALSO [[RELEASE 4]]
;3(017) JSR PC,DLPBYT ;IN USERS BUFFER
;3(017) BCS 14$ ;ERROR IF NO ROOM
MOV TCLCB(R5),R0 ;POINT R0 TO LCB
MOV #LB.ST2+2,R3 ;COMPUTE ADDRESS OF LAST WORD + 2
ADD R0,R3
ADD #LB.ST1,R0 ;COMPUTE ADDRESS OF FIRST WORD
JSR PC,DLPSTR ;SEND LOTS OF WORDS
11$: MOV TCXFR(R5),DT10DT(R5) ;SETUP INDIRECT DATA LENGTH
MOVB #1,DT10DF+1(R5) ;SEND SUCCESS CODE = 1
CLC ;INDICATE SUCCESS
13$: RTS PC ;RETURN
;
; HERE ON A PROTOCOL ERROR
;
14$: SEC ;FATAL ERROR
RTS PC ;RETURN
;
;
; HERE WITH INCORRECT LINE NUMBER
;
32$: MOV TCXFR(R5), DT10DT(R5) ;;++BS-SET UP INDIRECT DATA LENGTH
BEQ 33$ ;;++BS-DON'T SET INDIRECT FOR ZERO LENGTH
BIS #B15, DT10FN(R5);;++BS-INDICATE INDIRECT DATA TO FOLLOW
33$: ;;++BS-JUST SEND THE DIRECT HEADER
JSR PC, DLRJRQ ;;++BS-REJECT THE REQUEST
RTS PC ;;++BS-RETURN
;
;
; SUBROUTINE TO PERFORM THE "WRITE LINE COMMAND" FUNCTION.
; THE FIRST BYTE OF THE DATA IS THE FUNCTION CODE, IF OTHER
; DATA IS NEEDED IT FOLLOWS THE FUNCTION CODE.
;
; ON RETURN:
;
; C SET -- DTE20 FAILURE OR BADLY FORMED COMMAND
; C CLEAR -- R0 = 1 TO MEAN "SUCCESS", 2 TO MEAN "DELAYED"
;
DLTWLC:
MOVB DT11AD+1(R5),R0 ;GET LINE NUMBER
MOV #-1,DT10AK ;NOTE THAT WE EXPECT ED DATA
CLC ;INDICATE SUCCESS
RTS PC ;RETURN
;
12$: SEC ;FATAL ERROR
RTS PC ;RETURN
;
;
; COME HERE WHEN THE INDIRECT DATA HAS ARRIVED.
;
DLTWL1: MOV DT11Q(R5),R2 ;POINT TO WHERE STATUS IS KEPT
ADD #CHDAT,R2 ;POINT TO DATA PART
MOV DT11DT(R5),R4 ;SETUP THE COUNT
JSR PC,DLGBYT ;GET COMMAND CODE BYTE
BCS 11$ ;NONE, ERROR.
MOV #12$,R0 ;POINT TO DISPATCH TABLE
MOVB #1,DT10DF+1(R5) ;SET SUCCESS CODE
JSR PC,DLDISP ;DISPATCH TO HANDLER
11$: RTS PC ;RETURN
;
; DISPATCH TABLE
;
12$: .WORD <<13$-12$>/2>-2 ;MAX TABLE INDEX
.WORD 0 ;0 = INVALID
.WORD DLTL01 ;1 = ENABLE
.WORD DLTL02 ;2 = SET DTR
.WORD DLTL03 ;3 = ABORT AND HANG UP
.WORD DLTL04 ;4 = DISABLE
.WORD DLTL05 ;5 = SET CTS DELAY
.WORD DLTL06 ;6 = SET LENGTH OF SILO WARNING AREA
.WORD DLTL07 ;7 = SET OUTPUT IN TRANSPARENT MODE
.WORD DLTL08 ;8 = SET OUTPUT IN NON-TRANSPARENT MODE
.WORD DLTL09 ;9 = SET TRANSMISSION BLOCK LENGTH
.WORD DLTL10 ;10= SET RECORDS PER MESSAGE
.WORD DLTL11 ;11= SET LINE SIGNATURE
13$:
;
;
;
; SUBROUTINE TO PERFORM THE "WRITE DN60 COMMAND" FUNCTION.
; THE FIRST BYTE OF THE DATA IS THE FUNCTION CODE, IF OTHER
; DATA IS NEEDED IT FOLLOWS THE FUNCTION CODE.
;
; ON RETURN:
;
; C SET -- DTE20 FAILURE OR BADLY FORMED COMMAND
; C CLEAR -- R0 = 1 TO MEAN "SUCCESS", 2 TO MEAN "DELAYED"
;
DLTWEC:
MOV #-1,DT10AK ;NOTE THAT WE EXPECT ED DATA
CLC ;INDICATE SUCCESS
RTS PC ;RETURN
;
;
; COME HERE WHEN THE INDIRECT DATA ARRIVES.
;
DLTWS1: MOV DT11Q(R5),R2 ;POINT TO STATUS
ADD #CHDAT,R2 ;POINT TO DATA
MOV DT11DT(R5),R4 ;SETUP COUNT
JSR PC,DLGBYT ;GET COMMAND CODE BYTE
BCS 11$ ;NONE, ERROR.
MOV #12$,R0 ;POINT TO DISPATCH TABLE
MOVB #1,DT10DF+1(R5) ;SET SUCCESS CODE
JSR PC,DLDISP ;DISPATCH TO HANDLER
11$: RTS PC ;RETURN
;
; DISPATCH TABLE
;
12$: .WORD <<13$-12$>/2>-2 ;MAX TABLE INDEX
.WORD 0 ;0 = INVALID
; .WORD DLTE01 ;1 = ???
13$:
;
;
; SUBROUTINE FOR LINE COMMAND 1: ENABLE THE LINE
;
DLTL01: CLR NWLFLG ;;++BS- ASSUME THIS IS A NEW LINE
MOVB DT11AD+1(R5),R0 ;GET LINE NUMBER
MOV R1,-(SP) ;;++BS-SAVE R1
MOVB NDQ11S, R1 ;;++BS-GET NUMBER OF DQ11S
DEC R1 ;;++BS-CONVERT TO LINE NUMBER
CMPB R1, R0 ;;++BS-EXCEED MAX NUMBER ?
BGE 29$ ;;++BS-NO, CONTINUE
MOV (SP)+, R1 ;;++BS-YES, RESTORE R1
JMP 24$ ;;++BS-YES, REJECT REQUEST, NOT FATAL
29$: MOV (SP)+, R1 ;;++BS-RESTORE R1
ASL R0 ;LINE NUMBER * 2
TST DQLCB(R0) ;ALREADY A LINE CONTROL BLOCK?
BNE 11$ ;YES.
ASR R0 ;NO, PUT LINE NUMBER IN R0
JSR PC,DLENLN ;BUILD AN LCB
BCS 18$ ;OUT OF CORE
MOV #1, NWLFLG ;;++BS- INDICATE THIS IS A NEW LINE
11$: MOVB DT11AD+1(R5),R0 ;GET LINE NUMBER
ASL R0 ;LINE NUMBER * 2
MOV DQLCB(R0),R0 ;POINT R0 TO LCB
BIT #LS.ENB,(R0) ;IS THE LINE ENABLED?
BNE 17$ ;YES, CAN'T ENABLE IT AGAIN.
;3(023) BIT #LF.DIP!LF.ABC,LB.FGS(R0) ;DISABLE IN PROGRESS?
BIT #LF.DIP, LB.FGS(R0) ;;++BS-DISABLE IN PROGRESS ? 3(023)
BNE 18$ ;YES, GIVE DELAYED RETURN
;;++BS- THIS CODE DELETES THE BSC TASK AFTER THE LINE IS DISABLED
TST NWLFLG ;IS THIS A NEW LINE ?
BNE 25$ ;YES, THERE WAS NO BSC TASK
BIT #LF.DAC, LB.FGS(R0) ;NO, DID BSC DISABLE THE LINE ?
BEQ 18$ ;NO, GIVE DELAYED RETURN
JSR PC, HSSAVR ;YES, SAVE THE REGISTERS
MOV R0, R4 ;PUT POINTER TO LCB IN R4
MOV LB.TC1(R4), R0 ;GET POINTER TO BSC TASK
BEQ 26$ ;NO BSC, EXIT
MOV TCBP1, R3 ;R3 MUST POINT TO START OF CHAIN
JSR PC, DLRLTC ;RELEASE TCB AND UNLINK FROM CHAIN
MOV R3, TCBP1 ;UPDATE START OF CHAIN OF TCBS
CLR LB.TC1(R4) ;CLEAR BSC TCB POINTER
26$: ;CLEAN UP LCB
MOV #NDHASP, R2 ;GET NUMBER OF XLATE TCBS
27$: MOV R4, R1 ;[3(026)]POINT TO LCB
CLC ;CLEAR FOR ROTATE
ASL R2 ;MAKE EVEN FOR WORD OFFSET
ADD R2, R1 ;OFFSET INTO LCB
CLC ;CLEAR FOR ROTATE
ASR R2 ;GET BACK # OF XLATE TCBS
CLR LB.TC1(R1) ;CLEAR XLATE TCB POINTER IN LCB
SOB R2, 27$ ;CLEAR THE REST OF THE XLATE POINTERS
JSR PC, HSRESR ;RESTORE THE REGISTERS
25$:
;;++BS- END OF CODE THAT DELETES THE BSC TASK AFTER THE LINE IS DISABLED
MOV R0,TCLCB(R5) ;REMEMBER LCB
JSR PC,DLGBYT ;GET DEVICE TYPE
BCS 17$ ;NONE SPECIFIED
MOV R1,LB.DVT(R0) ;STORE DEVICE TYPE
JSR PC,DLGBYT ;GET CHARACTERISTICS
BCS 17$ ;NOT SPECIFIED
MOV R1,LB.FGS(R0) ;STORE CHARACTERISTICS
BIT #LF.PRI,R1 ;PRIMARY?
BNE 12$ ;YES.
MOV #3*JIFSEC,LB.EQW(R0) ;NO, MAKE SECONDARY
;12$: JSR PC,DLBTCB ;BUILD TCB'S FOR XLATE TASKS
12$:
.IF EQ, XLOPHP ;CHECK IF HASP PRESENT
CMP #TTHASP,LB.DVT(R0) ;IS THIS A HASP LINE?
BNE 20$ ;NO, CONTINUE
BR 19$ ;YES, BUT HASP NOT PRESENT- ERROR
20$:
.ENDC ;.IF EQ, XLOPHP
JSR PC,DLBTCB ;BUILD TCB'S FOR XLATE TASKS
BCS 18$ ;OUT OF STORAGE
MOV LB.TC1(R0),R1 ;POINT TO BSC TASK
BNE 13$ ;MAKE SURE BSC TCB EXISTS
STOPCD HSC ;TRAP OTHERWISE
13$:
CLR TCST2(R1) ;BE SURE IT IS INITIALIZED
CLR TCFG1(R1) ; SO THERE IS NO PROBLEMS WITH
CLR TCFG2(R1) ; ANY EARLIER ABORTS
BIS #LS.ENB,(R0) ;ENABLE THE LINE
CLR R2 ;INITIALIZE OFFSET IN TABLE
MOV LB.LNU(R0),R1 ;NO, INITIALIZE CURRENT MSG PTR
ASL R1 ;FOR WORD BOUNDARY PTR
CMP #TTHASP,LB.DVT(R0) ;HASP LINE?
BEQ 14$ ;YES.
ADD R5,R1 ;POINT TO CURRENT MSG FOR LINE
CLR TCCMSG(R1) ;CLEAR IT
BR 16$ ;AND EXIT
;
;
; HERE FOR HASP LINE, SET DEVICE MSG PTR
;
14$: JSR PC,DLGDTA ;GET DEVICE TABLE ADDRESS
ADD R5,R2 ;R2 IS RETURNED WITH OFFSET
ADD R5,R1 ;POINT TO PLACE TO SAVE
MOV R2,TCCMSG(R1) ;SAVE PTR TO DEVICE MESSAGES
MOV #5,R1 ;INITIALIZE ALL DEVICE MSG PTRS
15$: CLR (R2) ;CLEAR MSG PTR
ADD #2,R2 ;INCREMENT PTR FOR NEXT MSG
SOB R1,15$ ;COVER ALL DEVICE MSG PTRS
16$:
BIS #LF.ENC,LB.FGS(R0) ;ENABLE COMPLETE
BIC #LF.DAC,LB.FGS(R0) ;CLEAR DISABLE COMPLETE
21$: CLC ; NOT FATAL ERROR
RTS PC ; AND RETURN.
;
; HERE ON UNREASONABLE ERROR.
;
17$: SEC ;INDICATE FATAL ERROR
RTS PC ;RETURN.
;
; HERE IF SHORT ON STORAGE
;
18$: MOVB #2,DT10DF+1(R5) ;INDICATE OPERATION DELAYED
CLC ;BUT NOT UTTER FAILURE
RTS PC ;RETURN.
;
;HERE IF REQUESTED A LINE WE DO NOT HAVE
;
24$: JSR PC, DLRJRQ ;;++BS-REJECT THE REQUEST
RTS PC ;;++BS-RETURN
.IF EQ, XLOPHP ;NO HASP BUT HASP LINE INDICATED-ERROR
; HERE IF HASP REQUEST AND NO HASP SUPPORT
19$: MOVB #3, DT10DF+1(R5) ;INDICATE REQUEST REJECTED
BIS #LF.DAC, LB.FGS(R0) ;INDCATE LINE HAS BEEN DISABLED BY BSC TASK
BR 21$ ;NO HASP SUPPORT- RETURN
.ENDC ;.IF EQ, XLOPHP
NWLFLG: .WORD 0 ;FLAG TO INDICATE A NEW LCB WAS BUILT
;
;
; SUBROUTINE TO GET DEVICE TABLE OFFSET FOR MESSAGES
;
DLGDTA:
MOV R1,-(SP) ;SAVE LINE # * 2
ASR R1 ;GET LINE # BACK
TST R1 ;LOOP FOR NON-ZERO LINE
BEQ 12$ ;SKIP FOR LINE ZERO
11$: ADD #2*NDHASP,R2 ;[3(031)]GO OVER ONE LINE TABLE FOR DEVICES
SOB R1,11$ ;GET OFFSET FOR THE LINE
12$: ADD #TCDMSG,R2 ;COMPLETE OFFSET IN R2
MOV (SP)+,R1 ;RESTORE LINE # * 2
RTS PC ;AND RETURN
;
;
; SUBROUTINE TO BUILD THE LINE CONTROL BLOCK AND THE
; TASK CONTROL BLOCKS NEEDED FOR EACH DQ11 LINE.
;
; R0 = LINE NUMBER
;
; ON RETURN:
;
; C CLEAR: LCB ALLOCATED
;
; C SET: OUT OF STORAGE
;
DLENLN: MOV R0,-(SP) ;SAVE LINE NUMBER
MOV #LB.SIZ,R0 ;LENGTH OF A LCB
JSR PC,GETSTG ;GET SPACE FOR A LCB
BCC 11$ ;BRANCH IF ENOUGH SPACE
MOV (SP)+,R0 ;OUT OF SPACE--GET LINE NUMBER
SEC ;FLAG FAILURE
RTS PC ; AND RETURN, NO LCB CREATED.
;
; HERE IF THERE IS ENOUGH STORAGE FOR THE LCB
;
11$: MOV (SP)+,R1 ;GET LINE NUMBER
ASL R1 ;LINE NUMBER * 2
MOV R0,DQLCB(R1) ;STORE POINTER TO LCB
MOV DQCSR(R1),LB.SLA(R0) ;STORE CSR ADDRESS
MOV DQVEC(R1),LB.SLV(R0) ;STORE VECTOR ADDRESS
ASR R1 ;GET LINE NUMBER * 1
MOV R1,LB.LNU(R0) ;STORE LINE NUMBER
MOV #1*JIFSEC,LB.EQW(R0) ;TIME BETWEEN SENDING ENQ'S
MOV #3,LB.EQN(R0) ;NUMBER OF ENQ'S TO SEND BEFORE
; ASSUMING LINE IS DOWN.
MOV #MDMXSD,LB.MDS(R0) ;LENGTH OF SILO WARNING AREA FOR KMC11
MOV #DQTYPE,LB.TYP(R0) ;LINE DRIVER TYPE
CLR LB.FGS(R0) ;CLEAR LINE FLAGS
RTS PC ;RETURN AFTER BULDING LCB
;
;
;THIS SUBROUTINE BUILDS TCB FOR THE BSC AND XLATE TASKS.
; IN 3780/2780 WE NEED ONLY ONE TCB FOR XLATE TASK
; WHILE FOR HASP-MULTILEAVING WE NEED 5 TCB'S IN SIMULATE
; AND 4 TCB'S IN SUPPORT MODE OF OPERATION
;
DLBTCB: MOV R0,-(SP) ;SAVE POINTER TO LCB
MOV R0,R4 ;LCB POINTER IN R4
MOV LB.TC1(R0),R0 ;POINT TO BSC TCB
BNE 17$ ;ITS ALREADY SET UP
JSR PC,GETTCB ;GET A TASK CONTROL BLOCK
bcc 7$ ;got the tcb
jmp dlenlo ;out of storage
7$: MOV #DQDRVR,TCPC(R0) ;STORE INITIAL ADDRESS
BIS #BR3,TCPS(R0) ;SET PRIORITY LEVEL TO 3
MOV (SP),R4 ;GET POINTER TO LCB
MOV R4,TCLCB(R0) ;STORE LCB POINTER
MOV R0,LB.TC1(R4) ;STORE BSC TASK POINTER
MOV TCBP1,R1 ;GET HIGHEST-PRIORITY TCBS
MOV R0,TCBP1 ;PUT THIS TCB ON THE LIST
MOV R1,TCHAIN(R0) ; ...
17$: CLR R2 ;CLEAR DEVICE # INITIALLY
CMP #TTHASP,LB.DVT(R4) ;HASP LINE?
BEQ 11$ ;YES.
MOV #1,LB.NTC(R4) ;NO, SET UP FOR 1 TCB FOR 2780/3780
JSR PC,GETTCB ;GET A TASK CONTROL BLOCK
BCS dlenlo ;NO ROOM.
MOV #XLATE,TCPC(R0) ;STORE START ADR OF TASK
CLR TCDEV(R0) ;DEVICE IS 0 FOR 2780/3780
BR 13$ ;GO PAST HASP SETTINGS
11$: MOV #4,LB.NTC(R4) ;SET UP # OF TCB'S FOR HASP DEVICES
BIT #LF.SIM,LB.FGS(R4) ;IN SIMULATE MODE?
BEQ 12$ ;NO.
INC LB.NTC(R4) ;5 TCB FOR SIMULATE MODE
12$: INC R2 ;MAKE R2 DEVICE #
JSR PC,GETTCB ;GET TCB FOR XLATE TASK
BCS dlenlo ;NO ROOM
.IF NE, XLOPHP ;HASP PRESENT
MOV #XLHASP,TCPC(R0) ;SET UP START ADR OF TASK
.ENDC ;.IF NE, XLOPHP
MOV R2,TCDEV(R0) ;AND DEVICE # IN THE TCB
CLR TCFG1(R0) ;CLEAR FLAGS TO AVOID
CLR TCFG2(R0) ;PROBLEMS LATER
13$: BIS #BR1,TCPS(R0) ;SET PRIORITY LEVEL TO 1
MOV R4,TCLCB(R0) ;STORE LCB POINTER
MOV R4,R1 ;PRESERVE LCB PTR IN R4
ASL R2 ;DEVICE # * 2 FOR WORD PTR
ADD R2,R1 ;ADD DEVICE # TO GET XLATE TCB ADR
ASR R2 ;RESTORE R2 BACK TO DEVICE #
MOV R0,LB.TCD(R1) ;STORE COMP. POINTER
MOV TCBP3,R1 ;GET LOW-PRIORITY TCBS
MOV R0,TCBP3 ;PUT THIS TCB ON THE LIST
MOV R1,TCHAIN(R0) ; ...
;
; continued on next page
;
;
; here to get storage for line buffer for each device
;
MOV #150.,R0 ;LENGTH OF LINE BUFFER
JSR PC,GETSTG ;GET STORAGE FOR IT
BCS dlenlo ;OUT OF STORAGE
MOV TCBP3,R1 ;GET POINTER TO XLATE TCB
MOV R0,TCBFP(R1) ;STORE POINTER TO LINE BUFFER
MOV #150.,TCBFC(R1) ;STORE LENGTH OF LINE BUFFER
;
CMP #TTHASP,LB.DVT(R4) ;HASP LINE?
bne 14$ ;all done for 2780/3780
CMP LB.NTC(R4),R2 ;DONE WITH ALL DEVICES XLATE TCB'S
BNE 12$ ;NO
jsr pc,dlsiom ;set device in input/output mode
14$: MOV LB.SLV(R4),R1 ;GET VECTOR ADDRESS
MOV #BR7,R0 ;GET INITIAL PS
ADD LB.LNU(R4),R0 ;ADD LINE NUMBER
.IIF NE,FTRACE,BIS TRCFLG,R0 ;ADD TRACE BIT IF REQUESTED
MOV #DQAINT,(R1)+ ;STORE PC FOR INTERRUPT A
MOV R0,(R1)+ ;STORE PS FOR INTERRUPT A
MOV #DQBINT,(R1)+ ;STORE PC FOR INTERRUPT B
MOV R0,(R1)+ ;STORE PS FOR INTERRUPT B
MOV (SP)+,R0 ;RESTORE LCB POINTER IN R0
CLC ;CLEAR C TO FLAG SUCCESS
RTS PC ; AND RETURN.
;
;
; HERE IF WE RUN OUT OF STORAGE GETTING A TCB.
;
DLENLO: MOV (SP),R4 ;GET LCB POINTER
JSR PC,DLRTCB ;RELEASE ALL STORAGE FOR TCB AND LCB
MOV (SP)+,R0 ;GET LCB POINTER
SEC ;SET C AS A FLAG
RTS PC ; AND RETURN.
;
;
; THIS SUBROUTINE SETS A FLAG TO INDICATE WHETHER THE DEVICE
; IS DOING INPUT OR OUTPUT. FLAG IS USED BY XLATE TASKS.
;
DLSIOM: MOV R4,R1 ;PRESERVE R4
BIT #LF.SIM,LB.FGS(R4) ;SIMULATE MODE?
BEQ 11$ ;NO, MUST BE SUPPORT
ADD #2,R1 ;DEVICE 1 IS CONSOLE INPUT TO IBM
MOV LB.TCD(R1),R0 ;GET XLATE TCB PTR
BIS #TCIOM,TCFG1(R0) ;MARK AS INPUT DEVICE
JSR PC,DLFRBF ;DONT NEED BUFFER FOR INPUT
ADD #2,R1 ;BYPASS CONSOLE OUT
11$: ADD #4,R1 ;FOR CONSOLE INPUT (SUP), LPT (SIM)
MOV LB.TCD(R1),R0 ;GET XLATE TCB PTR
BIS #TCIOM,TCFG1(R0) ;FLAG INPUT DEVICE
JSR PC,DLFRBF ;FREE THE LINE BUFFER
ADD #2,R1 ;FOR PUNCH DEVICE
MOV LB.TCD(R1),R0 ;GET PTR TO XLATE TCB
BIS #TCIOM,TCFG1(R0) ;FLAG AS INPUT DEVICE
JSR PC,DLFRBF ;FREE THE INPUT LINE BUFFER
RTS PC ;AND RETURN
;
; THIS SUBROUTINE FREES THE LINE BUFFER STORAGE AND
; CLEARS THE POINTER IN THE XLATE TCB'S.
;
DLFRBF: MOV R0,-(SP) ;SAVE R0
MOV TCBFP(R0),R0 ;GET BUFFER POINTER
BEQ 11$ ;ITS ALREADY FREED
JSR PC,FRESTG ;FREE THE STORAGE
11$: MOV (SP)+,R0 ;RESTORE R0
CLR TCBFP(R0) ;CLEAR POINTER IN TCB
RTS PC ;RETURN
;
;
; SUBROUTINE TO RELEASE BSC AND XLATE TCBS
; NEEDS LCB POINTER IN R4 ON ENTRY
; R4 IS PRESERVED, R0, R2 ARE DESTROYED
;
DLRTCB: MOV LB.TC1(R4),R0 ;GET PTR TO BSC TASK
BEQ DLXTCB ;NO BSC, LOOK FOR XLATE TCB'S
MOV TCBP1,R3 ;R3 MUST POINT TO START OF CHAIN
JSR PC,DLRLTC ;RELEASE TCB AND UNLINK FROM CHAIN
MOV R3,TCBP1 ;UPDATE START OF CHAIN OF TCBS
CLR LB.TC1(R4) ;CLEAR BSC TCB POINTER
DLXTCB: MOV LB.NTC(R4),R2 ;GET # OF TCBS FOR XLATE
BEQ 16$ ;JUST IN CASE ITS ZERO
CMP #1,R2 ;2780/3780 MODE
BNE 11$ ;NO.
CLR R1 ;FOR 2780/3780 MODE
BR 12$ ;BYPASS HASP DEVICE LOGIC
11$: MOV R2,R1 ;START WITH HIGHEST DEVICE #
ASL R1 ;DEVICE # MUTLIPLIED BY 2
12$: ADD R4,R1 ;GET TCB PTR TO DEVICE'S
MOV LB.TCD(R1),R0 ;XLATE TASK
BEQ 15$ ;NONE FOR THIS, CHECK NEXT DEVICE
JSR PC,DLFRBF ;RELAESE LINE BUFFER
MOV R0,-(SP) ;SAVE XLATE TCB PTR
MOV TCSBF(R0),R0 ;ANY COMPRESSED BUFFER TO RELEASE?
BEQ 14$ ;NO.
JSR PC,FRESTG ;YES, RELEASE IT
14$: MOV (SP)+,R0 ;RESTORE XLATE PTR
CLR LB.TCD(R1) ;CLEAR POINTER TO TCB
MOV TCBP3,R3 ;POINT TO START OF TCB CHAIN
JSR PC,DLRLTC ;RELEASE AND UNLINK TCB FOR XLATE
MOV R3,TCBP3 ;UPDATE POINTER TO START OF TCB CHAIN
15$: SOB R2,11$ ;DO FOR ALL DEVICE XLATE TCB'S
CLR LB.TCD(R4) ;CLEAR ANY PREV XLATE POINTER
;
16$: CLC ;INDICATE SUCCESS
RTS PC ;RETURN
;
CLC ;INDICATE SUCCESS
RTS PC ;RETURN
;
;
;
; THIS SUBROUTINE FREES THE TCB WHOSE ADDRESS IS IN R0 AND
; UNLINKS THE TCB FROM THE CHAIN WHOSE START IS POINTED TO
; BY R3. R3 IS RETURNED WITH UPDATED POINTER TO START OF CHAIN.
; R1 IS DESTROYED BY THIS ROUTINE. R0 AND R2 ARE PRESERVED.
;
DLRLTC: MOV R2,-(SP) ;SAVE R2
CMP R3,R0 ;IS IT FIRST TCB OF CHAIN?
BNE 13$ ;NO, HUNT THRU THE CHAIN
MOV TCHAIN(R0),R3 ;YES, UPDATE POINTER TO START OF CHAIN
11$: JSR PC,FRETCB ;FREE THE TCB
12$: MOV (SP)+,R2 ;RESTORE R2
CLC ;INDICATE SUCCESS
RTS PC ;RETURN
;
13$: MOV R3,R1 ;MAKE FIRST TCB THE PREVIOUS ONE
14$: MOV TCHAIN(R1),R2 ;POINT TO NEXT TCB IN CHAIN
BEQ 16$ ;TCB MISSING FROM QUE
CMP R0,R2 ;MATCH OUR TCB?
BEQ 15$ ;YES.
MOV R2,R1 ;MAKE CURRENT THE PREV ONE
BR 14$ ;HUNT TILL MATCH
;
15$: MOV TCHAIN(R2),TCHAIN(R1) ;UNLINK TCB FROM CHAIN
BR 11$ ;FREE THE TCB AND EXIT
;
; HERE IF TCB IS FOUND MISSING FROM THE QUE
;
16$: STOPCD DTM ;TCB MISSING
;
;
; SUBROUTINE TO DO LINE COMMAND 02: SET DTR
;
DLTL02: MOVB DT11AD+1(R5),R0 ;GET LINE NUMBER
ASL R0 ;LINE NUMBER * 2
MOV DQLCB(R0),R0 ;GET LCB
BEQ 11$ ;SHOULD BE THERE
BIT #LS.ENB,(R0) ;IS THE LINE ENABLED?
BEQ 11$ ;NO. CAN'T SET DTR.
JSR PC,DQDTR1 ;SET DATA TERMINAL READY
CLC ;NOT FATAL ERROR
RTS PC ;RETURN.
;
; HERE IF NO LCB OR NOT ENABLED
;
11$:
JSR PC,DLRJRQ ;;++BS-REJECT THE REQUEST
RTS PC ;RETURN.
;
; SUBROUTINE TO DO LINE COMMAND 03: CLEAR DTR
;
DLTL03: MOVB DT11AD+1(R5),R0 ;GET LINE NUMBER
ASL R0 ;LINE NUMBER * 2
MOV DQLCB(R0),R0 ;GET LCB
BEQ 11$ ;SHOULD BE THERE
BIT #LS.ENB,(R0) ;IS THE LINE ENABLED?
BEQ 11$ ;NO, CAN'T CLEAR DTR.
JSR PC,DQDTR0 ;CLEAR DATA TERMINAL READY [1(665)]
CLC ;NOT FATAL ERROR
RTS PC ;RETURN.
;
; HERE IF NO LCB OR NOT ENABLED.
;
11$:
JSR PC,DLRJRQ ;;++BS-REJECT THE REQUEST
RTS PC ;RETURN.
;
; SUBROUTINE TO DO LINE COMMAND 04: DISABLE
;
DLTL04: MOVB DT11AD+1(R5),R0 ;GET LINE NUMBER
MOV R1, -(SP) ;;++BS-SAVE R1
MOVB NDQ11S, R1 ;;++BS-GET NUMBER OF DQ11S
DEC R1 ;;++BS-CONVERT TO LINE NUMBER
CMPB R1, R0 ;;++BS-EXCEED MAX NUMBER ?
BLT 11$ ;;++BS-YES, IGNORE
ASL R0 ;LINE NUMBER * 2
MOV DQLCB(R0),R0 ;GET LCB POINTER
BEQ 11$ ;DOESN'T MATTER IF NOT THERE
; BIC #LS.ENB,(R0) ;THERE, DISABLE IT.
; MOV R0,R4 ;POINT R4 TO LCB
; JSR PC,DLRTCB ;RELEASE BSC AND XLATE TCB'S
BIT #LS.ENB,(R0) ;WAS LINE ENABLED?
BEQ 11$ ;NO.
BIC #LS.ENB,(R0) ;THERE, DISABLE IT.
11$: MOV (SP)+,R1 ;;++BS-RESTORE R1
CLC ;NO FATAL ERROR
RTS PC ;RETURN.
;
;
; SUBROUTINE TO DO LINE COMMAND 05: SET CTS DELAY
;
DLTL05: MOVB DT11AD+1(R5),R0 ;GET LINE NUMBER
ASL R0 ;LINE NUMBER * 2
MOV DQLCB(R0),R0 ;GET LCB POINTER
BEQ 11$ ;SHOULD BE THERE
BIT #LS.ENB,(R0) ;IS THE LINE ENABLED?
BEQ 11$ ;NO, CAN'T SET CTS DELAY
JSR PC,DLGBYT ;GET LOW BITS OF CTS DELAY
BCS 11$ ;NOT SPECIFIED
MOVB R1,LB.CSD(R0) ;STORE LOW BITS
JSR PC,DLGBYT ;GET HIGH BITS
BCS 11$ ;NOT SPECIFIED
MOVB R1,LB.CSD+1(R0) ;STORE HIGH BITS
CLC ;NO FATAL ERROR
RTS PC ;RETURN.
;
; HERE IF THE LINE IS NOT ENABLED OR IF THE ARGUMENT IS
; NOT COMPLETELY SPECIFIED.
;
11$:
JSR PC,DLRJRQ ;;++BS-REJECT THE REQUEST
RTS PC ;RETURN.
;
; SUBROUTINE TO DO LINE COMMAND 06: SET LENGTH OF SILO WARNING AREA
; (THIS IS ONLY EFFECTIVE IF THE LINE DRIVER INCLUDES A KMC11)
;
DLTL06: MOVB DT11AD+1(R5),R0 ;GET LINE NUMBER
ASL R0 ;LINE NUMBER * 2
MOV DQLCB(R0),R0 ;GET LCB POINTER
BEQ 11$ ;NONE, ERROR.
BIT #LS.ENB,(R0) ;IS THE LINE ENABLED?
BEQ 11$ ;NO, ERROR.
JSR PC,DLGBYT ;GET LOW BITS OF LENGTH OF SILO WARNING AREA
BCS 11$ ;NOT SPECIFIED, ERROR.
MOVB R1,LB.MDS(R0) ;STORE LOW BITS
JSR PC,DLGBYT ;GET HIGH BITS
BCS 11$ ;NOT SPECIFIED, ERROR
MOVB R1,LB.MDS+1(R0) ;STORE HIGH BITS
CLR LB.MDU(R0) ;CLEAR MAX DEPTH USED
CLC ;NO FATAL ERROR
RTS PC ;RETURN.
;
; HERE IF THE LINE IS NOT ENABLED OR IF THE ARGUMENT
; IS OMITTED OR NOT COMPLETELY SPECIFIED.
;
11$:
JSR PC,DLRJRQ ;;++BS-REJECT THE REQUEST
RTS PC ;RETURN.
;
;
;
; SUBROUTINE TO DO LINE COMMAND 07: SET OUTPUT IN TRANSPARENCY
; THIS APPLIES ONLY TO HASP-MULTILEAVING LINES
;
DLTL07: MOVB DT11AD+1(R5),R0 ;GET THE LINE NUMBER
ASL R0 ;LINE NUMBER * 2
MOV DQLCB(R0),R0 ;GET LCB POINTER
BEQ 11$ ;NONE, ERROR.
BIT #LS.ENB,(R0) ;IS THE LINE ENABLED?
BEQ 11$ ;NO, ERROR.
BIS #LF.TSP,LB.FGS(R0) ;SET FLAG IN LINE CONTROL BLOCK
MOV LB.TC1(R0),R1 ;GET POINTER TO BSC TCB
BIS #TCTSP,TCFG1(R1) ;SET TRASPARENT FLAG FOR BSC
CLC ;NO FATAL ERROR
RTS PC ;RETURN
;
; HERE IF THE LINE IS NOT ENABLED OR IF THE ARGUMENT
; IS OMITTED OR NOT COMPLETELY SPECIFIED.
;
11$:
JSR PC,DLRJRQ ;;++BS-REJECT THE REQUEST
RTS PC ;RETURN.
;
; SUBROUTINE TO DO LINE COMMAND 08: SET OUTPUT IN NON-TRANSPARENCY
; THIS APPLIES ONLY TO HASP-MULTILEAVING LINES
;
DLTL08: MOVB DT11AD+1(R5),R0 ;GET THE LINE NUMBER
ASL R0 ;LINE NUMBER * 2
MOV DQLCB(R0),R0 ;GET LCB POINTER
BEQ 11$ ;NONE, ERROR.
BIT #LS.ENB,(R0) ;IS THE LINE ENABLED?
BEQ 11$ ;NO, ERROR.
BIC #LF.TSP,LB.FGS(R0) ;SET FLAG IN LINE CONTROL BLOCK
MOV LB.TC1(R0),R1 ;POINT TO BSC TCB
BIC #TCTSP,TCFG1(R1) ;CLEAR TRANSPARENCY FOR BSC TO LOOK AT
CLC ;NO FATAL ERROR
RTS PC ;RETURN
;
; HERE IF THE LINE IS NOT ENABLED OR IF THE ARGUMENT
; IS OMITTED OR NOT COMPLETELY SPECIFIED.
;
11$:
JSR PC,DLRJRQ ;;++BS-REJECT THE REQUEST
RTS PC ;RETURN.
;
;
; SUBROUTINE TO SET TRANSMISSION BLOCK SIZE
;
DLTL09: MOVB DT11AD+1(R5),R0 ;GET THE LINE NUMBER
ASL R0 ;LINE NUMBER * 2
MOV DQLCB(R0),R0 ;POINT TO THE LCB
BEQ 11$ ;NONE THERE, ERROR
BIT #LS.ENB,(R0) ;IS THE LINE ENABLED?
BEQ 11$ ;NO, ERROR
JSR PC,DLGBYT ;GET LOW ORDER BYTE OF BLOCK SIZE
BCS 11$ ;NOT SPECIFIED, ERROR
MOVB R1,LB.MBL(R0) ;STORE LOW BITS
JSR PC,DLGBYT ;GET HIGH ORDER BITS
BCS 11$ ;NOT SPECIFIED, ERROR
MOVB R1,LB.MBL+1(R0) ;STORE HIGH BITS
CLC ;INDICATE SUCCESS
RTS PC ;RETURN
;
11$:
JSR PC,DLRJRQ ;;++BS-REJECT THE REQUEST
RTS PC ;AND RETURN
;
; SUBROUTINE TO SET RECORDS PER MESSAGE FOR TRANSMISSION BLOCK
;
DLTL10: MOVB DT11AD+1(R5),R0 ;GET LINE NUMBER
ASL R0 ;LINE NUMBER * 2
MOV DQLCB(R0),R0 ;POINT TO THE LCB
BEQ 11$ ;NONE THERE, ERROR
BIT #LS.ENB,(R0) ;IS THE LINE ENABLED?
BEQ 11$ ;NO, ERROR
JSR PC,DLGBYT ;GET LOW ORDER BYTE OF # OF RECORDS
BCS 11$ ;NOT SPECIFIED, ERROR
MOVB R1,LB.MLR(R0) ;STORE LOW BITS
JSR PC,DLGBYT ;GET HIGH ORDER BITS
BCS 11$ ;NOT SPECIFIED, ERROR
MOVB R1,LB.MLR+1(R0) ;STORE HIGH BITS
CLC ;INDICATE SUCCESS
RTS PC ;RETURN
;
11$:
JSR PC,DLRJRQ ;;++BS-REJECT THE REQUEST
RTS PC ;AND RETURN
;
;
;
; SUBROUTINE TO SET LINE SIGNATURE (;;++BS-)
DLTL11: MOVB DT11AD+1(R5),R0 ;GET LINE NUMBER
ASL R0 ;LINE NUMBER * 2
MOV DQLCB(R0),R0 ;GET LCB POINTER
BEQ 11$ ;NONE, ERROR.
BIT #LS.ENB,(R0) ;IS THE LINE ENABLED?
BEQ 11$ ;NO, ERROR.
JSR PC,DLGBYT ;GET LOW BITS OF LENGTH OF SILO WARNING AREA
BCS 11$ ;NOT SPECIFIED, ERROR.
MOVB R1,LB.SIG(R0) ;STORE LOW BITS
JSR PC,DLGBYT ;GET HIGH BITS
BCS 11$ ;NOT SPECIFIED, ERROR
MOVB R1,LB.SIG+1(R0) ;STORE HIGH BITS
CLC ;NO FATAL ERROR
RTS PC ;RETURN.
;
; HERE IF THE LINE IS NOT ENABLED OR IF THE ARGUMENT
; IS OMITTED OR NOT COMPLETELY SPECIFIED.
;
11$: ;SEC ;FLAG AN ERROR
JSR PC, DLRJRQ ;;++BS-REJECT THE REQUEST
RTS PC ;RETURN.
;
; EACH SUBROUTINE OF THE FORM DLTDXX WHERE XX IS A DECIMAL NUMBER
; PERFORMS THE DEVICE COMMAND NUMBER XX.
;
; SUBROUTINE TO DO DEVICE COMMAND 01: SET CHARACTERISTICS
;
DLTD01: JSR PC,DLGBYT ;GET DEVICE TYPE
BCS 11$ ;NONE SPECIFIED
MOV TCXLT(R5),R0 ;POINT TO XLATE TCB
MOV R1,TCDVT(R0) ;STORE DEVICE TYPE
JMP DLTDOK ;SUCCESS.
;
11$: RTS PC ;ERROR RETURN.
;
;THE SUBROUTINE HAS BEEN NO OPTED. THIS IS NOW A LINE COMMAND FUNCTION
; SUBROUTINE TO DO DEVICE COMMAND 02: SET MAX LOGICAL RECORDS PER BLOCK
;
;DLTD02: JSR PC,DLGBYT ;GET LOW BYTE OF NUMBER
; BCS 11$ ;NOT SPECIFIED, ERROR
; MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
;; MOVB R1,TCMLR(R0) ;STORE LOW BYTE OF NUMBER
; MOV R3, -(SP) ;SAVE R3
; MOV TCLCB(R5), R3 ;GET LCB POINTER
; MOVB R1,LB.MLR(R3) ;STORE LOW BYTE OF NUMBER
; MOV (SP)+,R3 ;RESTORE R3
; JSR PC,DLGBYT ;GET HIGH BYTE
; BCS 11$ ;NOT SPECIFIED, ERROR.
;; MOVB R1,TCMLR+1(R0) ;STORE LOW BYTE
; MOV R3, -(SP) ;SAVE R3
; MOV TCLCB(R5),R3 ;GET LCB POINTER
; MOVB R1,LB.MLR+1(R3) ;STORE HIGH BYTE OF NUMBER
; MOV (SP)+,R3 ;RESTORE R3
; JMP DLTDOK ;INDICATE SUCCESS
;
;11$: RTS PC ;ERROR RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 03: DUMP OUTPUT [1(627)]
;
DLTD03: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK [1(627)]
BIS #TCDMP,TCFG1(R0) ;SET "DUMP OUTPUT" [1(627)]
JMP DLTDOK ;INDICATE SUCCESS [1(627)]
;
; SUBROUTINE TO DO DEVICE COMMAND 04: CLEAR "INPUT PERMISSION WAS REQUESTED"
;
DLTD04: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK [2(770)]
BIC #TCIWR,TCFG2(R0) ;CLEAR "INPUT PERMISSION WAS REQUESTED" [2(770)]
JMP DLTDOK ;INDICATE SUCCESS [2(770)]
;
; NOTE THAT COMMAND 05 IS RESERVED.
;
; SUBROUTINE TO DO DEVICE COMMAND 06: SET "INTERPRET CC ON INPUT"
;
DLTD06: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIS #TCPRI,TCFG1(R0) ;SET "CC ON INPUT"
JMP DLTDOK ;INDICATE SUCCESS
;
;
; SUBROUTINE TO DO DEVICE COMMAND 07: NO INTERPRET CC ON INPUT
;
DLTD07: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIC #TCPRI,TCFG1(R0) ;CLEAR "CC ON INPUT"
JMP DLTDOK ;INDICATE SUCCESS
;
; SUBROUTINE TO DO DEVICE COMMAND 08: INTERPRET CC ON OUTPUT
;
DLTD08: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIS #TCPRO,TCFG1(R0) ;SET "CC ON OUTPUT"
JMP DLTDOK ;INDICATE SUCCESS
;
; SUBROUTINE TO DO DEVICE COMMAND 09: NO CC ON OUTPUT
;
DLTD09: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIC #TCPRO,TCFG1(R0) ;CLEAR "CC ON OUTPUT"
JMP DLTDOK ;INDICATE SUCCESS
;
; SUBROUTINE TO DO DEVICE COMMAND 12: DO COMPONENT SELECTION
; THIS IS USED BY HASP-MULTILEAVING ONLY
;
DLTD12: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIS #TCCMP,TCFG1(R0) ;INDICATE "COMPONENT SELECTION"
JSR PC,DLGBYT ;GET COMPONENT CODE
BCS 11$ ;NONE SPECIFIED
MOVB R1,TCCTP(R0) ;STORE COMPONENT CODE
JMP DLTDOK ;INDICATE SUCCESS.
;
11$: RTS PC ;ERROR RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 13: NO COMPONENT SELECTION
;
DLTD13: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIC #TCCMP,TCFG1(R0) ;INDICATE NO COMPONENT SELECTION
JMP DLTDOK ;INDICATE SUCCESS
;
;
; SUBROUTINE TO DO DEVICE COMMAND 14: SET PRINTER PAGE COUNTER
; (NOT YET COMPLETELY IMPLEMENTED IN XLATE)
;
DLTD14: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIS #TCPCE,TCFG1(R0) ;TURN ON PAGE COUNTER
BIC #TCPCO,TCFG1(R0) ; AND TURN OFF INTERRUPT FLAG
JSR PC,DLGBYT ;GET LOW BYTE OF PAGE COUNTER
BCS 11$ ;NOT SUPPLIED
MOVB R1,TCPGC(R0) ;STORE LOW BYTE OF PAGE COUNTER
JSR PC,DLGBYT ;GET HIGH BYTE OF PAGE COUNTER
BCS 11$ ;NOT SUPPLIED
MOVB R1,TCPGC+1(R0) ;STORE HIGH BYTE OF PAGE COUNTER
JMP DLTDOK ;INDICATE SUCCESS
;
11$: RTS PC ;ERROR RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 15: NO PRINTER PAGE COUNTING
;
DLTD15: MOV TCXLT(R5),R0 ;GET POINTER TO XLATE TASK
BIC #TCPCE!TCPCO,TCFG1(R0) ;CLEAR PAGE COUNTER BITS
JMP DLTDOK ;INDICATE SUCCESS
;
; SUBROUTINE TO DO DEVICE COMMAND 16: SET BLOCK SIZE
;
;THIS SUBROUTINE HAS BEEN NO OPTED
;DLTD16: JSR PC,DLGBYT ;GET LOW BYTE OF SIZE
; BCS 11$ ;NONE SPECIFIED
; MOV TCXLT(R5),R0 ;POINT TO XLATE TCB
;; MOVB R1,TCMBL(R0) ;STORE LOW BYTE OF MAX BLOCK LENGTH
; MOV R3, -(SP) ;SAVE R3
; MOV TCLCB(R5),R3 ;GET LCB POINTER
; MOVB R1, LB.MBL(R3) ;STORE LOW BYTE OF MAX BLOCK LENGTH
; MOV (SP)+,R3 ;RESTORE R3
; JSR PC,DLGBYT ;GET HIGH BYTE
; BCS 11$ ;NONE SPECIFIED
;; MOVB R1,TCMBL+1(R0) ;STORE HIGH BYTE
; MOV R3, -(SP) ;SAVE R3
; MOV TCLCB(R5),R3 ;GET LCB POINTER
; MOVB R1,LB.MBL+1(R3) ;STORE HIGH BYTE OF MAX BLOCK LENGTH
; MOV (SP)+, R3 ;RESTORE R3
; JMP DLTDOK ;INDICATE SUCCESS
;;
;11$: RTS PC ;ERROR RETURN.
;;
; SUBROUTINE TO DO DEVICE COMMAND 17: DO SPACE COMPRESSION
;
DLTD17: MOV TCXLT(R5),R0 ;POINT R0 TO XLATE TASK
BIS #TCCPS,TCFG1(R0) ;INDICATE DO COMPRESSION
JMP DLTDOK ;INDICATE SUCCESS
;
; SUBROUTINE TO DO DEVICE COMMAND 18: DON'T DO SPACE COMPRESSION
;
DLTD18: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIC #TCCPS,TCFG1(R0) ;INDICATE DONT DO COMPRESSION
JMP DLTDOK ;INDICATE SUCCESS
;
;
; SUBROUTINE TO DO DEVICE COMMAND 19: USE OLD BSC PROTOCOL
;
DLTD19: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIS #TCOBS,TCFG1(R0) ;INDICATE USE OLD BSC
MOV TCLCB(R0),R0 ;POINT TO LCB
MOV LB.TC1(R0),R0 ;POINT TO BSC TASK
BIS #TCOBS,TCFG1(R0) ;TELL BSC TASK TO USE OLD BSC
JMP DLTDOK ;INDICATE SUCCESS
;
; SUBROUTINE TO DO DEVICE COMMAND 20: DONT USE OLD BSC
;
DLTD20: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIC #TCOBS,TCFG1(R0) ;NO OLD BSC PROTOCOL
MOV TCLCB(R0),R0 ;POINT TO LCB
MOV LB.TC1(R0),R0 ;POINT TO BSC TASK
BIC #TCOBS,TCFG1(R0) ;TELL BSC TASK NOT TO USE OLD BSC PROTOCOL
JMP DLTDOK ;INDICATE SUCCESS
;
; SUBROUTINE TO DO DEVICE COMMAND 21: REQUEST OUTPUT PERMISSION
;
DLTD21: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIT #TCIPR,TCFG2(R0) ;INPUT PERMISSION REQUESTED?
BNE 11$ ;YES, THIS IS A NO-OP.
BIS #TCOPR,TCFG2(R0) ;NO, FLAG OUTPUT PERMISSION REQUESTED
MOV TCLCB(R0),R0 ;POINT TO LCB
CMP #TTHASP,LB.DVT(R0) ;HASP LINE?
bne 11$ ;no
MOV LB.TC1(R0),R0 ;POINT TO BSC TASK
BIS #TCOPR,TCFG2(R0) ;TELL BSC TASK THERE IS OUTPUT TO DO
11$: JMP DLTWOK ;WAKE XLATE AND GIVE OK RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 22: GRANT INPUT PERMISSION
;
DLTD22: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIT #TCIPR,TCFG2(R0) ;HAS INPUT PERMISSION BEEN REQUESTED?
BEQ 11$ ;NO, THIS IS A NO-OP.
BIS #TCIPG,TCFG2(R0) ;YES, FLAG INPUT PERMISSION GRANTED
11$: JMP DLTWOK ;WAKE XLATE AND GIVE OK RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 23: SIGNAL OUTPUT EOF
;
DLTD23: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIS #TCOEF,TCFG2(R0) ;FLAG END-OF-FILE ON OUTPUT
JMP DLTWOK ;WAKE XLATE AND GIVE OK RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 24: CLEAR OUTPUT EOF COMPLETE
;
DLTD24: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIC #TCOEF!TCOEC,TCFG2(R0) ;CLEAR OUTPUT EOF FLAGS
JMP DLTWOK ;WAKE XLATE AND GIVE OK RETURN.
;
;
; SUBROUTINE TO DO DEVICE COMMAND 25: SIGNAL OUTPUT ABORT
;
DLTD25: MOV TCXLT(R5),R0 ;POINT TO THE XLATE TASK
MOV TCLCB(R0),R0 ;POINT TO LCB
CMP #TTHASP,LB.DVT(R0) ;HASP LINE?
BEQ 11$ ;YES, INDICATE ABORT TO DEVICE
MOV LB.TC1(R0),R0 ;POINT TO BSC TASK
BIS #TCOAB,TCFG2(R0) ;SIGNAL ABORT TO BSC TASK
11$: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIS #TCOAB,TCFG2(R0) ;SIGNAL ABORT TO XLATE TASK
JMP DLTWOK ;AWAKEN XLATE AND GIVE OK RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 26: CLEAR OUTPUT ABORT COMPLETE
;
DLTD26: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIC #TCOAB!TCOAC,TCFG2(R0) ;CLEAR ABORT BITS
JSR PC, HCLAOA ;;++BS-CLEAR ACTIVE BIT 3(016)
JMP DLTWOK ;AWAKEN XLATE AND GIVE OK RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 27: CLEAR INPUT EOF COMPLETE
;
DLTD27: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIC #TCIEC,TCFG2(R0) ;CLEAR INPUT EOF COMPLETE
JMP DLTWOK ;WAKE XLATE AND GIVE OK RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 28: SIGNAL INPUT ABORT
;
DLTD28: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
MOV TCLCB(R0),R0 ;POINT TO LCB
CMP #TTHASP,LB.DVT(R0) ;HASP LINE?
BEQ 11$ ;YES, INDICATE ABORT TO DEVICE
MOV LB.TC1(R0),R0 ;POINT TO BSC TASK
BIS #TCIAB,TCFG2(R0) ;SIGNAL ABORT
11$: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIS #TCIAB,TCFG2(R0) ;SIGNAL ABORT
JSR PC,DLDRAI ;DRAIN INPUT QUEUE
JMP DLTWOK ;WAKE XLATE AND GIVE OK RETURN.
;
; SUBROUTINE TO DO DEVICE COMMAND 29: CLEAR INPUT ABORT COMPLETE
;
DLTD29: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIC #TCIAB!TCIAC,TCFG2(R0) ;CLEAR ABORT BITS
JSR PC,HCLAIA ;;++BS-CLEAR THE ACTIVE BIT 3(016)
JSR PC,DLDRAI ;BE SURE THE QUEUE IS DRAINED
JMP DLTWOK ;WAKE XLATE AND GIVE OK RETURN.
;
;
; SUBROUTINE TO DO DEVICE COMMAND 30: SUSPEND DEVICE
; HAS MEANING FOR HASP ONLY
;
DLTD30: MOV TCXLT(R5),R0 ;GET XLATE TASK POINTER
BIS #TCDSP,TCFG2(R0) ;MARK DEVICE SUSPENDED
BIT #TCIOM,TCFG1(R0) ;INPUT DEVICE?
BEQ 11$ ;NO, EXIT
MOV TCDEV(R0),R1 ;GET DEV #
MOV TCLCB(R0),R0 ;POINT TO LCB
MOV LB.TC1(R0),R0 ;POINT TO BSC TCB
ASL R1 ;DEV # * 2
MOV SUSTBL(R1),R1 ;GET SUSPEND BIT FOR DEVICE
BIC R1,TCTFCS(R0) ;R0 STILL POINTS TO BSC
;THIS INDICATION GOES TO REMOTE
11$:
BR DLTWOK ;ALWAYS OK RETURN
;
; THIS SUBROUTINE TO DO DEVICE COMMAND 31: UNSUSPEND DEVICE
;
DLTD31: MOV TCXLT(R5),R0 ;POINT TO DEVICE'S XLATE TCB
BIC #TCDSP,TCFG2(R0) ;MARK DEVICE UNSUSPENDED
BIT #TCIOM,TCFG1(R0) ;INPUT DEVICE?
BEQ 11$ ;NO, EXIT
MOV TCDEV(R0),R1 ;GET DEV #
MOV TCLCB(R0),R0 ;POINT TO LCB
MOV LB.TC1(R0),R0 ;POINT TO BSC TCB
ASL R1 ;DEV # * 2
MOV SUSTBL(R1),R1 ;GET SUSPEND BIT FOR DEVICE
BIS R1,TCTFCS(R0) ;R0 STILL POINTS TO BSC
;THIS INDICATION GOES TO REMOTE
11$:
BR DLTWOK ;ALWAYS SUCCESS
;
; SUBROTINE TO DO DEVICE COMMAND 32: SET DEVICE RECORD SIZE
;
DLTD32: JSR PC,DLGBYT ;GET LOW BYTE OF SIZE
BCS 11$ ;NOT SPECIFIED, ERROR
MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
MOVB R1,TCRSZ(R0) ;STORE LOW BYTE OF SIZE
JSR PC,DLGBYT ;GET HIGH BYTE
BCS 11$ ;NOT SPECIFIED, ERROR
MOVB R1,TCRSZ+1(R0) ;STORE HIGH BYTE
JMP DLTDOK ;INDICATE SUCCESS
;
11$: RTS PC ;ERROR RETURN
;
;
; SUBROUTINE TO DRAIN THE INPUT QUEUE ON AN ABORT.
;
DLDRAI:
11$: MOV TCXLT(R5),R4 ;POINT TO XLATE TASK
MOV TCLCB(R4),R4 ;POINT TO LCB
MOV LB.LNU(R4),R1 ;GET LINE NUMBER
CMP #TTHASP,LB.DVT(R4) ;HASP LINE?
BNE 12$ ;NO, USE LINE NO AS I.D.
SWAB R1 ;PUT LINE # IN LEFT BYTE
ADD TCCTP(R0),R1 ;MAKE I.D. FOR HASP DEVICE
12$: JSR PC,DEQMID ;GET MESSAGE FROM THIS LINE
BCS 13$ ;NO MORE, ALL DONE.
MOV TCIDLE,R1 ;POINT TO "IDLE" TASK
JSR PC,QUEMSG ;SEND IT THE MESSAGE
BR 11$ ;GET THE REST
;
; HERE WHEN THERE ARE NO MORE MESSAGES FROM THIS LINE
;
13$: RTS PC ;RETURN.
;
; HERE TO WAKE THE XLATE TASK AND GIVE OK RETURN.
;
DLTWOK: MOV TCXLT(R5),R0 ;POINT TO XLATE TASK
BIT #EBINTR,(R0) ;WAITING FOR US?
BEQ DLTDOK ;NO.
BIC #EBINTR!EBWAIT,(R0) ;MAYBE, WAKE IT.
;
; HERE TO SUCCESSFULLY RETURN FROM A DEVICE COMMAND SUBROUTINE
;
DLTDOK: ;SUCCESS RETURN
CLC ;NO FATAL ERROR
RTS PC ;RETURN.
;
;
;
; THIS ROUTINE REDEFINED TO CHECK FOR ABNORMAL CONDITIONS
;(E.G. CHECKS TO SEE IF RUNNING LOW ON CHUNKS OR IF STREAM HAS
; ABORTED. )
; INPUTS:
; TCXLT(R5) POINTS TO THE TRANSLATION TASK
;
; ON RETURN:
;
; C SET: OUTPUT ABORTED OR SHORT OF CHUNKS.
; C CLEAR:
;
; R1 DESTROYED
;
DLNWCK: MOV TCXLT(R5),R1 ;POINT TO XLATE TASK
BIT #TCOAB,TCFG2(R1) ;HAS BSC STREAM ABORTED?
BNE 2$ ;YES.
CMP CHFREC,#CHLTEN ;NO, HAVE WE ENOUGH FREE CHUNKS?
BLE 3$ ;NO.
MOV TCLCB(R1),R0 ;YES, POINT TO LCB (R4 MAY BE IN USE)
CMP #TTHASP,LB.DVT(R0) ;HASP LINE?
BNE 13$ ;NO
CMP TCMSC(R1),#MSGXML ;ALREADY ENOUGH MESSAGES TO XMIT
BGT 4$ ;YES, WAIT BEFORE DOING ANY MORE
BR 14$ ;JOIN MAIN PATH
13$: CMP LB.MSC(R0),#MSGXML ;ALREADY ENOUGH MSGS TO XMIT?
BGT 5$ ;YES, WAIT BEFORE DOING ANY MORE.
14$: CMP TCXFR(R5),#DLWLMT ;HAVE WE PROCESSED ENOUGH BYTES?
BGE 6$ ;YES, WAIT UNTIL TRANSLATED.
CLC ;SIGNAL SUCCESS
RTS PC ;RETURN.
;
; HERE IF THE STREAM HAS BEEN ABORTED OR WE ARE SHORT OF CHUNKS.
;
2$:
trace trcspc,<tcfg2(r5)>
TWIDDL
BR 12$
3$:
trace trcspc,chfrec
TWIDDL
BR 12$
4$:
trace trcspc,<tcmsc(r1)>
TWIDDL
BR 12$
5$:
trace trcspc,<lb.msc(r0)>
TWIDDL
BR 12$
6$:
trace trcspc,<tcxfr(r5)>
TWIDDL
12$: SEC ;SIGNAL FAILURE
RTS PC ;RETURN.
;
;
;SUBROUTINE TO SET UP A REJECT TO THE PDP-10
;
;
;
DLRJRQ: MOVB #3, DT10DF+1(R5) ;;++BS-INDICATE COMMAND REJECTED
CLC ;;++BS-NOT A FATAL ERROR
RTS PC ;;++BS-RETURN
;
;
;
;;++BS-3(024) THIS SUBROUTINE CHECKS IF A DEVICE NUMBER IS LEGITIMATE
;;++BS-3(024) FOR THE MODE OF THE LINE. THE DEVICE NUMBER MUST BE ZERO
;;++BS-3(024) FOR 3780/2780. THE DEVICE NUMBER MUST BE BETWEEN ONE AND
;;++BS-3(024) FIVE, INCLUSIVE, FOR HASP. THIS ROUTINE ALSO SAVES THE
;;++BS-3(024) ADDRESS OF THE LAST CALL THAT HAD THE A DEVICE NUMBER.
;
;
; ON ENTRY:
;
; R1 = DEVICE NUMBER
;
; R4 = POINTER TO THE LINE CONTROL BLOCK
;
;
; ON RETURN:
;
; C-BIT CLEAR IMPLIES DEVICE NUMBER OK FOR MODE
;
; C-BIT SET IMPLIES DEVICE NUMBER ILLEGITIMATE FOR MODE
;
;
DLMCHK:
BIC #177770, R1 ;EXTRACT THE DEVICE NUMBER
BEQ 1$ ;IF ZERO, BETTER BE 3780/2780
BIT #LF.SIM, LB.FGS(R4) ;ARE WE DOING SIMULATION ?
BNE 4$ ;YES, UP TO DEVICE # 5 ALLOWED
CMP R1, #4 ;NO, SUPPORT, ONLY DEVICE # 4 ALLOWED
BGT 2$ ;ERROR, > THAN 4 FOR HASP SIMULATION
BR 5$ ;NOW MAKE SURE LINE IS IN HASP MODE
4$: CMP R1, #5 ;GREATER THAN 5 ?
BGT 2$ ;YES, ERROR, NUMBER TO BIG FOR HASP
5$: CMP #TTHASP, LB.DVT(R4) ;NO, HASP MODE ?
BNE 2$ ;NO, ERROR, ITS 3780/2780
BR 3$ ;YES, DEVICE NUMBER IS GOOD
1$: CMP #TTHASP, LB.DVT(R4) ;HASP MODE ?
BNE 3$ ;NO, 3780/2780, ZERO IS GOOD
2$: MOV (SP), DLIMPC ;SAVE THE ADDRESS OF THE CALLER
SEC ;TELL CALLER HE HAD A BAD DEVICE NUMBER
RTS PC ;RETURN TO CALLER
3$: CLC ;TELL CALLER HIS DEVICE NUMBER IS GOOD
RTS PC ;RETURN TO CALLER
DLIMPC: .WORD 0 ;PC OF LAST CALL WITH BAD DEVICE NUMBER
;;++BS-3(024) END OF DLMCHK
;
;
;
;