Google
 

Trailing-Edge - PDP-10 Archives - tops10_704_monitoranf_bb-x140c-sb - 10,7/mon/msccom.mac
There are 3 other files named msccom.mac in the archive. Click here to see a list.
TITLE	MSCCOM - COMMON DATA AND SUBROUTINES FOR MSCP DRIVERS	V20
SUBTTL	JOSEPH A. DZIEDZIC/JAD	10-NOV-87

	SEARCH	F,S,DEVPRM,SCAPRM,MSCPAR,MACSYM
	$RELOC
	$HIGH


;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
;  OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1984,1986,1988.
;ALL RIGHTS RESERVED.

.CPYRT<1984,1988>


XP	VMSCOM,20


MSCCOM:!ENTRY	MSCCOM		;LOAD IF LIBRARY SEARCH
	SUBTTL	ABBREVIATIONS USED IN MSCP DRIVERS


COMMENT	|

CTI	Connect Table Index - an index into the tables containing data and
	connect IDs for a particular connection to an MSCP server.

|; END OF COMMENT
	SUBTTL	SCS INTERFACE - MSCP DRIVER INITIALIZATION


;ROUTINE CALLED DURING SCS INITIALIZATION.  WE SET OUR NOTIFICATION
;ADDRESS VIA A CALL TO SC.SNA AND AWAIT GOOD THINGS TO HAPPEN.
;CALL:
;	PUSHJ	P,MSCINI
;RETURN:
;	CPOPJ ALWAYS
;CALLED IN SECTION 1.

	$CSENT	(MSCINI::)	;GLOBAL ENTRY
	SETZM	MSCZER		;ZERO THE IMPURE MEMORY
	MOVEI	T1,MSCLAS-MSCZER-1 ;NUMBER OF WORDS TO ZERO
	XMOVEI	T2,MSCZER	;SOURCE ADDRESS
	XMOVEI	T3,MSCZER+1	;DESTINATION ADDRESS
	EXTEND	T1,[XBLT]	;ZERO IT ALL
	SETOM	MSCCID		;LIKEWISE MAKE ALL CONNECT ID'S LOOK INVALID
	MOVEI	T1,CTILEN-1	;NUMBER OF WORDS TO COPY
	XMOVEI	T2,MSCCID	;SOURCE
	XMOVEI	T3,MSCCID+1	;DESTINATION
	EXTEND	T1,[XBLT]	;MOVE THE BITS
	BLCAL.	(SC.SNA##,<<.,MSCINT>>) ;TELL SCA ABOUT THIS ADDRESS
	  STOPCD .,STOP,MIF,	;++ MSCP DRIVER INITIALIZATION FAILED
	POPJ	P,		;ALL DONE, RETURN
	SUBTTL	SCS INTERFACE - SCS-SYSAP NOTIFICATION


;ROUTINE CALLED WHEN SCS DETERMINES THE SYSAP SHOULD BE TOLD ABOUT
;A CHANGE IN THE STATE OF ONE OF HIS CONNECTIONS, ETC.  SEE THE
;VARIOUS .SS??? NOTIFICATION DEFINITIONS IN SCAPRM.
;CALL:
;	T1/ REASON
;	T2 - T4/ REASON DEPENDENT DATA
;	PUSHJ	P,MSCINT
;RETURN:
;	CPOPJ ALWAYS
;ENTRIES IN THE DISPATCH TABLE FLAGGED WITH "*" ARE CALLED
;WITH THE CONNECT ID IN T2.

;ALL DRIVER ROUTINES ARE CALLED WITH THE CTI IN P4.
;P1, P2, AND P3 ARE AVAILABLE FOR USE BY THE DRIVER.

MSCINT::PUSHJ	P,SAVPQ##	;SAVE THE "PRESERVED" SCASER REGISTERS
	CAILE	T1,.SSAFT	;A CODE WE KNOW OF?
	STOPCD	.,STOP,NOR,	;++NOTIFICATION CODE OUT OF RANGE
	JRST	@MSCDSP(T1)	;DISPATCH BASED ON REASON

MSCDSP:	IFIW	MSCDGR		;.SSDGR - DATAGRAM RECEIVED *
	IFIW	MSCMGR		;.SSMGR - MESSAGE RECEIVED *
	IFIW	MSCPBC		;.SSPBC - PORT BROKE CONNECTION *
	IFIW	CPOPJ##		;.SSCTL - CONNECTION TO LISTEN
	IFIW	MSCCRA		;.SSCRA - CONNECTION RESPONSE AVAILABLE *
	IFIW	CPOPJ##		;.SSMSC - MESSAGE/DATAGRAM SEND COMPLETE
	IFIW	CPOPJ##		;.SSDDG - DATAGRAM DROPPED
	IFIW	CPOPJ##		;.SSLCL - LITTLE CREDIT LEFT
	IFIW	MSCONL		;.SSNCO - NODE COMING ONLINE
	IFIW	CPOPJ##		;.SSOSD - OK TO SEND DATA
	IFIW	CPOPJ##		;.SSRID - REQUEST DISCONNECT
	IFIW	MSCCDR		;.SSCIA - CREDIT IS AVAILABLE *
	IFIW	CPOPJ##		;.SSDMA - DMA OPERATION COMPLETE
IF1,<IFN <.-MSCDSP-1>-.SSAFT,<PRINTX ?Dispatch table MSCDSP is incomplete>>
;HERE TO CALL THE DRIVER DIRECTLY (IN MOST CASES).

MSCCDR:	PUSH	P,T1		;SAVE THE REASON CODE
	PUSHJ	P,MSCFCI	;FIND THE CTI FROM THE CONNECT ID
	  STOPCD TPOPJ##,DEBUG,ICI, ;++INVALID CONNECT ID
MSCCD0:	MOVE	P4,T1		;COPY THE CTI INTO P4
	POP	P,T1		;RESTORE THE REASON CODE
MSCCD1:	SKIPN	R,MSCDDT(P4)	;GET THE DISPATCH TABLE ADDRESS
	STOPCD	CPOPJ##,DEBUG,DDN, ;++DRIVER DISPATCH ADDRESS NOT SETUP
	ADD	R,T1		;OFFSET BY THE REASON CODE
....==DT.TAP
	SKIPL	MSCFLG(P4)	;IS THIS A TAPE DRIVER?
	SKIPA	J,MSCKDB(P4)	;NO, KDB ADDRESS GOES IN J
	MOVE	W,MSCKDB(P4)	;YES, KDB ADDRESS GOES IN W
IFN FTMP,<
	SKIPE	DINITF##	;SYSTEM STARTUP?
	S0PSHJ	MAPINI##	;COPY THE BOOT CPU'S MAP
> ;END IFN FTMP
	JRST	@(R)		;CALL THE DRIVER AND RETURN
;HERE WHEN PORT BROKE CONNECTION

MSCPBC:	PUSH	P,T1		;SAVE THE REASON CODE
	PUSHJ	P,MSCFCI	;FIND THE CTI FROM THE CONNECT ID
	  SKIPA			;CTI IS INVALID
	JRST	MSCCD0		;PROCEED, THINGS LOOK OK
	MOVX	T3,DT.IRC	;ARE WE IN THE MIDDLE OF A CONNECTION REQUEST?
	SKIPGE	MSCCID(T1)	;CID MUST STILL BE NEGATIVE IF SO
	TDNN	T3,MSCFLG(T1)	;AND FLAGS WORD MUST INDICATE THIS
	XCT	ICI		;NO, ERROR
	JRST	MSCCD0		;PRETEND EVERYTHING IS OK


;HERE ON CONNECTION RESPONSE AVAILABLE

MSCCRA:	SKIPN	T2		;HANDLE SCASER BRAIN DAMAGE
	XCT	MCI		;...
	LOAD	T1,SID,T2	;GET THE MSCCID TABLE INDEX FROM THE CONNECT ID
	SKIPL	MSCCID(T1)	;MAKE SURE WE'RE EXPECTING THIS
	STOPCD	CPOPJ##,DEBUG,UCR, ;++UNEXPECTED CONNECT RESPONSE
	MOVEM	T2,MSCCID(T1)	;SAVE THE FULL VERSION OF THE CONNECT ID
	MOVE	P4,T1		;GET THE CTI INTO T2
	MOVX	T1,.SSCRA	;REASON CODE
	JRST	MSCCD1		;REJOIN "CALL DRIVER" CODE


;HERE ON NODE ONLINE - TELL BOTH DISK AND TAPE DRIVER AS THEY WOULD
;EACH LIKE TO KNOW ABOUT THIS

MSCONL:	PUSH	P,T2		;SAVE THE PBI
IFN FTCIDSK,<
	SKIPE	[RAXDDT##]	;SKIP IF RAXKON NOT LOADED (DUMMY GLOBAL)
	PUSHJ	P,@RAXDDT##+.SSNCO ;CALL THE DRIVER
	MOVE	T2,(P)		;RESTORE THE PBI
>; END IFN FTCIDSK
IFN FTCITAP,<
	SKIPE	[TAXDDT##]	;SKIP IF TAXKON NOT LOADED (DUMMY GLOBAL)
	PUSHJ	P,@TAXDDT##+.SSNCO ;CALL THE DRIVER
>; END IFN FTCITAP
	PJRST	T2POPJ##	;RESTORE T2 AND RETURN
	SUBTTL	SCS-SYSAP NOTIFICATION - DATAGRAM RECEIVED


;ROUTINE TO PROCESS A DATAGRAM RECEIVED FROM A REMOTE NODE.
;CALL:
;	T2/ CONNECT ID
;	T3/ DATAGRAM ADDRESS
;	T4/ BYTE (6)FLAGS(30)RETURN BUFFER ROUTINE
;	PUSHJ	P,MSCDGR
;RETURN:
;	CPOPJ ALWAYS

MSCDGR:	$LDCID	P3,T2		;GET THE CONNECTION BLOCK ADDRESS
	MOVE	P3,.CBPBK(P3)	;GET THE PATH BLOCK ADDRESS
	MOVE	P2,T3		;COPY PACKET ADDRESS TO P2
	TXZ	T4,C%FLGM	;STRIP THE FLAGS
	MOVEM	T4,(P2)		;SAVE THE RETURN BUFFER ROUTINE ADDRESS
	MOVE	T1,.MHPKL(P2)	;TOTAL BLOCK LENGTH
	ADDI	T1,3		;ROUND ODD BYTES TO AN EVEN NUMBER OF WORDS
	LSH	T1,-2		;...
	ADDI	T1,EL%PAK	;INCLUDE THE ADDITIONAL WORD(S) WE SUPPLY
	PUSHJ	P,ALCSEB##	;ALLOCATE A SYSTEM ERROR BLOCK
	  PJRST	MSCRBF		;NOT AVAILABLE, IGNORE ERROR PACKET
	MOVEI	T2,SEC%EL	;GET THE BLOCK TYPE
	DPB	T2,[POINT 9,.EBTYP(T1),8] ;STORE IN HEADER
	LOAD	T2,PBDPN,(P3)	;GET THE DESTINATION PORT (NODE) NUMBER
	MOVEM	T2,.EBHDR+EL%NOD(T1) ;STORE IN BODY
	MOVE	T2,.MHPKL(P2)	;TOTAL BLOCK LENGTH
	ADDI	T2,3		;ROUND ODD BYTES TO AN EVEN NUMBER OF WORDS
	LSH	T2,-2		;...
	XMOVEI	T3,P.CRF(P2)	;FROM THE PACKET
	MOVEI	T4,.EBHDR+EL%PAK(T1) ;TO THE ERROR BLOCK
	EXTEND	T2,[XBLT]	;COPY THE PACKET
	PUSHJ	P,QUESEB##	;HAND THE BLOCK OFF TO DAEMON
	PJRST	MSCRBF		;RETURN BUFFER TO SCA AND RETURN
	SUBTTL	SCS-SYSAP NOTIFICATION - MESSAGE RECEIVED


;ROUTINE TO PROCESS A MESSAGE RECEIVED FROM A REMOTE NODE.
;CALL:
;	T2/ CONNECT ID
;	T3/ MESSAGE ADDRESS
;	T4/ BYTE (6)FLAGS(30)RETURN BUFFER ROUTINE
;	PUSHJ	P,MSCMGR
;RETURN:
;	CPOPJ ALWAYS

MSCMGR:	$LDCID	P3,T2		;GET THE CONNECTION BLOCK ADDRESS
	MOVE	P3,.CBPBK(P3)	;GET THE PATH BLOCK ADDRESS
	MOVE	P2,T3		;COPY PACKET ADDRESS TO P2
	TXZ	T4,C%FLGM	;STRIP THE FLAGS
	MOVEM	T4,(P2)		;SAVE THE RETURN BUFFER ROUTINE ADDRESS
	PUSHJ	P,MSCFCI	;FIND THE CTI
	  PJRST	MSCRBF		;NOT FOUND, TOSS THE PACKET AND RETURN
	MOVE	P4,T1		;COPY CTI TO P4
	PUSHJ	P,MSCRSW	;REVERSE THE STATUS BYTES
	LOAD	T1,PKYECD,(P2)	;GET THE END CODE
	TRZE	T1,OP%AVA	;AVAILABLE?
	JRST	MGRAVA		;YES, GO HANDLE IT
	TRZN	T1,OP%END	;REASONABLE?
	JRST	MGRBEC		;NO, GO INVESTIGATE
	CAIN	T1,OP%ABO	;AN ABORT END PACKET?
	PJRST	MSCRBF		;YES, NOTHING MORE NEEDS TO BE DONE
	MOVE	T2,P.CRF(P2)	;GET THE COMMAND REFERENCE NUMBER
	ASH	T2,-4		;RIGHT ADJUST IT IN 36 BITS
	TLNN	T2,-1		;LH NON-ZERO?
	JRST	MGRXFR		;NO, REGULAR MESSAGE
	CAIL	T1,OP%GCS	;IS IT A REASONABLE END CODE?
	CAILE	T1,OP%ONL	;...
	XCT	BEC		;NO, THE SERVER SCREWED UP
	HLRZS	T2		;FIND THE COMMAND REQUEST
	CAIN	T2,-1		;CHECK FOR -1 (ALL DONE)
	PJRST	MSCRBF		;DONE RETURN FROM INTERRUPT
	CAIGE	T2,CMDTBL	;INDEXED OFF END OF TABLE?
	CAME	T1,CMDTAB(T2)	;CHECK TO SEE THAT IT IS CONSISTENT
	STOPCD	MSCRBF,DEBUG,CRU, ;++ COMMAND REFERENCE NUMBER UNKNOWN

;AT THIS POINT P2 CONTAINS THE PACKET ADDRESS, P4 CONTAINS THE
;CTI, AND T2 CONTAINS THE REASON CODE.  USE THE REASON CODE AS
;A NEGATIVE INDEX INTO THE DRIVER DISPATCH TABLE AND CALL THE
;DRIVER IN RESPONSE TO THEIR REQUEST.

	MOVN	T1,T2		;NEGATE REASON, MOVE TO T1
	PJRST	MSCCD1		;CALL THE DRIVER AND RETURN
;THIS TABLE CONTAINS THE COMMAND CODE WE SHOULD EXPECT TO SEE WHEN
;WE HAVE RECEIVED A RESPONSE TO SOME FUNCTION WITH A RECALL CODE.

CMDTAB:	0			;DATA REQUEST, DOESN'T COME THROUGH HERE
	OP%SCC			;(.RRSCC) SET CONTROLLER CHARACTERISTICS
	OP%GUS			;(.RRGNU) GET NEXT UNIT
	OP%ONL			;(.RRONL) SET UNIT ONLINE
	OP%ONL			;(.RROON) ONCE BIND ONLINE
	OP%ONL			;(.RRAON) AVAILABLE UNIT ONLINE
	OP%GCS			;(.RRGCS) GET COMMAND STATUS
	OP%GUS			;(.RRGUS) GET UNIT STATUS
	0			;(.RRAVA) UNSOLICITED UNIT AVAILABLE
	0			;(.RRXFR) TRANSFER DONE
	OP%GUS			;(.RRCUS) CHECK UNIT STATUS
CMDTBL==.-CMDTAB		;LENGTH OF COMMAND LOOKUP TABLE
;HERE ON A UNIT AVAILABLE

MGRAVA:	BLCAL.	(SC.RMG##,<MSCCID(P4),[1],[0]>) ;REQUEST MORE CREDIT
	  JFCL			;IGNORE ERROR RETURN
	MOVNI	T1,.RRAVA	;REASON = UNSOLICITED UNIT AVAILABLE
	PJRST	MSCCD1		;CALL THE DRIVER AND RETURN

;HERE ON A RESPONSE TO A DATA TRANSFER REQUEST

MGRXFR:	MOVNI	T1,.RRXFR	;REASON = TRANSFER COMPLETE
	PJRST	MSCCD1		;CALL THE DRIVER AND RETURN

;HERE ON A BAD END CODE.  THE HSC APPEARS TO HAVE A BUG IN THAT IT WILL
;SEND AN END PACKET CONTAINING NO DATA AFTER A KL RELOAD IF THE VIRTUAL
;CIRCUIT WASN'T CLOSED IN AN ORDERLY FASHION.  THIS ROUTINE ATTEMPTS
;(PROBABLY IN VAIN) TO RECOVER FROM THIS CONDITION BY INITIATING A VC
;CLOSURE SO THE CONNECTION GETS RE-ESTABLISHED AGAIN.

MGRBEC:	PUSHJ	P,MSCRBF	;CLEAN UP AFTER OURSELVES FIRST
	SKIPN	DINITF##	;DURING INITIALIZATION?
	STOPCD	CPOPJ##,DEBUG,BEC, ;++ PACKET WITH BAD END CODE RECEIVED
	STOPCD	.+1,EVENT,INIBEC, ;++ BAD END CODE DURING INITIALIZATION
	LOAD	T1,PBPBI,(P3)	;GET PATH BLOCK INDEX OF VIRTUAL CIRCUIT
	BLCAL.	(PPDCVC##,<T1>)	;TELL PORT DRIVER TO CLOSE VC
	POPJ	P,		;RETURN, HAVOC WILL SOON HAPPEN
	SUBTTL	COMMON SUBROUTINES - CONVERT RH-20 STYLE CHANNEL COMMAND LIST


;ROUTINE TO CONVERT A RH-20 STYLE CHANNEL COMMAND LIST INTO A BHD AND
;AS MANY BSDS AS NEEDED TO COMPLETE THE TRANSFER.
;CALL:
;	T1/ OPCODE (OP.RD OR OP.WR)
;	T2/ TRANSFER MODE (BS.XXX)
;	T3/ ADDRESS OF CHANNEL COMMAND LIST
;	P1 - P4 AVAILABLE FOR USE
;	PUSHJ	P,MSCMIO
;RETURN:
;	CPOPJ IF ERRORS (NO BHD OR BSD AVAILABLE)
;	CPOPJ1 IF SUCCESS WITH:
;	P1/ BUFFER NAME
;	P2/ PACKET ADDRESS
;	P4/ BHD ADDRESS

MSCMIO::PUSHJ	P,SAVR##	;SAVE R
	PUSH	P,T1		;SAVE THE OPCODE
	PUSH	P,T3		;SAVE THE CHANNEL COMMAND LIST ADDRESS
	MOVE	P3,T2		;SAVE THE TRANSFER MODE
	PUSHJ	P,MSCGBF	;GET A BUFFER
	  JRST	TTPOPJ##	;COULDN'T, RESTORE AC'S AND ERROR RETURN
	POP	P,R		;GET CHANNEL COMMAND LIST ADDRESS IN R
	MOVE	T1,(P)		;GET THE OPCODE
	PUSHJ	P,REVFUL##	;REVERSE IT FOR THE HSC
	MOVEM	T1,P.OPCD(P2)	;STORE IN THE PACKET
	PUSHJ	P,PPDGBH##	;GET A BUFFER HEADER
	  JRST	MSCMI6		;NOT AVAILABLE, RETURN PACKET AND ERROR RETURN
	MOVE	P4,T2		;COPY BHD ADDRESS TO P4
	SETZM	.BHBSA(P4)	;MAKE SURE BSD LIST POINTER IS ZERO
	PUSHJ	P,PPDGCN##	;GET A COMMAND REFERENCE NUMBER
	MOVEM	T4,P.CRF(P2)	;STORE IN PACKET
	LSH	T1,^D35-BHPIDX	;POSITION INDEX
	LSH	T4,^D35-BHPKEY-4 ;POSITION KEY
	IOR	T1,T4		;GET THE BUFFER NAME
	MOVE	P1,T1		;SAVE IN P1 FOR RETURN
	PUSHJ	P,REVFUL##	;RESERVE FOR THE HSC
	MOVEM	T1,P.BUFF+1(P2)	;STORE IN PACKET
	MOVE	T1,(P)		;GET OPCODE BACK
	CAIN	T1,OP.RD	;READING (I.E., WRITING INTO KL MEMORY)?
	TXO	T4,BH.WRT	;YES, SET WRITABLE BIT
	MOVEM	T4,.BHKEY(P4)	;STORE THE KEY (MINUS VALID BIT)
	SETZM	.BHLEN(P4)	;ZERO NIBBLE COUNT AND TOTAL SEGMENT LENGTH
	PUSH	P,P3		;SAVE TRANSFER MODE ON STACK
	XMOVEI	P3,.BHBSA-.BSNXT(P4) ;INIT FIRST BSD LINK WORD
MSCMI1:	LDB	T1,[POINTR (0(R),CC.OPC)] ;GET OPCODE FROM CCW
	CAIL	T1,.CCFDT	;DATA TRANSFER?
	CAILE	T1,.CCRTH	;...
	JRST	MSCMI2		;NO, SEE IF END OR GOTO WORD
	PUSHJ	P,PPDGBD##	;GET A BUFFER SEGMENT DESCRIPTOR
	  JRST	MSCMI5		;NOT AVAILABLE, RETURN ETC. AND ERROR RETURN
	MOVEM	T1,.BSNXT(P3)	;STORE PHYSICAL BSD ADDRESS IN PREVIOUS LINK
	MOVE	P3,T2		;GET VIRTUAL BSD ADDRESS IN P3
	LDB	T1,[POINTR (0(R),CC.WDC)] ;GET WORD COUNT
	MOVS	T2,(P)		;GET TRANSFER MODE
	CAIE	T2,(BS.ICM)	;INDUSTRY COMPATIBLE MODE?
	CAIN	T2,(BS.HDM)	;HIGH DENSITY MODE?
	IMULI	T1,HDNPW	;CONVERT TO NIBBLES
	CAIN	T2,(BS.CDM)	;CORE DUMP MODE?
	IMULI	T1,CDNPW	;CONVERT TO NIBBLES
	MOVEM	T1,.BSLEN(P3)	;STORE LENGTH OF THIS SEGMENT
	ADDM	T1,.BHLEN(P4)	;INCLUDE LENGTH IN TOTAL TRANSFER LENGTH
	LDB	T1,[POINTR (0(R),CC.ADR)] ;GET ADDRESS
	TDO	T1,(P)		;SET TRANSFER MODE
	MOVEM	T1,.BSADR(P3)	;STORE ADDRESS OF THIS SEGMENT
	SETZM	.BSNXT(P3)	;ENSURE LINK TO NEXT IS ZERO IN LAST BSD
	MOVSI	T1,(CC.HLT)	;WAS HALT BIT SET IN TRANSFER?
	TDNN	T1,0(R)		;...
	AOJA	R,MSCMI1	;NO, LOOP TO NEXT CCW

MSCMI2:	CAIE	T1,.CCJMP	;JUMP OPCODE?
	JRST	MSCMI3		;NO, ASSUME HALT OPCODE
	LDB	R,[POINTR (0(R),CC.ADR)] ;GET ADDRESS OF NEXT CCW
	JRST	MSCMI1		;KEEP PLUGGING AWAY

MSCMI3:	MOVEI	T1,1		;WAS TRANSFER FOR AN ODD NUMBER OF NIBBLES?
	TDNN	T1,.BHLEN(P4)	;...
	JRST	MSCMI4		;NO, NO NEED FOR A THROW-AWAY WORD AT END
	PUSHJ	P,PPDGBD##	;GET ANOTHER BUFFER SEGMENT DESCRIPTOR
	  JRST	MSCMI5		;NOT AVAILABLE, RETURN ETC. AND RETURN
	MOVEM	T1,.BSNXT(P3)	;STORE PHYSICAL BSD ADDRESS IN PREVIOUS LINK
	MOVE	P3,T2		;GET VIRTUAL BSD ADDRESS IN P3
				;USE FIRST 4 BITS OF .BSLEN AS THROW-AWAY WORD
	ADDI	T1,.BSLEN	;OFFSET PHYSICAL BSD ADDRESS TO .BSLEN
	TDO	T1,(P)		;SET TRANSFER MODE
	MOVEM	T1,.BSADR(P3)	;STORE PHYSICAL ADDRESS OF JUNK WORD
	MOVEI	T1,1		;GET LENGTH IN NIBBLES
	MOVEM	T1,.BSLEN(P3)	;STORE LENGTH OF THIS SEGMENT
	ADDM	T1,.BHLEN(P4)	;INCLUDE LENGTH IN TOTAL TRANSFER LENGTH
	SETZM	.BSNXT(P3)	;ENSURE LINK TO NEXT IS ZERO IN LAST BSD
MSCMI4:	MOVX	T1,BH.VAL!BH.PRE ;GET VALID AND PRESERVE BITS
	IORM	T1,.BHKEY(P4)	;THIS BHD IS NOW VALID
	MOVE	T1,.BHLEN(P4)	;GET THE TOTAL TRANSFER LENGTH IN T1
	LSH	T1,4-1		;POSITION NIBBLE COUNT IN 32 BITS, DIVIDE BY 2
				; TO GET BYTE COUNT
	PUSHJ	P,REVFUL##	;REVERSE FOR THE HSC
	MOVEM	T1,P.BCNT(P2)	;STORE IN PACKET
	ADJSP	P,-2		;TOSS THE JUNK FROM THE STACK
	JRST	CPOPJ1##	;SKIP RETURN

;HERE IF WE COULDN'T GET ONE OF THE BSD'S WE DESIRED

MSCMI5:	ADJSP	P,-1		;REMOVE THE TRANSFER MODE FROM THE STACK
	MOVE	T1,P1		;GET THE BUFFER NAME
	PUSHJ	P,PPDRHD##	;RETURN BHD AND ANY BSDS

;HERE IF WE COULDN'T GET A BHD

MSCMI6:	ADJSP	P,-1		;REMOVE THE OPCODE FROM THE STACK
	PJRST	MSCRBF		;RETURN THE PACKET AND TAKE THE ERROR RETURN
	SUBTTL	COMMON SUBROUTINES - SET CONTROLLER CHARACTERISTICS


;ROUTINE TO SEND A SET CONTROLLER CHARACTERISTICS MESSAGE.
;CALL:
;	P4/ CTI
;	PUSHJ	P,MSCSCC
;RETURN:
;	CPOPJ ALWAYS

MSCSCC::PUSHJ	P,MSCGBF	;GET A BUFFER FROM SCA
	  POPJ	P,		;NONE AVAILABLE
	$LDCID	P3,MSCCID(P4)	;GET THE CONNECTION BLOCK ADDRESS
	MOVE	P3,.CBPBK(P3)	;GET THE PATH BLOCK ADDRESS
	PUSHJ	P,VAXTOD##	;GET THE VAX-STYLE DATE SCRUNCHED AROUND IN T1/T2
	DMOVEM	T1,P.TIME(P2)	;STORE IN THE PACKET
	SETZM	P.HTMO(P2)	;ZERO TIMEOUT WORD
	MOVX	T1,CF.MSC+CF.THS+CF.576+CF.ATN ;ALL THE GOOD BITS
	PUSHJ	P,REVFUL##	;REVERSE THE BITS
	MOVEM	T1,P.CNTF(P2)	;STORE IN PACKET
	SETZB	T1,P.CDPR(P2)	;CONTROLLER DEPENDENT PARAMETERS ARE ZERO
	MOVEI	T2,OP.SCC	;OPERATION = SET CONTROLLER CHARACTERISTICS
	MOVEI	T3,P%CDPR	;GET THE LENGTH
	MOVEI	R,.RRSCC	;GET THE RECALL CODE
	PJRST	MSCSPK		;SEND THE PACKET AND RETURN
	SUBTTL	COMMON SUBROUTINES - GET NEXT UNIT/GET UNIT STATUS


;ROUTINE TO RETURN THE NEXT UNIT FROM THE HSC OR GET THE STATUS
;OF A PARTICULAR UNIT.
;CALL:
;	T1/ CURRENT UNIT NUMBER
;	P2/ PACKET ADDRESS (TO BE REUSED)
;	P4/ CTI
;	PUSHJ	P,MSCGNU/MSCGUS
;RETURN:
;	CPOPJ ALWAYS

MSCGNU::MOVE	T2,[MD.NXU+OP.GUS] ;ASK HSC FOR STATUS OF NEXT UNIT
	MOVEI	R,.RRGNU	;RECALL CODE
	JRST	MSCGU1		;JOIN COMMON CODE

MSCCUS::SKIPA	R,[.RRCUS]	;RECALL CODE
MSCGUS::MOVEI	R,.RRGUS	;RECALL CODE
	MOVEI	T2,OP.GUS	;ASK HSC FOR STATUS OF THIS UNIT
MSCGU1:	MOVEI	T3,P%OPCD	;MESSAGE LENGTH
	PJRST	MSCSPK		;SEND THE PACKET AND RETURN
	SUBTTL	COMMON SUBROUTINES - ONLINE/OFFLINE A UNIT


;ROUTINE TO ONLINE/OFFLINE A UNIT.
;CALL:
;	T1/ UNIT NUMBER (ALA HSC)
;	P2/ PACKET ADDRESS (TO BE REUSED)
;	P4/ CTI
;	R/ RECALL CODE (FOR MSCUON CALLS)
;	PUSHJ	P,MSCUON/MSCUOF
;RETURN:
;	CPOPJ ALWAYS

MSCUOF::SETO	R,		;NO RECALL CODE FOR OFFLINE
	SKIPA	T2,[OP.AVL]	;OPCODE = AVAILABLE
MSCUON::MOVEI	T2,OP.ONL	;OPCODE = ONLINE
	MOVEI	T3,P%SHUN	;SIZE OF PACKET
	PJRST	MSCSPK		;SEND THE PACKET AND RETURN
	SUBTTL	COMMON SUBROUTINES - GET COMMAND STATUS


;ROUTINE TO SEND A GET COMMAND STATUS PACKET.
;CALL:
;	T1/ UNIT NUMBER (ALA HSC)
;	T2/ COMMAND REFERENCE NUMBER
;	P4/ CTI
;	PUSHJ	P,MSCGCS
;RETURN:
;	CPOPJ ALWAYS

MSCGCS::PUSH	P,T1		;SAVE THE AC'S A BIT
	PUSH	P,T2		;...
	PUSHJ	P,MSCGBF	;GET A BUFFER
	  JRST	TTPOPJ##	;NONE AVAILABLE
	POP	P,T2		;RESTORE THE AC'S
	POP	P,T1		;...
	MOVEM	T2,P.OTRF(P2)	;STORE THE COMMAND REFERENCE NUMBER
	MOVEI	T2,OP.GCS	;OPCODE = GET COMMAND STATUS
	MOVEI	T3,P%OTRF	;SIZE OF PACKET
	MOVEI	R,.RRGCS	;RECALL CODE
	PJRST	MSCSPK		;SEND THE PACKET AND RETURN
	SUBTTL	COMMON SUBROUTINES - SEND A PACKET


;ROUTINE TO SEND A PACKET OVER THE CI.
;CALL:
;	T1/ UNIT NUMBER
;	T2/ OPCODE PLUS MODIFIERS
;	T3/ LENGTH OF PACKET
;	P2/ PACKET ADDRESS
;	P4/ CTI
;	R/ RECALL CODE
;	PUSHJ	P,MSCSPK
;RETURN:
;	CPOPJ ALWAYS

MSCSPK:	PUSHJ	P,PPDGCN##	;GET NEXT COMMAND REFERENCE NUMBER
	HRRM	R,MSCFLG(P4)	;SAVE THE RECALL CODE
	LSH	R,4		;POSITION IN 32 BITS
	HRL	T4,R		;INCLUDE IN COMMAND REFERENCE NUMBER
	MOVEM	T4,P.CRF(P2)	;STORE
	LSH	T1,4		;POSITION UNIT NUMBER FOR HSC
	PUSHJ	P,REVFUL##	;REVERSE THE BITS
	MOVEM	T1,P.UNIT(P2)	;STORE
	MOVE	T1,T2		;OPCODE, MODIFIERS
	PUSHJ	P,REVFUL##	;REVERSE THE BITS
	MOVEM	T1,P.OPCD(P2)	;STORE OPCODE AND MODIFIERS
	SKIPG	T4,MSCCID(P4)	;MAKE SURE OUR CONNECT ID IS VALID
	JRST	MSCSP1		;DRIVER SHOULDN'T HAVE GOTTEN HERE
	BLCAL.	(SC.SMG##,<T4,[0],T3,P2,[2],[0],[0]>) ;SEND THE PACKET
	  JRST	MSCSP1		;FAILED, GO FOOL AROUND
	POPJ	P,		;SUCCESS, RETURN

MSCSP1:	STOPCD	.+1,DEBUG,MPF,	;++MSCCOM PACKET SEND FAILED
	MOVE	T1,P2		;COPY PACKET ADDRESS
	PUSHJ	P,MSCRBF	;RETURN THE PACKET
	SETOM	MSCCID(P4)	;MAKE THE CONNECT ID LOOK INVALID
	MOVX	T1,DT.IRC!DT.IDC ;CLEAR ALL STATUS BITS
	ANDCAM	T1,MSCFLG(P4)	;...
	MOVX	T1,DT.GAW	;INDICATE IT HAS GONE AWAY
	IORM	T1,MSCFLG(P4)	;...
	POPJ	P,		;RETURN
	SUBTTL	COMMON SUBROUTINES - GET/RETURN A BUFFER FROM/TO SCA


;ROUTINE TO GET A BUFFER FROM SCA TO BUILD A PACKET IN.
;CALL:
;	PUSHJ	P,MSCGBF
;RETURN:
;	CPOPJ IF ERROR WITH:
;	T1/ ERROR CODE
;	CPOPJ1 IF SUCCESS WITH:
;	P2/ PACKET ADDRESS

MSCGBF::MOVEI	T1,1		;JUST WANT ONE BUFFER
	PUSHJ	P,SC.ABF##	;ASK SCASER FOR ONE
	  POPJ	P,		;NONE AVAILABLE?
	MOVEM	T3,(T1)		;SAVE THE RETURN THIS BUFFER ROUTINE ADDRESS
	MOVE	P2,T1		;RETURN PACKET ADDRESS IN P2
	JRST	CPOPJ1##	;SKIP RETURN


;ROUTINE TO RETURN A BUFFER TO SCA OBTAINED BY CALLING MSCGBF.
;CALL:
;	P2/ PACKET ADDRESS
;	PUSHJ	P,MSCRBF
;RETURN:
;	CPOPJ ALWAYS

MSCRBF::SKIPE	T1,P2		;ANYTHING THERE?
	PUSHJ	P,@(P2)		;YES, CALL THE RETURN BUFFER ROUTINE
	POPJ	P,		;RETURN
	SUBTTL	CONNECT ID TABLE ROUTINES


;ROUTINE TO RETURN A CTI GIVEN A CONNECT ID.
;CALL:
;	T2/ CONNECT ID
;	PUSHJ	P,MSCFCI
;RETURN:
;	CPOPJ IF NO MATCH WITH:
;	T1/ PURPORTED CTI
;	CPOPJ1 IF MATCH WITH:
;	T1/ CTI

MSCFCI:	SKIPN	T1,T2		;CHECK FOR BROKEN SCASER, ZERO T1 IF SO
	STOPCD	CPOPJ##,DEBUG,MCI, ;++MISSING CONNECT ID
	LOAD	T1,SID,T2	;GET THE MSCCID TABLE INDEX FROM THE CONNECT ID
	CAMN	T2,MSCCID(T1)	;A QUICK SANITY CHECK
	AOS	(P)		;MATCHES, SET FOR SKIP RETURN
	POPJ	P,		;RETURN


;ROUTINE TO OBTAIN A FREE CTI.
;CALL:
;	PUSHJ	P,MSCGCI
;RETURN:
;	CPOPJ IF NO FREE SLOTS
;	CPOPJ1 IF FREE CTI OBTAINED WITH:
;	T1/ CTI

MSCGCI::CIOFF			;PREVENT RACES
	MOVSI	T1,-CTILEN	;-VE LENGTH OF TABLES
	MOVX	T2,DT.USE	;THE "IN USE" BIT
	TDNE	T2,MSCFLG(T1)	;IS THIS CTI FREE?
	AOBJN	T1,.-1		;NO, LOOP FOR REMAINDER OF TABLES
	JUMPGE	T1,MSGCI1	;JUMP IF WE DIDN'T FIND A FREE SLOT
	HRRZS	T1		;ISOLATE JUST THE TABLE INDEX
	MOVEM	T2,MSCFLG(T1)	;CLAIM THIS SLOT, AND CLEAR OTHER FLAGS
	SETOM	MSCCID(T1)	;NO CONNECT ID AS OF YET
	SETZM	MSCDDT(T1)	;NO DISPATCH TABLE ADDRESS
	SETZM	MSCKDB(T1)	;AND NO KDB ADDRESS
	AOS	(P)		;SET FOR A SKIP RETURN
MSGCI1:	PJRST	CIONPJ##	;INTERRUPTS BACK ON AND RETURN
	SUBTTL	COMMON SUBROUTINES - MISCELLANEOUS


;ROUTINE TO REVERSE THE STATUS WORD IN A PACKET.
;CALL:
;	P2/ PACKET ADDRESS
;	PUSHJ	P,MSCRSW
;RETURN:
;	CPOPJ ALWAYS WITH:
;	T1/ REVERSED STATUS WORD

MSCRSW::MOVE	T1,P.STS(P2)	;GET THE STATUS WORD
	PUSHJ	P,REVFUL##	;REVERSE THE BYTES
	MOVEM	T1,P.STS(P2)	;PUT IT BACK
	POPJ	P,		;RETURN


;ROUTINE TO RETURN THE UNIT NUMBER FROM A PACKET.
;CALL:
;	P2/ PACKET ADDRESS
;	PUSHJ	P,MSCGUN
;RETURN:
;	CPOPJ ALWAYS WITH:
;	T1/ UNIT NUMBER

MSCGUN::MOVE	T1,P.UNIT(P2)	;GET THE UNIT NUMBER
	PUSHJ	P,REVFUL##	;REVERSE THE BYTES
	LSH	T1,-4		;RIGHT-JUSTIFY IT
	ANDI	T1,177777	;KEEP JUST THE UNIT NUMBER
	POPJ	P,		;RETURN
	SUBTTL	DATA STORAGE


	$LOW

	CTILEN==1_WID(SID)	;MAXIMUM LENGTH OF TABLES INDEXED BY CTI

MSCZER:!			;START OF AREA TO ZERO
MSCCID::BLOCK	CTILEN		;CONNECT ID
MSCFLG::BLOCK	CTILEN		;FLAGS
MSCDDT::BLOCK	CTILEN		;MSCP DRIVER DISPATCH TABLE ADDRESS
MSCKDB::BLOCK	CTILEN		;KDB ADDRESS

MSCDKA::BLOCK	C%SBLL		;DISK KDB ADDRESS INDEXED BY SYSTEM BLOCK INDEX
MSCTKA::BLOCK	C%SBLL		;TAPE KDB ADDRESS INDEXED BY SYSTEM BLOCK INDEX
MSCLAS==.-1			;END OF AREA TO ZERO
	$HIGH
	SUBTTL	THE END


	MSCEND::!END