Commit | Line | Data |
---|---|---|
a570deab KT |
1 | |
2 | /* | |
3 | * Scaled down version of C Library printf. | |
4 | * Only %s %u %d (==%u) %o %x %D are recognized. | |
5 | * Used to print diagnostic information | |
6 | * directly on console tty. | |
7 | * Since it is not interrupt driven, | |
8 | * all system activities are pretty much | |
9 | * suspended. | |
10 | * Printf should not be used for chit-chat. | |
11 | */ | |
12 | printf(fmt, x1) | |
13 | register char *fmt; | |
14 | unsigned x1; | |
15 | { | |
16 | register c; | |
17 | register unsigned int *adx; | |
18 | char *s; | |
19 | ||
20 | adx = &x1; | |
21 | loop: | |
22 | while((c = *fmt++) != '%') { | |
23 | if(c == '\0') | |
24 | return; | |
25 | putchar(c); | |
26 | } | |
27 | c = *fmt++; | |
28 | if(c == 'd' || c == 'u' || c == 'o' || c == 'x') | |
29 | printn((long)*adx, c=='o'? 8: (c=='x'? 16:10)); | |
30 | else if(c == 's') { | |
31 | s = (char *)*adx; | |
32 | while(c = *s++) | |
33 | putchar(c); | |
34 | } else if (c == 'D') { | |
35 | printn(*(long *)adx, 10); | |
36 | adx += (sizeof(long) / sizeof(int)) - 1; | |
37 | } else if (c == 'c') | |
38 | putchar((char *)*adx); | |
39 | adx++; | |
40 | goto loop; | |
41 | } | |
42 | ||
43 | /* | |
44 | * Print an unsigned integer in base b. | |
45 | */ | |
46 | printn(n, b) | |
47 | long n; | |
48 | { | |
49 | register long a; | |
50 | ||
51 | if (n<0) { /* shouldn't happen */ | |
52 | putchar('-'); | |
53 | n = -n; | |
54 | } | |
55 | if(a = n/b) | |
56 | printn(a, b); | |
57 | putchar("0123456789ABCDEF"[(int)(n%b)]); | |
58 | } | |
59 | ||
60 | ||
61 | ||
62 | struct device { | |
63 | int rcsr,rbuf; | |
64 | int tcsr,tbuf; | |
65 | }; | |
66 | struct device *KLADDR {0177560}; | |
67 | putchar(c) | |
68 | register c; | |
69 | { | |
70 | register s; | |
71 | register unsigned timo; | |
72 | ||
73 | /* | |
74 | * If last char was a break or null, don't print | |
75 | if ((KLADDR->rbuf&0177) == 0) | |
76 | return; | |
77 | */ | |
78 | timo = 60000; | |
79 | /* | |
80 | * Try waiting for the console tty to come ready, | |
81 | * otherwise give up after a reasonable time. | |
82 | */ | |
83 | while((KLADDR->tcsr&0200) == 0) | |
84 | if(--timo == 0) | |
85 | break; | |
86 | if(c == 0) | |
87 | return; | |
88 | s = KLADDR->tcsr; | |
89 | KLADDR->tcsr = 0; | |
90 | KLADDR->tbuf = c; | |
91 | if(c == '\n') { | |
92 | putchar('\r'); | |
93 | putchar(0177); | |
94 | putchar(0177); | |
95 | } | |
96 | putchar(0); | |
97 | KLADDR->tcsr = s; | |
98 | } | |
99 | ||
100 | getchar() | |
101 | { | |
102 | register c; | |
103 | ||
104 | KLADDR->rcsr = 1; | |
105 | while((KLADDR->rcsr&0200)==0); | |
106 | c = KLADDR->rbuf&0177; | |
107 | if (c=='\r') | |
108 | c = '\n'; | |
109 | putchar(c); | |
110 | return(c); | |
111 | } | |
112 | ||
113 | gets(buf) | |
114 | char *buf; | |
115 | { | |
116 | register char *lp; | |
117 | register c; | |
118 | ||
119 | lp = buf; | |
120 | for (;;) { | |
121 | c = getchar() & 0177; | |
122 | if (c>='A' && c<='Z') | |
123 | c -= 'A' - 'a'; | |
124 | if (lp != buf && *(lp-1) == '\\') { | |
125 | lp--; | |
126 | if (c>='a' && c<='z') { | |
127 | c += 'A' - 'a'; | |
128 | goto store; | |
129 | } | |
130 | switch ( c) { | |
131 | case '(': | |
132 | c = '{'; | |
133 | break; | |
134 | case ')': | |
135 | c = '}'; | |
136 | break; | |
137 | case '!': | |
138 | c = '|'; | |
139 | break; | |
140 | case '^': | |
141 | c = '~'; | |
142 | break; | |
143 | case '\'': | |
144 | c = '`'; | |
145 | break; | |
146 | } | |
147 | } | |
148 | store: | |
149 | switch(c) { | |
150 | case '\n': | |
151 | case '\r': | |
152 | c = '\n'; | |
153 | *lp++ = '\0'; | |
154 | return; | |
155 | case '\b': | |
156 | case '#': | |
157 | lp--; | |
158 | if (lp < buf) | |
159 | lp = buf; | |
160 | continue; | |
161 | case '@': | |
162 | lp = buf; | |
163 | putchar('\n'); | |
164 | continue; | |
165 | default: | |
166 | *lp++ = c; | |
167 | } | |
168 | } | |
169 | } |