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