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