Google
 

Trailing-Edge - PDP-10 Archives - dec-10-omona-u-mc9 - rdxser.mac
There are 2 other files named rdxser.mac in the archive. Click here to see a list.
TITLE RDXSER -REMOTE DATA ENTRY SERVICE ROUTINE TO SUPPORT MCS10 - V016
SUBTTL D. TODD  01 FEB 77
	SEARCH F,S,NETPRM
	$RELOC
	$HIGH
;*** COPYRIGHT 1975,1976,1977 DIGITAL EQUIPMENT CORP., MAYNARD, MASS. ***
XP	VRDXSER,016	;PUT VERSION NUMBER IN GLOB AND LOADER MAP

NETRDX::ENTRY	NETRDX

RDXSER::ENTRY	RDXSER	;LOADING IF IN LIBRARY SEARCH MODE


COMMENT\			;;;REVISION HISTORY

V0		;INITIAL PRODUCT IMPLEMENTATION
\
comment ?
           Subj: RDXSER (Remote Data Entry Services Routine)

1. DEVICE RDcnnu

  The device mnemonic is RDAnn0...RDHnn7, thru RDHnn7;the buffer size is
103  (base  8)  words  (100  user  data).  This  device name follows the
standard  6.02  device  naming convention, although there are no generic
searches  allowed.  The first two letters define the device RD; c is the
controller number in the range A - H; nn is the node number in the range
1  -  77;  and  u  is  the unit number. The device exists only on a DN80
series  remote  concentrator running network software (ANF-10). The DN80
remote  concentrator must be assembled to correspond to the DECsystem-10
device  RD,  the controller number, and the unit number. The primary use
of  this device is to support multi-drop polling of intelligent buffered
terminals.


2. DATA MODES

  The first word of each user data buffer contains a control word of the
form ddddd, where ddddd is the multi-drop number of the terminal.  The
ddddd is represented as 7-bit ASCII
characters  and must be in the  above format. Leading digits are signi-
ficant  and  must  be  ASCII  blanks  or zeroes.  The remainder of the
user  buffer  contains   7-bit  ASCII  data.   Data  is  transmitted and
received
 exactly as  it  appears  in  the  user buffer. There is no insertion of
fillers  or  deletions  of  characters  by  rub-outs.  This  mode may be
considered to be IMAGE ASCII mode.


3. MPX CHANNEL

  This  device  can  be  multiplexed  with other devices on the same MPX
channel. (For further information see the section on programming the MPX
channel in the DECsystem-10 Monitor Call Manual.)
4. SOFTWARE INTERRUPTS AND NON-BLOCKING I/O

  The  pseudo-software interrupt system and non-blocking I/O can be used
with remote data entry devices. (For further information see the section
on  programming the pseudo-software interrupt system in the DECsystem-10
Monitor Call Manual.)


5. STATUS INFORMATION

   Bit 18   IO.IMP  -  improper mode - the bit is set if the line number
            specified is not in the polling sequence.

   Bit 19   IO.DER  -  device error - the bit is set if the device fails
            and the terminal is in the polling list.

   Bit 20   IO.DTE  -  channel  error  -  the  bit  is set if trouble is
            detected on the entire multi-drop line.

   Bit 21   IO.BKT - block too large - the bit is set if the user's data
            buffer exceeds the maximum length of a single DDCMP message.

   Bit 22   IO.EOF - end-of-file

   Bit 23   IO.ACT  -  I/O  active  -  the bit is set when the device is
            active.
?
SUBTTL RDXSER - ROUTINE TO SUPPORT REMOTE DATA ENTRY DEVICES

;SPECIAL BITS IN LH(S)

IOSCLO==400		;DEV HAS BEEN CLOSED
IOSREL==1000		;DEV HAS BEEN RELEASED
IOSDRP==2000		;MULTI DROP LINE
IOSCON==4000		;DEVICE IS CONNECTED
IOSERR==10000		;ERROR DETECTED AT INT. LEVEL
IOSHDV==100000		;HUNG DEVICE

;DISPATCH TABLE
	POPJ	P,0		;SPECIAL ERROR STATUS
	JRST	RDXOPN		;(-3)  LENGTH CAN BE GOTTEN FROM DDB
	JRST	CPOPJ##		;(-2)  INITIALIZE
	JRST	NETHNG##	;(-1)  HUNG DEVICE
NDEVRX::JRST	NETRLS##	;(0)  RELEASE
	JRST	RDXCLO		;(1)  CLOSE OUTPUT
	JRST	RDXOUT		;(2)  OUTPUT
	JRST	RDXINP		;(3)  INPUT

RDANDP::JRST	RDXDAT		;(-6)  DATA MESSAGE

	JRST	RDXSTS		;(-5)  STSTUS MESSAGE
	JRST	RDXINT		;(-4)  INIT
RDXSTS==CPOPJ##
RDXCLO==CPOPJ##
RDXOPN:	LDB	T1,NETDVT##	;GET THE DEVICE ATTRIBUTES BITS
	TRNN	T1,DRX.MD	;IS IT MULTI DROP
	JRST	REGSIZ##	;NO
	MOVSI	T1,IOSDRP	;SET THE BIT
	IORM	T1,DEVIOS(F)
	MOVEI	T1,1		;SO THE USER CAN FIND OUT
	MOVEM	T1,DEVSTS(F)
	JRST	REGSIZ##
SUBTTL RDXDAT (-6)  DATA MESSAGE
RDXDAT:				;ENTRY FROM DDB DISPATCH
	SKIPN	P3,NETDEV##(F)	;GET THE LOCATION OF THE MONITOR BUFFERS
	POPJ	P,		;NO BUFFERS IGNORE THE MESSAGE
	MOVE	S,DEVIOS(F)	;GET THE STATUS BITS
	MOVE	P2,MBFIBC##(P3)	;COMPUTE THE BUFFER LOCATION
	LDB	T1,PBUFSZ##	;GET THE USER BUFFER SIZE
	IMULI	P2,(T1)		;LENGTH
	ADDI	P2,MBFMBF##(P3)	;ADD THE OFFSET
	MOVEI	T2,1(P2)	;CLEAR THE BUFFER
	HRLI	T2,(P2)		;WITH A BLT
	SETZM	(P2)		;FIRST WORD
	ADDI	T1,-1(P2)	;COMPUTE THE END OF THE BUFFER
	BLT	T2,(T1)		;CLEAR IT
	LDB	T4,PBUFSZ##	;GET THE BUFFER SIZE
	SUBI	T4,1		;MINUS THE WC
	TLNE	S,IOSDRP	;MULTI DROP
	SUBI	T4,1		;COUNT THE DROP NUMBER
	IMULI	T4,5		;FIVE CHARACTER/WORD
	MOVNS	T4		;NEGATIVE
	MOVSI	T4,-1(T4)	;MAKE A AOBJN POINTER
	TLNN	S,IOSDRP	;CHECK FOR A DROP NUMBER
	JRST	RDXDA0		;NO SKIP IT
;HERE TO READ THE DROP NUMBER
	PUSHJ	P,EBI2BI##	;READ THE DROP NUMBER
	PUSHJ	P,BI2ASC	;CONVERT TO ASCII
	MOVEM	T1,1(P2)	;STORE AS FIRST DATA WORD
	SKIPA	T3,[POINT 7,2(P2)]	;OUTPUT BYTE POINTER
RDXDA0:	MOVE	T3,[POINT 7,1(P2)]	;OUTPUT BYTE POINTER
RDXDA1:	SOJL	P4,RDXDA2		;NO, END OF BUFFER
	ILDB	T1,P1		;GET A BYTE
	IDPB	T1,T3		;STORE THE CHARACTER
	AOBJN	T4,RDXDA1	;REDUCE THE COUNT
	MOVEI	T1,IOBKTL	;BLOCK TOO LAGE
	IORM	T1,DEVSTS(F)	;SET THE ERROR
	IBP	P1		;SKIP THE DATA
RDXDA9:	SOJG	P4,.-1		;CONTINUE THRU THE DATA FIELD
RDXDA2:	HRRZM	T3,(P2)		;STORE THE WORD COUNT
	PUSHJ	P,AVIMBF##	;ADVANCE THE MONITOR BUFFER
	HRLZI	T1,-1		;GET A MINUS ONE
	ADDM	T1,NETDRQ##(F)	;REDUCE THE DATA REQUEST COUNT
	POPJ	P,		;RETURN
SUBTTL RDXOUT OUTPUT ROUTINES
RDXOUT:				;CALLED FROM UUOCON
	PUSHJ	P,SAVE3##	;SAVE THE P'S
	PUSHJ	P,SETUP##	;SET UP R,W,S
RDXOU1:	MOVSI	S,IO		;GET THE DIRECTION BIT
	IORB	S,DEVIOS(F)	;STORE THE BIT
	TLNE	S,IOSERR+IOSHDV	;ERROR DETECTED AT INT. LEVEL?
	POPJ	P,		;YES, RETURN
	TLZN	S,IOBEG		;FIRST OUTPUT AFTER INIT
	JRST	RDXGO		;NO
	ANDB	S,DEVIOS(F)	;YES, CLEAR IOBEG
RDXGO:	MOVEI	P1,@DEVOAD(F)	;GET THE POINTER TO THE OUTPUT BUFFER
	SKIPG	1(P1)		;EMPTY BUFFER
	JRST	RDXADV		;YES, ADVANCE TO THE NEXT BUFFER
	TLNE	S,IOSERR	;ANY ERRORS AT INTERRUPT LEVEL
	JRST	RDXOFF		;YES, SHUT DOWN THE RDX
	PUSHJ	P,CHKDRQ##	;ANY DATA REQUESTS
	  CAIA			;NO, SHUT DOWN
	JRST	RDXOU2		;YES, CONTINUE
	TRNN	S,IOACT		;IS I/O ACTIVE
	PUSHJ	P,DLYDRQ##	;NO, WAIT FOR A DATA REQUEST
	  JRST	DEVERR##	;AIO
	JRST 	RDXOU1		;TRY AGAIN
RDXOU2:	PUSHJ	P,DAPHDR##	;MAKE A HEADER/PCB
	  JRST	[TDNE	S,[XWD IOSERR,IOACT]	;IS I/O ACTIVE
		JRST	RDXOFF	;TURN OF THE RDX
		PUSHJ P,NETSLP##	;NO, WAIT FOR CORE
		JRST	RDXOU2]	;TRY AGAIN
	TRNN	S,IOACT		;IS I/O ACTIVE
	PUSHJ	P,SETACT##	;NO SET IT ACTIVE
	MOVEI	P1,@DEVOAD(F)	;GET THE OUTPUT BUFFER BACK
	HRRZ	T1,1(P1)	;GET THE WORD COUNT
	TLNE	S,IOSDRP	;CHECK FOR A DROP
	SUBI	T1,1		;MINUS 1 FOR THE DROP NUMBER
	IMULI	T1,5		;CONVERT TO BYTES
	MOVEM	T1,PCBOC2##(U)	;STORE THE BYTE COUNT
	TLNN	S,IOSDRP	;CHECK FOR A DROP NUMBER
	JRST	RDXOU4		;NO
	PUSH	P,T1		;SAVE THE COUNT
	MOVE	T1,2(P1)	;GET THE DROP NUMBER IN ASCII
	PUSHJ	P,ASC2BI	;CONVERT TO BINARY
	  SETZ	T1,		;ILLEGAL DROP NUMBER
	CAILE	T1,^D127	;ONE OR TWO BYTES
	AOS	(P)		;TWO BYTES
	EXCH	T1,(P)		;PUT THE COUNT IN T1 AND SAVE THE DROP #
	ADDI	T1,1		;COUNT THE DROP NUMBER
RDXOU4:	ADDI	T1,1		;COUNT THE TYPE FILED
	PUSHJ	P,BI2EBI##	;OUTPUT THE COUNT FIELD
	MOVEI	T1,DC.DAR	;TYPE FIELD DATA WITH EOR
	PUSHJ	P,BI2EBI##	;WRITE
	TLNN	S,IOSDRP	;CHECK FOR A DROP NUMBER
	JRST	RDXOU3		;NO
	POP	P,T1		;RESTORE THE DROP NUMBER
	PUSHJ	P,BI2EBI##	;PUT THE DROP NUMBER IN THE MESSAGE
RDXOU3:	ADDM	P3,PCBOCT##(U)	;UPDATE THE PROTOCOL COUNT
	MOVEI	T1,2(P1)	;POINT TO THE DATAFIELD
	TLNE	S,IOSDRP	;MULTI DROP
	ADDI	T1,1		;YES, SKIP THE DROP NUMBER
	HRLI	T1,(POINT 7)	;MAKE A BYTE POINTER
	MOVEM	T1,PCBOA2##(U)	;STORE THE POINTER
	PJRST	DAPWRT##	;SEND THE MESSAGE
SUBTTL RDXINT (-4)  INIT
;COME HERE AT INTERRUPT LEVEL WHEN A MESSAGE HAS BEEN SENT BY THE FEK

RDXINT:	PUSHJ	P,SAVE3##	;SAVE THE P'S
	PUSHJ	P,SAVJW##	;SAVE J AND W
	PUSHJ	P,SETUP##	;SET UP THE ACS
;	JRST	RDXADV		;YES, ADVANCE THE BUFFER

;HERE TO ADVANCE TO THE NEXT BUFFER
RDXADV:				;ADVANCE TO THE NEXT BUFFER
	TLZN	S,IOSCLO	;INTERRUPT FROM A CLOSE
	PUSHJ	P,ADVBFE##	;NO, ADVANCE
	  JRST	RDXOFF		;NONE LEFT
	TRNE	S,IOACT
	PUSHJ	P,SETIOD##	;SET I/O DONE
	PUSHJ	P,STOIOS##	;STORE IOS
	PJRST	RDXGO		;TRY ANOTHER BUFFER
RDXOFF:
IFN FTKI10!FTKL10,<
	PUSHJ	P,RTEVM##	;RETURN ANY EVM TO THE MONITOR
>
	TRNE	S,IOACT		;CLEAR ACT
	PUSHJ	P,SETIOD##	;SET IO DONE
	PJRST	CLRACT##	;EXIT THE INTERRUPT
SUBTTL RDXINP (3)  INPUT
;RDX INPUT ROUTINE
RDXINP:				;ENTRY FROM INPUT UUO
	PUSHJ	P,SAVE3##	;SAVE THE P'S
RDXINX:	PUSHJ	P,SETUP##	;LOAD THE ACS
	TLZE	S,IOBEG		;FIRST INPUT UUO
	ANDB	S,DEVIOS(F)	;YES, CLEAR FIRST TIME
	SKIPE	P3,NETDEV##(F)	;GET MONITOR BUFFER ADDRESS
	JRST	RDXIN1		;BUFFER EXISTS
	LDB 	T1,PBUFSZ##	;GET THE BUFFER SIZE
	HRLI	T1,2		;NUMBER OF BUFFERS
	PUSHJ	P,BLDMBF##	;BUILD THE BUFFERS
	MOVE	P3,NETDEV##(F)	;LOAD THE POINTER TO THE MBF
RDXIN1:	MOVSI	S,IO		;SET UP INPUT
	ANDCAB	S,DEVIOS(F)	;CLEAR THE BIT
	SKIPE	MBFBFC##(P3)	;ANY DATA IN MONITOR BUFFERS?
	JRST	RDXIN2		;YES, PROCESS IT.
	MOVEI	T1,IOBKTL	;GET THE DEVICE STATUS BITS
	TDNE	T1,DEVSTS(F)	;IS TOO LARGE SET
	TRO	S,IOBKTL	;YES, SET IN S
	ANDCAM	T1,DEVSTS(F)
	TDNE	S,[XWD IOEND,IOBKTL]	;ANY ERRORS
	PJRST	STOIOS##		;YES, STORE S AND EXIT
	PUSHJ	P,DRQMBF##	;SEND DATA REQUESTS
	MOVEI	T1,DEPAIO	;NON, BLOCKING I/O
	TDNE	T1,DEVAIO(F)	;FOR THIS DEVICE
	PJRST	RDXOFF		;SHUT DOWN
	PUSHJ	P,NETHIB##	;WAIT FOR THE DATA
	JRST	RDXIN1		;NO, TRY AGAIN
RDXIN2:
RDXIGO:	PUSHJ	P,SETACT##	;SET I/O ACTIVE
	PUSHJ	P,NETBCL##	;CLEAR THE INPUT BUFFER
	MOVE	P1,MBFOBC##(P3)	;COMPUT THE LOCATION OF THE DATA
	LDB	T1,PBUFSZ##	;GET THE SIZE
	IMULI	P1,(T1)		;GET THE RELATIVE BUFFER ADDRESS
	ADDI	P1,MBFMBF##(P3)	;ADD THE OFFSET
	MOVEI	T4,@DEVIAD(F)	;GET THE LOCATION OF THE USER'S BUFFER
	LDB	T1,[POINT 12,(T4),17] ;SIZE OF THE USER'S BUFFER
	SUBI	T1,1		;MINUS THE HEADER
	HRRZ	T2,(P1)		;SIZE OF THE DATA
	CAILE	T2,(T1)		;COMPARE FOR A FIT
	TROA	S,IOBKTL	;NO, SET BLOCK TOO LARGE
	MOVEI	T1,(T2)		;MAX SIZE THAT WILL FIT
	ADDI	T4,1		;POINT TO THE WORD COUNT WORD
	HRLI	T4,(P1)		;MAKE A BLT POINTER
	ADDI	T1,(T4)		;END OF THE BUFFER
	BLT	T4,(T1)		;MOVE THE DATA TO THE USER'S BUFFER
	PUSHJ	P,ADVBFF##	;ADVANCE THE USER'S BUFFER
	  TRZ	S,IOACT		;NO MORE BUFFERS CLEAR I/O ACT
	PUSHJ	P,AVOMBF##	;ADVANCE THE MONITOR BUFFER
	  CAIA			;NONE LEFT
	TRNE	S,IODERR!IOIMPM!IODTER	;ANY ERRORS
	TRZ	S,IOACT		;YES, CLEAR ACT
	PUSHJ	P,STOIOS##	;STORE S
				; NO MORE UNTIL NEXT UUO
	TRNE	S,IOACT		;IS I/O STILL ACTIVE?
	JRST	RDXIGO		;YES, DO ANOTHER BUFFER
;COME HERE WHEN I/O GOES INACTIVE FOR ANY REASON.
;  IF THERE HAVE BEEN NO ERRORS, ATTEMPT TO KEEP THE MONITOR BUFFERS
;  FULL.

IFN FTKI10!FTKL10,<
	PUSHJ	P,RTEVM##	;RETURN ANY EVM
>
	TDNE	S,[XWD IOEND,IODERR+IOIMPM+IODTER]
	POPJ	P,		;ANY ERRORS OR EOF YES, EXIT
	PJRST	DRQMBF##	;NO, SEND DATA REQUESTS AND EXIT
;SUBROUTINE TSTRDX - CHECK FOR A RDX DEVICE
;CALL	MOVE	T1,DEVICE NAME
;	PUSHJ	P,TSTRDX
;RETURN	CPOPJ			;NOPE
;	CPOPJ1			;YES, AND THE DDB IS BUIT F=DDB

TSTRDX::			;ENTRY FROM UUOCON
	TLC	T1,(SIXBIT /RD/)	;COMPLEMENT RD BITS
	TLCE	T1,(SIXBIT /RD/)	;IS IT RDCNNU DEVICE
	POPJ	P,		;NO, CONTINUE SEARCH THRU UUOCON
	PUSHJ	P,SAVJW##	;SAVE J AND W
	PUSHJ	P,SAVE3##	;SAVE THE P'S
	PUSH	P,T1		;SAVE THE DEVICE NAME
	PUSHJ	P,DVSCVT##	;GET THE STATION NUMBER IN T2
	  JRST	TPOPJ##		;ILLEGAL STATION NUMBER
	CAMN	T2,JBTLOC##	;LOCAL STATION
	JRST	TPOPJ##		;YES, ILLEGAL
	MOVEI	T1,(T2)		;NODE NUMBER TO T1
	PUSHJ	P,SRCNDB##	;FIND THE NODE DATA BLOCK
	  JRST	TPOPJ##		;NODE DOES NOT EXIST
	MOVEI	T1,(SIXBIT /RDA/); GET THE DATA ENTRY DEVICE NAME
	MOVEI	P1,(W)		;COPY THE NODE NUMBER
	PUSHJ	P,SRCNDT##	;IS THIS DEVICE SUPPORTED
	  JRST	TPOPJ##		;NO, ERROR RETURN
	LDB	T1,[POINT 6,(P),17] ;GET THE CHANNEL NUMBER
	MOVEI	T1,-41(T1)	;CONVERT CHANNEL NUMBER TO (0-7)
	TRNE	T1,777770	;IN RANGE
	JRST	TPOPJ##		;NO
	LSH	T1,3		;POSITION
	LDB	T2,[POINT 6,(P),35] ;GET THE UNIT NUMBER
	MOVEI	T2,-20(T2)	;CONVERT TO BINARY
	CAILE	T2,7		;MUST BE LESS THAN 10
	JRST	TPOPJ##		;ILLEGAL
	IORI	T2,(T1)		;COMBINE THE CHANNEL WITH THE UNIT
	MOVE	P2,(P)		;DEVICE NAME TO P2
	SETZM	P3,		;CLEAR LOGICAL NAME
	PUSH	P,T2		;SAVE THE NEW PUNIT VALUE
	PUSHJ	P,MAKDDB##	;BUILD A DDB FOR THIS DEVICE
	  JRST	[POP	P,T2	;RESTORE THE UNIT
		JRST	TPOPJ##]; EXIT
	POP	P,T2		;GET THE UNIT
	DPB	T2,PUNIT##	;STORE IT
	PUSHJ	P,NCSCNT##	;CONNECT THE DEVICE
	  JRST	TPOPJ##		;EXIT
	JRST	TPOPJ1##	;LEGAL DEVICE AND CONNECTED
;SUBROUTINE ASC2BI - CONVERT AN ASCII NUMBER IN T1 TO BINARY
;CALL	MOVE	T1,[ASCII /FFDDD/]
;	PUSHJ	P,ASC2BI
;RETURN	CPOPJ

ASC2BI:
	MOVE	T3,T1		;COPY THE ARGUMENT
	SETZ	T1,		;CLEAR RESULT WORD
ASC2B1:	LSHC	T2,7		;GET A DIGIT
	ANDI	T2,177		;REMOVE OLD BITS
	CAIN	T2," "		;IS IT A BLANK
	MOVEI	T2,"0"		;YES, MAKE A ZERO
	CAIL	T2,"0"		;IS IT A DIGIT
	CAILE	T2,"9"		;0-9
	POPJ	P,		;NO, EXIT
	SUBI	T2,"0"		;CONVERT TO BINARY
	IMULI	T1,^D10		;SHIFT THE RESULT
	ADDI	T1,(T2)		;MAKE A SUM
	JUMPN	T3,ASC2B1	;CONTINUE IF ANY DIGITS LEFT
	JRST	CPOPJ1##	;YES, EXIT

;SUBROUTINE BI2ASC - CONVERT BINARY DIGITS IN T1 TO ASCII
;CALL	MOVE	T1,BIN
;	PUSHJ	P,BI2ASC
;RETURN	CPOPJ

BI2ASC:
	MOVE	T2,T1		;COPY THE ARGUEMNT
	MOVE	T1,[ASCII /00000/]	;START WITH ZEROS
BI2AS1:	IDIVI	T2,^D10		;GET THE LAST DIGIT FIRST
	ADDI	T3,"0"		;CONVERT TO ASCII
	HRLM	T3,(P)		;SAVE THE DIGIT
	SKIPE	T2		;END OF DIGITS
	PUSHJ	P,BI2AS1	;NO DO IT AGAIN
	HLLZ	T2,(P)		;GET THE DIGIT BACK
	LSH	T2,^D11		;LEFT JUSTIFY
	LSH	T1,-1		;MAKE ALIGNMENT RIGHT
	LSHC	T1,^D8		;INSERT THE NEW DIGIT
	POPJ	P,		;RETURN
	$LIT
RDXEND::END