1 /* $NetBSD: ite.c,v 1.18 2016/02/26 18:11:11 christos 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/stand/common/grfreg.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 127 iteconfig(void) 128 { 129 int dtype, fboff, slotno, i; 130 uint8_t *va; 131 struct hp_hw *hw; 132 struct grfreg *gr; 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 gr = (struct grfreg *) hw->hw_kva; 140 /* XXX: redundent but safe */ 141 if (badaddr((void *)gr) || gr->gr_id != GRFHWID) 142 continue; 143 for (dtype = 0; dtype < nitesw; dtype++) 144 if (itesw[dtype].ite_hwid == gr->gr_id2) 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 *) gr; 154 fboff = (gr->gr_fbomsb << 8) | gr->gr_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 = gr->gr_fbwidth_h << 8 | gr->gr_fbwidth_l; 160 ip->fbheight = gr->gr_fbheight_h << 8 | gr->gr_fbheight_l; 161 ip->dwidth = gr->gr_dwidth_h << 8 | gr->gr_dwidth_l; 162 ip->dheight = gr->gr_dheight_h << 8 | gr->gr_dheight_l; 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 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 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 /* ARGSUSED */ 293 void 294 iteputchar(dev_t dev, int c) 295 { 296 struct ite_data *ip = &ite_data[itecons]; 297 struct itesw *sp = ip->isw; 298 299 c &= 0x7F; 300 switch (c) { 301 302 case '\n': 303 if (++ip->cury == ip->rows) { 304 ip->cury--; 305 (*sp->ite_scroll)(ip); 306 ite_clrtoeol(ip, sp, ip->cury, 0); 307 } 308 else 309 (*sp->ite_cursor)(ip, MOVE_CURSOR); 310 break; 311 312 case '\r': 313 ip->curx = 0; 314 (*sp->ite_cursor)(ip, MOVE_CURSOR); 315 break; 316 317 case '\b': 318 if (--ip->curx < 0) 319 ip->curx = 0; 320 else 321 (*sp->ite_cursor)(ip, MOVE_CURSOR); 322 break; 323 324 default: 325 if (c < ' ' || c == 0177) 326 break; 327 (*sp->ite_putc)(ip, c, ip->cury, ip->curx); 328 (*sp->ite_cursor)(ip, DRAW_CURSOR); 329 itecheckwrap(ip, sp); 330 break; 331 } 332 } 333 334 static void 335 itecheckwrap(struct ite_data *ip, struct itesw *sp) 336 { 337 if (++ip->curx == ip->cols) { 338 ip->curx = 0; 339 if (++ip->cury == ip->rows) { 340 --ip->cury; 341 (*sp->ite_scroll)(ip); 342 ite_clrtoeol(ip, sp, ip->cury, 0); 343 return; 344 } 345 } 346 (*sp->ite_cursor)(ip, MOVE_CURSOR); 347 } 348 349 static void 350 ite_clrtoeol(struct ite_data *ip, struct itesw *sp, int y, int x) 351 { 352 353 (*sp->ite_clear)(ip, y, x, 1, ip->cols - x); 354 (*sp->ite_cursor)(ip, DRAW_CURSOR); 355 } 356 357 /* ARGSUSED */ 358 int 359 itegetchar(dev_t dev) 360 { 361 362 #ifdef SMALL 363 return 0; 364 #else 365 return kbdgetc(); 366 #endif 367 } 368 #endif 369