+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * %sccs.include.noredist.c%
+ *
+ * @(#)prf.c 7.1 (Berkeley) %G%
+ */
+
+#include <sys/types.h>
+
+/*
+ * Scaled down version of C Library printf.
+ * Used to print diagnostic information directly on console tty.
+ *
+ * One additional format: %b is supported to decode error registers.
+ * Usage is:
+ * printf("reg=%b\n", regval, "<base><arg>*");
+ * Where <base> is the output base expressed as a control character,
+ * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of
+ * characters, the first of which gives the bit number to be inspected
+ * (origin 1), and the next characters (up to a control character, i.e.
+ * a character <= 32), give the name of the register. Thus
+ * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
+ * would produce output:
+ * reg=3<BITTWO,BITONE>
+ */
+/*VARARGS1*/
+printf(fmt, x1)
+ char *fmt;
+ unsigned x1;
+{
+
+ prf(fmt, &x1);
+}
+
+prf(fmt, adx)
+ register char *fmt;
+ register *adx;
+{
+ register int b, c, i;
+ char *s, sep;
+
+loop:
+ while ((c = *fmt++) != '%') {
+ if(c == '\0')
+ return;
+ putchar(c);
+ }
+again:
+ c = *fmt++;
+ /*
+ * THIS CODE IS BYTE-ORDER DEPENDENT IN HANDLING %c
+ * AND IGNORES SHORT/LONG DISTINCTIONS.
+ */
+ switch (c) {
+
+ case 'l':
+ goto again;
+ case 'x': case 'X':
+ b = 16;
+ goto number;
+ case 'd': case 'D':
+ case 'u': /* what a joke */
+ b = 10;
+ goto number;
+ case 'o': case 'O':
+ b = 8;
+number:
+ printn((u_long)*adx, b);
+ break;
+ case 'c':
+ b = *adx;
+ for (i = 24; i >= 0; i -= 8)
+ if (c = (b >> i) & 0x7f)
+ putchar(c);
+ break;
+#ifndef notyet
+ case 'b':
+ b = *adx++;
+ s = (char *)*adx;
+ printn((u_long)b, *s++);
+ if (b) {
+ sep = '<';
+ while (i = *s++) {
+ if (b & (1 << (i-1))) {
+ putchar(sep);
+ sep = ',';
+ for (; (c = *s) > 32; s++)
+ putchar(c);
+ } else
+ for (; *s > 32; s++)
+ ;
+ }
+ if (sep != '<')
+ putchar('>');
+ }
+ break;
+#endif
+
+ case 's':
+ s = (char *)*adx;
+ while (c = *s++)
+ putchar(c);
+ break;
+ }
+ adx++;
+ goto loop;
+}
+
+/*
+ * Printn prints a number n in base b.
+ * We don't use recursion to avoid deep kernel stacks.
+ */
+printn(n, b)
+ u_long n;
+{
+ char prbuf[11];
+ register char *cp;
+
+ if (b == 10 && (int)n < 0) {
+ putchar('-');
+ n = (unsigned)(-(int)n);
+ }
+ cp = prbuf;
+ do {
+ *cp++ = "0123456789abcdef"[n%b];
+ n /= b;
+ } while (n);
+ do
+ putchar(*--cp);
+ while (cp > prbuf);
+}
+
+#define lf 10
+#define cr 13
+
+putchar(c)
+char c;
+{
+ if (c == lf)
+{
+ sput(cr);
+wait(60000);
+}
+ sput(c);
+ return(0);
+}
+
+wait(n) { while(n--) ; }