/
/ PDP-11 C.
/ Stdio.
/
/ Flush.
/

	.globl	fflush
	.globl	_flush
	.globl	_put

/
/ This gets written out for 0 byte
/ writes in normal mode.
/ A bug in RSX makes all this necessary.
/

blank:	.ascii	" "
	.even

/
/ fflush(ioptr);
/ FILE *ioptr;
/

fflush:	jsr	r0,_save	/Get a stack frame.
	mov	12(r5),r4	/Grab ioptr.
	call	_ckiov

	bit	$VF_OUT,(r4)	/Output IOV.
	beq	0f		/Br if not.
	bit	$VF_UBF,(r4)	/Unbuffered IOV.
	bne	0f		/Br if yes
	call	_flush		/Do it.

0:	jmp	_ret		/Done.

/
/ This routine flushes the line
/ buffer in the IOV.
/ V_R0(r4) is nbytes.
/ V_R1(r4) is a buffer pointer.
/

_flush:	mov	r0,-(sp)	/This save may
	mov	r1,-(sp)	/No be necessary.

	mov	V_RBUF(r4),r0	/Buffer address
	mov	V_R0(r4),r1	/Byte count
	beq	0f		/Duck out if zero
	call	_put		/Out it goes.
	mov	r0,V_R1(r4)	/Reset buffer pointer.
	clr	V_R0(r4)	/Clear byte count.

0:	mov	(sp)+,r1	/Return
	mov	(sp)+,r0	/
	return			/

/
/ Put a record.
/ r0 = address
/ r1 = byte count.
/ r4 = iov.
/
/ This routine does newline checking.
/ The "u" option implies the "n" option
/ so binary works as advertised.
/

_put:	mov	r0,-(sp)	/Save the world.
	mov	r1,-(sp)	/
	mov	r2,-(sp)	/
	mov	r3,-(sp)	/

	mov	r0,r2		/Point just past the
	add	r1,r2		/End of the record.

/
/ Record devices.
/

	bit	$VF_REC,(r4)	/Record device?
	beq	2f		/No

	bit	$VF_NOS,(r4)	/No newlines?
	beq	0f		/No
	clr	r2		/Set no slew byte.
	mov	$IO.WAL,r3	/IO.WAL used for the write.
	br	1f		/

0:	mov	$IO.WVB,r3	/Set default IO.WVB.
	cmpb	-(r2),$12	/Newline
	bne	0f		/No
	mov	$' ,r2		/Set normal slew
	dec	r1		/Remove from byte count
	bne	1f		/
	mov	$blank,r0	/Bug in RSX.
	inc	r1		/
	br	1f		/

0:	mov	$'$,r2		/Prompt slew.

1:	clr	-(sp)		/Do the I/O.
	clr	-(sp)		/
	clr	-(sp)		/
	mov	r2,-(sp)	/Slew
	mov	r1,-(sp)	/Nbytes.
	mov	r0,-(sp)	/Address.
	mov	r3,r0		/Do
	call	_qiow		/Write.
	bcs	3f		/Error
	br	4f		/All OK.

/
/ Block devices.
/

2:	bit	$VF_NOS,(r4)	/No newlines?
	bne	0f		/Yes
	cmpb	-(r2),$12	/Delete trailing newline.
	bne	0f		/Not a newline
	dec	r1		/

0:	cmp	r1,V_RSIZ(r4)	/If this record is longer than
	blos	0f		/The longest record already out
	mov	r1,V_RSIZ(r4)	/Reset the size

0:	mov	r1,-(sp)	/Save updated byte count.
	mov	r1,r0		/Put out RCW.
	call	outb		/
	mov	(sp),r0		/
	swab	r0		/
	call	outb		/

	mov	(sp),r2		/Byte count
	mov	10(sp),r3	/Address

0:	dec	r2		/Put out the record
	bmi	0f		/
	movb	(r3)+,r0	/
	call	outb		/
	br	0b		/

0:	bit	$1,(sp)+	/Is this odd length record
	beq	1f		/No
	clr	r0		/Put out NUL.
	call	outb		/

/
/ Update EOF location.
/

1:	cmp	V_RBLK(r4),V_EFBK(r4) /EOF high lbn.
	bhi	0f		/Must fix
	blo	4f		/Ok
	cmp	V_RBLK+2(r4),V_EFBK+2(r4) /EOF low lbn.
	bhi	0f		/Must fix
	blo	4f		/Ok
	cmp	V_RBYT(r4),V_FFBY(r4) /EOF byte number.
	blos	4f		/Ok

0:	mov	V_RBLK(r4),V_EFBK(r4) /Update
	mov	V_RBLK+2(r4),V_EFBK+2(r4) /EOF
	mov	V_RBYT(r4),V_FFBY(r4) /Location.
	br	4f		/

3:	bis	$VF_ERR,(r4)	/Set error flag.

4:	mov	(sp)+,r3	/Return
	mov	(sp)+,r2	/
	mov	(sp)+,r1	/
	mov	(sp)+,r0	/
	return			/

/
/ Put out a byte to a block buffered
/ device.
/ r0 = byte.
/ Uses r0, r1
/

outb:	mov	V_RBYT(r4),r1	/Get byte location
	add	V_BBUF(r4),r1	/
	movb	r0,(r1)		/Save byte

	inc	V_RBYT(r4)	/Fix byte number.
	cmp	V_RBYT(r4),$512./Is the block full?
	blo	0f		/No
	call	_wvb		/Yes, write it out
	add	$1,V_RBLK+2(r4)	/Fix
	adc	V_RBLK(r4)	/Blocknumber
	clr	V_RBYT(r4)	/And start at byte 0.

0:	return			/Return
