xref: /csrg-svn/lib/libc/vax/stdio.old/fputs.s (revision 34826)
124422Smckusick/*
224422Smckusick * Copyright (c) 1985 Regents of the University of California.
334435Sbostic * All rights reserved.
434435Sbostic *
534435Sbostic * Redistribution and use in source and binary forms are permitted
6*34826Sbostic * provided that the above copyright notice and this paragraph are
7*34826Sbostic * duplicated in all such forms and that any documentation,
8*34826Sbostic * advertising materials, and other materials related to such
9*34826Sbostic * distribution and use acknowledge that the software was developed
10*34826Sbostic * by the University of California, Berkeley.  The name of the
11*34826Sbostic * University may not be used to endorse or promote products derived
12*34826Sbostic * from this software without specific prior written permission.
13*34826Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*34826Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*34826Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1624422Smckusick */
1724422Smckusick
18*34826Sbostic#if defined(LIBC_SCCS) && !defined(lint)
19*34826Sbostic	.asciz "@(#)fputs.s	5.6 (Berkeley) 06/27/88"
20*34826Sbostic#endif /* LIBC_SCCS and not lint */
2124422Smckusick
2224422Smckusick/*
2324422Smckusick * fputs(s, iop);
2424422Smckusick * char *s;
2524422Smckusick * FILE *iop;
2624422Smckusick *
2724422Smckusick * arguments: a source string and a file pointer.
2824422Smckusick * side effects: writes to the file indicated by iop using the data in
2924422Smckusick *	the null-terminated source string.
3024422Smckusick * result: technically void; for compatibility we return 0 for the null
3124422Smckusick *	string, non-zero otherwise.  We return zero for errors too.
3224422Smckusick */
3324422Smckusick
3424422Smckusick#include "DEFS.h"
3524422Smckusick
3624422Smckusick#define		NBF	04
3724422Smckusick#define		LBF	0200
3824422Smckusick
3924422Smckusick#define		NL	012
4024422Smckusick
4124422SmckusickENTRY(fputs, R11|R10|R9)
4224422Smckusick
4324422Smckusick#define		S	r11
4424422Smckusick	movl	4(ap),S
4524422Smckusick#define		IOP	r10
4624422Smckusick#define		_CNT
4724422Smckusick#define		_PTR	4
4824422Smckusick#define		_BASE	8
4924422Smckusick#define		_BUFSIZ	12
5024422Smckusick#define		_FLAG	16
5124422Smckusick	movl	8(ap),IOP
5224422Smckusick
5324422Smckusick#define		UNBUF	-4(fp)
5424422Smckusick
5524422Smckusick#define		COUNT	r9
5624422Smckusick
5724422Smckusick	/*
5824422Smckusick	 * For compatibility (sigh).
5924422Smckusick	 */
6024422Smckusick	tstb	(S)
6124422Smckusick	jeql	Lerror
6224422Smckusick
6324422Smckusick	/*
6424422Smckusick	 * For unbuffered I/O, line buffer the output line.
6524422Smckusick	 * Ugly but fast -- and doesn't CURRENTLY break anything (sigh).
6624422Smckusick	 */
6724422Smckusick	movab	-1028(sp),sp
6824422Smckusick	bicw3	$~NBF,_FLAG(IOP),UNBUF
6924422Smckusick	jeql	1f
7024422Smckusick
7124422Smckusick	bicw2	$NBF,_FLAG(IOP)		/* Clear no-buffering flag */
7224422Smckusick	movl	sp,_BASE(IOP)		/* Create a buffer */
7324422Smckusick	movl	sp,_PTR(IOP)
7424422Smckusick	cvtwl	$1024,_BUFSIZ(IOP)
7524422Smckusick	jbr	2f
7624422Smckusick
7724422Smckusick1:
7826007Sdonn	tstl	_CNT(IOP)		/* Has a buffer been allocated? */
7926007Sdonn	jgtr	2f
8024422Smckusick	pushl	IOP			/* Get _flsbuf() to do the work */
8124422Smckusick	pushl	$0
8224422Smckusick	calls	$2,__flsbuf
8324422Smckusick	tstl	r0
8424422Smckusick	jlss	Lerror
8524422Smckusick	incl	_CNT(IOP)		/* Unput the char we sent */
8624422Smckusick	decl	_PTR(IOP)
8724422Smckusick2:
8824422Smckusick
8924422Smckusick	/*
9024422Smckusick	 * Search for the terminating null.
9124422Smckusick	 * We only need to look at _BUFSIZ bytes or less on each pass.
9224422Smckusick	 */
9324422SmckusickLloop:
9424422Smckusick	addl3	_BASE(IOP),_BUFSIZ(IOP),COUNT	/* How many bytes? */
9524422Smckusick	subl2	_PTR(IOP),COUNT
9624422Smckusick	locc	$0,COUNT,(S)		/* Look for a null */
9724422Smckusick	jeql	Lagain
9824422Smckusick
9924422Smckusick	subl2	r0,COUNT		/* Copy the data */
10024422Smckusick	movc3	COUNT,(S),*_PTR(IOP)
10124422Smckusick	movl	r3,_PTR(IOP)		/* Fix up IOP */
10224422Smckusick	subl2	COUNT,_CNT(IOP)
10324422Smckusick	bitw	$LBF,_FLAG(IOP)		/* If line buffered... */
10424422Smckusick	jneq	1f
10526992Sbloom	tstw	UNBUF			/* or unbuffered... */
10626992Sbloom	jneq	1f
10724422Smckusick	tstl	_CNT(IOP)		/* or a full buffer... */
10824422Smckusick	jgtr	2f
10924422Smckusick1:
11024422Smckusick	pushl	IOP			/* ... flush the buffer */
11124422Smckusick	calls	$1,_fflush
11224422Smckusick	tstl	r0
11324422Smckusick	jlss	Lerror
11424422Smckusick2:
11524422Smckusick
11624422Smckusick	/*
11724422Smckusick	 * Fix up buffering again.
11824422Smckusick	 */
11924422SmckusickLfixup:
12024422Smckusick	tstw	UNBUF
12124422Smckusick	jeql	1f
12224422Smckusick	bisw2	$NBF,_FLAG(IOP)		/* Reset flag */
12324422Smckusick	clrl	_BASE(IOP)		/* Clear data structure */
12424422Smckusick	clrl	_BUFSIZ(IOP)
12524422Smckusick	clrl	_CNT(IOP)
12624422Smckusick1:
12724422Smckusick	cvtbl	$NL,r0			/* Compatibility hack */
12824422Smckusick	ret
12924422Smckusick
13024422Smckusick	/*
13124422Smckusick	 * We didn't find the null -- loop.
13224422Smckusick	 */
13324422SmckusickLagain:
13424422Smckusick	movc3	COUNT,(S),*_PTR(IOP)	/* Copy the data */
13524422Smckusick	movl	r1,S
13624422Smckusick	movl	r3,_PTR(IOP)		/* Fix up IOP */
13724422Smckusick	subl2	COUNT,_CNT(IOP)
13824422Smckusick	pushl	IOP			/* The buffer is full -- flush it */
13924422Smckusick	calls	$1,_fflush
14024422Smckusick	tstl	r0
14124422Smckusick	jlss	Lerror
14224422Smckusick	tstb	(S)			/* More data? */
14324422Smckusick	jneq	Lloop
14424422Smckusick	jbr	Lfixup
14524422Smckusick
14624422Smckusick	/*
14724422Smckusick	 * Bomb out.  Return 0 (why not? that's what the old one did).
14824422Smckusick	 */
14924422SmckusickLerror:
15024422Smckusick	clrl	r0
15124422Smckusick	ret
152