xref: /csrg-svn/lib/libc/vax/stdio.old/puts.s (revision 34826)
124424Smckusick/*
224424Smckusick * 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.
1624424Smckusick */
1724424Smckusick
18*34826Sbostic#if defined(LIBC_SCCS) && !defined(lint)
19*34826Sbostic	.asciz "@(#)puts.s	5.6 (Berkeley) 06/27/88"
20*34826Sbostic#endif /* LIBC_SCCS and not lint */
2124424Smckusick
2224424Smckusick/*
2324424Smckusick * puts(s);
2424424Smckusick * char *s;
2524424Smckusick *
2624424Smckusick * argument: a source string.
2724424Smckusick * side effects: writes to the standard output using the data in
2824424Smckusick *	the null-terminated source string; a newline is appended.
2924424Smckusick * result: technically void; for compatibility we return 0 for the null
3024424Smckusick *	string, non-zero otherwise.  We return zero for errors too.
3124424Smckusick */
3224424Smckusick
3324424Smckusick#include "DEFS.h"
3424424Smckusick
3524424Smckusick#define		NBF	04
3624424Smckusick#define		LBF	0200
3724424Smckusick
3824424Smckusick#define		NL	012
3924424Smckusick
4024424SmckusickENTRY(puts, R11|R10|R9)
4124424Smckusick
4224424Smckusick#define		S	r11
4324424Smckusick	movl	4(ap),S
4424424Smckusick#define		IOP	r10
4524424Smckusick#define		_CNT
4624424Smckusick#define		_PTR	4
4724424Smckusick#define		_BASE	8
4824424Smckusick#define		_BUFSIZ	12
4924424Smckusick#define		_FLAG	16
5024424Smckusick	movab	__iob+20,IOP
5124424Smckusick
5224424Smckusick#define		UNBUF	-4(fp)
5324424Smckusick
5424424Smckusick#define		COUNT	r9
5524424Smckusick
5624424Smckusick	/*
5724424Smckusick	 * For unbuffered I/O, line buffer the output line.
5824424Smckusick	 * Ugly but fast -- and doesn't CURRENTLY break anything (sigh).
5924424Smckusick	 */
6024424Smckusick	movab	-1028(sp),sp
6124424Smckusick	bicw3	$~NBF,_FLAG(IOP),UNBUF
6224424Smckusick	jeql	1f
6324424Smckusick
6424424Smckusick	bicw2	$NBF,_FLAG(IOP)		/* Clear no-buffering flag */
6524424Smckusick	movl	sp,_BASE(IOP)		/* Create a buffer */
6624424Smckusick	movl	sp,_PTR(IOP)
6724424Smckusick	cvtwl	$1024,_BUFSIZ(IOP)
6824424Smckusick	jbr	2f
6924424Smckusick
7024424Smckusick1:
7126007Sdonn	tstl	_CNT(IOP)		/* Has a buffer been allocated? */
7226007Sdonn	jgtr	2f
7324424Smckusick	pushl	IOP			/* Get _flsbuf() to make one */
7424424Smckusick	pushl	$0
7524424Smckusick	calls	$2,__flsbuf
7624424Smckusick	tstl	r0
7724424Smckusick	jlss	Lerror
7824424Smckusick	incl	_CNT(IOP)		/* Unput the char we sent */
7924424Smckusick	decl	_PTR(IOP)
8024424Smckusick2:
8124424Smckusick
8224424Smckusick	/*
8324424Smckusick	 * Search for the terminating null.
8424424Smckusick	 */
8524424SmckusickLloop:
8624424Smckusick	addl3	_BASE(IOP),_BUFSIZ(IOP),COUNT	/* How many bytes? */
8724424Smckusick	subl2	_PTR(IOP),COUNT
8824424Smckusick	locc	$0,COUNT,(S)		/* Look for a null */
8924424Smckusick	jeql	Lagain
9024424Smckusick
9124424Smckusick	subl2	r0,COUNT		/* Copy the data */
9224424Smckusick	movc3	COUNT,(S),*_PTR(IOP)
9324424Smckusick	movl	r3,_PTR(IOP)		/* Fix up IOP */
9424424Smckusick	subl2	COUNT,_CNT(IOP)
9524424Smckusick
9624424SmckusickLnl:
9724424Smckusick	movb	$NL,*_PTR(IOP)		/* Append a newline */
9824424Smckusick	incl	_PTR(IOP)
9924424Smckusick	decl	_CNT(IOP)
10024424Smckusick
10124424Smckusick	bitw	$LBF,_FLAG(IOP)		/* If line buffered... */
10224424Smckusick	jneq	1f
10326992Sbloom	tstw	UNBUF			/* or unbuffered... */
10426992Sbloom	jneq	1f
10524424Smckusick	tstl	_CNT(IOP)		/* or a full buffer... */
10624424Smckusick	jgtr	2f
10724424Smckusick1:
10824424Smckusick	pushl	IOP			/* ... flush the buffer */
10924424Smckusick	calls	$1,_fflush
11024424Smckusick	tstl	r0
11124424Smckusick	jlss	Lerror
11224424Smckusick2:
11324424Smckusick
11424424Smckusick	/*
11524424Smckusick	 * Fix up buffering again.
11624424Smckusick	 */
11724424Smckusick	tstw	UNBUF
11824424Smckusick	jeql	1f
11924424Smckusick	bisw2	$NBF,_FLAG(IOP)		/* Reset flag */
12024424Smckusick	clrl	_BASE(IOP)		/* Clear data structure */
12124424Smckusick	clrl	_BUFSIZ(IOP)
12224424Smckusick	clrl	_CNT(IOP)
12324424Smckusick1:
12424424Smckusick	cvtbl	$NL,r0			/* Compatibility hack */
12524424Smckusick	ret
12624424Smckusick
12724424Smckusick	/*
12824424Smckusick	 * We didn't find the null -- loop.
12924424Smckusick	 */
13024424SmckusickLagain:
13124424Smckusick	movc3	COUNT,(S),*_PTR(IOP)	/* Copy the data */
13224424Smckusick	movl	r1,S
13324424Smckusick	movl	r3,_PTR(IOP)		/* Fix up IOP */
13424424Smckusick	subl2	COUNT,_CNT(IOP)
13524424Smckusick	pushl	IOP			/* The buffer is full -- flush it */
13624424Smckusick	calls	$1,_fflush
13724424Smckusick	tstl	r0
13824424Smckusick	jlss	Lerror
13924424Smckusick	tstb	(S)			/* More data? */
14024424Smckusick	jneq	Lloop
14124424Smckusick	jbr	Lnl
14224424Smckusick
14324424Smckusick	/*
14424424Smckusick	 * Bomb out.  Return 0 (why not? that's what the old one did).
14524424Smckusick	 */
14624424SmckusickLerror:
14724424Smckusick	clrl	r0
14824424Smckusick	ret
149