ite.c revision 1.21 1 /* $NetBSD: ite.c,v 1.21 2025/05/26 12:25:12 tsutsui Exp $ */
2
3 /*
4 * Copyright (c) 1988 University of Utah.
5 * Copyright (c) 1990, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * the Systems Programming Group of the University of Utah Computer
10 * Science Department.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * from: Utah $Hdr: ite.c 1.24 93/06/25$
37 *
38 * @(#)ite.c 8.1 (Berkeley) 7/8/93
39 */
40
41 /*
42 * Standalone Internal Terminal Emulator (CRT and keyboard)
43 */
44
45 #ifdef ITECONSOLE
46
47 #include <sys/param.h>
48 #include <dev/cons.h>
49
50 #include <hp300/dev/diofbreg.h>
51 #include <hp300/dev/intioreg.h>
52 #include <hp300/dev/dioreg.h>
53 #include <hp300/dev/sgcreg.h>
54 #include <dev/ic/stireg.h>
55
56 #include <hp300/stand/common/device.h>
57 #include <hp300/stand/common/itevar.h>
58 #include <hp300/stand/common/kbdvar.h>
59 #include <hp300/stand/common/consdefs.h>
60 #include <hp300/stand/common/samachdep.h>
61
62 static void iteconfig(void);
63 static void ite_clrtoeol(struct ite_data *, struct itesw *, int, int);
64 static void itecheckwrap(struct ite_data *, struct itesw *);
65
66 #define GID_STI 0x100 /* any value which is not a DIO fb, really */
67
68 struct itesw itesw[] = {
69 {
70 .ite_hwid = GID_TOPCAT,
71 .ite_probe = NULL,
72 .ite_init = topcat_init,
73 .ite_clear = ite_dio_clear,
74 .ite_putc = ite_dio_putc8bpp,
75 .ite_cursor = ite_dio_cursor,
76 .ite_scroll = ite_dio_scroll
77 },
78
79 {
80 .ite_hwid = GID_GATORBOX,
81 .ite_probe = NULL,
82 .ite_init = gbox_init,
83 .ite_clear = ite_dio_clear,
84 .ite_putc = ite_dio_putc8bpp,
85 .ite_cursor = ite_dio_cursor,
86 .ite_scroll = gbox_scroll
87 },
88
89 {
90 .ite_hwid = GID_RENAISSANCE,
91 .ite_probe = NULL,
92 .ite_init = rbox_init,
93 .ite_clear = ite_dio_clear,
94 .ite_putc = ite_dio_putc8bpp,
95 .ite_cursor = ite_dio_cursor,
96 .ite_scroll = ite_dio_scroll
97 },
98
99 {
100 .ite_hwid = GID_LRCATSEYE,
101 .ite_probe = NULL,
102 .ite_init = topcat_init,
103 .ite_clear = ite_dio_clear,
104 .ite_putc = ite_dio_putc8bpp,
105 .ite_cursor = ite_dio_cursor,
106 .ite_scroll = ite_dio_scroll
107 },
108
109 {
110 .ite_hwid = GID_HRCCATSEYE,
111 .ite_probe = NULL,
112 .ite_init = topcat_init,
113 .ite_clear = ite_dio_clear,
114 .ite_putc = ite_dio_putc8bpp,
115 .ite_cursor = ite_dio_cursor,
116 .ite_scroll = ite_dio_scroll
117 },
118
119 {
120 .ite_hwid = GID_HRMCATSEYE,
121 .ite_probe = NULL,
122 .ite_init = topcat_init,
123 .ite_clear = ite_dio_clear,
124 .ite_putc = ite_dio_putc8bpp,
125 .ite_cursor = ite_dio_cursor,
126 .ite_scroll = ite_dio_scroll
127 },
128
129 {
130 .ite_hwid = GID_DAVINCI,
131 .ite_probe = NULL,
132 .ite_init = dvbox_init,
133 .ite_clear = ite_dio_clear,
134 .ite_putc = ite_dio_putc8bpp,
135 .ite_cursor = ite_dio_cursor,
136 .ite_scroll = ite_dio_scroll
137 },
138
139 {
140 .ite_hwid = GID_HYPERION,
141 .ite_probe = NULL,
142 .ite_init = hyper_init,
143 .ite_clear = ite_dio_clear,
144 .ite_putc = ite_dio_putc1bpp,
145 .ite_cursor = ite_dio_cursor,
146 .ite_scroll = ite_dio_scroll
147 },
148
149 {
150 .ite_hwid = GID_TIGER,
151 .ite_probe = NULL,
152 .ite_init = tvrx_init,
153 .ite_clear = ite_dio_clear,
154 .ite_putc = ite_dio_putc1bpp,
155 .ite_cursor = ite_dio_cursor,
156 .ite_scroll = ite_dio_scroll
157 },
158
159 {
160 .ite_hwid = GID_A1474MID,
161 .ite_probe = sti_dio_probe,
162 .ite_init = sti_iteinit_dio,
163 .ite_clear = sti_clear,
164 .ite_putc = sti_putc,
165 .ite_cursor = sti_cursor,
166 .ite_scroll = sti_scroll
167 },
168
169 {
170 .ite_hwid = GID_A147xVGA,
171 .ite_probe = sti_dio_probe,
172 .ite_init = sti_iteinit_dio,
173 .ite_clear = sti_clear,
174 .ite_putc = sti_putc,
175 .ite_cursor = sti_cursor,
176 .ite_scroll = sti_scroll
177 },
178
179 {
180 .ite_hwid = GID_STI,
181 .ite_probe = NULL,
182 .ite_init = sti_iteinit_sgc,
183 .ite_clear = sti_clear,
184 .ite_putc = sti_putc,
185 .ite_cursor = sti_cursor,
186 .ite_scroll = sti_scroll
187 },
188 };
189
190 /* these guys need to be in initialized data */
191 int itecons = -1;
192 struct ite_data ite_data[NITE] = { { 0 } };
193
194 /*
195 * Locate all bitmapped displays
196 */
197 static void
198 iteconfig(void)
199 {
200 int dtype, fboff, slotno, i;
201 uint8_t *va;
202 struct hp_hw *hw;
203 struct diofbreg *fb;
204 struct ite_data *ip;
205
206 i = 0;
207 for (hw = sc_table; hw < &sc_table[MAXCTLRS]; hw++) {
208 if (!HW_ISDEV(hw, D_BITMAP))
209 continue;
210 fb = (struct diofbreg *)hw->hw_kva;
211 /* XXX: redundent but safe */
212 if (badaddr((void *)fb) || fb->id != GRFHWID)
213 continue;
214 for (dtype = 0; dtype < __arraycount(itesw); dtype++)
215 if (itesw[dtype].ite_hwid == fb->fbid)
216 break;
217 if (dtype == __arraycount(itesw))
218 continue;
219 if (i >= NITE)
220 break;
221 ip = &ite_data[i];
222 ip->scode = hw->hw_sc;
223 ip->isw = &itesw[dtype];
224 ip->regbase = (void *)fb;
225 fboff = (fb->fbomsb << 8) | fb->fbolsb;
226 ip->fbbase = (void *)(*((u_char *)ip->regbase + fboff) << 16);
227 /* DIO II: FB offset is relative to select code space */
228 if (DIO_ISDIOII(ip->scode))
229 ip->fbbase = (uint8_t *)ip->fbbase + (int)ip->regbase;
230 ip->fbwidth = fb->fbwmsb << 8 | fb->fbwlsb;
231 ip->fbheight = fb->fbhmsb << 8 | fb->fbhlsb;
232 ip->dwidth = fb->dwmsb << 8 | fb->dwlsb;
233 ip->dheight = fb->dhmsb << 8 | fb->dhlsb;
234 /*
235 * XXX some displays (e.g. the davinci) appear
236 * to return a display height greater than the
237 * returned FB height. Guess we should go back
238 * to getting the display dimensions from the
239 * fontrom...
240 */
241 if (ip->dwidth > ip->fbwidth)
242 ip->dwidth = ip->fbwidth;
243 if (ip->dheight > ip->fbheight)
244 ip->dheight = ip->fbheight;
245 /* confirm hardware is what we think it is */
246 if (itesw[dtype].ite_probe != NULL &&
247 (*itesw[dtype].ite_probe)(ip) != 0)
248 continue;
249 ip->alive = 1;
250 i++;
251 }
252
253 /*
254 * Now probe for SGC frame buffers.
255 */
256 switch (machineid) {
257 case HP_400:
258 case HP_425:
259 case HP_433:
260 break;
261 default:
262 return;
263 }
264
265 /* SGC frame buffers can only be STI... */
266 for (dtype = 0; dtype < __arraycount(itesw); dtype++)
267 if (itesw[dtype].ite_hwid == GID_STI)
268 break;
269 if (dtype == __arraycount(itesw))
270 return;
271
272 for (slotno = 0; slotno < SGC_NSLOTS; slotno++) {
273 va = (uint8_t *)IIOV(SGC_BASE + (slotno * SGC_DEVSIZE));
274
275 /* Check to see if hardware exists. */
276 if (badaddr(va) != 0)
277 continue;
278
279 /* Check hardware. */
280 if (va[3] == STI_DEVTYPE1) {
281 if (i >= NITE)
282 break;
283 ip = &ite_data[i];
284 ip->scode = slotno;
285 ip->isw = &itesw[dtype];
286 /* to get CN_MIDPRI */
287 ip->regbase = (uint8_t *)(INTIOBASE + FB_BASE);
288 /* ...and do not need an ite_probe() check */
289 ip->alive = 1;
290 i++;
291 /* we only support one SGC frame buffer at the moment */
292 break;
293 }
294 }
295 }
296
297 #ifdef CONSDEBUG
298 /*
299 * Allows us to cycle through all possible consoles (NITE ites and serial port)
300 * by using SHIFT-RESET on the keyboard.
301 */
302 int whichconsole = -1;
303 #endif
304
305 void
306 iteprobe(struct consdev *cp)
307 {
308 int ite;
309 struct ite_data *ip;
310 int unit, pri;
311
312 #ifdef CONSDEBUG
313 whichconsole = (whichconsole + 1) % (NITE+1);
314 #endif
315
316 if (itecons != -1)
317 return;
318
319 iteconfig();
320 unit = -1;
321 pri = CN_DEAD;
322 for (ite = 0; ite < NITE; ite++) {
323 #ifdef CONSDEBUG
324 if (ite < whichconsole)
325 continue;
326 #endif
327 ip = &ite_data[ite];
328 if (ip->alive == 0)
329 continue;
330 if ((int)ip->regbase == INTIOBASE + FB_BASE) {
331 pri = CN_INTERNAL;
332 unit = ite;
333 } else if (unit < 0) {
334 pri = CN_NORMAL;
335 unit = ite;
336 }
337 }
338 ip = &ite_data[unit];
339 curcons_scode = ip->scode;
340 cp->cn_dev = unit;
341 cp->cn_pri = pri;
342 }
343
344 void
345 iteinit(struct consdev *cp)
346 {
347 int ite = cp->cn_dev;
348 struct ite_data *ip;
349
350 if (itecons != -1)
351 return;
352
353 ip = &ite_data[ite];
354
355 ip->curx = 0;
356 ip->cury = 0;
357 ip->cursorx = 0;
358 ip->cursory = 0;
359
360 (*ip->isw->ite_init)(ip);
361 (*ip->isw->ite_cursor)(ip, DRAW_CURSOR);
362
363 itecons = ite;
364 kbdinit();
365 }
366
367 void
368 iteputchar(dev_t dev, int c)
369 {
370 struct ite_data *ip = &ite_data[itecons];
371 struct itesw *sp = ip->isw;
372
373 c &= 0x7F;
374 switch (c) {
375
376 case '\n':
377 if (++ip->cury == ip->rows) {
378 ip->cury--;
379 (*sp->ite_scroll)(ip);
380 ite_clrtoeol(ip, sp, ip->cury, 0);
381 }
382 else
383 (*sp->ite_cursor)(ip, MOVE_CURSOR);
384 break;
385
386 case '\r':
387 ip->curx = 0;
388 (*sp->ite_cursor)(ip, MOVE_CURSOR);
389 break;
390
391 case '\b':
392 if (--ip->curx < 0)
393 ip->curx = 0;
394 else
395 (*sp->ite_cursor)(ip, MOVE_CURSOR);
396 break;
397
398 default:
399 if (c < ' ' || c == 0177)
400 break;
401 (*sp->ite_putc)(ip, c, ip->cury, ip->curx);
402 (*sp->ite_cursor)(ip, DRAW_CURSOR);
403 itecheckwrap(ip, sp);
404 break;
405 }
406 }
407
408 static void
409 itecheckwrap(struct ite_data *ip, struct itesw *sp)
410 {
411 if (++ip->curx == ip->cols) {
412 ip->curx = 0;
413 if (++ip->cury == ip->rows) {
414 --ip->cury;
415 (*sp->ite_scroll)(ip);
416 ite_clrtoeol(ip, sp, ip->cury, 0);
417 return;
418 }
419 }
420 (*sp->ite_cursor)(ip, MOVE_CURSOR);
421 }
422
423 static void
424 ite_clrtoeol(struct ite_data *ip, struct itesw *sp, int y, int x)
425 {
426
427 (*sp->ite_clear)(ip, y, x, 1, ip->cols - x);
428 (*sp->ite_cursor)(ip, DRAW_CURSOR);
429 }
430
431 int
432 itegetchar(dev_t dev)
433 {
434
435 #ifdef SMALL
436 return 0;
437 #else
438 return kbdgetc();
439 #endif
440 }
441 #endif
442