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