1 1.40 riastrad /* $NetBSD: ite_cc.c,v 1.40 2018/09/03 16:29:22 riastradh Exp $ */ 2 1.9 chopps 3 1.22 chopps /* 4 1.22 chopps * Copyright (c) 1994 Christian E. Hopps 5 1.22 chopps * All rights reserved. 6 1.22 chopps * 7 1.22 chopps * Redistribution and use in source and binary forms, with or without 8 1.22 chopps * modification, are permitted provided that the following conditions 9 1.22 chopps * are met: 10 1.22 chopps * 1. Redistributions of source code must retain the above copyright 11 1.22 chopps * notice, this list of conditions and the following disclaimer. 12 1.22 chopps * 2. Redistributions in binary form must reproduce the above copyright 13 1.22 chopps * notice, this list of conditions and the following disclaimer in the 14 1.22 chopps * documentation and/or other materials provided with the distribution. 15 1.22 chopps * 3. All advertising materials mentioning features or use of this software 16 1.22 chopps * must display the following acknowledgement: 17 1.22 chopps * This product includes software developed by Christian E. Hopps. 18 1.22 chopps * 4. The name of the author may not be used to endorse or promote products 19 1.22 chopps * derived from this software without specific prior written permission 20 1.22 chopps * 21 1.22 chopps * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 1.22 chopps * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 1.22 chopps * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 1.22 chopps * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 1.22 chopps * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 1.22 chopps * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 1.22 chopps * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 1.22 chopps * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 1.22 chopps * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 1.22 chopps * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 1.22 chopps */ 32 1.26 is 33 1.26 is #include "opt_amigaccgrf.h" 34 1.31 aymeric 35 1.31 aymeric #include <sys/cdefs.h> 36 1.40 riastrad __KERNEL_RCSID(0, "$NetBSD: ite_cc.c,v 1.40 2018/09/03 16:29:22 riastradh Exp $"); 37 1.26 is 38 1.19 chopps #include "grfcc.h" 39 1.19 chopps #if NGRFCC > 0 40 1.19 chopps 41 1.10 chopps #include <sys/param.h> 42 1.10 chopps #include <sys/conf.h> 43 1.10 chopps #include <sys/proc.h> 44 1.16 chopps #include <sys/device.h> 45 1.10 chopps #include <sys/ioctl.h> 46 1.10 chopps #include <sys/tty.h> 47 1.10 chopps #include <sys/systm.h> 48 1.12 chopps #include <sys/queue.h> 49 1.16 chopps #include <sys/termios.h> 50 1.11 chopps #include <dev/cons.h> 51 1.16 chopps #include <machine/cpu.h> 52 1.10 chopps #include <amiga/dev/itevar.h> 53 1.10 chopps #include <amiga/dev/iteioctl.h> 54 1.10 chopps #include <amiga/amiga/cc.h> 55 1.16 chopps #include <amiga/amiga/device.h> 56 1.10 chopps #include <amiga/dev/grfabs_reg.h> 57 1.16 chopps #include <amiga/dev/grfioctl.h> 58 1.16 chopps #include <amiga/dev/grfvar.h> 59 1.16 chopps #include <amiga/dev/grf_ccreg.h> 60 1.10 chopps #include <amiga/dev/viewioctl.h> 61 1.10 chopps #include <amiga/dev/viewvar.h> 62 1.10 chopps 63 1.14 chopps #ifndef KFONT_CUSTOM 64 1.14 chopps #ifdef KFONT_8X11 65 1.16 chopps #define kernel_font_width kernel_font_width_8x11 66 1.16 chopps #define kernel_font_height kernel_font_height_8x11 67 1.16 chopps #define kernel_font_baseline kernel_font_baseline_8x11 68 1.16 chopps #define kernel_font_boldsmear kernel_font_boldsmear_8x11 69 1.16 chopps #define kernel_font_lo kernel_font_lo_8x11 70 1.16 chopps #define kernel_font_hi kernel_font_hi_8x11 71 1.16 chopps #define kernel_font kernel_font_8x11 72 1.16 chopps #define kernel_cursor kernel_cursor_8x11 73 1.14 chopps #else 74 1.16 chopps #define kernel_font_width kernel_font_width_8x8 75 1.16 chopps #define kernel_font_height kernel_font_height_8x8 76 1.16 chopps #define kernel_font_baseline kernel_font_baseline_8x8 77 1.16 chopps #define kernel_font_boldsmear kernel_font_boldsmear_8x8 78 1.16 chopps #define kernel_font_lo kernel_font_lo_8x8 79 1.16 chopps #define kernel_font_hi kernel_font_hi_8x8 80 1.16 chopps #define kernel_font kernel_font_8x8 81 1.16 chopps #define kernel_cursor kernel_cursor_8x8 82 1.14 chopps #endif 83 1.14 chopps #endif 84 1.3 mw 85 1.30 aymeric extern u_char kernel_font_width, kernel_font_height, kernel_font_baseline; 86 1.13 chopps extern short kernel_font_boldsmear; 87 1.13 chopps extern u_char kernel_font_lo, kernel_font_hi; 88 1.13 chopps extern u_char kernel_font[], kernel_cursor[]; 89 1.1 mw 90 1.27 is 91 1.29 is #if !defined(USE_C_BFOPS) && !defined(__m68k__) 92 1.27 is #define USE_C_BFOPS 93 1.29 is #endif 94 1.29 is 95 1.27 is #if !defined(USE_C_BFOPS) 96 1.34 kristerw #define BFEXT(v,p,o,w) __asm("bfextu %1@{%2:%3},%0" : "=d" (v) : \ 97 1.27 is "a"(p), "d"(o), "d"(w)) 98 1.34 kristerw #define BFINS(v,p,o,w) __asm("bfins %0,%1@{%2:%3}" : /* no output */ : \ 99 1.27 is "d"(v), "a"(p), "d"(o), "d"(w)) 100 1.34 kristerw #define BFCLR(p,o,w) __asm("bfclr %0@{%1:%2}" : /* no output */ : \ 101 1.27 is "a"(p), "d"(o), "d"(w)) 102 1.34 kristerw #define BFCHG(p,o,w) __asm("bfchg %0@{%1:%2}" : /* no output */ : \ 103 1.27 is "a"(p), "d"(o), "d"(w)) 104 1.34 kristerw #define BFSET(p,o,w) __asm("bfset %0@{%1:%2}" : /* no output */ : \ 105 1.27 is "a"(p), "d"(o), "d"(w)) 106 1.27 is #else 107 1.27 is #define BFEXT(v,p,o,w) do {v = ((u_int8_t *)(p))[(o)>>3];} while (0) 108 1.27 is #define BFINS(v,p,o,w) do {((u_int8_t *)(p))[(o)>>3] = (v);} while (0) 109 1.27 is #define BFCLR(p,o,w) BFINS(0x00,p,o,w) 110 1.27 is #define BFSET(p,o,w) BFINS(0xff,p,o,w) 111 1.27 is #define BFCHG(p,o,w) do {((u_int8_t *)(p))[(o)>>3] ^= 0xff;} while (0) 112 1.27 is #endif 113 1.27 is 114 1.3 mw /* 115 1.3 mw * This is what ip->priv points to; 116 1.3 mw * it contains local variables for custom-chip ites. 117 1.3 mw */ 118 1.13 chopps struct ite_priv { 119 1.13 chopps view_t *view; /* the view for this ite. */ 120 1.13 chopps u_char **row_ptr; /* array of pointers into the bitmap */ 121 1.13 chopps u_long row_bytes; 122 1.13 chopps u_long cursor_opt; 123 1.13 chopps u_int *column_offset; /* array of offsets for columns */ 124 1.13 chopps u_int row_offset; /* the row offset */ 125 1.13 chopps u_short width; /* the bitmap width */ 126 1.13 chopps u_short underline; /* where the underline goes */ 127 1.13 chopps u_short ft_x; /* the font width */ 128 1.13 chopps u_short ft_y; /* the font height */ 129 1.13 chopps u_char *font_cell[256]; /* the font pointer */ 130 1.13 chopps }; 131 1.13 chopps typedef struct ite_priv ipriv_t; 132 1.3 mw 133 1.30 aymeric void view_deinit(struct ite_softc *); 134 1.30 aymeric void view_init(struct ite_softc *); 135 1.3 mw 136 1.30 aymeric static void putc8(struct ite_softc *, int, int, int, int); 137 1.30 aymeric static void clear8(struct ite_softc *, int, int, int, int); 138 1.30 aymeric static void scroll8(struct ite_softc *, int, int, int, int); 139 1.30 aymeric static void cursor32(struct ite_softc *, int); 140 1.30 aymeric static void scrollbmap(bmap_t *, u_short, u_short, u_short, u_short, 141 1.30 aymeric short, short, u_char); 142 1.13 chopps 143 1.13 chopps /* patchable */ 144 1.13 chopps int ite_default_x = 0; /* def leftedge offset */ 145 1.13 chopps int ite_default_y = 0; /* def topedge offset */ 146 1.13 chopps int ite_default_width = 640; /* def width */ 147 1.13 chopps int ite_default_depth = 2; /* def depth */ 148 1.6 mw #if defined (GRF_NTSC) 149 1.13 chopps int ite_default_height = 400; /* def NTSC height */ 150 1.6 mw #elif defined (GRF_PAL) 151 1.13 chopps int ite_default_height = 512; /* def PAL height */ 152 1.6 mw #else 153 1.13 chopps int ite_default_height = 400; /* def NON-PAL/NTSC height (?) */ 154 1.6 mw #endif 155 1.3 mw 156 1.30 aymeric int ite_newsize(struct ite_softc *, struct itewinsize *); 157 1.30 aymeric static void putc_nm(ipriv_t *, u_char *, u_char *, u_int, u_int, 158 1.30 aymeric u_int, u_int); 159 1.30 aymeric static void putc_in(ipriv_t *, u_char *, u_char *, u_int, u_int, 160 1.30 aymeric u_int, u_int); 161 1.30 aymeric static void putc_ul(ipriv_t *, u_char *, u_char *, u_int, u_int, 162 1.30 aymeric u_int, u_int); 163 1.30 aymeric static void putc_ul_in(ipriv_t *, u_char *, u_char *, u_int, u_int, 164 1.30 aymeric u_int, u_int); 165 1.30 aymeric static void putc_bd(ipriv_t *, u_char *, u_char *, u_int, u_int, 166 1.30 aymeric u_int, u_int); 167 1.30 aymeric static void putc_bd_in(ipriv_t *, u_char *, u_char *, u_int, u_int, 168 1.30 aymeric u_int, u_int); 169 1.30 aymeric static void putc_bd_ul(ipriv_t *, u_char *, u_char *, u_int, u_int, 170 1.30 aymeric u_int, u_int); 171 1.30 aymeric static void putc_bd_ul_in(ipriv_t *, u_char *, u_char *, u_int, u_int, 172 1.30 aymeric u_int, u_int); 173 1.25 veego 174 1.16 chopps /* 175 1.16 chopps * called from grf_cc to return console priority 176 1.16 chopps */ 177 1.16 chopps int 178 1.30 aymeric grfcc_cnprobe(void) 179 1.16 chopps { 180 1.16 chopps return(CN_INTERNAL); 181 1.16 chopps } 182 1.16 chopps 183 1.16 chopps /* 184 1.30 aymeric * called from grf_cc to init ite portion of 185 1.16 chopps * grf_softc struct 186 1.16 chopps */ 187 1.16 chopps void 188 1.30 aymeric grfcc_iteinit(struct grf_softc *gp) 189 1.1 mw { 190 1.16 chopps gp->g_itecursor = cursor32; 191 1.16 chopps gp->g_iteputc = putc8; 192 1.16 chopps gp->g_iteclear = clear8; 193 1.16 chopps gp->g_itescroll = scroll8; 194 1.16 chopps gp->g_iteinit = view_init; 195 1.16 chopps gp->g_itedeinit = view_deinit; 196 1.1 mw } 197 1.1 mw 198 1.30 aymeric int 199 1.30 aymeric ite_newsize(struct ite_softc *ip, struct itewinsize *winsz) 200 1.1 mw { 201 1.13 chopps extern struct view_softc views[]; 202 1.33 gehenna extern const struct cdevsw view_cdevsw; 203 1.13 chopps struct view_size vs; 204 1.30 aymeric ipriv_t *cci = ip->priv; 205 1.25 veego u_long i; 206 1.13 chopps int error; 207 1.13 chopps 208 1.13 chopps vs.x = winsz->x; 209 1.13 chopps vs.y = winsz->y; 210 1.13 chopps vs.width = winsz->width; 211 1.13 chopps vs.height = winsz->height; 212 1.13 chopps vs.depth = winsz->depth; 213 1.33 gehenna /* XXX type of vs ? */ 214 1.38 christos error = (*view_cdevsw.d_ioctl)(0, VIOCSSIZE, (void *)&vs, -1, NULL); 215 1.13 chopps 216 1.13 chopps /* 217 1.13 chopps * Reinitialize our structs 218 1.13 chopps */ 219 1.30 aymeric cci->view = views[0].view; 220 1.13 chopps 221 1.30 aymeric ip->cols = cci->view->display.width / ip->ftwidth; 222 1.13 chopps ip->rows = cci->view->display.height / ip->ftheight; 223 1.13 chopps 224 1.13 chopps /* 225 1.13 chopps * save new values so that future opens use them 226 1.13 chopps * this may not be correct when we implement Virtual Consoles 227 1.13 chopps */ 228 1.13 chopps ite_default_height = cci->view->display.height; 229 1.13 chopps ite_default_width = cci->view->display.width; 230 1.13 chopps ite_default_x = cci->view->display.x; 231 1.13 chopps ite_default_y = cci->view->display.y; 232 1.13 chopps ite_default_depth = cci->view->bitmap->depth; 233 1.13 chopps 234 1.30 aymeric if (cci->row_ptr) 235 1.13 chopps free_chipmem(cci->row_ptr); 236 1.13 chopps if (cci->column_offset) 237 1.13 chopps free_chipmem(cci->column_offset); 238 1.3 mw 239 1.13 chopps cci->row_ptr = alloc_chipmem(sizeof(u_char *) * ip->rows); 240 1.13 chopps cci->column_offset = alloc_chipmem(sizeof(u_int) * ip->cols); 241 1.30 aymeric 242 1.13 chopps if (cci->row_ptr == NULL || cci->column_offset == NULL) 243 1.13 chopps panic("no chipmem for itecc data"); 244 1.30 aymeric 245 1.6 mw 246 1.13 chopps cci->width = cci->view->bitmap->bytes_per_row << 3; 247 1.13 chopps cci->underline = ip->ftbaseline + 1; 248 1.30 aymeric cci->row_offset = cci->view->bitmap->bytes_per_row 249 1.13 chopps + cci->view->bitmap->row_mod; 250 1.13 chopps cci->ft_x = ip->ftwidth; 251 1.13 chopps cci->ft_y = ip->ftheight; 252 1.30 aymeric 253 1.13 chopps cci->row_bytes = cci->row_offset * ip->ftheight; 254 1.6 mw 255 1.13 chopps cci->row_ptr[0] = VDISPLAY_LINE (cci->view, 0, 0); 256 1.30 aymeric for (i = 1; i < ip->rows; i++) 257 1.13 chopps cci->row_ptr[i] = cci->row_ptr[i-1] + cci->row_bytes; 258 1.13 chopps 259 1.13 chopps /* initialize the column offsets */ 260 1.13 chopps cci->column_offset[0] = 0; 261 1.30 aymeric for (i = 1; i < ip->cols; i++) 262 1.13 chopps cci->column_offset[i] = cci->column_offset[i - 1] + cci->ft_x; 263 1.13 chopps 264 1.13 chopps /* initialize the font cell pointers */ 265 1.13 chopps cci->font_cell[ip->font_lo] = ip->font; 266 1.13 chopps for (i=ip->font_lo+1; i<=ip->font_hi; i++) 267 1.13 chopps cci->font_cell[i] = cci->font_cell[i-1] + ip->ftheight; 268 1.30 aymeric 269 1.13 chopps return (error); 270 1.3 mw } 271 1.3 mw 272 1.11 chopps void 273 1.30 aymeric view_init(register struct ite_softc *ip) 274 1.3 mw { 275 1.13 chopps struct itewinsize wsz; 276 1.13 chopps ipriv_t *cci; 277 1.13 chopps 278 1.13 chopps cci = ip->priv; 279 1.6 mw 280 1.13 chopps if (cci) 281 1.13 chopps return; 282 1.6 mw 283 1.6 mw ip->font = kernel_font; 284 1.6 mw ip->font_lo = kernel_font_lo; 285 1.6 mw ip->font_hi = kernel_font_hi; 286 1.6 mw ip->ftwidth = kernel_font_width; 287 1.6 mw ip->ftheight = kernel_font_height; 288 1.6 mw ip->ftbaseline = kernel_font_baseline; 289 1.6 mw ip->ftboldsmear = kernel_font_boldsmear; 290 1.6 mw 291 1.6 mw /* Find the correct set of rendering routines for this font. */ 292 1.13 chopps if (ip->ftwidth > 8) 293 1.6 mw panic("kernel font size not supported"); 294 1.13 chopps cci = alloc_chipmem(sizeof (*cci)); 295 1.13 chopps if (cci == NULL) 296 1.13 chopps panic("no memory for console device."); 297 1.1 mw 298 1.6 mw ip->priv = cci; 299 1.6 mw cci->cursor_opt = 0; 300 1.6 mw cci->view = NULL; 301 1.6 mw cci->row_ptr = NULL; 302 1.6 mw cci->column_offset = NULL; 303 1.1 mw 304 1.13 chopps wsz.x = ite_default_x; 305 1.13 chopps wsz.y = ite_default_y; 306 1.13 chopps wsz.width = ite_default_width; 307 1.13 chopps wsz.height = ite_default_height; 308 1.13 chopps wsz.depth = ite_default_depth; 309 1.13 chopps 310 1.13 chopps ite_newsize (ip, &wsz); 311 1.16 chopps cc_mode(ip->grf, GM_GRFON, NULL, 0, 0); 312 1.6 mw } 313 1.6 mw 314 1.6 mw int 315 1.38 christos ite_grf_ioctl(struct ite_softc *ip, u_long cmd, void *addr, int flag, 316 1.37 christos struct lwp *l) 317 1.6 mw { 318 1.13 chopps struct winsize ws; 319 1.13 chopps struct itewinsize *is; 320 1.33 gehenna extern const struct cdevsw ite_cdevsw; 321 1.33 gehenna extern const struct cdevsw view_cdevsw; 322 1.13 chopps ipriv_t *cci; 323 1.13 chopps int error; 324 1.13 chopps 325 1.13 chopps cci = ip->priv; 326 1.13 chopps error = 0; 327 1.13 chopps 328 1.13 chopps switch (cmd) { 329 1.13 chopps case ITEIOCGWINSZ: 330 1.13 chopps is = (struct itewinsize *)addr; 331 1.13 chopps is->x = cci->view->display.x; 332 1.13 chopps is->y = cci->view->display.y; 333 1.13 chopps is->width = cci->view->display.width; 334 1.13 chopps is->height = cci->view->display.height; 335 1.13 chopps is->depth = cci->view->bitmap->depth; 336 1.13 chopps break; 337 1.13 chopps case ITEIOCSWINSZ: 338 1.13 chopps is = (struct itewinsize *)addr; 339 1.13 chopps 340 1.13 chopps if (ite_newsize(ip, is)) 341 1.13 chopps error = ENOMEM; 342 1.13 chopps else { 343 1.13 chopps ws.ws_row = ip->rows; 344 1.13 chopps ws.ws_col = ip->cols; 345 1.13 chopps ws.ws_xpixel = cci->view->display.width; 346 1.13 chopps ws.ws_ypixel = cci->view->display.height; 347 1.13 chopps ite_reset (ip); 348 1.13 chopps /* 349 1.30 aymeric * XXX tell tty about the change 350 1.30 aymeric * XXX this is messy, but works 351 1.13 chopps */ 352 1.33 gehenna (*ite_cdevsw.d_ioctl)(0, TIOCSWINSZ, 353 1.38 christos (void *)&ws, 0, l); 354 1.13 chopps } 355 1.13 chopps break; 356 1.13 chopps case ITEIOCDSPWIN: 357 1.16 chopps cc_mode(ip->grf, GM_GRFON, NULL, 0, 0); 358 1.13 chopps break; 359 1.13 chopps case ITEIOCREMWIN: 360 1.16 chopps cc_mode(ip->grf, GM_GRFOFF, NULL, 0, 0); 361 1.13 chopps break; 362 1.13 chopps case VIOCSCMAP: 363 1.13 chopps case VIOCGCMAP: 364 1.13 chopps /* 365 1.13 chopps * XXX needs to be fixed when multiple console implemented 366 1.13 chopps * XXX watchout for that -1 its not really the kernel talking 367 1.13 chopps * XXX these two commands don't use the proc pointer though 368 1.13 chopps */ 369 1.37 christos error = (*view_cdevsw.d_ioctl)(0, cmd, addr, -1, l); 370 1.13 chopps break; 371 1.13 chopps default: 372 1.32 atatat error = EPASSTHROUGH; 373 1.13 chopps break; 374 1.13 chopps } 375 1.13 chopps return (error); 376 1.1 mw } 377 1.1 mw 378 1.11 chopps void 379 1.30 aymeric view_deinit(struct ite_softc *ip) 380 1.1 mw { 381 1.13 chopps ip->flags &= ~ITE_INITED; 382 1.1 mw } 383 1.1 mw 384 1.6 mw /*** (M<8)-by-N routines ***/ 385 1.6 mw 386 1.3 mw static void 387 1.13 chopps cursor32(struct ite_softc *ip, int flag) 388 1.3 mw { 389 1.13 chopps int cend, ofs, h, cstart, dr_plane; 390 1.25 veego u_char *pl; 391 1.13 chopps ipriv_t *cci; 392 1.13 chopps bmap_t *bm; 393 1.13 chopps view_t *v; 394 1.13 chopps 395 1.13 chopps cci = ip->priv; 396 1.13 chopps v = cci->view; 397 1.13 chopps bm = v->bitmap; 398 1.13 chopps dr_plane = (bm->depth > 1 ? bm->depth-1 : 0); 399 1.13 chopps 400 1.13 chopps if (flag == END_CURSOROPT) 401 1.13 chopps cci->cursor_opt--; 402 1.13 chopps else if (flag == START_CURSOROPT) { 403 1.13 chopps if (!cci->cursor_opt) 404 1.13 chopps cursor32 (ip, ERASE_CURSOR); 405 1.13 chopps cci->cursor_opt++; 406 1.13 chopps return; /* if we are already opted. */ 407 1.6 mw } 408 1.30 aymeric 409 1.30 aymeric if (cci->cursor_opt) 410 1.13 chopps return; /* if we are still nested. */ 411 1.13 chopps /* else we draw the cursor. */ 412 1.13 chopps cstart = 0; 413 1.30 aymeric cend = ip->ftheight-1; 414 1.13 chopps pl = VDISPLAY_LINE(v, dr_plane, (ip->cursory * ip->ftheight + cstart)); 415 1.13 chopps ofs = (ip->cursorx * ip->ftwidth); 416 1.30 aymeric 417 1.13 chopps if (flag != DRAW_CURSOR && flag != END_CURSOROPT) { 418 1.13 chopps /* 419 1.13 chopps * erase the cursor 420 1.13 chopps */ 421 1.36 jmc int hh; 422 1.13 chopps 423 1.13 chopps if (dr_plane) { 424 1.36 jmc for (hh = cend; hh >= 0; hh--) { 425 1.27 is BFCLR(pl, ofs, ip->ftwidth); 426 1.13 chopps pl += cci->row_offset; 427 1.13 chopps } 428 1.13 chopps } else { 429 1.36 jmc for (hh = cend; hh >= 0; hh--) { 430 1.27 is BFCHG(pl, ofs, ip->ftwidth); 431 1.13 chopps pl += cci->row_offset; 432 1.13 chopps } 433 1.13 chopps } 434 1.6 mw } 435 1.30 aymeric 436 1.30 aymeric if (flag != DRAW_CURSOR && flag != MOVE_CURSOR && 437 1.13 chopps flag != END_CURSOROPT) 438 1.13 chopps return; 439 1.30 aymeric 440 1.30 aymeric /* 441 1.13 chopps * draw the cursor 442 1.13 chopps */ 443 1.13 chopps 444 1.40 riastrad ip->cursorx = uimin(ip->curx, ip->cols-1); 445 1.6 mw ip->cursory = ip->cury; 446 1.6 mw cstart = 0; 447 1.30 aymeric cend = ip->ftheight-1; 448 1.13 chopps pl = VDISPLAY_LINE(v, dr_plane, ip->cursory * ip->ftheight + cstart); 449 1.13 chopps ofs = ip->cursorx * ip->ftwidth; 450 1.13 chopps 451 1.6 mw if (dr_plane) { 452 1.13 chopps for (h = cend; h >= 0; h--) { 453 1.27 is BFSET(pl, ofs, ip->ftwidth); 454 1.13 chopps pl += cci->row_offset; 455 1.13 chopps } 456 1.6 mw } else { 457 1.13 chopps for (h = cend; h >= 0; h--) { 458 1.27 is BFCHG(pl, ofs, ip->ftwidth); 459 1.13 chopps pl += cci->row_offset; 460 1.13 chopps } 461 1.6 mw } 462 1.3 mw } 463 1.3 mw 464 1.6 mw 465 1.6 mw static inline 466 1.30 aymeric int expbits(int data) 467 1.3 mw { 468 1.13 chopps int i, nd = 0; 469 1.13 chopps 470 1.13 chopps if (data & 1) 471 1.13 chopps nd |= 0x02; 472 1.13 chopps for (i=1; i < 32; i++) { 473 1.13 chopps if (data & (1 << i)) 474 1.13 chopps nd |= 0x5 << (i-1); 475 1.6 mw } 476 1.13 chopps nd &= ~data; 477 1.13 chopps return(~nd); 478 1.6 mw } 479 1.3 mw 480 1.3 mw 481 1.6 mw /* Notes: optimizations given the kernel_font_(width|height) #define'd. 482 1.6 mw * the dbra loops could be elminated and unrolled using height, 483 1.6 mw * the :width in the bfxxx instruction could be made immediate instead 484 1.6 mw * of a data register as it now is. 485 1.6 mw * the underline could be added when the loop is unrolled 486 1.6 mw * 487 1.6 mw * It would look like hell but be very fast.*/ 488 1.30 aymeric 489 1.30 aymeric static void 490 1.30 aymeric putc_nm(register ipriv_t *cci, register u_char *p, register u_char *f, 491 1.30 aymeric register u_int co, register u_int ro, register u_int fw, 492 1.30 aymeric register u_int fh) 493 1.6 mw { 494 1.6 mw while (fh--) { 495 1.27 is BFINS(*f++, p, co, fw); 496 1.6 mw p += ro; 497 1.6 mw } 498 1.6 mw } 499 1.6 mw 500 1.30 aymeric static void 501 1.30 aymeric putc_in(register ipriv_t *cci, register u_char *p, register u_char *f, 502 1.30 aymeric register u_int co, register u_int ro, register u_int fw, 503 1.30 aymeric register u_int fh) 504 1.6 mw { 505 1.6 mw while (fh--) { 506 1.30 aymeric BFINS(~(*f++), p, co, fw); 507 1.6 mw p += ro; 508 1.6 mw } 509 1.6 mw } 510 1.6 mw 511 1.6 mw 512 1.30 aymeric static void 513 1.30 aymeric putc_ul(register ipriv_t *cci, register u_char *p, register u_char *f, 514 1.30 aymeric register u_int co, register u_int ro, register u_int fw, 515 1.30 aymeric register u_int fh) 516 1.6 mw { 517 1.6 mw int underline = cci->underline; 518 1.6 mw while (underline--) { 519 1.27 is BFINS(*f++,p,co,fw); 520 1.6 mw p += ro; 521 1.6 mw } 522 1.6 mw 523 1.27 is BFINS(expbits(*f++),p,co,fw); 524 1.6 mw p += ro; 525 1.6 mw 526 1.6 mw underline = fh - cci->underline - 1; 527 1.6 mw while (underline--) { 528 1.27 is BFINS(*f++,p,co,fw); 529 1.6 mw p += ro; 530 1.6 mw } 531 1.6 mw } 532 1.6 mw 533 1.6 mw 534 1.30 aymeric static void 535 1.30 aymeric putc_ul_in(register ipriv_t *cci, register u_char *p, register u_char *f, 536 1.30 aymeric register u_int co, register u_int ro, register u_int fw, 537 1.30 aymeric register u_int fh) 538 1.6 mw { 539 1.6 mw int underline = cci->underline; 540 1.6 mw while (underline--) { 541 1.27 is BFINS(~(*f++),p,co,fw); 542 1.6 mw p += ro; 543 1.6 mw } 544 1.6 mw 545 1.27 is BFINS(~expbits(*f++),p,co,fw); 546 1.6 mw p += ro; 547 1.6 mw 548 1.6 mw underline = fh - cci->underline - 1; 549 1.6 mw while (underline--) { 550 1.27 is BFINS(~(*f++),p,co,fw); 551 1.6 mw p += ro; 552 1.6 mw } 553 1.6 mw } 554 1.6 mw 555 1.6 mw /* bold */ 556 1.30 aymeric static void 557 1.30 aymeric putc_bd(register ipriv_t *cci, register u_char *p, register u_char *f, 558 1.30 aymeric register u_int co, register u_int ro, register u_int fw, 559 1.30 aymeric register u_int fh) 560 1.6 mw { 561 1.10 chopps u_short ch; 562 1.30 aymeric 563 1.6 mw while (fh--) { 564 1.6 mw ch = *f++; 565 1.29 is ch |= ch >> 1; 566 1.29 is BFINS(ch,p,co,fw); 567 1.6 mw p += ro; 568 1.3 mw } 569 1.6 mw } 570 1.3 mw 571 1.30 aymeric static void 572 1.30 aymeric putc_bd_in(register ipriv_t *cci, register u_char *p, register u_char *f, 573 1.30 aymeric register u_int co, register u_int ro, register u_int fw, 574 1.30 aymeric register u_int fh) 575 1.6 mw { 576 1.10 chopps u_short ch; 577 1.30 aymeric 578 1.6 mw while (fh--) { 579 1.6 mw ch = *f++; 580 1.29 is ch |= ch >> 1; 581 1.29 is BFINS(~ch,p,co,fw); 582 1.6 mw p += ro; 583 1.3 mw } 584 1.6 mw } 585 1.6 mw 586 1.3 mw 587 1.30 aymeric static void 588 1.30 aymeric putc_bd_ul(register ipriv_t *cci, register u_char *p, register u_char *f, 589 1.30 aymeric register u_int co, register u_int ro, register u_int fw, 590 1.30 aymeric register u_int fh) 591 1.6 mw { 592 1.6 mw int underline = cci->underline; 593 1.10 chopps u_short ch; 594 1.6 mw 595 1.6 mw while (underline--) { 596 1.6 mw ch = *f++; 597 1.29 is ch |= ch >> 1; 598 1.29 is BFINS(ch,p,co,fw); 599 1.6 mw p += ro; 600 1.6 mw } 601 1.6 mw 602 1.6 mw ch = *f++; 603 1.29 is ch |= ch >> 1; 604 1.29 is BFINS(expbits(ch),p,co,fw); 605 1.6 mw p += ro; 606 1.6 mw 607 1.6 mw underline = fh - cci->underline - 1; 608 1.6 mw while (underline--) { 609 1.6 mw ch = *f++; 610 1.29 is ch |= ch >> 1; 611 1.29 is BFINS(ch,p,co,fw); 612 1.6 mw p += ro; 613 1.3 mw } 614 1.3 mw } 615 1.3 mw 616 1.3 mw 617 1.30 aymeric static void 618 1.30 aymeric putc_bd_ul_in(register ipriv_t *cci, register u_char *p, register u_char *f, 619 1.30 aymeric register u_int co, register u_int ro, register u_int fw, 620 1.30 aymeric register u_int fh) 621 1.1 mw { 622 1.6 mw int underline = cci->underline; 623 1.10 chopps u_short ch; 624 1.30 aymeric 625 1.6 mw while (underline--) { 626 1.6 mw ch = *f++; 627 1.29 is ch |= ch >> 1; 628 1.29 is BFINS(~ch,p,co,fw); 629 1.6 mw p += ro; 630 1.6 mw } 631 1.6 mw 632 1.6 mw ch = *f++; 633 1.29 is ch |= ch >> 1; 634 1.29 is BFINS(~expbits(ch),p,co,fw); 635 1.6 mw p += ro; 636 1.6 mw 637 1.6 mw underline = fh - cci->underline - 1; 638 1.6 mw while (underline--) { 639 1.6 mw ch = *f++; 640 1.29 is ch |= ch >> 1; 641 1.29 is BFINS(~ch,p,co,fw); 642 1.6 mw p += ro; 643 1.6 mw } 644 1.6 mw } 645 1.1 mw 646 1.3 mw 647 1.30 aymeric typedef void cc_putc_func(ipriv_t *, u_char *, u_char *, u_int, u_int, 648 1.30 aymeric u_int, u_int); 649 1.6 mw 650 1.6 mw cc_putc_func *put_func[ATTR_ALL+1] = { 651 1.6 mw putc_nm, 652 1.6 mw putc_in, 653 1.6 mw putc_ul, 654 1.6 mw putc_ul_in, 655 1.6 mw putc_bd, 656 1.6 mw putc_bd_in, 657 1.6 mw putc_bd_ul, 658 1.6 mw putc_bd_ul_in, 659 1.6 mw /* no support for blink */ 660 1.6 mw putc_nm, 661 1.6 mw putc_in, 662 1.6 mw putc_ul, 663 1.6 mw putc_ul_in, 664 1.6 mw putc_bd, 665 1.6 mw putc_bd_in, 666 1.6 mw putc_bd_ul, 667 1.6 mw putc_bd_ul_in 668 1.6 mw }; 669 1.3 mw 670 1.3 mw 671 1.6 mw /* FIX: shouldn't this advance the cursor even if the character to 672 1.6 mw be output is not available in the font? -ch */ 673 1.1 mw 674 1.3 mw static void 675 1.30 aymeric putc8(struct ite_softc *ip, int c, int dy, int dx, int mode) 676 1.1 mw { 677 1.23 chopps ipriv_t *cci = (ipriv_t *) ip->priv; 678 1.23 chopps /* 679 1.23 chopps * if character is higher than font has glyphs, substitute 680 1.23 chopps * highest glyph. 681 1.23 chopps */ 682 1.23 chopps c = (u_char)c; 683 1.23 chopps if (c < ip->font_lo || c > ip->font_hi) 684 1.23 chopps c = ip->font_hi; 685 1.23 chopps put_func[mode](cci, cci->row_ptr[dy], cci->font_cell[c], 686 1.23 chopps cci->column_offset[dx], cci->row_offset, cci->ft_x, cci->ft_y); 687 1.1 mw } 688 1.1 mw 689 1.3 mw static void 690 1.13 chopps clear8(struct ite_softc *ip, int sy, int sx, int h, int w) 691 1.1 mw { 692 1.6 mw ipriv_t *cci = (ipriv_t *) ip->priv; 693 1.6 mw bmap_t *bm = cci->view->bitmap; 694 1.1 mw 695 1.3 mw if ((sx == 0) && (w == ip->cols)) 696 1.3 mw { 697 1.3 mw /* common case: clearing whole lines */ 698 1.3 mw while (h--) 699 1.3 mw { 700 1.6 mw int i; 701 1.30 aymeric u_char *ptr = cci->row_ptr[sy]; 702 1.6 mw for (i=0; i < ip->ftheight; i++) { 703 1.39 cegger memset(ptr, 0, bm->bytes_per_row); 704 1.6 mw ptr += bm->bytes_per_row + bm->row_mod; /* don't get any smart 705 1.35 wiz ideas, because this is for 706 1.6 mw interleaved bitmaps */ 707 1.6 mw } 708 1.3 mw sy++; 709 1.3 mw } 710 1.3 mw } 711 1.3 mw else 712 1.3 mw { 713 1.3 mw /* clearing only part of a line */ 714 1.3 mw /* XXX could be optimized MUCH better, but is it worth the trouble? */ 715 1.3 mw while (h--) 716 1.3 mw { 717 1.6 mw u_char *pl = cci->row_ptr[sy]; 718 1.3 mw int ofs = sx * ip->ftwidth; 719 1.3 mw int i, j; 720 1.3 mw for (i = w-1; i >= 0; i--) 721 1.3 mw { 722 1.3 mw u_char *ppl = pl; 723 1.3 mw for (j = ip->ftheight-1; j >= 0; j--) 724 1.3 mw { 725 1.27 is BFCLR(ppl, ofs, ip->ftwidth); 726 1.30 aymeric ppl += bm->row_mod + bm->bytes_per_row; 727 1.3 mw } 728 1.3 mw ofs += ip->ftwidth; 729 1.3 mw } 730 1.3 mw sy++; 731 1.3 mw } 732 1.3 mw } 733 1.1 mw } 734 1.1 mw 735 1.3 mw /* Note: sx is only relevant for SCROLL_LEFT or SCROLL_RIGHT. */ 736 1.3 mw static void 737 1.30 aymeric scroll8(register struct ite_softc *ip, register int sy, int sx, int count, 738 1.30 aymeric int dir) 739 1.1 mw { 740 1.6 mw bmap_t *bm = ((ipriv_t *)ip->priv)->view->bitmap; 741 1.6 mw u_char *pl = ((ipriv_t *)ip->priv)->row_ptr[sy]; 742 1.6 mw 743 1.30 aymeric if (dir == SCROLL_UP) 744 1.1 mw { 745 1.3 mw int dy = sy - count; 746 1.3 mw 747 1.6 mw /*FIX: add scroll bitmap call */ 748 1.13 chopps cursor32(ip, ERASE_CURSOR); 749 1.13 chopps scrollbmap (bm, 0, dy*ip->ftheight, 750 1.6 mw bm->bytes_per_row >> 3, (ip->bottom_margin-dy+1)*ip->ftheight, 751 1.6 mw 0, -(count*ip->ftheight), 0x1); 752 1.6 mw /* if (ip->cursory <= bot || ip->cursory >= dy) { 753 1.6 mw ip->cursory -= count; 754 1.6 mw } */ 755 1.1 mw } 756 1.30 aymeric else if (dir == SCROLL_DOWN) 757 1.1 mw { 758 1.3 mw 759 1.6 mw /* FIX: add scroll bitmap call */ 760 1.13 chopps cursor32(ip, ERASE_CURSOR); 761 1.13 chopps scrollbmap (bm, 0, sy*ip->ftheight, 762 1.6 mw bm->bytes_per_row >> 3, (ip->bottom_margin-sy+1)*ip->ftheight, 763 1.6 mw 0, count*ip->ftheight, 0x1); 764 1.6 mw /* if (ip->cursory <= bot || ip->cursory >= sy) { 765 1.6 mw ip->cursory += count; 766 1.6 mw } */ 767 1.1 mw } 768 1.30 aymeric else if (dir == SCROLL_RIGHT) 769 1.1 mw { 770 1.3 mw int sofs = (ip->cols - count) * ip->ftwidth; 771 1.3 mw int dofs = (ip->cols) * ip->ftwidth; 772 1.3 mw int i, j; 773 1.3 mw 774 1.13 chopps cursor32(ip, ERASE_CURSOR); 775 1.3 mw for (j = ip->ftheight-1; j >= 0; j--) 776 1.3 mw { 777 1.3 mw int sofs2 = sofs, dofs2 = dofs; 778 1.3 mw for (i = (ip->cols - (sx + count))-1; i >= 0; i--) 779 1.3 mw { 780 1.3 mw int t; 781 1.3 mw sofs2 -= ip->ftwidth; 782 1.3 mw dofs2 -= ip->ftwidth; 783 1.27 is BFEXT(t, pl, sofs2, ip->ftwidth); 784 1.27 is BFINS(t, pl, dofs2, ip->ftwidth); 785 1.3 mw } 786 1.30 aymeric pl += bm->row_mod + bm->bytes_per_row; 787 1.3 mw } 788 1.1 mw } 789 1.3 mw else /* SCROLL_LEFT */ 790 1.1 mw { 791 1.3 mw int sofs = (sx) * ip->ftwidth; 792 1.3 mw int dofs = (sx - count) * ip->ftwidth; 793 1.3 mw int i, j; 794 1.3 mw 795 1.13 chopps cursor32(ip, ERASE_CURSOR); 796 1.3 mw for (j = ip->ftheight-1; j >= 0; j--) 797 1.3 mw { 798 1.3 mw int sofs2 = sofs, dofs2 = dofs; 799 1.3 mw for (i = (ip->cols - sx)-1; i >= 0; i--) 800 1.3 mw { 801 1.3 mw int t; 802 1.27 is BFEXT(t, pl, sofs2, ip->ftwidth); 803 1.27 is BFINS(t, pl, dofs2, ip->ftwidth); 804 1.3 mw sofs2 += ip->ftwidth; 805 1.3 mw dofs2 += ip->ftwidth; 806 1.3 mw } 807 1.30 aymeric pl += bm->row_mod + bm->bytes_per_row; 808 1.3 mw } 809 1.30 aymeric } 810 1.1 mw } 811 1.1 mw 812 1.30 aymeric void 813 1.30 aymeric scrollbmap(bmap_t *bm, u_short x, u_short y, u_short width, u_short height, 814 1.30 aymeric short dx, short dy, u_char mask) 815 1.6 mw { 816 1.30 aymeric u_short depth = bm->depth; 817 1.10 chopps u_short lwpr = bm->bytes_per_row >> 2; 818 1.6 mw if (dx) { 819 1.6 mw /* FIX: */ panic ("delta x not supported in scroll bitmap yet."); 820 1.30 aymeric } 821 1.6 mw if (bm->flags & BMF_INTERLEAVED) { 822 1.6 mw height *= depth; 823 1.6 mw depth = 1; 824 1.6 mw } 825 1.6 mw if (dy == 0) { 826 1.6 mw return; 827 1.6 mw } 828 1.6 mw if (dy > 0) { 829 1.6 mw int i; 830 1.6 mw for (i=0; i < depth && mask; i++, mask >>= 1) { 831 1.6 mw if (0x1 & mask) { 832 1.6 mw u_long *pl = (u_long *)bm->plane[i]; 833 1.6 mw u_long *src_y = pl + (lwpr*y); 834 1.6 mw u_long *dest_y = pl + (lwpr*(y+dy)); 835 1.6 mw u_long count = lwpr*(height-dy); 836 1.6 mw u_long *clr_y = src_y; 837 1.6 mw u_long clr_count = dest_y - src_y; 838 1.6 mw u_long bc, cbc; 839 1.30 aymeric 840 1.6 mw src_y += count - 1; 841 1.6 mw dest_y += count - 1; 842 1.6 mw 843 1.6 mw bc = count >> 4; 844 1.6 mw count &= 0xf; 845 1.30 aymeric 846 1.6 mw while (bc--) { 847 1.6 mw *dest_y-- = *src_y--; *dest_y-- = *src_y--; 848 1.6 mw *dest_y-- = *src_y--; *dest_y-- = *src_y--; 849 1.6 mw *dest_y-- = *src_y--; *dest_y-- = *src_y--; 850 1.6 mw *dest_y-- = *src_y--; *dest_y-- = *src_y--; 851 1.6 mw *dest_y-- = *src_y--; *dest_y-- = *src_y--; 852 1.6 mw *dest_y-- = *src_y--; *dest_y-- = *src_y--; 853 1.6 mw *dest_y-- = *src_y--; *dest_y-- = *src_y--; 854 1.6 mw *dest_y-- = *src_y--; *dest_y-- = *src_y--; 855 1.6 mw } 856 1.6 mw while (count--) { 857 1.6 mw *dest_y-- = *src_y--; 858 1.6 mw } 859 1.6 mw 860 1.6 mw cbc = clr_count >> 4; 861 1.6 mw clr_count &= 0xf; 862 1.6 mw 863 1.6 mw while (cbc--) { 864 1.6 mw *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; 865 1.6 mw *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; 866 1.6 mw *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; 867 1.6 mw *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; 868 1.6 mw } 869 1.6 mw while (clr_count--) { 870 1.6 mw *clr_y++ = 0; 871 1.6 mw } 872 1.6 mw } 873 1.6 mw } 874 1.6 mw } else if (dy < 0) { 875 1.6 mw int i; 876 1.6 mw for (i=0; i < depth && mask; i++, mask >>= 1) { 877 1.6 mw if (0x1 & mask) { 878 1.6 mw u_long *pl = (u_long *)bm->plane[i]; 879 1.6 mw u_long *src_y = pl + (lwpr*(y-dy)); 880 1.30 aymeric u_long *dest_y = pl + (lwpr*y); 881 1.6 mw long count = lwpr*(height + dy); 882 1.6 mw u_long *clr_y = dest_y + count; 883 1.6 mw u_long clr_count = src_y - dest_y; 884 1.6 mw u_long bc, cbc; 885 1.6 mw 886 1.6 mw bc = count >> 4; 887 1.6 mw count &= 0xf; 888 1.30 aymeric 889 1.6 mw while (bc--) { 890 1.6 mw *dest_y++ = *src_y++; *dest_y++ = *src_y++; 891 1.6 mw *dest_y++ = *src_y++; *dest_y++ = *src_y++; 892 1.6 mw *dest_y++ = *src_y++; *dest_y++ = *src_y++; 893 1.6 mw *dest_y++ = *src_y++; *dest_y++ = *src_y++; 894 1.6 mw *dest_y++ = *src_y++; *dest_y++ = *src_y++; 895 1.6 mw *dest_y++ = *src_y++; *dest_y++ = *src_y++; 896 1.6 mw *dest_y++ = *src_y++; *dest_y++ = *src_y++; 897 1.6 mw *dest_y++ = *src_y++; *dest_y++ = *src_y++; 898 1.6 mw } 899 1.6 mw while (count--) { 900 1.6 mw *dest_y++ = *src_y++; 901 1.6 mw } 902 1.6 mw 903 1.6 mw cbc = clr_count >> 4; 904 1.6 mw clr_count &= 0xf; 905 1.6 mw 906 1.6 mw while (cbc--) { 907 1.6 mw *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; 908 1.6 mw *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; 909 1.6 mw *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; 910 1.6 mw *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; 911 1.6 mw } 912 1.6 mw while (clr_count--) { 913 1.6 mw *clr_y++ = 0; 914 1.6 mw } 915 1.6 mw } 916 1.6 mw } 917 1.6 mw } 918 1.6 mw } 919 1.19 chopps 920 1.19 chopps #endif /* NGRFCC */ 921