xref: /csrg-svn/lib/libc/vax/stdio.old/fputs.s (revision 42637)
124422Smckusick/*
224422Smckusick * Copyright (c) 1985 Regents of the University of California.
334435Sbostic * All rights reserved.
434435Sbostic *
5*42637Sbostic * %sccs.include.redist.c%
624422Smckusick */
724422Smckusick
834826Sbostic#if defined(LIBC_SCCS) && !defined(lint)
9*42637Sbostic	.asciz "@(#)fputs.s	5.7 (Berkeley) 06/01/90"
1034826Sbostic#endif /* LIBC_SCCS and not lint */
1124422Smckusick
1224422Smckusick/*
1324422Smckusick * fputs(s, iop);
1424422Smckusick * char *s;
1524422Smckusick * FILE *iop;
1624422Smckusick *
1724422Smckusick * arguments: a source string and a file pointer.
1824422Smckusick * side effects: writes to the file indicated by iop using the data in
1924422Smckusick *	the null-terminated source string.
2024422Smckusick * result: technically void; for compatibility we return 0 for the null
2124422Smckusick *	string, non-zero otherwise.  We return zero for errors too.
2224422Smckusick */
2324422Smckusick
2424422Smckusick#include "DEFS.h"
2524422Smckusick
2624422Smckusick#define		NBF	04
2724422Smckusick#define		LBF	0200
2824422Smckusick
2924422Smckusick#define		NL	012
3024422Smckusick
3124422SmckusickENTRY(fputs, R11|R10|R9)
3224422Smckusick
3324422Smckusick#define		S	r11
3424422Smckusick	movl	4(ap),S
3524422Smckusick#define		IOP	r10
3624422Smckusick#define		_CNT
3724422Smckusick#define		_PTR	4
3824422Smckusick#define		_BASE	8
3924422Smckusick#define		_BUFSIZ	12
4024422Smckusick#define		_FLAG	16
4124422Smckusick	movl	8(ap),IOP
4224422Smckusick
4324422Smckusick#define		UNBUF	-4(fp)
4424422Smckusick
4524422Smckusick#define		COUNT	r9
4624422Smckusick
4724422Smckusick	/*
4824422Smckusick	 * For compatibility (sigh).
4924422Smckusick	 */
5024422Smckusick	tstb	(S)
5124422Smckusick	jeql	Lerror
5224422Smckusick
5324422Smckusick	/*
5424422Smckusick	 * For unbuffered I/O, line buffer the output line.
5524422Smckusick	 * Ugly but fast -- and doesn't CURRENTLY break anything (sigh).
5624422Smckusick	 */
5724422Smckusick	movab	-1028(sp),sp
5824422Smckusick	bicw3	$~NBF,_FLAG(IOP),UNBUF
5924422Smckusick	jeql	1f
6024422Smckusick
6124422Smckusick	bicw2	$NBF,_FLAG(IOP)		/* Clear no-buffering flag */
6224422Smckusick	movl	sp,_BASE(IOP)		/* Create a buffer */
6324422Smckusick	movl	sp,_PTR(IOP)
6424422Smckusick	cvtwl	$1024,_BUFSIZ(IOP)
6524422Smckusick	jbr	2f
6624422Smckusick
6724422Smckusick1:
6826007Sdonn	tstl	_CNT(IOP)		/* Has a buffer been allocated? */
6926007Sdonn	jgtr	2f
7024422Smckusick	pushl	IOP			/* Get _flsbuf() to do the work */
7124422Smckusick	pushl	$0
7224422Smckusick	calls	$2,__flsbuf
7324422Smckusick	tstl	r0
7424422Smckusick	jlss	Lerror
7524422Smckusick	incl	_CNT(IOP)		/* Unput the char we sent */
7624422Smckusick	decl	_PTR(IOP)
7724422Smckusick2:
7824422Smckusick
7924422Smckusick	/*
8024422Smckusick	 * Search for the terminating null.
8124422Smckusick	 * We only need to look at _BUFSIZ bytes or less on each pass.
8224422Smckusick	 */
8324422SmckusickLloop:
8424422Smckusick	addl3	_BASE(IOP),_BUFSIZ(IOP),COUNT	/* How many bytes? */
8524422Smckusick	subl2	_PTR(IOP),COUNT
8624422Smckusick	locc	$0,COUNT,(S)		/* Look for a null */
8724422Smckusick	jeql	Lagain
8824422Smckusick
8924422Smckusick	subl2	r0,COUNT		/* Copy the data */
9024422Smckusick	movc3	COUNT,(S),*_PTR(IOP)
9124422Smckusick	movl	r3,_PTR(IOP)		/* Fix up IOP */
9224422Smckusick	subl2	COUNT,_CNT(IOP)
9324422Smckusick	bitw	$LBF,_FLAG(IOP)		/* If line buffered... */
9424422Smckusick	jneq	1f
9526992Sbloom	tstw	UNBUF			/* or unbuffered... */
9626992Sbloom	jneq	1f
9724422Smckusick	tstl	_CNT(IOP)		/* or a full buffer... */
9824422Smckusick	jgtr	2f
9924422Smckusick1:
10024422Smckusick	pushl	IOP			/* ... flush the buffer */
10124422Smckusick	calls	$1,_fflush
10224422Smckusick	tstl	r0
10324422Smckusick	jlss	Lerror
10424422Smckusick2:
10524422Smckusick
10624422Smckusick	/*
10724422Smckusick	 * Fix up buffering again.
10824422Smckusick	 */
10924422SmckusickLfixup:
11024422Smckusick	tstw	UNBUF
11124422Smckusick	jeql	1f
11224422Smckusick	bisw2	$NBF,_FLAG(IOP)		/* Reset flag */
11324422Smckusick	clrl	_BASE(IOP)		/* Clear data structure */
11424422Smckusick	clrl	_BUFSIZ(IOP)
11524422Smckusick	clrl	_CNT(IOP)
11624422Smckusick1:
11724422Smckusick	cvtbl	$NL,r0			/* Compatibility hack */
11824422Smckusick	ret
11924422Smckusick
12024422Smckusick	/*
12124422Smckusick	 * We didn't find the null -- loop.
12224422Smckusick	 */
12324422SmckusickLagain:
12424422Smckusick	movc3	COUNT,(S),*_PTR(IOP)	/* Copy the data */
12524422Smckusick	movl	r1,S
12624422Smckusick	movl	r3,_PTR(IOP)		/* Fix up IOP */
12724422Smckusick	subl2	COUNT,_CNT(IOP)
12824422Smckusick	pushl	IOP			/* The buffer is full -- flush it */
12924422Smckusick	calls	$1,_fflush
13024422Smckusick	tstl	r0
13124422Smckusick	jlss	Lerror
13224422Smckusick	tstb	(S)			/* More data? */
13324422Smckusick	jneq	Lloop
13424422Smckusick	jbr	Lfixup
13524422Smckusick
13624422Smckusick	/*
13724422Smckusick	 * Bomb out.  Return 0 (why not? that's what the old one did).
13824422Smckusick	 */
13924422SmckusickLerror:
14024422Smckusick	clrl	r0
14124422Smckusick	ret
142