Commit | Line | Data |
---|---|---|
202e9631 KM |
1 | /* |
2 | * Copyright (c) 1985 Regents of the University of California. | |
2c817985 KB |
3 | * All rights reserved. |
4 | * | |
019bea33 | 5 | * %sccs.include.redist.c% |
202e9631 KM |
6 | */ |
7 | ||
4afb9d15 | 8 | #if defined(LIBC_SCCS) && !defined(lint) |
019bea33 | 9 | .asciz "@(#)puts.s 5.7 (Berkeley) %G%" |
4afb9d15 | 10 | #endif /* LIBC_SCCS and not lint */ |
202e9631 KM |
11 | |
12 | /* | |
13 | * puts(s); | |
14 | * char *s; | |
15 | * | |
16 | * argument: a source string. | |
17 | * side effects: writes to the standard output using the data in | |
18 | * the null-terminated source string; a newline is appended. | |
19 | * result: technically void; for compatibility we return 0 for the null | |
20 | * string, non-zero otherwise. We return zero for errors too. | |
21 | */ | |
22 | ||
23 | #include "DEFS.h" | |
24 | ||
25 | #define NBF 04 | |
26 | #define LBF 0200 | |
27 | ||
28 | #define NL 012 | |
29 | ||
30 | ENTRY(puts, R11|R10|R9) | |
31 | ||
32 | #define S r11 | |
33 | movl 4(ap),S | |
34 | #define IOP r10 | |
35 | #define _CNT | |
36 | #define _PTR 4 | |
37 | #define _BASE 8 | |
38 | #define _BUFSIZ 12 | |
39 | #define _FLAG 16 | |
40 | movab __iob+20,IOP | |
41 | ||
42 | #define UNBUF -4(fp) | |
43 | ||
44 | #define COUNT r9 | |
45 | ||
46 | /* | |
47 | * For unbuffered I/O, line buffer the output line. | |
48 | * Ugly but fast -- and doesn't CURRENTLY break anything (sigh). | |
49 | */ | |
50 | movab -1028(sp),sp | |
51 | bicw3 $~NBF,_FLAG(IOP),UNBUF | |
52 | jeql 1f | |
53 | ||
54 | bicw2 $NBF,_FLAG(IOP) /* Clear no-buffering flag */ | |
55 | movl sp,_BASE(IOP) /* Create a buffer */ | |
56 | movl sp,_PTR(IOP) | |
57 | cvtwl $1024,_BUFSIZ(IOP) | |
58 | jbr 2f | |
59 | ||
60 | 1: | |
3a8b31bb DS |
61 | tstl _CNT(IOP) /* Has a buffer been allocated? */ |
62 | jgtr 2f | |
202e9631 KM |
63 | pushl IOP /* Get _flsbuf() to make one */ |
64 | pushl $0 | |
65 | calls $2,__flsbuf | |
66 | tstl r0 | |
67 | jlss Lerror | |
68 | incl _CNT(IOP) /* Unput the char we sent */ | |
69 | decl _PTR(IOP) | |
70 | 2: | |
71 | ||
72 | /* | |
73 | * Search for the terminating null. | |
74 | */ | |
75 | Lloop: | |
76 | addl3 _BASE(IOP),_BUFSIZ(IOP),COUNT /* How many bytes? */ | |
77 | subl2 _PTR(IOP),COUNT | |
78 | locc $0,COUNT,(S) /* Look for a null */ | |
79 | jeql Lagain | |
80 | ||
81 | subl2 r0,COUNT /* Copy the data */ | |
82 | movc3 COUNT,(S),*_PTR(IOP) | |
83 | movl r3,_PTR(IOP) /* Fix up IOP */ | |
84 | subl2 COUNT,_CNT(IOP) | |
85 | ||
86 | Lnl: | |
87 | movb $NL,*_PTR(IOP) /* Append a newline */ | |
88 | incl _PTR(IOP) | |
89 | decl _CNT(IOP) | |
90 | ||
91 | bitw $LBF,_FLAG(IOP) /* If line buffered... */ | |
92 | jneq 1f | |
38dd0e83 JB |
93 | tstw UNBUF /* or unbuffered... */ |
94 | jneq 1f | |
202e9631 KM |
95 | tstl _CNT(IOP) /* or a full buffer... */ |
96 | jgtr 2f | |
97 | 1: | |
98 | pushl IOP /* ... flush the buffer */ | |
99 | calls $1,_fflush | |
100 | tstl r0 | |
101 | jlss Lerror | |
102 | 2: | |
103 | ||
104 | /* | |
105 | * Fix up buffering again. | |
106 | */ | |
107 | tstw UNBUF | |
108 | jeql 1f | |
109 | bisw2 $NBF,_FLAG(IOP) /* Reset flag */ | |
110 | clrl _BASE(IOP) /* Clear data structure */ | |
111 | clrl _BUFSIZ(IOP) | |
112 | clrl _CNT(IOP) | |
113 | 1: | |
114 | cvtbl $NL,r0 /* Compatibility hack */ | |
115 | ret | |
116 | ||
117 | /* | |
118 | * We didn't find the null -- loop. | |
119 | */ | |
120 | Lagain: | |
121 | movc3 COUNT,(S),*_PTR(IOP) /* Copy the data */ | |
122 | movl r1,S | |
123 | movl r3,_PTR(IOP) /* Fix up IOP */ | |
124 | subl2 COUNT,_CNT(IOP) | |
125 | pushl IOP /* The buffer is full -- flush it */ | |
126 | calls $1,_fflush | |
127 | tstl r0 | |
128 | jlss Lerror | |
129 | tstb (S) /* More data? */ | |
130 | jneq Lloop | |
131 | jbr Lnl | |
132 | ||
133 | /* | |
134 | * Bomb out. Return 0 (why not? that's what the old one did). | |
135 | */ | |
136 | Lerror: | |
137 | clrl r0 | |
138 | ret |