1 /* $NetBSD: ite.c,v 1.23 2025/05/30 19:19:26 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_scroll(struct ite_data *); 64 static void itecheckwrap(struct ite_data *); 65 66 #define GID_STI 0x100 /* any value which is not a DIO fb, really */ 67 68 static const 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 static int itecons = -1; 192 static 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 *)(*((uint8_t *)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 const struct itesw *sp; 350 351 if (itecons != -1) 352 return; 353 354 ip = &ite_data[ite]; 355 sp = ip->isw; 356 357 ip->curx = 0; 358 ip->cury = 0; 359 ip->cursorx = 0; 360 ip->cursory = 0; 361 362 (*sp->ite_init)(ip); 363 (*sp->ite_cursor)(ip, DRAW_CURSOR); 364 365 itecons = ite; 366 kbdinit(); 367 } 368 369 void 370 iteputchar(dev_t dev, int c) 371 { 372 struct ite_data *ip = &ite_data[itecons]; 373 const struct itesw *sp = ip->isw; 374 375 c &= 0x7F; 376 switch (c) { 377 378 case '\n': 379 if (++ip->cury == ip->rows) { 380 ip->cury--; 381 ite_scroll(ip); 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); 404 break; 405 } 406 } 407 408 static void 409 itecheckwrap(struct ite_data *ip) 410 { 411 const struct itesw *sp = ip->isw; 412 413 if (++ip->curx == ip->cols) { 414 ip->curx = 0; 415 if (++ip->cury == ip->rows) { 416 --ip->cury; 417 ite_scroll(ip); 418 return; 419 } 420 } 421 (*sp->ite_cursor)(ip, MOVE_CURSOR); 422 } 423 424 static void 425 ite_scroll(struct ite_data *ip) 426 { 427 const struct itesw *sp = ip->isw; 428 429 /* Erase the cursor before scrolling */ 430 (*sp->ite_cursor)(ip, ERASE_CURSOR); 431 /* Scroll the screen up by one line */ 432 (*sp->ite_scroll)(ip); 433 /* Clear the entire bottom line after scrolling */ 434 (*sp->ite_clear)(ip, ip->rows - 1, 0, 1, ip->cols); 435 /* Redraw the cursor */ 436 (*sp->ite_cursor)(ip, DRAW_CURSOR); 437 } 438 439 int 440 itegetchar(dev_t dev) 441 { 442 443 #ifdef SMALL 444 return 0; 445 #else 446 return kbdgetc(); 447 #endif 448 } 449 #endif 450