	.Title	VSEND -- Variable Send data 
	.Ident		-V1.0d-
;
;       -------------------------------------------------
;           A S E A   B R O W N   B O V E R I     B. V.
;       -------------------------------------------------
;
;       Afdeling		Industrial Division group VGA
;       Tel.                    010 - 4078911    (centrale)
;
;       Adres                   Marten Meesweg 5
;                               3068 AV  ROTTERDAM
;       Postadres               Postbus 301
;                               3000 AH  ROTTERDAM
;       . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;       Filenaam                VSEND.MAC
;       Taal                    MACRO-11
;
;       Datum originele versie  12-Jun-87
;       Originele versie door   Hans Hamakers
;       Tel. intern             631
;
;
;       Korte beschrijving:
;
;           Subroutine to send packets of more tha 26 bytes
;
;	Assembleren:
;
;           MAC VSEND,VSEND=VSEND
;
;       ---------------------
;       W I J Z I G I N G E N
;       ---------------------
;       datum           inhoud                                  A.trail versie
;       -----           ------                                  ------  ------
;	 3-Jul-87	Test statusbits after CRAW and MAP	JHA01	01b
;	16-Sep-87	Support clustering with VRECVE		JHA02	01c
;	 7-Dec-87	Always start with VSEN01 partition	JHA03	01d

	.PSECT	BBNL$D,RW,D
;
	.ENABL	MCL
;
	.NLIST	BEX
;
REGION:	RDBBK$	,VSEN01,,<RS.WRT!RS.RED!RS.DEL>
;
WINDOW:	WDBBK$	,128.,,,,<WS.WRT!WS.RED!WS.DEL>,BUFFER
;
;   Global patchable locations :
;
$VSAPR:: 7			; APR
$SClus:: 0			; Clustered				;JHA02
;
WNDFLG:	0
;
TASKNM:	.RAD50	/....../
;
TSKNAM:	.BLKW	2		; Task to send to
;
BUFFER:	.BLKW	8.		; 8. word packet buffer

	.SBTTL	VSEND -- Fortran interface
;
;
;   CALL   VSEND(TASK,BUFFER,BUFLEN,IDSW)
;
	.PSECT	BBNL$I,RO,I
;
VSEND::
;
	CALL	$SAVAL		;
;
	CMP	(R5)+,#4	; 4 arguments ?
	BNE	FTNEXT		;  No  : => Exit
;
	CMP	(R5),#-1	; Argument specified ?
	BEQ	FTNEXT		;  No : => Exit
	MOV	(R5)+,R1	; Address of Taskname
;
	CMP	(R5),#-1	; Argument specified ?
	BEQ	FTNEXT		;  No : => Exit
	MOV	(R5)+,R2	; Address of buffer
;
	CMP	(R5),#-1	; Argument specified ?
	BEQ	FTNEXT		;  No : => Exit
	MOV	@(R5)+,R3	; Byte count
;
	CMP	(R5),#-1	; Argument specified ?
	BEQ	FTNEXT		;  No : => Exit
;
	CALL	PROCES		;
;
	CLC			; Clear carry
	MOV	R4,@(R5)	; Copy error code
	BPL	FTNEXT		; Positive => 
	SEC			; Set carry
FTNEXT:
;
	RETURN			; Exit

	.SBTTL	$VSEND -- Macro interface
;
$VSEND::
;
;
;    R1  = Address of taskname
;    R2  = Address of Buffer
;    R3  = Bytecount
;
;	CALL	$VSEND
;
;  output:
;
;    $DSW     = Errorcode
;    Carry bit  = Error indicator
;
$VSEND::

	CALL	$SAVAL		;
;
	CALL	PROCES		;
;
	CLC			; Clear carry
	MOV	R4,$DSW		; Copy error code
	BPL	MACEXT		; Positive => 
	SEC			; Set carry
MACEXT:
	RETURN			;

	.SBTTL	PROCES -- Send process
;
PROCES:
;
;    R1  = Address of taskname
;    R2  = Address of Buffer
;    R3  = Bytecount
;
;  output:
;
;    R4  = Errorcode
;
; Determine the task to send to .....
;
	MOV	(R1)+,TSKNAM+0	; Copy
	MOV	(R1)+,TSKNAM+2	;   taskname
;
	TST	R3		; Byte count  0 ?
	BNE	20$		;  No : => 20$
10$:
	MOV	#IE.IBS,R4	; "Illegal buffer size"
	JMP	PROEXT		;       => Exit
20$:
;
; Calculate region size .....
;
	MOV	R3,R4		; Copy byte-count
	ASH	#-6.,R4		; Make 32. word block count
	MOV	R3,-(SP)	; Copy byte-count
	BIC	#177700,(SP)	; Leave bit 0..5
	TST	(SP)+		; Any bit set ?
	BEQ	30$		;  No : => 30$
	INC	R4		; One more 32. word block 
30$:
	CLR	WINDOW+W.NLEN	; Clear old length
;
	MOV	#^RVSE,REGION+R.GNAM					;JHA03
	MOV	#^RN01,REGION+R.GNAM+2					;JHA03
				; Default name				;JHA03
	MOV	R4,REGION+R.GSIZ; Insert regionsize
	ASH	#6.,R4		; R4 = Region size
	SUB	R3,R4		; R4 = Rest size ( to clear )
	MOV	R3,BUFFER	; Insert bytecount in buffer
	TST	$SCLUS		; Clustered ?				;JHA02
	BNE	40$		;  Yes : => 40$				;JHA02
	TST	WNDFLG		; Do we have a window
	BNE	70$		;  Yes => 70$
40$:									;JHA02
;
; Insert APR .....
;
	MOVB	$VSAPR,WINDOW+W.NAPR
;
; Create window .....
;
	CRAW$S	#WINDOW		;
	BCC	50$		; OK ?  => 50$
	MOV	$DSW,R4		; Copy error code
	JMP	PROEXT		;       => Exit
50$:
	TST	$SCLUS		; Clustered ?				;JHA02
	BNE	70$		;  Yes : => 70$				;JHA02
	BIT	#WS.UNM!WS.ELW,WINDOW+W.NSTS				;JHA01
				; Window unmapped or eliminated ?	;JHA01
	BEQ	60$		;  No : => 60$				;JHA01
	MOV	#IE.WOV,R4	; Force window overflow error		;JHA01
	JMP	PROEXT		;       => Exit				;JHA01
60$:									;JHA01
	MOV	#1,WNDFLG	; We have a window			;JHA02
70$:
;
; Create region .....
;
	CRRG$S	#REGION		;
	BCC	80$		; OK ?  => 80$
	MOV	$DSW,R4		; Copy error code
	BR	PROEXT		;       => Exit
80$:
;
; Is it a new region ?
;
	BIT	#RS.CRR,REGION+R.GSTS
	BNE	90$		;  Yes: => 90$
	INC	REGION+R.GNAM+2	; Other name
	BR	70$		; Try again				;JHA03
90$:
;
; Attach region .....
;
	ATRG$S	#REGION		;
	BCC	100$		; OK ?  => 100$
	MOV	$DSW,R4		; Copy error code
	BR	PROEXT		;       => Exit
100$:
;
; Copy region id to WDB .....
;
	MOV	REGION+R.GID,WINDOW+W.NRID
;
; Map window .....
;
	MAP$S	#WINDOW		;
	BCC	110$		; OK ?  => 110$
	MOV	$DSW,R4		; Copy error code
	BR	PROEXT		;       => Exit
110$:
	TST	$SCLUS		; Clustered ?				;JHA02
	BNE	120$		;  Yes : => 120$			;JHA02
	BIT	#WS.UNM,WINDOW+W.NSTS					;JHA01
				; Window unmapped ?			;JHA01
	BEQ	120$		;  No : => 120$				;JHA01
	MOV	#IE.WOV,R4	; Force window overflow error		;JHA01
	JMP	PROEXT		;       => Exit				;JHA01
120$:									;JHA01
;
	MOV	WINDOW+W.NBAS,R1
;
; R1 => Region
; R2 => User buffer
; R3 =  Count
; R4 =  Rest size
;
; Copy data .....
;
130$:
	MOVB	(R2)+,(R1)+	; Copy
	SOB	R3,130$		;    data
;
; Clear rest of region .....
;
	TST	R4		; Any bytes to clear ?
	BEQ	150$		;  No : => 150$
140$:
	CLRB	(R1)+		; Clear
	SOB	R4,140$		;    rest
150$:
;
; Send reference .....
;
	SREF$S	#TSKNAM,#WINDOW	;
	BCC	160$		; OK ? => 160$
	MOV	$DSW,R4		; Copy error code
	BR	PROEXT		;      => Exit
160$:
;
; Unmap window .....

	UMAP$S	#WINDOW		;
	BCC	170$		; OK ? => 170$
	MOV	$DSW,R4		; Copy error code
	BR	PROEXT		;      => Exit
170$:
;
; Detach region .....
;
	DTRG$S	#REGION		;
	BCC	180$		; OK ? => 180$
	MOV	$DSW,R4		; Copy error code
	BR	PROEXT		;      => Exit
180$:
	MOV	#IS.SUC,R4	; Successfull
	BR	PROEX1		;      => Exit
;
PROEXT:
;
	UMAP$S	#WINDOW		; Unmap
	DTRG$S	#REGION		; Detach
;
PROEX1:
;
	RETURN			;
;
	.END
