1 /* $NetBSD: ite_ul.c,v 1.11 2002/01/28 09:57:00 aymeric Exp $ */ 2 3 /*- 4 * Copyright (c) 1995 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Ignatios Souvatzis. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <sys/cdefs.h> 40 __KERNEL_RCSID(0, "$NetBSD: ite_ul.c,v 1.11 2002/01/28 09:57:00 aymeric Exp $"); 41 42 #include "grful.h" 43 #if NGRFUL > 0 44 45 #include <sys/param.h> 46 #include <sys/conf.h> 47 #include <sys/proc.h> 48 #include <sys/device.h> 49 #include <sys/ioctl.h> 50 #include <sys/tty.h> 51 #include <sys/systm.h> 52 #include <dev/cons.h> 53 #include <machine/cpu.h> 54 #include <amiga/amiga/device.h> 55 #include <amiga/amiga/isr.h> 56 #include <amiga/dev/itevar.h> 57 #include <amiga/dev/grfioctl.h> 58 #include <amiga/dev/grfvar.h> 59 #include <amiga/dev/grf_ulreg.h> 60 61 #ifndef KFONT_CUSTOM 62 #ifdef KFONT_8X11 63 #define kernel_font_width kernel_font_width_8x11 64 #define kernel_font_height kernel_font_height_8x11 65 #define kernel_font_baseline kernel_font_baseline_8x11 66 #define kernel_font_boldsmear kernel_font_boldsmear_8x11 67 #define kernel_font_lo kernel_font_lo_8x11 68 #define kernel_font_hi kernel_font_hi_8x11 69 #define kernel_font kernel_font_8x11 70 #define kernel_cursor kernel_cursor_8x11 71 #else 72 #define kernel_font_width kernel_font_width_8x8 73 #define kernel_font_height kernel_font_height_8x8 74 #define kernel_font_baseline kernel_font_baseline_8x8 75 #define kernel_font_boldsmear kernel_font_boldsmear_8x8 76 #define kernel_font_lo kernel_font_lo_8x8 77 #define kernel_font_hi kernel_font_hi_8x8 78 #define kernel_font kernel_font_8x8 79 #define kernel_cursor kernel_cursor_8x8 80 #endif 81 #endif 82 83 extern u_int8_t kernel_font_width, kernel_font_height, kernel_font_baseline; 84 extern short kernel_font_boldsmear; 85 extern u_int8_t kernel_font_lo, kernel_font_hi; 86 extern u_int8_t kernel_font[], kernel_cursor[]; 87 88 89 #ifdef DEBUG_UL 90 #define gsp_out(ba,cmd,len) gsp_dump(cmd,len); gsp_write(ba,cmd,len) 91 #else 92 #define gsp_out(ba,cmd,len) gsp_write(ba,cmd,len) 93 #endif 94 95 int ulowell_console = 1; 96 97 void ulowell_cursor(struct ite_softc *, int); 98 void ulowell_scroll(struct ite_softc *, int, int, int, int); 99 void ulowell_deinit(struct ite_softc *); 100 void ulowell_clear(struct ite_softc *, int, int, int, int); 101 void ulowell_putc(struct ite_softc *, int, int, int, int); 102 void ulowell_init(struct ite_softc *); 103 104 #ifdef DEBUG_UL 105 void gsp_dump(u_int16_t *, int); 106 #endif 107 108 /* Text always on overlay plane, so: */ 109 110 #define UL_FG(ip) 0xFFFF 111 #define UL_BG(ip) 0x0000 112 113 /* 114 * this function is called from grf_ul to init the grf_softc->g_conpri 115 * field each time a ulowell board is attached. 116 */ 117 int 118 grful_cnprobe(void) 119 { 120 static int done; 121 int uv; 122 123 if (ulowell_console && done == 0) 124 uv = CN_INTERNAL; 125 else 126 uv = CN_NORMAL; 127 done = 1; 128 return(uv); 129 } 130 131 /* 132 * init the required fields in the grf_softc struct for a 133 * grf to function as an ite. 134 */ 135 void 136 grful_iteinit(struct grf_softc *gp) 137 { 138 gp->g_iteinit = ulowell_init; 139 gp->g_itedeinit = ulowell_deinit; 140 gp->g_iteclear = ulowell_clear; 141 gp->g_iteputc = ulowell_putc; 142 gp->g_itescroll = ulowell_scroll; 143 gp->g_itecursor = ulowell_cursor; 144 } 145 146 void 147 ulowell_init(struct ite_softc *ip) 148 { 149 struct gspregs *ba; 150 151 u_int16_t *sp; 152 u_int16_t cmd[8]; 153 154 int i; 155 156 ba = (struct gspregs *) ip->grf->g_regkva; 157 158 ip->font = kernel_font; 159 ip->font_lo = kernel_font_lo; 160 ip->font_hi = kernel_font_hi; 161 ip->ftwidth = kernel_font_width; 162 ip->ftheight = kernel_font_height; 163 ip->ftbaseline = kernel_font_baseline; 164 ip->ftboldsmear = kernel_font_boldsmear; 165 166 /* upload font data */ 167 168 ba->ctrl = LBL|INCW; 169 ba->hstadrh = 0xFFA2; 170 ba->hstadrl = 0x0200; 171 172 ba->data = 0x0000; 173 ba->data = 0xFFA3; 174 ba->data = ip->ftwidth; 175 ba->data = ip->ftheight; 176 ba->data = ip->ftbaseline; 177 ba->data = 1; 178 ba->data = ip->font_lo; 179 ba->data = ip->font_hi; 180 ba->data = ip->ftboldsmear; 181 182 ba->hstadrh = 0xFFA3; 183 ba->hstadrl = 0x0000; 184 185 /* 186 * font has to be word aligned and padded to word boundary. 187 * 8 bit wide fonts will be byte swapped in the bit swap 188 * routine. 189 */ 190 191 i = (ip->font_hi - ip->font_lo + 1) * ip->ftheight; 192 if (ip->ftwidth <= 8) 193 i /= 2; 194 for (sp = (u_int16_t *)ip->font; i>0; --i,++sp) { 195 ba->data = *sp; 196 } 197 198 /* bitwise mirror the font: */ 199 200 cmd[0] = GCMD_FNTMIR; 201 gsp_out(ba, cmd, 1); 202 203 ip->priv = NULL; 204 ip->cursor_opt = 0; 205 206 if (ip->ftwidth >0 && ip->ftheight > 0) { 207 ip->cols = ip->grf->g_display.gd_dwidth / ip->ftwidth; 208 ip->rows = ip->grf->g_display.gd_dheight / ip->ftheight; 209 } 210 211 ulowell_clear(ip, 0, 0, ip->rows, ip->cols); 212 213 /* 214 * switch overlay plane 0 on again, in case s.b. did a GM_GRFOVOFF 215 * XXX maybe this should be done on each output, by the TMS code? 216 * what happens on panic? 217 218 ba->ctrl = LBL; 219 GSPSETHADRS(ba, 0xFE800000); 220 ba->data = 0; 221 ba->hstadrl = 0x0020; 222 gup->gus_ovslct |= 1; 223 ba->data = gup->gus_ovslct; 224 */ 225 226 #ifdef UL_DEBUG 227 printf("ulowell_init: %d %d %d %d %d %d\n", ip->ftwidth, ip->ftheight, 228 ip->ftbaseline, ip->font_lo, ip->font_hi, ip->ftboldsmear); 229 #endif 230 } 231 232 233 void ulowell_cursor(struct ite_softc *ip, int flag) 234 { 235 struct gspregs *ba; 236 u_int16_t cmd[7]; 237 238 ba = (struct gspregs *)ip->grf->g_regkva; 239 240 if (flag == END_CURSOROPT) 241 --ip->cursor_opt; 242 else if (flag == START_CURSOROPT) { 243 if (!ip->cursor_opt) 244 ulowell_cursor(ip, ERASE_CURSOR); 245 ++ip->cursor_opt; 246 return; /* if we are already opted */ 247 } 248 249 if (ip->cursor_opt) 250 return; /* if we are still nested. */ 251 252 /* else we draw the cursor */ 253 254 if (flag != DRAW_CURSOR && flag != END_CURSOROPT) { 255 /* erase cursor */ 256 #if 0 257 cmd[0] = GCMD_PIXBLT; 258 cmd[1] = 1024 - ip->ftwidth; 259 cmd[2] = 1024 - ip->ftheight; 260 cmd[3] = ip->ftwidth; 261 cmd[4] = ip->ftheight; 262 cmd[5] = ip->cursorx * ip->ftwidth; 263 cmd[6] = ip->cursory * ip->ftheight; 264 gsp_out(ba, cmd, 7); 265 #endif 266 cmd[0] = GCMD_FILL; 267 cmd[1] = UL_FG(ip); 268 cmd[2] = ip->cursorx * ip->ftwidth; 269 cmd[3] = ip->cursory * ip->ftheight; 270 cmd[4] = ip->ftwidth; 271 cmd[5] = ip->ftheight; 272 cmd[6] = 10; /* thats src xor dst */ 273 gsp_out(ba, cmd, 7); 274 } 275 276 if (flag != DRAW_CURSOR && flag != MOVE_CURSOR && 277 flag != END_CURSOROPT) 278 return; 279 280 /* draw cursor */ 281 282 ip->cursorx = min(ip->curx, ip->cols-1); 283 ip->cursory = ip->cury; 284 #if 0 285 cmd[0] = GCMD_PIXBLT; 286 cmd[1] = ip->cursorx * ip->ftwidth; 287 cmd[2] = ip->cursory * ip->ftheight; 288 cmd[3] = ip->ftwidth; 289 cmd[4] = ip->ftheight; 290 cmd[5] = 1024 - ip->ftwidth; 291 cmd[6] = 1024 - ip->ftheight; 292 gsp_out(ba, cmd, 7); 293 #endif 294 cmd[0] = GCMD_FILL; 295 cmd[1] = UL_FG(ip); 296 cmd[2] = ip->cursorx * ip->ftwidth; 297 cmd[3] = ip->cursory * ip->ftheight; 298 cmd[4] = ip->ftwidth; 299 cmd[5] = ip->ftheight; 300 cmd[6] = 10; /* thats src xor dst */ 301 gsp_out(ba, cmd, 7); 302 303 } 304 305 306 307 static void screen_up(struct ite_softc *ip, int top, int bottom, int lines) 308 { 309 struct gspregs *ba; 310 311 u_int16_t cmd[7]; 312 313 ba = (struct gspregs *)ip->grf->g_regkva; 314 315 #ifdef DEBUG_UL 316 printf("screen_up %d %d %d ->",top,bottom,lines); 317 #endif 318 /* do some bounds-checking here.. */ 319 320 if (top >= bottom) 321 return; 322 323 if (top + lines >= bottom) 324 { 325 ulowell_clear (ip, top, 0, bottom - top, ip->cols); 326 return; 327 } 328 329 cmd[0] = GCMD_PIXBLT; 330 cmd[1] = 0; /* x */ 331 cmd[2] = top * ip->ftheight; /* y */ 332 cmd[3] = ip->cols * ip->ftwidth; /* w */ 333 cmd[4] = (bottom-top+1) * ip->ftheight; /* h */ 334 cmd[5] = 0; /* dst x */ 335 cmd[6] = (top-lines) * ip->ftheight; /* dst y */ 336 gsp_out(ba, cmd, 7); 337 338 ulowell_clear(ip, bottom-lines+1, 0, lines-1, ip->cols); 339 }; 340 341 static void screen_down(struct ite_softc *ip, int top, int bottom, int lines) 342 { 343 struct gspregs *ba; 344 345 u_int16_t cmd[7]; 346 347 ba = (struct gspregs *)ip->grf->g_regkva; 348 349 #ifdef DEBUG_UL 350 printf("screen_down %d %d %d ->",top,bottom,lines); 351 #endif 352 353 /* do some bounds-checking here.. */ 354 355 if (top >= bottom) 356 return; 357 358 if (top + lines >= bottom) 359 { 360 ulowell_clear (ip, top, 0, bottom - top, ip->cols); 361 return; 362 } 363 364 cmd[0] = GCMD_PIXBLT; 365 cmd[1] = 0; /* x */ 366 cmd[2] = top * ip->ftheight; /* y */ 367 cmd[3] = ip->cols * ip->ftwidth; /* w */ 368 cmd[4] = (bottom - top - lines) * ip->ftheight; /* h */ 369 cmd[5] = 0; /* dst x */ 370 cmd[6] = (top + lines) * ip->ftheight; /* dst y */ 371 gsp_out(ba, cmd, 7); 372 373 ulowell_clear(ip, top, 0, lines, ip->cols); 374 }; 375 376 void ulowell_deinit(struct ite_softc *ip) 377 { 378 ip->flags &= ~ITE_INITED; 379 } 380 381 382 void ulowell_putc(struct ite_softc *ip, int c, int dy, int dx, int mode) 383 { 384 struct gspregs *ba; 385 u_int16_t cmd[8]; 386 387 ba = (struct gspregs *)ip->grf->g_regkva; 388 389 cmd[0] = GCMD_CHAR; 390 cmd[1] = c & 0xff; 391 cmd[2] = 0x0; 392 cmd[3] = UL_FG(ip); 393 cmd[4] = dx * ip->ftwidth; 394 cmd[5] = dy * ip->ftheight; 395 cmd[6] = mode; 396 gsp_write(ba, cmd, 7); 397 } 398 399 void ulowell_clear(struct ite_softc *ip, int sy, int sx, int h, int w) 400 { 401 /* XXX TBD */ 402 struct gspregs * ba; 403 404 u_int16_t cmd[7]; 405 406 #ifdef DEBUG_UL 407 printf("ulowell_clear %d %d %d %d ->",sy,sx,h,w); 408 #endif 409 ba = (struct gspregs *)ip->grf->g_regkva; 410 411 cmd[0] = GCMD_FILL; 412 cmd[1] = 0x0; /* XXX */ 413 cmd[2] = sx * ip->ftwidth; 414 cmd[3] = sy * ip->ftheight; 415 cmd[4] = w * ip->ftwidth; 416 cmd[5] = h * ip->ftheight; 417 cmd[6] = 0; 418 419 gsp_out(ba, cmd, 7); 420 } 421 422 void ulowell_scroll(struct ite_softc *ip, int sy, int sx, int count, int dir) 423 { 424 struct gspregs *ba; 425 u_int16_t cmd[7]; 426 427 ba = (struct gspregs *)ip->grf->g_regkva; 428 429 #ifdef DEBUG_UL 430 printf("ulowell_scroll %d %d %d %d ->",sy,sx,count,dir); 431 #endif 432 433 ulowell_cursor(ip, ERASE_CURSOR); 434 435 if (dir == SCROLL_UP) { 436 screen_up (ip, sy, ip->bottom_margin, count); 437 } else if (dir == SCROLL_DOWN) { 438 screen_down (ip, sy, ip->bottom_margin, count); 439 } else if (dir == SCROLL_RIGHT) { 440 cmd[0] = GCMD_PIXBLT; 441 cmd[1] = sx * ip->ftwidth; 442 cmd[2] = sy * ip->ftheight; 443 cmd[3] = (ip->cols - sx - count) * ip->ftwidth; 444 cmd[4] = ip->ftheight; 445 cmd[5] = (sx + count) * ip->ftwidth; 446 cmd[6] = sy * ip->ftheight; 447 gsp_out(ba,cmd,7); 448 ulowell_clear (ip, sy, sx, 1, count); 449 } else { 450 cmd[0] = GCMD_PIXBLT; 451 cmd[1] = sx * ip->ftwidth; 452 cmd[2] = sy * ip->ftheight; 453 cmd[3] = (ip->cols - sx) * ip->ftwidth; 454 cmd[4] = ip->ftheight; 455 cmd[5] = (sx - count) * ip->ftwidth; 456 cmd[6] = sy * ip->ftheight; 457 gsp_out(ba,cmd,7); 458 ulowell_clear (ip, sy, ip->cols - count, 1, count); 459 } 460 } 461 462 #ifdef DEBUG_UL 463 void 464 gsp_dump(cmd,len) 465 u_int16_t *cmd; 466 int len; 467 { 468 printf("gsp"); 469 while (len-- > 0) 470 printf(" %lx",*cmd++); 471 printf("\n"); 472 } 473 #endif 474 #endif /* NGRFUL */ 475