1 /* $NetBSD: ite.c,v 1.20 2023/04/21 22:44:27 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/sgcreg.h>
53 #include <dev/ic/stireg.h>
54
55 #include <hp300/stand/common/device.h>
56 #include <hp300/stand/common/itevar.h>
57 #include <hp300/stand/common/kbdvar.h>
58 #include <hp300/stand/common/consdefs.h>
59 #include <hp300/stand/common/samachdep.h>
60
61 static void iteconfig(void);
62 static void ite_clrtoeol(struct ite_data *, struct itesw *, int, int);
63 static void itecheckwrap(struct ite_data *, struct itesw *);
64
65 #define GID_STI 0x100 /* any value which is not a DIO fb, really */
66
67 struct itesw itesw[] = {
68 { GID_TOPCAT,
69 topcat_init, ite_dio_clear, ite_dio_putc8bpp,
70 ite_dio_cursor, ite_dio_scroll },
71
72 { GID_GATORBOX,
73 gbox_init, ite_dio_clear, ite_dio_putc8bpp,
74 ite_dio_cursor, gbox_scroll },
75
76 { GID_RENAISSANCE,
77 rbox_init, ite_dio_clear, ite_dio_putc8bpp,
78 ite_dio_cursor, ite_dio_scroll },
79
80 { GID_LRCATSEYE,
81 topcat_init, ite_dio_clear, ite_dio_putc8bpp,
82 ite_dio_cursor, ite_dio_scroll },
83
84 { GID_HRCCATSEYE,
85 topcat_init, ite_dio_clear, ite_dio_putc8bpp,
86 ite_dio_cursor, ite_dio_scroll },
87
88 { GID_HRMCATSEYE,
89 topcat_init, ite_dio_clear, ite_dio_putc8bpp,
90 ite_dio_cursor, ite_dio_scroll },
91
92 { GID_DAVINCI,
93 dvbox_init, ite_dio_clear, ite_dio_putc8bpp,
94 ite_dio_cursor, ite_dio_scroll },
95
96 { GID_HYPERION,
97 hyper_init, ite_dio_clear, ite_dio_putc1bpp,
98 ite_dio_cursor, ite_dio_scroll },
99
100 { GID_TIGER,
101 tvrx_init, ite_dio_clear, ite_dio_putc1bpp,
102 ite_dio_cursor, ite_dio_scroll },
103
104 { GID_A1474MID,
105 dumb_init, dumb_clear, dumb_putc,
106 dumb_cursor, dumb_scroll },
107
108 { GID_A147xVGA,
109 dumb_init, dumb_clear, dumb_putc,
110 dumb_cursor, dumb_scroll },
111
112 { GID_STI,
113 sti_iteinit_sgc, sti_clear, sti_putc,
114 sti_cursor, sti_scroll },
115 };
116 int nitesw = sizeof(itesw) / sizeof(itesw[0]);
117
118 /* these guys need to be in initialized data */
119 int itecons = -1;
120 struct ite_data ite_data[NITE] = { { 0 } };
121 int ite_scode[NITE] = { 0 };
122
123 /*
124 * Locate all bitmapped displays
125 */
126 static void
iteconfig(void)127 iteconfig(void)
128 {
129 int dtype, fboff, slotno, i;
130 uint8_t *va;
131 struct hp_hw *hw;
132 struct diofbreg *fb;
133 struct ite_data *ip;
134
135 i = 0;
136 for (hw = sc_table; hw < &sc_table[MAXCTLRS]; hw++) {
137 if (!HW_ISDEV(hw, D_BITMAP))
138 continue;
139 fb = (struct diofbreg *)hw->hw_kva;
140 /* XXX: redundent but safe */
141 if (badaddr((void *)fb) || fb->id != GRFHWID)
142 continue;
143 for (dtype = 0; dtype < nitesw; dtype++)
144 if (itesw[dtype].ite_hwid == fb->fbid)
145 break;
146 if (dtype == nitesw)
147 continue;
148 if (i >= NITE)
149 break;
150 ite_scode[i] = hw->hw_sc;
151 ip = &ite_data[i];
152 ip->isw = &itesw[dtype];
153 ip->regbase = (void *)fb;
154 fboff = (fb->fbomsb << 8) | fb->fbolsb;
155 ip->fbbase = (void *)(*((u_char *)ip->regbase + fboff) << 16);
156 /* DIO II: FB offset is relative to select code space */
157 if (ip->regbase >= (void *)DIOIIBASE)
158 ip->fbbase = (char*)ip->fbbase + (int)ip->regbase;
159 ip->fbwidth = fb->fbwmsb << 8 | fb->fbwlsb;
160 ip->fbheight = fb->fbhmsb << 8 | fb->fbhlsb;
161 ip->dwidth = fb->dwmsb << 8 | fb->dwlsb;
162 ip->dheight = fb->dhmsb << 8 | fb->dhlsb;
163 /*
164 * XXX some displays (e.g. the davinci) appear
165 * to return a display height greater than the
166 * returned FB height. Guess we should go back
167 * to getting the display dimensions from the
168 * fontrom...
169 */
170 if (ip->dwidth > ip->fbwidth)
171 ip->dwidth = ip->fbwidth;
172 if (ip->dheight > ip->fbheight)
173 ip->dheight = ip->fbheight;
174 ip->alive = 1;
175 i++;
176 }
177
178 /*
179 * Now probe for SGC frame buffers.
180 */
181 switch (machineid) {
182 case HP_400:
183 case HP_425:
184 case HP_433:
185 break;
186 default:
187 return;
188 }
189
190 /* SGC frame buffers can only be STI... */
191 for (dtype = 0; dtype < __arraycount(itesw); dtype++) {
192 if (itesw[dtype].ite_hwid == GID_STI)
193 break;
194 }
195 if (dtype == __arraycount(itesw))
196 return;
197
198 for (slotno = 0; slotno < SGC_NSLOTS; slotno++) {
199 va = (uint8_t *)IIOV(SGC_BASE + (slotno * SGC_DEVSIZE));
200
201 /* Check to see if hardware exists. */
202 if (badaddr(va) != 0)
203 continue;
204
205 /* Check hardware. */
206 if (va[3] == STI_DEVTYPE1) {
207 if (i >= NITE)
208 break;
209 ip = &ite_data[i];
210 ip->scode = slotno;
211 ip->isw = &itesw[dtype];
212 /* to get CN_MIDPRI */
213 ip->regbase = (uint8_t *)(INTIOBASE + FB_BASE);
214 /* ...and do not need an ite_probe() check */
215 ip->alive = 1;
216 i++;
217 /* we only support one SGC frame buffer at the moment */
218 break;
219 }
220 }
221 }
222
223 #ifdef CONSDEBUG
224 /*
225 * Allows us to cycle through all possible consoles (NITE ites and serial port)
226 * by using SHIFT-RESET on the keyboard.
227 */
228 int whichconsole = -1;
229 #endif
230
231 void
iteprobe(struct consdev * cp)232 iteprobe(struct consdev *cp)
233 {
234 int ite;
235 struct ite_data *ip;
236 int unit, pri;
237
238 #ifdef CONSDEBUG
239 whichconsole = (whichconsole + 1) % (NITE+1);
240 #endif
241
242 if (itecons != -1)
243 return;
244
245 iteconfig();
246 unit = -1;
247 pri = CN_DEAD;
248 for (ite = 0; ite < NITE; ite++) {
249 #ifdef CONSDEBUG
250 if (ite < whichconsole)
251 continue;
252 #endif
253 ip = &ite_data[ite];
254 if (ip->alive == 0)
255 continue;
256 if ((int)ip->regbase == INTIOBASE + FB_BASE) {
257 pri = CN_INTERNAL;
258 unit = ite;
259 } else if (unit < 0) {
260 pri = CN_NORMAL;
261 unit = ite;
262 }
263 }
264 curcons_scode = ite_scode[unit];
265 cp->cn_dev = unit;
266 cp->cn_pri = pri;
267 }
268
269 void
iteinit(struct consdev * cp)270 iteinit(struct consdev *cp)
271 {
272 int ite = cp->cn_dev;
273 struct ite_data *ip;
274
275 if (itecons != -1)
276 return;
277
278 ip = &ite_data[ite];
279
280 ip->curx = 0;
281 ip->cury = 0;
282 ip->cursorx = 0;
283 ip->cursory = 0;
284
285 (*ip->isw->ite_init)(ip);
286 (*ip->isw->ite_cursor)(ip, DRAW_CURSOR);
287
288 itecons = ite;
289 kbdinit();
290 }
291
292 void
iteputchar(dev_t dev,int c)293 iteputchar(dev_t dev, int c)
294 {
295 struct ite_data *ip = &ite_data[itecons];
296 struct itesw *sp = ip->isw;
297
298 c &= 0x7F;
299 switch (c) {
300
301 case '\n':
302 if (++ip->cury == ip->rows) {
303 ip->cury--;
304 (*sp->ite_scroll)(ip);
305 ite_clrtoeol(ip, sp, ip->cury, 0);
306 }
307 else
308 (*sp->ite_cursor)(ip, MOVE_CURSOR);
309 break;
310
311 case '\r':
312 ip->curx = 0;
313 (*sp->ite_cursor)(ip, MOVE_CURSOR);
314 break;
315
316 case '\b':
317 if (--ip->curx < 0)
318 ip->curx = 0;
319 else
320 (*sp->ite_cursor)(ip, MOVE_CURSOR);
321 break;
322
323 default:
324 if (c < ' ' || c == 0177)
325 break;
326 (*sp->ite_putc)(ip, c, ip->cury, ip->curx);
327 (*sp->ite_cursor)(ip, DRAW_CURSOR);
328 itecheckwrap(ip, sp);
329 break;
330 }
331 }
332
333 static void
itecheckwrap(struct ite_data * ip,struct itesw * sp)334 itecheckwrap(struct ite_data *ip, struct itesw *sp)
335 {
336 if (++ip->curx == ip->cols) {
337 ip->curx = 0;
338 if (++ip->cury == ip->rows) {
339 --ip->cury;
340 (*sp->ite_scroll)(ip);
341 ite_clrtoeol(ip, sp, ip->cury, 0);
342 return;
343 }
344 }
345 (*sp->ite_cursor)(ip, MOVE_CURSOR);
346 }
347
348 static void
ite_clrtoeol(struct ite_data * ip,struct itesw * sp,int y,int x)349 ite_clrtoeol(struct ite_data *ip, struct itesw *sp, int y, int x)
350 {
351
352 (*sp->ite_clear)(ip, y, x, 1, ip->cols - x);
353 (*sp->ite_cursor)(ip, DRAW_CURSOR);
354 }
355
356 int
itegetchar(dev_t dev)357 itegetchar(dev_t dev)
358 {
359
360 #ifdef SMALL
361 return 0;
362 #else
363 return kbdgetc();
364 #endif
365 }
366 #endif
367