xref: /original-bsd/sys/luna68k/stand/subr_prf.c (revision efe8c834)
1 /*
2  * Copyright (c) 1992 OMRON Corporation.
3  * Copyright (c) 1992, 1993
4  *	The Regents of the University of California.  All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * OMRON Corporation.
8  *
9  * %sccs.include.redist.c%
10  *
11  *	@(#)subr_prf.c	8.1 (Berkeley) 06/10/93
12  */
13 
14 #include <sys/param.h>
15 #include <luna68k/stand/romvec.h>
16 
17 #define TOCONS	0x1
18 #define TOTTY	0x2
19 #define TOLOG	0x4
20 
21 /*
22  * In case console is off,
23  * panicstr contains argument to last
24  * call to panic.
25  */
26 char	*panicstr;
27 
28 extern	cnputc();			/* standard console putc */
29 int	(*v_putc)() = cnputc;		/* routine to putc on virtual console */
30 
31 /*
32  * Scaled down version of C Library printf.
33  * Used to print diagnostic information directly on console tty.
34  * Since it is not interrupt driven, all system activities are
35  * suspended.  Printf should not be used for chit-chat.
36  *
37  * One additional format: %b is supported to decode error registers.
38  * Usage is:
39  *	printf("reg=%b\n", regval, "<base><arg>*");
40  * Where <base> is the output base expressed as a control character,
41  * e.g. \10 gives octal; \20 gives hex.  Each arg is a sequence of
42  * characters, the first of which gives the bit number to be inspected
43  * (origin 1), and the next characters (up to a control character, i.e.
44  * a character <= 32), give the name of the register.  Thus
45  *	printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
46  * would produce output:
47  *	reg=3<BITTWO,BITONE>
48  *
49  * Another additional format: %r is used to pass an additional format string
50  * and argument list recursively.  Usage is typically:
51  *
52  * fn(otherstuff, fmt [, arg1, ... ] )
53  *	char *fmt;
54  *	u_int arg1, ...;
55  *
56  *	printf("prefix: %r, other stuff\n", fmt, &arg1);
57  */
58 #if defined(tahoe)
59 int	consintr;
60 #endif
61 
62 /*VARARGS1*/
63 printf(fmt, x1)
64 	char *fmt;
65 	unsigned x1;
66 {
67 #if defined(tahoe)
68 	register int savintr;
69 
70 	savintr = consintr, consintr = 0;	/* disable interrupts */
71 #endif
72 	prf(fmt, &x1, TOCONS        , (struct tty *)NULL);
73 
74 
75 #if defined(tahoe)
76 	consintr = savintr;			/* reenable interrupts */
77 #endif
78 }
79 
80 prf(fmt, adx, flags, ttyp)
81 	register char *fmt;
82 	register u_int *adx;
83 	struct tty *ttyp;
84 {
85 	register int b, c, i;
86 	char *s;
87 	int any;
88 
89 loop:
90 	while ((c = *fmt++) != '%') {
91 		if (c == '\0')
92 			return;
93 		putchar(c, flags, ttyp);
94 	}
95 again:
96 	c = *fmt++;
97 	/* THIS CODE IS MACHINE DEPENDENT IN HANDLING %l? AND %c */
98 	switch (c) {
99 
100 	case 'l':
101 		goto again;
102 	case 'x': case 'X':
103 		b = 16;
104 		goto number;
105 	case 'd': case 'D':
106 		b = -10;
107 		goto number;
108 	case 'u':
109 		b = 10;
110 		goto number;
111 	case 'o': case 'O':
112 		b = 8;
113 number:
114 		printn((u_long)*adx, b, flags, ttyp);
115 		break;
116 	case 'c':
117 		b = *adx;
118 #if BYTE_ORDER == LITTLE_ENDIAN
119 		for (i = 24; i >= 0; i -= 8)
120 			if (c = (b >> i) & 0x7f)
121 				putchar(c, flags, ttyp);
122 #endif
123 #if BYTE_ORDER == BIG_ENDIAN
124 		if (c = (b & 0x7f))
125 			putchar(c, flags, ttyp);
126 #endif
127 		break;
128 	case 'b':
129 		b = *adx++;
130 		s = (char *)*adx;
131 		printn((u_long)b, *s++, flags, ttyp);
132 		any = 0;
133 		if (b) {
134 			while (i = *s++) {
135 				if (b & (1 << (i-1))) {
136 					putchar(any ? ',' : '<', flags, ttyp);
137 					any = 1;
138 					for (; (c = *s) > 32; s++)
139 						putchar(c, flags, ttyp);
140 				} else
141 					for (; *s > 32; s++)
142 						;
143 			}
144 			if (any)
145 				putchar('>', flags, ttyp);
146 		}
147 		break;
148 
149 	case 's':
150 		s = (char *)*adx;
151 		while (c = *s++)
152 			putchar(c, flags, ttyp);
153 		break;
154 
155 	case 'r':
156 		s = (char *)*adx++;
157 		prf(s, (u_int *)*adx, flags, ttyp);
158 		break;
159 
160 	case '%':
161 		putchar('%', flags, ttyp);
162 		break;
163 
164 	default:
165 		break;
166 	}
167 	adx++;
168 	goto loop;
169 }
170 
171 /*
172  * Printn prints a number n in base b.
173  * We don't use recursion to avoid deep kernel stacks.
174  */
175 printn(n, b, flags, ttyp)
176 	u_long n;
177 	struct tty *ttyp;
178 {
179 	char prbuf[11];
180 	register char *cp;
181 
182 	if (b == -10) {
183 		if ((int)n < 0) {
184 			putchar('-', flags, ttyp);
185 			n = (unsigned)(-(int)n);
186 		}
187 		b = -b;
188 	}
189 	cp = prbuf;
190 	do {
191 		*cp++ = "0123456789abcdef"[n%b];
192 		n /= b;
193 	} while (n);
194 	do
195 		putchar(*--cp, flags, ttyp);
196 	while (cp > prbuf);
197 }
198 
199 /*
200  * Panic is called on unresolvable fatal errors.
201  * It prints "panic: mesg", and then reboots.
202  * If we are called twice, then we avoid trying to
203  * sync the disks as this often leads to recursive panics.
204  */
205 panic(s)
206 	char *s;
207 {
208 	if (!panicstr) {
209 		panicstr = s;
210 	}
211 	printf("panic: %s\n", s);
212 
213 	ROM_abort();
214 }
215 
216 /*
217  * Print a character on console or users terminal.
218  * If destination is console then the last MSGBUFS characters
219  * are saved in msgbuf for inspection later.
220  */
221 /*ARGSUSED*/
222 putchar(c, flags, ttyp)
223 	register int c;
224 	struct tty *ttyp;
225 {
226 
227 
228 
229 
230 
231 
232 
233 
234 
235 
236 
237 
238 
239 
240 
241 
242 
243 
244 
245 
246 
247 
248 
249 
250 
251 
252 		(*v_putc)(c);
253 }
254