124422Smckusick/* 224422Smckusick * Copyright (c) 1985 Regents of the University of California. 334435Sbostic * All rights reserved. 434435Sbostic * 5*42637Sbostic * %sccs.include.redist.c% 624422Smckusick */ 724422Smckusick 834826Sbostic#if defined(LIBC_SCCS) && !defined(lint) 9*42637Sbostic .asciz "@(#)fputs.s 5.7 (Berkeley) 06/01/90" 1034826Sbostic#endif /* LIBC_SCCS and not lint */ 1124422Smckusick 1224422Smckusick/* 1324422Smckusick * fputs(s, iop); 1424422Smckusick * char *s; 1524422Smckusick * FILE *iop; 1624422Smckusick * 1724422Smckusick * arguments: a source string and a file pointer. 1824422Smckusick * side effects: writes to the file indicated by iop using the data in 1924422Smckusick * the null-terminated source string. 2024422Smckusick * result: technically void; for compatibility we return 0 for the null 2124422Smckusick * string, non-zero otherwise. We return zero for errors too. 2224422Smckusick */ 2324422Smckusick 2424422Smckusick#include "DEFS.h" 2524422Smckusick 2624422Smckusick#define NBF 04 2724422Smckusick#define LBF 0200 2824422Smckusick 2924422Smckusick#define NL 012 3024422Smckusick 3124422SmckusickENTRY(fputs, R11|R10|R9) 3224422Smckusick 3324422Smckusick#define S r11 3424422Smckusick movl 4(ap),S 3524422Smckusick#define IOP r10 3624422Smckusick#define _CNT 3724422Smckusick#define _PTR 4 3824422Smckusick#define _BASE 8 3924422Smckusick#define _BUFSIZ 12 4024422Smckusick#define _FLAG 16 4124422Smckusick movl 8(ap),IOP 4224422Smckusick 4324422Smckusick#define UNBUF -4(fp) 4424422Smckusick 4524422Smckusick#define COUNT r9 4624422Smckusick 4724422Smckusick /* 4824422Smckusick * For compatibility (sigh). 4924422Smckusick */ 5024422Smckusick tstb (S) 5124422Smckusick jeql Lerror 5224422Smckusick 5324422Smckusick /* 5424422Smckusick * For unbuffered I/O, line buffer the output line. 5524422Smckusick * Ugly but fast -- and doesn't CURRENTLY break anything (sigh). 5624422Smckusick */ 5724422Smckusick movab -1028(sp),sp 5824422Smckusick bicw3 $~NBF,_FLAG(IOP),UNBUF 5924422Smckusick jeql 1f 6024422Smckusick 6124422Smckusick bicw2 $NBF,_FLAG(IOP) /* Clear no-buffering flag */ 6224422Smckusick movl sp,_BASE(IOP) /* Create a buffer */ 6324422Smckusick movl sp,_PTR(IOP) 6424422Smckusick cvtwl $1024,_BUFSIZ(IOP) 6524422Smckusick jbr 2f 6624422Smckusick 6724422Smckusick1: 6826007Sdonn tstl _CNT(IOP) /* Has a buffer been allocated? */ 6926007Sdonn jgtr 2f 7024422Smckusick pushl IOP /* Get _flsbuf() to do the work */ 7124422Smckusick pushl $0 7224422Smckusick calls $2,__flsbuf 7324422Smckusick tstl r0 7424422Smckusick jlss Lerror 7524422Smckusick incl _CNT(IOP) /* Unput the char we sent */ 7624422Smckusick decl _PTR(IOP) 7724422Smckusick2: 7824422Smckusick 7924422Smckusick /* 8024422Smckusick * Search for the terminating null. 8124422Smckusick * We only need to look at _BUFSIZ bytes or less on each pass. 8224422Smckusick */ 8324422SmckusickLloop: 8424422Smckusick addl3 _BASE(IOP),_BUFSIZ(IOP),COUNT /* How many bytes? */ 8524422Smckusick subl2 _PTR(IOP),COUNT 8624422Smckusick locc $0,COUNT,(S) /* Look for a null */ 8724422Smckusick jeql Lagain 8824422Smckusick 8924422Smckusick subl2 r0,COUNT /* Copy the data */ 9024422Smckusick movc3 COUNT,(S),*_PTR(IOP) 9124422Smckusick movl r3,_PTR(IOP) /* Fix up IOP */ 9224422Smckusick subl2 COUNT,_CNT(IOP) 9324422Smckusick bitw $LBF,_FLAG(IOP) /* If line buffered... */ 9424422Smckusick jneq 1f 9526992Sbloom tstw UNBUF /* or unbuffered... */ 9626992Sbloom jneq 1f 9724422Smckusick tstl _CNT(IOP) /* or a full buffer... */ 9824422Smckusick jgtr 2f 9924422Smckusick1: 10024422Smckusick pushl IOP /* ... flush the buffer */ 10124422Smckusick calls $1,_fflush 10224422Smckusick tstl r0 10324422Smckusick jlss Lerror 10424422Smckusick2: 10524422Smckusick 10624422Smckusick /* 10724422Smckusick * Fix up buffering again. 10824422Smckusick */ 10924422SmckusickLfixup: 11024422Smckusick tstw UNBUF 11124422Smckusick jeql 1f 11224422Smckusick bisw2 $NBF,_FLAG(IOP) /* Reset flag */ 11324422Smckusick clrl _BASE(IOP) /* Clear data structure */ 11424422Smckusick clrl _BUFSIZ(IOP) 11524422Smckusick clrl _CNT(IOP) 11624422Smckusick1: 11724422Smckusick cvtbl $NL,r0 /* Compatibility hack */ 11824422Smckusick ret 11924422Smckusick 12024422Smckusick /* 12124422Smckusick * We didn't find the null -- loop. 12224422Smckusick */ 12324422SmckusickLagain: 12424422Smckusick movc3 COUNT,(S),*_PTR(IOP) /* Copy the data */ 12524422Smckusick movl r1,S 12624422Smckusick movl r3,_PTR(IOP) /* Fix up IOP */ 12724422Smckusick subl2 COUNT,_CNT(IOP) 12824422Smckusick pushl IOP /* The buffer is full -- flush it */ 12924422Smckusick calls $1,_fflush 13024422Smckusick tstl r0 13124422Smckusick jlss Lerror 13224422Smckusick tstb (S) /* More data? */ 13324422Smckusick jneq Lloop 13424422Smckusick jbr Lfixup 13524422Smckusick 13624422Smckusick /* 13724422Smckusick * Bomb out. Return 0 (why not? that's what the old one did). 13824422Smckusick */ 13924422SmckusickLerror: 14024422Smckusick clrl r0 14124422Smckusick ret 142