1 1.40 jandberg /* $NetBSD: amidisplaycc.c,v 1.40 2022/07/06 14:34:13 jandberg Exp $ */ 2 1.3 aymeric 3 1.1 is /*- 4 1.1 is * Copyright (c) 2000 Jukka Andberg. 5 1.1 is * All rights reserved. 6 1.1 is * 7 1.1 is * Redistribution and use in source and binary forms, with or without 8 1.1 is * modification, are permitted provided that the following conditions 9 1.1 is * are met: 10 1.1 is * 1. Redistributions of source code must retain the above copyright 11 1.1 is * notice, this list of conditions and the following disclaimer. 12 1.1 is * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 is * notice, this list of conditions and the following disclaimer in the 14 1.1 is * documentation and/or other materials provided with the distribution. 15 1.1 is * 3. The name of the author may not be used to endorse or promote products 16 1.1 is * derived from this software without specific prior written permission 17 1.1 is * 18 1.1 is * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 1.1 is * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 1.1 is * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 1.1 is * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 1.1 is * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 1.1 is * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 1.1 is * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 1.1 is * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 1.1 is * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 1.1 is * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 1.1 is */ 29 1.4 aymeric 30 1.4 aymeric #include <sys/cdefs.h> 31 1.40 jandberg __KERNEL_RCSID(0, "$NetBSD: amidisplaycc.c,v 1.40 2022/07/06 14:34:13 jandberg Exp $"); 32 1.1 is 33 1.1 is /* 34 1.1 is * wscons interface to amiga custom chips. Contains the necessary functions 35 1.3 aymeric * to render text on bitmapped screens. Uses the functions defined in 36 1.1 is * grfabs_reg.h for display creation/destruction and low level setup. 37 1.2 jandberg * 38 1.30 jandberg * For each virtual terminal a new screen (a grfabs view) is allocated. 39 1.30 jandberg * Also one more view is allocated for the mapped screen on demand. 40 1.1 is */ 41 1.1 is 42 1.1 is #include "amidisplaycc.h" 43 1.1 is #include "grfcc.h" 44 1.1 is #include "view.h" 45 1.2 jandberg #include "opt_amigaccgrf.h" 46 1.17 jandberg #include "kbd.h" 47 1.1 is 48 1.1 is #if NAMIDISPLAYCC>0 49 1.1 is 50 1.1 is #include <sys/param.h> 51 1.1 is #include <sys/types.h> 52 1.1 is #include <sys/device.h> 53 1.1 is #include <sys/malloc.h> 54 1.1 is #include <sys/systm.h> 55 1.1 is 56 1.1 is #include <sys/conf.h> 57 1.1 is 58 1.1 is #include <amiga/dev/grfabs_reg.h> 59 1.17 jandberg #include <amiga/dev/kbdvar.h> 60 1.1 is #include <amiga/dev/viewioctl.h> 61 1.1 is #include <amiga/amiga/device.h> 62 1.1 is #include <dev/wscons/wsconsio.h> 63 1.1 is #include <dev/wscons/wscons_raster.h> 64 1.1 is #include <dev/wscons/wsdisplayvar.h> 65 1.1 is #include <dev/cons.h> 66 1.2 jandberg #include <dev/wsfont/wsfont.h> 67 1.2 jandberg 68 1.30 jandberg /* These can be lowered if you are sure you don't need that much colors. */ 69 1.2 jandberg #define MAXDEPTH 8 70 1.2 jandberg #define MAXROWS 128 71 1.1 is 72 1.2 jandberg #define ADJUSTCOLORS 73 1.2 jandberg 74 1.2 jandberg #define MAXCOLORS (1<<MAXDEPTH) 75 1.2 jandberg 76 1.2 jandberg struct amidisplaycc_screen; 77 1.1 is struct amidisplaycc_softc 78 1.1 is { 79 1.2 jandberg struct amidisplaycc_screen * currentscreen; 80 1.2 jandberg 81 1.2 jandberg /* display turned on? */ 82 1.2 jandberg int ison; 83 1.2 jandberg 84 1.2 jandberg /* stuff relating to the mapped screen */ 85 1.2 jandberg view_t * gfxview; 86 1.2 jandberg int gfxwidth; 87 1.2 jandberg int gfxheight; 88 1.2 jandberg int gfxdepth; 89 1.2 jandberg int gfxon; 90 1.1 is }; 91 1.1 is 92 1.1 is 93 1.3 aymeric /* 94 1.1 is * Configuration stuff. 95 1.1 is */ 96 1.1 is 97 1.26 chs static int amidisplaycc_match(device_t, cfdata_t, void *); 98 1.26 chs static void amidisplaycc_attach(device_t, device_t, void *); 99 1.1 is 100 1.26 chs CFATTACH_DECL_NEW(amidisplaycc, sizeof(struct amidisplaycc_softc), 101 1.10 thorpej amidisplaycc_match, amidisplaycc_attach, NULL, NULL); 102 1.1 is 103 1.16 chs static int amidisplaycc_attached; 104 1.16 chs 105 1.1 is cons_decl(amidisplaycc_); 106 1.1 is 107 1.1 is /* end of configuration stuff */ 108 1.1 is 109 1.2 jandberg /* private utility functions */ 110 1.2 jandberg 111 1.3 aymeric static int amidisplaycc_setvideo(struct amidisplaycc_softc *, int); 112 1.2 jandberg 113 1.3 aymeric static int amidisplaycc_setemulcmap(struct amidisplaycc_screen *, 114 1.3 aymeric struct wsdisplay_cmap *); 115 1.2 jandberg 116 1.3 aymeric static int amidisplaycc_cmapioctl(view_t *, u_long, struct wsdisplay_cmap *); 117 1.3 aymeric static int amidisplaycc_setcmap(view_t *, struct wsdisplay_cmap *); 118 1.3 aymeric static int amidisplaycc_getcmap(view_t *, struct wsdisplay_cmap *); 119 1.33 jandberg static int amidisplaycc_setgfxview(struct amidisplaycc_softc *, int); 120 1.33 jandberg static void amidisplaycc_initgfxview(struct amidisplaycc_softc *); 121 1.33 jandberg static int amidisplaycc_getfbinfo(struct amidisplaycc_softc *, struct wsdisplayio_fbinfo *); 122 1.3 aymeric 123 1.15 jandberg static int amidisplaycc_setfont(struct amidisplaycc_screen *, const char *); 124 1.15 jandberg static const struct wsdisplay_font * amidisplaycc_getbuiltinfont(void); 125 1.39 jandberg static void amidisplaycc_cursor_undraw(struct amidisplaycc_screen *); 126 1.39 jandberg static void amidisplaycc_cursor_draw(struct amidisplaycc_screen *); 127 1.39 jandberg static void amidisplaycc_cursor_xor(struct amidisplaycc_screen *, int, int); 128 1.1 is 129 1.2 jandberg static void dprintf(const char *fmt, ...); 130 1.1 is 131 1.2 jandberg /* end of private utility functions */ 132 1.1 is 133 1.1 is /* emulops for wscons */ 134 1.3 aymeric void amidisplaycc_cursor(void *, int, int, int); 135 1.3 aymeric int amidisplaycc_mapchar(void *, int, unsigned int *); 136 1.3 aymeric void amidisplaycc_putchar(void *, int, int, u_int, long); 137 1.3 aymeric void amidisplaycc_copycols(void *, int, int, int, int); 138 1.3 aymeric void amidisplaycc_erasecols(void *, int, int, int, long); 139 1.3 aymeric void amidisplaycc_copyrows(void *, int, int, int); 140 1.3 aymeric void amidisplaycc_eraserows(void *, int, int, long); 141 1.7 junyoung int amidisplaycc_allocattr(void *, int, int, int, long *); 142 1.1 is /* end of emulops for wscons */ 143 1.1 is 144 1.2 jandberg 145 1.1 is /* accessops for wscons */ 146 1.20 christos int amidisplaycc_ioctl(void *, void *, u_long, void *, int, struct lwp *); 147 1.19 jmmv paddr_t amidisplaycc_mmap(void *, void *, off_t, int); 148 1.3 aymeric int amidisplaycc_alloc_screen(void *, const struct wsscreen_descr *, void **, 149 1.3 aymeric int *, int *, long *); 150 1.3 aymeric void amidisplaycc_free_screen( void *, void *); 151 1.3 aymeric int amidisplaycc_show_screen(void *, void *, int, void (*)(void *, int, int), 152 1.3 aymeric void *); 153 1.3 aymeric int amidisplaycc_load_font(void *, void *, struct wsdisplay_font *); 154 1.3 aymeric void amidisplaycc_pollc(void *, int); 155 1.1 is /* end of accessops for wscons */ 156 1.1 is 157 1.3 aymeric /* 158 1.1 is * These structures are passed to wscons, and they contain the 159 1.1 is * display-specific callback functions. 160 1.1 is */ 161 1.1 is 162 1.1 is const struct wsdisplay_accessops amidisplaycc_accessops = { 163 1.1 is amidisplaycc_ioctl, 164 1.1 is amidisplaycc_mmap, 165 1.1 is amidisplaycc_alloc_screen, 166 1.1 is amidisplaycc_free_screen, 167 1.1 is amidisplaycc_show_screen, 168 1.2 jandberg amidisplaycc_load_font, 169 1.2 jandberg amidisplaycc_pollc 170 1.1 is }; 171 1.1 is 172 1.1 is const struct wsdisplay_emulops amidisplaycc_emulops = { 173 1.1 is amidisplaycc_cursor, 174 1.1 is amidisplaycc_mapchar, 175 1.1 is amidisplaycc_putchar, 176 1.1 is amidisplaycc_copycols, 177 1.1 is amidisplaycc_erasecols, 178 1.1 is amidisplaycc_copyrows, 179 1.1 is amidisplaycc_eraserows, 180 1.7 junyoung amidisplaycc_allocattr 181 1.1 is }; 182 1.1 is 183 1.30 jandberg /* Add some of our own data to the wsscreen_descr */ 184 1.1 is struct amidisplaycc_screen_descr { 185 1.2 jandberg struct wsscreen_descr wsdescr; 186 1.2 jandberg int depth; 187 1.1 is }; 188 1.1 is 189 1.2 jandberg #define ADCC_SCREEN(name, width, height, depth, fontwidth, fontheight) \ 190 1.2 jandberg /* CONSTCOND */ \ 191 1.2 jandberg {{ \ 192 1.2 jandberg name, \ 193 1.2 jandberg width / fontwidth, \ 194 1.2 jandberg height / fontheight, \ 195 1.2 jandberg &amidisplaycc_emulops, fontwidth, fontheight, \ 196 1.2 jandberg (depth > 1 ? WSSCREEN_WSCOLORS : 0) | WSSCREEN_REVERSE | \ 197 1.2 jandberg WSSCREEN_HILIT | WSSCREEN_UNDERLINE }, \ 198 1.2 jandberg depth } 199 1.1 is 200 1.14 jandberg /* 201 1.30 jandberg * List of supported screen types. 202 1.14 jandberg * 203 1.30 jandberg * The first item in list is used for the console screen. 204 1.30 jandberg * A suitable screen size is guessed for it by looking 205 1.14 jandberg * at the GRF_* options. 206 1.14 jandberg */ 207 1.1 is struct amidisplaycc_screen_descr amidisplaycc_screentab[] = { 208 1.2 jandberg /* name, width, height, depth, fontwidth==8, fontheight */ 209 1.14 jandberg 210 1.14 jandberg #if defined(GRF_PAL) && !defined(GRF_NTSC) 211 1.14 jandberg ADCC_SCREEN("default", 640, 512, 3, 8, 8), 212 1.14 jandberg #else 213 1.14 jandberg ADCC_SCREEN("default", 640, 400, 3, 8, 8), 214 1.14 jandberg #endif 215 1.2 jandberg ADCC_SCREEN("80x50", 640, 400, 3, 8, 8), 216 1.2 jandberg ADCC_SCREEN("80x40", 640, 400, 3, 8, 10), 217 1.2 jandberg ADCC_SCREEN("80x25", 640, 400, 3, 8, 16), 218 1.14 jandberg ADCC_SCREEN("80x24", 640, 192, 3, 8, 8), 219 1.14 jandberg 220 1.14 jandberg ADCC_SCREEN("80x64", 640, 512, 3, 8, 8), 221 1.14 jandberg ADCC_SCREEN("80x51", 640, 510, 3, 8, 10), 222 1.14 jandberg ADCC_SCREEN("80x32", 640, 512, 3, 8, 16), 223 1.14 jandberg ADCC_SCREEN("80x31", 640, 248, 3, 8, 8), 224 1.2 jandberg 225 1.2 jandberg ADCC_SCREEN("640x400x1", 640, 400, 1, 8, 8), 226 1.2 jandberg ADCC_SCREEN("640x400x2", 640, 400, 2, 8, 8), 227 1.2 jandberg ADCC_SCREEN("640x400x3", 640, 400, 3, 8, 8), 228 1.2 jandberg 229 1.2 jandberg ADCC_SCREEN("640x200x1", 640, 200, 1, 8, 8), 230 1.14 jandberg ADCC_SCREEN("640x200x2", 640, 200, 2, 8, 8), 231 1.14 jandberg ADCC_SCREEN("640x200x3", 640, 200, 3, 8, 8), 232 1.1 is }; 233 1.1 is 234 1.1 is #define ADCC_SCREENPTR(index) &amidisplaycc_screentab[index].wsdescr 235 1.1 is const struct wsscreen_descr *amidisplaycc_screens[] = { 236 1.1 is ADCC_SCREENPTR(0), 237 1.1 is ADCC_SCREENPTR(1), 238 1.1 is ADCC_SCREENPTR(2), 239 1.1 is ADCC_SCREENPTR(3), 240 1.1 is ADCC_SCREENPTR(4), 241 1.1 is ADCC_SCREENPTR(5), 242 1.1 is ADCC_SCREENPTR(6), 243 1.1 is ADCC_SCREENPTR(7), 244 1.1 is ADCC_SCREENPTR(8), 245 1.1 is ADCC_SCREENPTR(9), 246 1.14 jandberg ADCC_SCREENPTR(10), 247 1.14 jandberg ADCC_SCREENPTR(11), 248 1.14 jandberg ADCC_SCREENPTR(12), 249 1.14 jandberg ADCC_SCREENPTR(13), 250 1.14 jandberg ADCC_SCREENPTR(14), 251 1.1 is }; 252 1.1 is 253 1.2 jandberg #define NELEMS(arr) (sizeof(arr)/sizeof((arr)[0])) 254 1.2 jandberg 255 1.1 is /* 256 1.30 jandberg * This structure is passed to wscons. It contains pointers 257 1.1 is * to the available display modes. 258 1.1 is */ 259 1.1 is 260 1.1 is const struct wsscreen_list amidisplaycc_screenlist = { 261 1.1 is sizeof(amidisplaycc_screens)/sizeof(amidisplaycc_screens[0]), 262 1.1 is amidisplaycc_screens 263 1.1 is }; 264 1.1 is 265 1.1 is /* 266 1.1 is * Our own screen structure. One will be created for each screen. 267 1.1 is */ 268 1.1 is 269 1.1 is struct amidisplaycc_screen 270 1.1 is { 271 1.2 jandberg struct amidisplaycc_softc *device; 272 1.2 jandberg 273 1.2 jandberg int isconsole; 274 1.2 jandberg int isvisible; 275 1.2 jandberg view_t * view; 276 1.1 is 277 1.2 jandberg int ncols; 278 1.2 jandberg int nrows; 279 1.2 jandberg 280 1.2 jandberg int cursorrow; 281 1.2 jandberg int cursorcol; 282 1.39 jandberg int cursordrawn; 283 1.2 jandberg 284 1.2 jandberg /* Active bitplanes for each character row. */ 285 1.2 jandberg int rowmasks[MAXROWS]; 286 1.2 jandberg 287 1.2 jandberg /* Mapping of colors to screen colors. */ 288 1.2 jandberg int colormap[MAXCOLORS]; 289 1.2 jandberg 290 1.2 jandberg /* Copies of display parameters for convenience */ 291 1.2 jandberg int width; 292 1.2 jandberg int height; 293 1.2 jandberg int depth; 294 1.2 jandberg 295 1.2 jandberg int widthbytes; /* bytes_per_row */ 296 1.2 jandberg int linebytes; /* widthbytes + row_mod */ 297 1.2 jandberg int rowbytes; /* linebytes * fontheight */ 298 1.2 jandberg 299 1.2 jandberg u_char * planes[MAXDEPTH]; 300 1.2 jandberg 301 1.15 jandberg const struct wsdisplay_font * wsfont; 302 1.15 jandberg int wsfontcookie; /* if -1, builtin font */ 303 1.2 jandberg int fontwidth; 304 1.2 jandberg int fontheight; 305 1.1 is }; 306 1.1 is 307 1.1 is typedef struct amidisplaycc_screen adccscr_t; 308 1.1 is 309 1.3 aymeric /* 310 1.1 is * Need one statically allocated screen for early init. 311 1.3 aymeric * The rest are mallocated when needed. 312 1.1 is */ 313 1.1 is adccscr_t amidisplaycc_consolescreen; 314 1.1 is 315 1.3 aymeric /* 316 1.2 jandberg * Default palettes for 2, 4 and 8 color emulation displays. 317 1.2 jandberg */ 318 1.2 jandberg 319 1.2 jandberg /* black, grey */ 320 1.2 jandberg static u_char pal2red[] = { 0x00, 0xaa }; 321 1.2 jandberg static u_char pal2grn[] = { 0x00, 0xaa }; 322 1.2 jandberg static u_char pal2blu[] = { 0x00, 0xaa }; 323 1.2 jandberg 324 1.2 jandberg /* black, red, green, grey */ 325 1.2 jandberg static u_char pal4red[] = { 0x00, 0xaa, 0x00, 0xaa }; 326 1.2 jandberg static u_char pal4grn[] = { 0x00, 0x00, 0xaa, 0xaa }; 327 1.2 jandberg static u_char pal4blu[] = { 0x00, 0x00, 0x00, 0xaa }; 328 1.2 jandberg 329 1.2 jandberg /* black, red, green, brown, blue, magenta, cyan, grey */ 330 1.2 jandberg static u_char pal8red[] = { 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa}; 331 1.2 jandberg static u_char pal8grn[] = { 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0xaa, 0xaa}; 332 1.2 jandberg static u_char pal8blu[] = { 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa}; 333 1.2 jandberg 334 1.2 jandberg static struct wsdisplay_cmap pal2 = { 0, 2, pal2red, pal2grn, pal2blu }; 335 1.2 jandberg static struct wsdisplay_cmap pal4 = { 0, 4, pal4red, pal4grn, pal4blu }; 336 1.2 jandberg static struct wsdisplay_cmap pal8 = { 0, 8, pal8red, pal8grn, pal8blu }; 337 1.2 jandberg 338 1.2 jandberg #ifdef GRF_AGA 339 1.2 jandberg extern int aga_enable; 340 1.2 jandberg #else 341 1.2 jandberg static int aga_enable = 0; 342 1.2 jandberg #endif 343 1.2 jandberg 344 1.2 jandberg /* 345 1.1 is * This gets called at console init to determine the priority of 346 1.1 is * this console device. 347 1.1 is * 348 1.30 jandberg * Pointers to this and other functions must present 349 1.1 is * in constab[] in conf.c for this to work. 350 1.1 is */ 351 1.1 is void 352 1.3 aymeric amidisplaycc_cnprobe(struct consdev *cd) 353 1.1 is { 354 1.1 is cd->cn_pri = CN_INTERNAL; 355 1.1 is 356 1.3 aymeric /* 357 1.1 is * Yeah, real nice. But if we win the console then the wscons system 358 1.1 is * does the proper initialization. 359 1.1 is */ 360 1.1 is cd->cn_dev = NODEV; 361 1.1 is } 362 1.1 is 363 1.1 is /* 364 1.1 is * This gets called if this device is used as the console. 365 1.1 is */ 366 1.1 is void 367 1.3 aymeric amidisplaycc_cninit(struct consdev * cd) 368 1.1 is { 369 1.2 jandberg void * cookie; 370 1.2 jandberg long attr; 371 1.2 jandberg int x; 372 1.2 jandberg int y; 373 1.1 is 374 1.3 aymeric /* 375 1.1 is * This will do the basic stuff we also need. 376 1.1 is */ 377 1.1 is grfcc_probe(); 378 1.1 is 379 1.1 is #if NVIEW>0 380 1.1 is viewprobe(); 381 1.1 is #endif 382 1.1 is 383 1.3 aymeric /* 384 1.1 is * Set up wscons to handle the details. 385 1.1 is * It will then call us back when it needs something 386 1.1 is * display-specific. It will also set up cn_tab properly, 387 1.1 is * something which we failed to do at amidisplaycc_cnprobe(). 388 1.1 is */ 389 1.1 is 390 1.2 jandberg /* 391 1.2 jandberg * The alloc_screen knows to allocate the first screen statically. 392 1.2 jandberg */ 393 1.1 is amidisplaycc_alloc_screen(NULL, &amidisplaycc_screentab[0].wsdescr, 394 1.1 is &cookie, &x, &y, &attr); 395 1.1 is wsdisplay_cnattach(&amidisplaycc_screentab[0].wsdescr, 396 1.1 is cookie, x, y, attr); 397 1.17 jandberg 398 1.17 jandberg #if NKBD>0 399 1.17 jandberg /* tell kbd device it is used as console keyboard */ 400 1.17 jandberg kbd_cnattach(); 401 1.17 jandberg #endif 402 1.1 is } 403 1.1 is 404 1.2 jandberg static int 405 1.26 chs amidisplaycc_match(device_t parent, cfdata_t cf, void *aux) 406 1.1 is { 407 1.26 chs char *name = aux; 408 1.1 is 409 1.2 jandberg if (matchname("amidisplaycc", name) == 0) 410 1.36 rin return 0; 411 1.1 is 412 1.30 jandberg /* Allow only one of us. */ 413 1.16 chs if (amidisplaycc_attached) 414 1.36 rin return 0; 415 1.1 is 416 1.1 is return 1; 417 1.1 is } 418 1.1 is 419 1.2 jandberg /* ARGSUSED */ 420 1.2 jandberg static void 421 1.26 chs amidisplaycc_attach(device_t parent, device_t self, void *aux) 422 1.1 is { 423 1.2 jandberg struct wsemuldisplaydev_attach_args waa; 424 1.2 jandberg struct amidisplaycc_softc * adp; 425 1.2 jandberg 426 1.16 chs amidisplaycc_attached = 1; 427 1.16 chs 428 1.26 chs adp = device_private(self); 429 1.8 aymeric 430 1.8 aymeric grfcc_probe(); 431 1.8 aymeric 432 1.8 aymeric #if NVIEW>0 433 1.8 aymeric viewprobe(); 434 1.8 aymeric #endif 435 1.1 is 436 1.3 aymeric /* 437 1.1 is * Attach only at real configuration time. Console init is done at 438 1.1 is * the amidisplaycc_cninit function above. 439 1.3 aymeric */ 440 1.2 jandberg if (adp) { 441 1.2 jandberg printf(": Amiga custom chip graphics %s", 442 1.2 jandberg aga_enable ? "(AGA)" : ""); 443 1.3 aymeric 444 1.2 jandberg if (amidisplaycc_consolescreen.isconsole) { 445 1.31 jandberg amidisplaycc_consolescreen.device = adp; 446 1.2 jandberg adp->currentscreen = &amidisplaycc_consolescreen; 447 1.2 jandberg printf(" (console)"); 448 1.2 jandberg } else 449 1.2 jandberg adp->currentscreen = NULL; 450 1.2 jandberg 451 1.1 is printf("\n"); 452 1.1 is 453 1.2 jandberg adp->ison = 1; 454 1.2 jandberg 455 1.3 aymeric /* 456 1.3 aymeric * Mapped screen properties. 457 1.2 jandberg * Would need a way to configure. 458 1.2 jandberg */ 459 1.2 jandberg adp->gfxview = NULL; 460 1.2 jandberg adp->gfxon = 0; 461 1.14 jandberg adp->gfxwidth = amidisplaycc_screentab[0].wsdescr.ncols * 462 1.14 jandberg amidisplaycc_screentab[0].wsdescr.fontwidth; 463 1.14 jandberg adp->gfxheight = amidisplaycc_screentab[0].wsdescr.nrows * 464 1.14 jandberg amidisplaycc_screentab[0].wsdescr.fontheight; 465 1.2 jandberg 466 1.2 jandberg if (aga_enable) 467 1.2 jandberg adp->gfxdepth = 8; 468 1.2 jandberg else 469 1.2 jandberg adp->gfxdepth = 4; 470 1.2 jandberg 471 1.3 aymeric if (NELEMS(amidisplaycc_screentab) != 472 1.2 jandberg NELEMS(amidisplaycc_screens)) 473 1.2 jandberg panic("invalid screen definitions"); 474 1.2 jandberg 475 1.1 is waa.scrdata = &amidisplaycc_screenlist; 476 1.2 jandberg waa.console = amidisplaycc_consolescreen.isconsole; 477 1.1 is waa.accessops = &amidisplaycc_accessops; 478 1.26 chs waa.accesscookie = adp; 479 1.37 thorpej config_found(self, &waa, wsemuldisplaydevprint, CFARGS_NONE); 480 1.2 jandberg 481 1.2 jandberg wsfont_init(); 482 1.1 is } 483 1.1 is } 484 1.1 is 485 1.1 is /* 486 1.30 jandberg * Foreground color, background color, and style are packed into one 487 1.30 jandberg * long attribute. These macros are used to create/split the attribute. 488 1.1 is */ 489 1.1 is 490 1.1 is #define MAKEATTR(fg, bg, mode) (((fg)<<16) | ((bg)<<8) | (mode)) 491 1.1 is #define ATTRFG(attr) (((attr)>>16) & 255) 492 1.1 is #define ATTRBG(attr) (((attr)>>8) & 255) 493 1.1 is #define ATTRMO(attr) ((attr) & 255) 494 1.1 is 495 1.3 aymeric /* 496 1.1 is * Called by wscons to draw/clear the cursor. 497 1.1 is * We do this by xorring the block to the screen. 498 1.1 is * 499 1.1 is * This simple implementation will break if the screen is modified 500 1.1 is * under the cursor before clearing it. 501 1.1 is */ 502 1.1 is void 503 1.3 aymeric amidisplaycc_cursor(void *screen, int on, int row, int col) 504 1.2 jandberg { 505 1.2 jandberg adccscr_t * scr; 506 1.1 is 507 1.1 is scr = screen; 508 1.1 is 509 1.1 is if (row < 0 || col < 0 || row >= scr->nrows || col >= scr->ncols) 510 1.1 is return; 511 1.1 is 512 1.39 jandberg amidisplaycc_cursor_undraw(scr); 513 1.2 jandberg 514 1.2 jandberg if (on) { 515 1.2 jandberg scr->cursorrow = row; 516 1.2 jandberg scr->cursorcol = col; 517 1.39 jandberg amidisplaycc_cursor_draw(scr); 518 1.2 jandberg } else { 519 1.2 jandberg scr->cursorrow = -1; 520 1.2 jandberg scr->cursorcol = -1; 521 1.2 jandberg } 522 1.39 jandberg } 523 1.39 jandberg 524 1.39 jandberg void 525 1.39 jandberg amidisplaycc_cursor_undraw(struct amidisplaycc_screen * scr) 526 1.39 jandberg { 527 1.39 jandberg if (scr->cursordrawn) { 528 1.39 jandberg amidisplaycc_cursor_xor(scr, scr->cursorrow, scr->cursorcol); 529 1.39 jandberg scr->cursordrawn = 0; 530 1.39 jandberg } 531 1.39 jandberg } 532 1.39 jandberg 533 1.39 jandberg void 534 1.39 jandberg amidisplaycc_cursor_draw(struct amidisplaycc_screen * scr) 535 1.39 jandberg { 536 1.39 jandberg if (!scr->cursordrawn && scr->cursorrow >= 0 && scr->cursorcol >= 0) { 537 1.39 jandberg amidisplaycc_cursor_xor(scr, scr->cursorrow, scr->cursorcol); 538 1.39 jandberg scr->cursordrawn = 1; 539 1.39 jandberg } 540 1.39 jandberg } 541 1.39 jandberg 542 1.39 jandberg void 543 1.39 jandberg amidisplaycc_cursor_xor(struct amidisplaycc_screen * scr, int row, int col) 544 1.39 jandberg { 545 1.39 jandberg u_char * dst; 546 1.39 jandberg int i; 547 1.39 jandberg 548 1.39 jandberg KASSERT(scr); 549 1.39 jandberg KASSERT(row >= 0); 550 1.39 jandberg KASSERT(col >= 0); 551 1.39 jandberg 552 1.39 jandberg dst = scr->planes[0]; 553 1.39 jandberg dst += row * scr->rowbytes; 554 1.39 jandberg dst += col; 555 1.2 jandberg 556 1.2 jandberg for (i = scr->fontheight ; i > 0 ; i--) { 557 1.2 jandberg *dst ^= 255; 558 1.2 jandberg dst += scr->linebytes; 559 1.1 is } 560 1.1 is } 561 1.1 is 562 1.1 is int 563 1.3 aymeric amidisplaycc_mapchar(void *screen, int ch, unsigned int *chp) 564 1.1 is { 565 1.1 is if (ch > 0 && ch < 256) { 566 1.1 is *chp = ch; 567 1.36 rin return 5; 568 1.1 is } 569 1.1 is *chp = ' '; 570 1.36 rin return 0; 571 1.1 is } 572 1.1 is 573 1.3 aymeric /* 574 1.3 aymeric * Write a character to screen with color / bgcolor / hilite(bold) / 575 1.2 jandberg * underline / reverse. 576 1.1 is * Surely could be made faster but I'm not sure if its worth the 577 1.1 is * effort as scrolling is at least a magnitude slower. 578 1.1 is */ 579 1.1 is void 580 1.3 aymeric amidisplaycc_putchar(void *screen, int row, int col, u_int ch, long attr) 581 1.2 jandberg { 582 1.2 jandberg adccscr_t * scr; 583 1.2 jandberg u_char * dst; 584 1.2 jandberg u_char * font; 585 1.2 jandberg 586 1.2 jandberg int fontheight; 587 1.2 jandberg u_int8_t * fontreal; 588 1.2 jandberg int fontlow; 589 1.2 jandberg int fonthigh; 590 1.2 jandberg 591 1.2 jandberg int bmapoffset; 592 1.2 jandberg int linebytes; 593 1.2 jandberg int underline; 594 1.2 jandberg int fgcolor; 595 1.2 jandberg int bgcolor; 596 1.2 jandberg int plane; 597 1.2 jandberg int depth; 598 1.2 jandberg int mode; 599 1.2 jandberg int bold; 600 1.2 jandberg u_char f; 601 1.2 jandberg int j; 602 1.1 is 603 1.1 is scr = screen; 604 1.1 is 605 1.1 is if (row < 0 || col < 0 || row >= scr->nrows || col >= scr->ncols) 606 1.1 is return; 607 1.1 is 608 1.1 is /* Extract the colors from the attribute */ 609 1.1 is fgcolor = ATTRFG(attr); 610 1.1 is bgcolor = ATTRBG(attr); 611 1.2 jandberg mode = ATTRMO(attr); 612 1.1 is 613 1.1 is /* Translate to screen colors */ 614 1.1 is fgcolor = scr->colormap[fgcolor]; 615 1.1 is bgcolor = scr->colormap[bgcolor]; 616 1.1 is 617 1.2 jandberg if (mode & WSATTR_REVERSE) { 618 1.1 is j = fgcolor; 619 1.1 is fgcolor = bgcolor; 620 1.1 is bgcolor = j; 621 1.1 is } 622 1.1 is 623 1.2 jandberg bold = (mode & WSATTR_HILIT) > 0; 624 1.2 jandberg underline = (mode & WSATTR_UNDERLINE) > 0; 625 1.1 is 626 1.15 jandberg fontreal = scr->wsfont->data; 627 1.15 jandberg fontlow = scr->wsfont->firstchar; 628 1.15 jandberg fonthigh = fontlow + scr->wsfont->numchars - 1; 629 1.1 is 630 1.32 riastrad fontheight = uimin(scr->fontheight, scr->wsfont->fontheight); 631 1.2 jandberg depth = scr->depth; 632 1.2 jandberg linebytes = scr->linebytes; 633 1.1 is 634 1.2 jandberg if (ch < fontlow || ch > fonthigh) 635 1.2 jandberg ch = fontlow; 636 1.1 is 637 1.2 jandberg /* Find the location where the wanted char is in the font data */ 638 1.15 jandberg fontreal += scr->wsfont->fontheight * (ch - fontlow); 639 1.1 is 640 1.2 jandberg bmapoffset = row * scr->rowbytes + col; 641 1.1 is 642 1.1 is scr->rowmasks[row] |= fgcolor | bgcolor; 643 1.1 is 644 1.1 is for (plane = 0 ; plane < depth ; plane++) { 645 1.3 aymeric dst = scr->planes[plane] + bmapoffset; 646 1.3 aymeric 647 1.1 is if (fgcolor & 1) { 648 1.1 is if (bgcolor & 1) { 649 1.1 is /* fg=on bg=on (fill) */ 650 1.1 is 651 1.2 jandberg for (j = 0 ; j < fontheight ; j++) { 652 1.1 is *dst = 255; 653 1.2 jandberg dst += linebytes; 654 1.1 is } 655 1.1 is } else { 656 1.1 is /* fg=on bg=off (normal) */ 657 1.3 aymeric 658 1.2 jandberg font = fontreal; 659 1.2 jandberg for (j = 0 ; j < fontheight ; j++) { 660 1.1 is f = *(font++); 661 1.2 jandberg f |= f >> bold; 662 1.1 is *dst = f; 663 1.2 jandberg dst += linebytes; 664 1.1 is } 665 1.1 is 666 1.1 is if (underline) 667 1.2 jandberg *(dst - linebytes) = 255; 668 1.1 is } 669 1.1 is } else { 670 1.1 is if (bgcolor & 1) { 671 1.1 is /* fg=off bg=on (inverted) */ 672 1.3 aymeric 673 1.2 jandberg font = fontreal; 674 1.2 jandberg for (j = 0 ; j < fontheight ; j++) { 675 1.1 is f = *(font++); 676 1.2 jandberg f |= f >> bold; 677 1.1 is *dst = ~f; 678 1.2 jandberg dst += linebytes; 679 1.1 is } 680 1.1 is 681 1.3 aymeric if (underline) 682 1.2 jandberg *(dst - linebytes) = 0; 683 1.3 aymeric } else { 684 1.1 is /* fg=off bg=off (clear) */ 685 1.1 is 686 1.2 jandberg for (j = 0 ; j < fontheight ; j++) { 687 1.1 is *dst = 0; 688 1.2 jandberg dst += linebytes; 689 1.1 is } 690 1.1 is } 691 1.1 is } 692 1.1 is fgcolor >>= 1; 693 1.1 is bgcolor >>= 1; 694 1.1 is } 695 1.1 is } 696 1.1 is 697 1.3 aymeric /* 698 1.2 jandberg * Copy characters on a row to another position on the same row. 699 1.2 jandberg */ 700 1.1 is 701 1.1 is void 702 1.3 aymeric amidisplaycc_copycols(void *screen, int row, int srccol, int dstcol, int ncols) 703 1.2 jandberg { 704 1.2 jandberg adccscr_t * scr; 705 1.2 jandberg u_char * src; 706 1.2 jandberg u_char * dst; 707 1.2 jandberg 708 1.2 jandberg int bmapoffset; 709 1.2 jandberg int linebytes; 710 1.2 jandberg int depth; 711 1.2 jandberg int plane; 712 1.2 jandberg int i; 713 1.2 jandberg int j; 714 1.1 is 715 1.1 is scr = screen; 716 1.1 is 717 1.3 aymeric if (srccol < 0 || srccol + ncols > scr->ncols || 718 1.1 is dstcol < 0 || dstcol + ncols > scr->ncols || 719 1.1 is row < 0 || row >= scr->nrows) 720 1.1 is return; 721 1.1 is 722 1.2 jandberg depth = scr->depth; 723 1.2 jandberg linebytes = scr->linebytes; 724 1.2 jandberg bmapoffset = row * scr->rowbytes; 725 1.1 is 726 1.1 is for (plane = 0 ; plane < depth ; plane++) { 727 1.2 jandberg src = scr->planes[plane] + bmapoffset; 728 1.1 is 729 1.1 is for (j = 0 ; j < scr->fontheight ; j++) { 730 1.2 jandberg dst = src; 731 1.1 is 732 1.1 is if (srccol < dstcol) { 733 1.1 is 734 1.1 is for (i = ncols - 1 ; i >= 0 ; i--) 735 1.2 jandberg dst[dstcol + i] = src[srccol + i]; 736 1.1 is 737 1.1 is } else { 738 1.1 is 739 1.1 is for (i = 0 ; i < ncols ; i++) 740 1.2 jandberg dst[dstcol + i] = src[srccol + i]; 741 1.1 is 742 1.1 is } 743 1.2 jandberg src += linebytes; 744 1.1 is } 745 1.1 is } 746 1.1 is } 747 1.1 is 748 1.2 jandberg /* 749 1.2 jandberg * Erase part of a row. 750 1.2 jandberg */ 751 1.2 jandberg 752 1.3 aymeric void 753 1.3 aymeric amidisplaycc_erasecols(void *screen, int row, int startcol, int ncols, 754 1.3 aymeric long attr) 755 1.2 jandberg { 756 1.2 jandberg adccscr_t * scr; 757 1.2 jandberg u_char * dst; 758 1.2 jandberg 759 1.2 jandberg int bmapoffset; 760 1.2 jandberg int linebytes; 761 1.2 jandberg int bgcolor; 762 1.2 jandberg int depth; 763 1.2 jandberg int plane; 764 1.2 jandberg int fill; 765 1.2 jandberg int j; 766 1.1 is 767 1.1 is scr = screen; 768 1.1 is 769 1.1 is if (row < 0 || row >= scr->nrows || 770 1.1 is startcol < 0 || startcol + ncols > scr->ncols) 771 1.1 is return; 772 1.1 is 773 1.2 jandberg depth = scr->depth; 774 1.2 jandberg linebytes = scr->linebytes; 775 1.2 jandberg bmapoffset = row * scr->rowbytes + startcol; 776 1.1 is 777 1.2 jandberg /* Erase will be done using the set background color. */ 778 1.1 is bgcolor = ATTRBG(attr); 779 1.1 is bgcolor = scr->colormap[bgcolor]; 780 1.1 is 781 1.1 is for(plane = 0 ; plane < depth ; plane++) { 782 1.1 is 783 1.1 is fill = (bgcolor & 1) ? 255 : 0; 784 1.1 is 785 1.2 jandberg dst = scr->planes[plane] + bmapoffset; 786 1.2 jandberg 787 1.2 jandberg for (j = 0 ; j < scr->fontheight ; j++) { 788 1.2 jandberg memset(dst, fill, ncols); 789 1.2 jandberg dst += linebytes; 790 1.1 is } 791 1.1 is } 792 1.1 is } 793 1.1 is 794 1.2 jandberg /* 795 1.2 jandberg * Copy a number of rows to another location on the screen. 796 1.2 jandberg */ 797 1.2 jandberg 798 1.1 is void 799 1.3 aymeric amidisplaycc_copyrows(void *screen, int srcrow, int dstrow, int nrows) 800 1.2 jandberg { 801 1.2 jandberg adccscr_t * scr; 802 1.2 jandberg u_char * src; 803 1.2 jandberg u_char * dst; 804 1.2 jandberg 805 1.2 jandberg int srcbmapoffset; 806 1.2 jandberg int dstbmapoffset; 807 1.2 jandberg int widthbytes; 808 1.2 jandberg int fontheight; 809 1.2 jandberg int linebytes; 810 1.2 jandberg u_int copysize; 811 1.2 jandberg int rowdelta; 812 1.2 jandberg int rowbytes; 813 1.2 jandberg int srcmask; 814 1.2 jandberg int dstmask; 815 1.2 jandberg int bmdelta; 816 1.2 jandberg int depth; 817 1.2 jandberg int plane; 818 1.2 jandberg int i; 819 1.2 jandberg int j; 820 1.1 is 821 1.1 is scr = screen; 822 1.1 is 823 1.1 is if (srcrow < 0 || srcrow + nrows > scr->nrows || 824 1.1 is dstrow < 0 || dstrow + nrows > scr->nrows) 825 1.1 is return; 826 1.1 is 827 1.2 jandberg depth = scr->depth; 828 1.1 is 829 1.2 jandberg widthbytes = scr->widthbytes; 830 1.2 jandberg rowbytes = scr->rowbytes; 831 1.2 jandberg linebytes = scr->linebytes; 832 1.2 jandberg fontheight = scr->fontheight; 833 1.3 aymeric 834 1.2 jandberg srcbmapoffset = rowbytes * srcrow; 835 1.2 jandberg dstbmapoffset = rowbytes * dstrow; 836 1.1 is 837 1.1 is if (srcrow < dstrow) { 838 1.1 is /* Move data downwards, need to copy from down to up */ 839 1.2 jandberg bmdelta = -rowbytes; 840 1.1 is rowdelta = -1; 841 1.1 is 842 1.2 jandberg srcbmapoffset += rowbytes * (nrows - 1); 843 1.1 is srcrow += nrows - 1; 844 1.1 is 845 1.2 jandberg dstbmapoffset += rowbytes * (nrows - 1); 846 1.1 is dstrow += nrows - 1; 847 1.1 is } else { 848 1.1 is /* Move data upwards, copy up to down */ 849 1.2 jandberg bmdelta = rowbytes; 850 1.1 is rowdelta = 1; 851 1.1 is } 852 1.1 is 853 1.2 jandberg if (widthbytes == linebytes) 854 1.2 jandberg copysize = rowbytes; 855 1.1 is else 856 1.1 is copysize = 0; 857 1.1 is 858 1.2 jandberg for (j = 0 ; j < nrows ; j++) { 859 1.1 is /* Need to copy only planes that have data on src or dst */ 860 1.1 is srcmask = scr->rowmasks[srcrow]; 861 1.1 is dstmask = scr->rowmasks[dstrow]; 862 1.1 is scr->rowmasks[dstrow] = srcmask; 863 1.1 is 864 1.1 is for (plane = 0 ; plane < depth ; plane++) { 865 1.1 is 866 1.1 is if (srcmask & 1) { 867 1.3 aymeric /* 868 1.3 aymeric * Source row has data on this 869 1.3 aymeric * plane, copy it. 870 1.1 is */ 871 1.1 is 872 1.2 jandberg src = scr->planes[plane] + srcbmapoffset; 873 1.2 jandberg dst = scr->planes[plane] + dstbmapoffset; 874 1.1 is 875 1.1 is if (copysize > 0) { 876 1.1 is 877 1.2 jandberg memcpy(dst, src, copysize); 878 1.1 is 879 1.1 is } else { 880 1.1 is 881 1.3 aymeric /* 882 1.3 aymeric * Data not continuous, 883 1.3 aymeric * must do in pieces 884 1.1 is */ 885 1.2 jandberg for (i=0 ; i < fontheight ; i++) { 886 1.2 jandberg memcpy(dst, src, widthbytes); 887 1.1 is 888 1.2 jandberg src += linebytes; 889 1.2 jandberg dst += linebytes; 890 1.1 is } 891 1.1 is } 892 1.1 is } else if (dstmask & 1) { 893 1.3 aymeric /* 894 1.1 is * Source plane is empty, but dest is not. 895 1.1 is * so all we need to is clear it. 896 1.1 is */ 897 1.1 is 898 1.2 jandberg dst = scr->planes[plane] + dstbmapoffset; 899 1.1 is 900 1.1 is if (copysize > 0) { 901 1.1 is /* Do it all */ 902 1.22 cegger memset(dst, 0, copysize); 903 1.1 is } else { 904 1.2 jandberg for (i = 0 ; i < fontheight ; i++) { 905 1.22 cegger memset(dst, 0, widthbytes); 906 1.2 jandberg dst += linebytes; 907 1.1 is } 908 1.1 is } 909 1.1 is } 910 1.1 is 911 1.1 is srcmask >>= 1; 912 1.1 is dstmask >>= 1; 913 1.1 is } 914 1.1 is srcbmapoffset += bmdelta; 915 1.1 is dstbmapoffset += bmdelta; 916 1.1 is 917 1.1 is srcrow += rowdelta; 918 1.1 is dstrow += rowdelta; 919 1.1 is } 920 1.1 is } 921 1.1 is 922 1.2 jandberg /* 923 1.2 jandberg * Erase some rows. 924 1.2 jandberg */ 925 1.2 jandberg 926 1.1 is void 927 1.3 aymeric amidisplaycc_eraserows(void *screen, int row, int nrows, long attr) 928 1.2 jandberg { 929 1.2 jandberg adccscr_t * scr; 930 1.2 jandberg u_char * dst; 931 1.2 jandberg 932 1.2 jandberg int bmapoffset; 933 1.2 jandberg int fillsize; 934 1.2 jandberg int bgcolor; 935 1.2 jandberg int depth; 936 1.2 jandberg int plane; 937 1.2 jandberg int fill; 938 1.2 jandberg int j; 939 1.2 jandberg 940 1.2 jandberg int widthbytes; 941 1.2 jandberg int linebytes; 942 1.2 jandberg int rowbytes; 943 1.2 jandberg 944 1.1 is 945 1.1 is scr = screen; 946 1.1 is 947 1.1 is if (row < 0 || row + nrows > scr->nrows) 948 1.1 is return; 949 1.39 jandberg amidisplaycc_cursor_undraw(scr); 950 1.1 is 951 1.2 jandberg depth = scr->depth; 952 1.2 jandberg widthbytes = scr->widthbytes; 953 1.2 jandberg linebytes = scr->linebytes; 954 1.2 jandberg rowbytes = scr->rowbytes; 955 1.2 jandberg 956 1.2 jandberg bmapoffset = row * rowbytes; 957 1.1 is 958 1.2 jandberg if (widthbytes == linebytes) 959 1.2 jandberg fillsize = rowbytes * nrows; 960 1.1 is else 961 1.1 is fillsize = 0; 962 1.1 is 963 1.1 is bgcolor = ATTRBG(attr); 964 1.1 is bgcolor = scr->colormap[bgcolor]; 965 1.1 is 966 1.1 is for (j = 0 ; j < nrows ; j++) 967 1.1 is scr->rowmasks[row+j] = bgcolor; 968 1.1 is 969 1.1 is for (plane = 0 ; plane < depth ; plane++) { 970 1.2 jandberg dst = scr->planes[plane] + bmapoffset; 971 1.3 aymeric fill = (bgcolor & 1) ? 255 : 0; 972 1.1 is 973 1.1 is if (fillsize > 0) { 974 1.1 is /* If the rows are continuous, write them all. */ 975 1.1 is memset(dst, fill, fillsize); 976 1.1 is } else { 977 1.1 is for (j = 0 ; j < scr->fontheight * nrows ; j++) { 978 1.2 jandberg memset(dst, fill, widthbytes); 979 1.2 jandberg dst += linebytes; 980 1.1 is } 981 1.1 is } 982 1.1 is bgcolor >>= 1; 983 1.1 is } 984 1.39 jandberg amidisplaycc_cursor_draw(scr); 985 1.1 is } 986 1.1 is 987 1.2 jandberg 988 1.2 jandberg /* 989 1.2 jandberg * Compose an attribute value from foreground color, 990 1.2 jandberg * background color, and flags. 991 1.2 jandberg */ 992 1.1 is int 993 1.7 junyoung amidisplaycc_allocattr(void *screen, int fg, int bg, int flags, long *attrp) 994 1.2 jandberg { 995 1.2 jandberg adccscr_t * scr; 996 1.2 jandberg int maxcolor; 997 1.2 jandberg int newfg; 998 1.2 jandberg int newbg; 999 1.1 is 1000 1.1 is scr = screen; 1001 1.1 is maxcolor = (1 << scr->view->bitmap->depth) - 1; 1002 1.1 is 1003 1.1 is /* Ensure the colors are displayable. */ 1004 1.1 is newfg = fg & maxcolor; 1005 1.1 is newbg = bg & maxcolor; 1006 1.1 is 1007 1.1 is #ifdef ADJUSTCOLORS 1008 1.3 aymeric /* 1009 1.1 is * Hack for low-color screens, if background color is nonzero 1010 1.1 is * but would be displayed as one, adjust it. 1011 1.1 is */ 1012 1.1 is if (bg > 0 && newbg == 0) 1013 1.1 is newbg = maxcolor; 1014 1.1 is 1015 1.3 aymeric /* 1016 1.1 is * If foreground and background colors are different but would 1017 1.1 is * display the same fix them by modifying the foreground. 1018 1.1 is */ 1019 1.1 is if (fg != bg && newfg == newbg) { 1020 1.1 is if (newbg > 0) 1021 1.1 is newfg = 0; 1022 1.1 is else 1023 1.1 is newfg = maxcolor; 1024 1.1 is } 1025 1.1 is #endif 1026 1.1 is *attrp = MAKEATTR(newfg, newbg, flags); 1027 1.1 is 1028 1.36 rin return 0; 1029 1.1 is } 1030 1.1 is 1031 1.1 is int 1032 1.20 christos amidisplaycc_ioctl(void *dp, void *vs, u_long cmd, void *data, int flag, 1033 1.19 jmmv struct lwp *l) 1034 1.2 jandberg { 1035 1.2 jandberg struct amidisplaycc_softc *adp; 1036 1.2 jandberg 1037 1.2 jandberg adp = dp; 1038 1.2 jandberg 1039 1.2 jandberg if (adp == NULL) { 1040 1.2 jandberg printf("amidisplaycc_ioctl: adp==NULL\n"); 1041 1.36 rin return EINVAL; 1042 1.2 jandberg } 1043 1.2 jandberg 1044 1.2 jandberg #define UINTDATA (*(u_int*)data) 1045 1.2 jandberg #define INTDATA (*(int*)data) 1046 1.2 jandberg #define FBINFO (*(struct wsdisplay_fbinfo*)data) 1047 1.2 jandberg 1048 1.1 is switch (cmd) 1049 1.1 is { 1050 1.1 is case WSDISPLAYIO_GTYPE: 1051 1.2 jandberg UINTDATA = WSDISPLAY_TYPE_AMIGACC; 1052 1.36 rin return 0; 1053 1.2 jandberg 1054 1.2 jandberg case WSDISPLAYIO_SVIDEO: 1055 1.2 jandberg dprintf("amidisplaycc: WSDISPLAYIO_SVIDEO %s\n", 1056 1.2 jandberg UINTDATA ? "On" : "Off"); 1057 1.2 jandberg 1058 1.36 rin return amidisplaycc_setvideo(adp, UINTDATA); 1059 1.2 jandberg 1060 1.2 jandberg case WSDISPLAYIO_GVIDEO: 1061 1.2 jandberg dprintf("amidisplaycc: WSDISPLAYIO_GVIDEO\n"); 1062 1.3 aymeric UINTDATA = adp->ison ? 1063 1.2 jandberg WSDISPLAYIO_VIDEO_ON : WSDISPLAYIO_VIDEO_OFF; 1064 1.3 aymeric 1065 1.36 rin return 0; 1066 1.2 jandberg 1067 1.2 jandberg case WSDISPLAYIO_SMODE: 1068 1.35 rin switch (INTDATA) { 1069 1.35 rin case WSDISPLAYIO_MODE_EMUL: 1070 1.33 jandberg return amidisplaycc_setgfxview(adp, 0); 1071 1.35 rin case WSDISPLAYIO_MODE_MAPPED: 1072 1.35 rin case WSDISPLAYIO_MODE_DUMBFB: 1073 1.33 jandberg return amidisplaycc_setgfxview(adp, 1); 1074 1.35 rin default: 1075 1.36 rin return EINVAL; 1076 1.35 rin } 1077 1.2 jandberg 1078 1.2 jandberg case WSDISPLAYIO_GINFO: 1079 1.2 jandberg FBINFO.width = adp->gfxwidth; 1080 1.2 jandberg FBINFO.height = adp->gfxheight; 1081 1.2 jandberg FBINFO.depth = adp->gfxdepth; 1082 1.2 jandberg FBINFO.cmsize = 1 << FBINFO.depth; 1083 1.36 rin return 0; 1084 1.2 jandberg 1085 1.2 jandberg case WSDISPLAYIO_PUTCMAP: 1086 1.2 jandberg case WSDISPLAYIO_GETCMAP: 1087 1.36 rin return amidisplaycc_cmapioctl(adp->gfxview, cmd, 1088 1.36 rin (struct wsdisplay_cmap*)data); 1089 1.33 jandberg case WSDISPLAYIO_GET_FBINFO: 1090 1.33 jandberg amidisplaycc_initgfxview(adp); 1091 1.33 jandberg return amidisplaycc_getfbinfo(adp, data); 1092 1.1 is } 1093 1.1 is 1094 1.36 rin return EPASSTHROUGH; 1095 1.2 jandberg 1096 1.2 jandberg #undef UINTDATA 1097 1.2 jandberg #undef INTDATA 1098 1.2 jandberg #undef FBINFO 1099 1.1 is } 1100 1.1 is 1101 1.33 jandberg static int 1102 1.33 jandberg amidisplaycc_getfbinfo(struct amidisplaycc_softc *adp, struct wsdisplayio_fbinfo *fbinfo) 1103 1.33 jandberg { 1104 1.33 jandberg bmap_t *bm; 1105 1.33 jandberg 1106 1.33 jandberg KASSERT(adp); 1107 1.33 jandberg 1108 1.33 jandberg if (adp->gfxview == NULL) { 1109 1.33 jandberg return ENOMEM; 1110 1.33 jandberg } 1111 1.33 jandberg 1112 1.33 jandberg bm = adp->gfxview->bitmap; 1113 1.33 jandberg KASSERT(bm); 1114 1.33 jandberg 1115 1.33 jandberg memset(fbinfo, 0, sizeof(*fbinfo)); 1116 1.40 jandberg fbinfo->fbi_fbsize = bm->bytes_per_row * bm->rows * adp->gfxdepth; 1117 1.33 jandberg fbinfo->fbi_fboffset = 0; 1118 1.33 jandberg fbinfo->fbi_width = bm->bytes_per_row * 8; 1119 1.33 jandberg fbinfo->fbi_height = bm->rows; 1120 1.33 jandberg fbinfo->fbi_stride = bm->bytes_per_row; 1121 1.40 jandberg fbinfo->fbi_bitsperpixel = adp->gfxdepth; 1122 1.33 jandberg fbinfo->fbi_pixeltype = WSFB_CI; 1123 1.33 jandberg fbinfo->fbi_flags = 0; 1124 1.33 jandberg fbinfo->fbi_subtype.fbi_cmapinfo.cmap_entries = 1 << adp->gfxdepth; 1125 1.33 jandberg 1126 1.36 rin return 0; 1127 1.33 jandberg } 1128 1.33 jandberg 1129 1.33 jandberg /* 1130 1.33 jandberg * Initialize (but not display) the view used for graphics. 1131 1.33 jandberg */ 1132 1.33 jandberg static void 1133 1.33 jandberg amidisplaycc_initgfxview(struct amidisplaycc_softc *adp) 1134 1.33 jandberg { 1135 1.33 jandberg dimen_t dimension; 1136 1.33 jandberg 1137 1.33 jandberg if (adp->gfxview == NULL) { 1138 1.33 jandberg /* First time here, create the screen */ 1139 1.33 jandberg dimension.width = adp->gfxwidth; 1140 1.33 jandberg dimension.height = adp->gfxheight; 1141 1.33 jandberg adp->gfxview = grf_alloc_view(NULL, 1142 1.33 jandberg &dimension, 1143 1.33 jandberg adp->gfxdepth); 1144 1.33 jandberg } 1145 1.33 jandberg } 1146 1.2 jandberg 1147 1.2 jandberg /* 1148 1.2 jandberg * Switch to either emulation (text) or mapped (graphics) mode 1149 1.2 jandberg * We keep an extra screen for mapped mode so it does not 1150 1.2 jandberg * interfere with emulation screens. 1151 1.2 jandberg * 1152 1.2 jandberg * Once the extra screen is created, it never goes away. 1153 1.2 jandberg */ 1154 1.2 jandberg static int 1155 1.33 jandberg amidisplaycc_setgfxview(struct amidisplaycc_softc *adp, int on) 1156 1.2 jandberg { 1157 1.3 aymeric dprintf("amidisplaycc: switching to %s mode.\n", 1158 1.2 jandberg on ? "mapped" : "emul"); 1159 1.2 jandberg 1160 1.2 jandberg /* Current mode same as requested mode? */ 1161 1.2 jandberg if ( (on > 0) == (adp->gfxon > 0) ) 1162 1.36 rin return 0; 1163 1.2 jandberg 1164 1.2 jandberg if (!on) { 1165 1.3 aymeric /* 1166 1.2 jandberg * Switch away from mapped mode. If there is 1167 1.2 jandberg * a emulation screen, switch to it, otherwise 1168 1.2 jandberg * just try to hide the mapped screen. 1169 1.2 jandberg */ 1170 1.2 jandberg adp->gfxon = 0; 1171 1.2 jandberg if (adp->currentscreen) 1172 1.2 jandberg grf_display_view(adp->currentscreen->view); 1173 1.2 jandberg else if (adp->gfxview) 1174 1.2 jandberg grf_remove_view(adp->gfxview); 1175 1.2 jandberg 1176 1.36 rin return 0; 1177 1.2 jandberg } 1178 1.3 aymeric 1179 1.2 jandberg /* switch to mapped mode then */ 1180 1.33 jandberg amidisplaycc_initgfxview(adp); 1181 1.2 jandberg 1182 1.2 jandberg if (adp->gfxview) { 1183 1.2 jandberg adp->gfxon = 1; 1184 1.2 jandberg 1185 1.2 jandberg grf_display_view(adp->gfxview); 1186 1.2 jandberg } else { 1187 1.2 jandberg printf("amidisplaycc: failed to make mapped screen\n"); 1188 1.36 rin return ENOMEM; 1189 1.2 jandberg } 1190 1.36 rin return 0; 1191 1.2 jandberg } 1192 1.2 jandberg 1193 1.2 jandberg /* 1194 1.2 jandberg * Map the graphics screen. It must have been created before 1195 1.2 jandberg * by switching to mapped mode by using an ioctl. 1196 1.2 jandberg */ 1197 1.1 is paddr_t 1198 1.19 jmmv amidisplaycc_mmap(void *dp, void *vs, off_t off, int prot) 1199 1.2 jandberg { 1200 1.2 jandberg struct amidisplaycc_softc * adp; 1201 1.2 jandberg bmap_t * bm; 1202 1.2 jandberg paddr_t rv; 1203 1.2 jandberg 1204 1.2 jandberg adp = (struct amidisplaycc_softc*)dp; 1205 1.2 jandberg 1206 1.2 jandberg /* Check we are in mapped mode */ 1207 1.2 jandberg if (adp->gfxon == 0 || adp->gfxview == NULL) { 1208 1.2 jandberg dprintf("amidisplaycc_mmap: Not in mapped mode\n"); 1209 1.2 jandberg return (paddr_t)(-1); 1210 1.2 jandberg } 1211 1.2 jandberg 1212 1.2 jandberg /* 1213 1.30 jandberg * Screen reserved for graphics is used to avoid writing 1214 1.30 jandberg * over the text screens. 1215 1.2 jandberg */ 1216 1.2 jandberg 1217 1.2 jandberg bm = adp->gfxview->bitmap; 1218 1.2 jandberg 1219 1.2 jandberg /* Check that the offset is valid */ 1220 1.2 jandberg if (off < 0 || off >= bm->depth * bm->bytes_per_row * bm->rows) { 1221 1.2 jandberg dprintf("amidisplaycc_mmap: Offset out of range\n"); 1222 1.2 jandberg return (paddr_t)(-1); 1223 1.2 jandberg } 1224 1.2 jandberg 1225 1.2 jandberg rv = (paddr_t)bm->hardware_address; 1226 1.2 jandberg rv += off; 1227 1.2 jandberg 1228 1.29 phx return MD_BTOP(rv); 1229 1.1 is } 1230 1.1 is 1231 1.2 jandberg 1232 1.2 jandberg /* 1233 1.2 jandberg * Create a new screen. 1234 1.30 jandberg * 1235 1.2 jandberg * NULL dp signifies console and then memory is allocated statically 1236 1.2 jandberg * and the screen is automatically displayed. 1237 1.2 jandberg * 1238 1.2 jandberg * A font with suitable size is searched and if not found 1239 1.2 jandberg * the builtin 8x8 font is used. 1240 1.2 jandberg * 1241 1.2 jandberg * There are separate default palettes for 2, 4 and 8+ color 1242 1.2 jandberg * screens. 1243 1.2 jandberg */ 1244 1.2 jandberg 1245 1.1 is int 1246 1.3 aymeric amidisplaycc_alloc_screen(void *dp, const struct wsscreen_descr *screenp, 1247 1.3 aymeric void **cookiep, int *curxp, int *curyp, 1248 1.3 aymeric long *defattrp) 1249 1.2 jandberg { 1250 1.2 jandberg const struct amidisplaycc_screen_descr * adccscreenp; 1251 1.2 jandberg struct amidisplaycc_screen * scr; 1252 1.2 jandberg struct amidisplaycc_softc * adp; 1253 1.2 jandberg view_t * view; 1254 1.2 jandberg 1255 1.2 jandberg dimen_t dimension; 1256 1.2 jandberg int fontheight; 1257 1.2 jandberg int fontwidth; 1258 1.2 jandberg int maxcolor; 1259 1.2 jandberg int depth; 1260 1.2 jandberg int i; 1261 1.2 jandberg int j; 1262 1.1 is 1263 1.2 jandberg adccscreenp = (const struct amidisplaycc_screen_descr *)screenp; 1264 1.1 is depth = adccscreenp->depth; 1265 1.1 is 1266 1.2 jandberg adp = dp; 1267 1.2 jandberg 1268 1.1 is maxcolor = (1 << depth) - 1; 1269 1.1 is 1270 1.1 is /* Sanity checks because of fixed buffers */ 1271 1.1 is if (depth > MAXDEPTH || maxcolor >= MAXCOLORS) 1272 1.36 rin return ENOMEM; 1273 1.1 is if (screenp->nrows > MAXROWS) 1274 1.36 rin return ENOMEM; 1275 1.1 is 1276 1.2 jandberg fontwidth = screenp->fontwidth; 1277 1.2 jandberg fontheight = screenp->fontheight; 1278 1.2 jandberg 1279 1.2 jandberg /* 1280 1.2 jandberg * The screen size is defined in characters. 1281 1.2 jandberg * Calculate the pixel size using the font size. 1282 1.2 jandberg */ 1283 1.2 jandberg 1284 1.2 jandberg dimension.width = screenp->ncols * fontwidth; 1285 1.2 jandberg dimension.height = screenp->nrows * fontheight; 1286 1.1 is 1287 1.1 is view = grf_alloc_view(NULL, &dimension, depth); 1288 1.1 is if (view == NULL) 1289 1.36 rin return ENOMEM; 1290 1.1 is 1291 1.3 aymeric /* 1292 1.1 is * First screen gets the statically allocated console screen. 1293 1.1 is * Others are allocated dynamically. 1294 1.1 is */ 1295 1.2 jandberg if (adp == NULL) { 1296 1.1 is scr = &amidisplaycc_consolescreen; 1297 1.2 jandberg if (scr->isconsole) 1298 1.2 jandberg panic("more than one console?"); 1299 1.2 jandberg 1300 1.1 is scr->isconsole = 1; 1301 1.1 is } else { 1302 1.21 cegger scr = malloc(sizeof(adccscr_t), M_DEVBUF, M_WAITOK|M_ZERO); 1303 1.1 is } 1304 1.1 is 1305 1.1 is scr->view = view; 1306 1.1 is 1307 1.1 is scr->ncols = screenp->ncols; 1308 1.1 is scr->nrows = screenp->nrows; 1309 1.1 is 1310 1.2 jandberg /* Copies of most used values */ 1311 1.2 jandberg scr->width = dimension.width; 1312 1.2 jandberg scr->height = dimension.height; 1313 1.2 jandberg scr->depth = depth; 1314 1.2 jandberg scr->widthbytes = view->bitmap->bytes_per_row; 1315 1.2 jandberg scr->linebytes = scr->widthbytes + view->bitmap->row_mod; 1316 1.2 jandberg scr->rowbytes = scr->linebytes * fontheight; 1317 1.2 jandberg 1318 1.2 jandberg scr->device = adp; 1319 1.2 jandberg 1320 1.2 jandberg 1321 1.15 jandberg /* 1322 1.15 jandberg * Try to find a suitable font. 1323 1.15 jandberg * Avoid everything but the builtin font for console screen. 1324 1.15 jandberg * Builtin font is used if no other is found, even if it 1325 1.15 jandberg * has the wrong size. 1326 1.15 jandberg */ 1327 1.15 jandberg 1328 1.15 jandberg KASSERT(fontwidth == 8); 1329 1.2 jandberg 1330 1.15 jandberg scr->wsfont = NULL; 1331 1.2 jandberg scr->wsfontcookie = -1; 1332 1.2 jandberg scr->fontwidth = fontwidth; 1333 1.2 jandberg scr->fontheight = fontheight; 1334 1.2 jandberg 1335 1.2 jandberg if (adp) 1336 1.15 jandberg amidisplaycc_setfont(scr, NULL); 1337 1.2 jandberg 1338 1.15 jandberg if (scr->wsfont == NULL) 1339 1.15 jandberg { 1340 1.15 jandberg scr->wsfont = amidisplaycc_getbuiltinfont(); 1341 1.15 jandberg scr->wsfontcookie = -1; 1342 1.2 jandberg } 1343 1.2 jandberg 1344 1.15 jandberg KASSERT(scr->wsfont); 1345 1.15 jandberg KASSERT(scr->wsfont->stride == 1); 1346 1.2 jandberg 1347 1.2 jandberg for (i = 0 ; i < depth ; i++) { 1348 1.2 jandberg scr->planes[i] = view->bitmap->plane[i]; 1349 1.2 jandberg } 1350 1.2 jandberg 1351 1.1 is for (i = 0 ; i < MAXROWS ; i++) 1352 1.1 is scr->rowmasks[i] = 0; 1353 1.1 is 1354 1.1 is /* Simple one-to-one mapping for most colors */ 1355 1.1 is for (i = 0 ; i < MAXCOLORS ; i++) 1356 1.1 is scr->colormap[i] = i; 1357 1.1 is 1358 1.3 aymeric /* 1359 1.1 is * Arrange the most used pens to quickest colors. 1360 1.1 is * The default color for given depth is (1<<depth)-1. 1361 1.1 is * It is assumed it is used most and it is mapped to 1362 1.1 is * color that can be drawn by writing data to one bitplane 1363 1.1 is * only. 1364 1.1 is * So map colors 3->2, 7->4, 15->8 and so on. 1365 1.1 is */ 1366 1.1 is for (i = 2 ; i < MAXCOLORS ; i *= 2) { 1367 1.1 is j = i * 2 - 1; 1368 1.1 is 1369 1.1 is if (j < MAXCOLORS) { 1370 1.1 is scr->colormap[i] = j; 1371 1.1 is scr->colormap[j] = i; 1372 1.1 is } 1373 1.1 is } 1374 1.1 is 1375 1.2 jandberg /* 1376 1.2 jandberg * Set the default colormap. 1377 1.2 jandberg */ 1378 1.2 jandberg if (depth == 1) 1379 1.2 jandberg amidisplaycc_setemulcmap(scr, &pal2); 1380 1.2 jandberg else if (depth == 2) 1381 1.2 jandberg amidisplaycc_setemulcmap(scr, &pal4); 1382 1.2 jandberg else 1383 1.2 jandberg amidisplaycc_setemulcmap(scr, &pal8); 1384 1.2 jandberg 1385 1.1 is *cookiep = scr; 1386 1.1 is 1387 1.11 jandberg /* cursor initially at top left */ 1388 1.11 jandberg scr->cursorrow = -1; 1389 1.11 jandberg scr->cursorcol = -1; 1390 1.1 is *curxp = 0; 1391 1.1 is *curyp = 0; 1392 1.1 is amidisplaycc_cursor(scr, 1, *curxp, *curyp); 1393 1.1 is 1394 1.1 is *defattrp = MAKEATTR(maxcolor, 0, 0); 1395 1.1 is 1396 1.1 is /* Show the console automatically */ 1397 1.2 jandberg if (adp == NULL) 1398 1.1 is grf_display_view(scr->view); 1399 1.1 is 1400 1.2 jandberg if (adp) { 1401 1.15 jandberg dprintf("amidisplaycc: allocated screen; %dx%dx%d; font=%s\n", 1402 1.2 jandberg dimension.width, 1403 1.2 jandberg dimension.height, 1404 1.15 jandberg depth, 1405 1.15 jandberg scr->wsfont->name); 1406 1.2 jandberg } 1407 1.2 jandberg 1408 1.36 rin return 0; 1409 1.1 is } 1410 1.1 is 1411 1.2 jandberg 1412 1.2 jandberg /* 1413 1.2 jandberg * Destroy a screen. 1414 1.2 jandberg */ 1415 1.2 jandberg 1416 1.1 is void 1417 1.3 aymeric amidisplaycc_free_screen(void *dp, void *screen) 1418 1.1 is { 1419 1.2 jandberg struct amidisplaycc_screen * scr; 1420 1.2 jandberg struct amidisplaycc_softc * adp; 1421 1.2 jandberg 1422 1.1 is scr = screen; 1423 1.13 jandberg adp = (struct amidisplaycc_softc*)dp; 1424 1.1 is 1425 1.1 is if (scr == NULL) 1426 1.1 is return; 1427 1.1 is 1428 1.2 jandberg /* Free the used font */ 1429 1.15 jandberg if (scr->wsfont && scr->wsfontcookie != -1) 1430 1.15 jandberg wsfont_unlock(scr->wsfontcookie); 1431 1.15 jandberg scr->wsfont = NULL; 1432 1.15 jandberg scr->wsfontcookie = -1; 1433 1.2 jandberg 1434 1.2 jandberg if (adp->currentscreen == scr) 1435 1.2 jandberg adp->currentscreen = NULL; 1436 1.2 jandberg 1437 1.1 is if (scr->view) 1438 1.1 is grf_free_view(scr->view); 1439 1.1 is scr->view = NULL; 1440 1.1 is 1441 1.1 is /* Take care not to free the statically allocated console screen */ 1442 1.1 is if (scr != &amidisplaycc_consolescreen) { 1443 1.1 is free(scr, M_DEVBUF); 1444 1.1 is } 1445 1.1 is } 1446 1.1 is 1447 1.2 jandberg /* 1448 1.2 jandberg * Switch to another vt. Switch is always made immediately. 1449 1.2 jandberg */ 1450 1.2 jandberg 1451 1.2 jandberg /* ARGSUSED2 */ 1452 1.1 is int 1453 1.3 aymeric amidisplaycc_show_screen(void *dp, void *screen, int waitok, 1454 1.3 aymeric void (*cb) (void *, int, int), void *cbarg) 1455 1.1 is { 1456 1.1 is adccscr_t *scr; 1457 1.2 jandberg struct amidisplaycc_softc *adp; 1458 1.1 is 1459 1.2 jandberg adp = (struct amidisplaycc_softc*)dp; 1460 1.1 is scr = screen; 1461 1.2 jandberg 1462 1.2 jandberg if (adp == NULL) { 1463 1.2 jandberg dprintf("amidisplaycc_show_screen: adp==NULL\n"); 1464 1.36 rin return EINVAL; 1465 1.2 jandberg } 1466 1.2 jandberg if (scr == NULL) { 1467 1.2 jandberg dprintf("amidisplaycc_show_screen: scr==NULL\n"); 1468 1.36 rin return EINVAL; 1469 1.2 jandberg } 1470 1.2 jandberg 1471 1.2 jandberg if (adp->gfxon) { 1472 1.2 jandberg dprintf("amidisplaycc: Screen shift while in gfx mode?"); 1473 1.2 jandberg adp->gfxon = 0; 1474 1.2 jandberg } 1475 1.2 jandberg 1476 1.2 jandberg adp->currentscreen = scr; 1477 1.2 jandberg adp->ison = 1; 1478 1.2 jandberg 1479 1.1 is grf_display_view(scr->view); 1480 1.2 jandberg 1481 1.36 rin return 0; 1482 1.1 is } 1483 1.1 is 1484 1.1 is /* 1485 1.15 jandberg * Load/set a font. 1486 1.2 jandberg * 1487 1.15 jandberg * Only setting is supported, as the wsfont pseudo-device can 1488 1.15 jandberg * handle the loading of fonts for us. 1489 1.1 is */ 1490 1.1 is int 1491 1.3 aymeric amidisplaycc_load_font(void *dp, void *cookie, struct wsdisplay_font *font) 1492 1.2 jandberg { 1493 1.27 mlelstv struct amidisplaycc_softc * adp __diagused; 1494 1.27 mlelstv struct amidisplaycc_screen * scr __diagused; 1495 1.2 jandberg 1496 1.2 jandberg adp = dp; 1497 1.2 jandberg scr = cookie; 1498 1.2 jandberg 1499 1.15 jandberg KASSERT(adp); 1500 1.15 jandberg KASSERT(scr); 1501 1.15 jandberg KASSERT(font); 1502 1.15 jandberg KASSERT(font->name); 1503 1.15 jandberg 1504 1.15 jandberg if (font->data) 1505 1.15 jandberg { 1506 1.15 jandberg /* request to load the font, not supported */ 1507 1.36 rin return EINVAL; 1508 1.2 jandberg } 1509 1.15 jandberg else 1510 1.15 jandberg { 1511 1.15 jandberg /* request to use the given font on this screen */ 1512 1.15 jandberg return amidisplaycc_setfont(scr, font->name); 1513 1.2 jandberg } 1514 1.2 jandberg } 1515 1.2 jandberg 1516 1.2 jandberg /* 1517 1.2 jandberg * Set display on/off. 1518 1.2 jandberg */ 1519 1.2 jandberg static int 1520 1.3 aymeric amidisplaycc_setvideo(struct amidisplaycc_softc *adp, int mode) 1521 1.2 jandberg { 1522 1.2 jandberg view_t * view; 1523 1.2 jandberg 1524 1.2 jandberg if (adp == NULL) { 1525 1.2 jandberg dprintf("amidisplaycc_setvideo: adp==NULL\n"); 1526 1.36 rin return EINVAL; 1527 1.2 jandberg } 1528 1.2 jandberg if (adp->currentscreen == NULL) { 1529 1.2 jandberg dprintf("amidisplaycc_setvideo: adp->currentscreen==NULL\n"); 1530 1.36 rin return EINVAL; 1531 1.2 jandberg } 1532 1.2 jandberg 1533 1.2 jandberg /* select graphics or emulation screen */ 1534 1.2 jandberg if (adp->gfxon && adp->gfxview) 1535 1.2 jandberg view = adp->gfxview; 1536 1.2 jandberg else 1537 1.2 jandberg view = adp->currentscreen->view; 1538 1.2 jandberg 1539 1.2 jandberg if (mode) { 1540 1.2 jandberg /* on */ 1541 1.2 jandberg 1542 1.2 jandberg grf_display_view(view); 1543 1.2 jandberg dprintf("amidisplaycc: video is now on\n"); 1544 1.2 jandberg adp->ison = 1; 1545 1.2 jandberg 1546 1.2 jandberg } else { 1547 1.2 jandberg /* off */ 1548 1.2 jandberg 1549 1.2 jandberg grf_remove_view(view); 1550 1.2 jandberg dprintf("amidisplaycc: video is now off\n"); 1551 1.2 jandberg adp->ison = 0; 1552 1.2 jandberg } 1553 1.2 jandberg 1554 1.36 rin return 0; 1555 1.2 jandberg } 1556 1.2 jandberg 1557 1.2 jandberg /* 1558 1.2 jandberg * Handle the WSDISPLAY_[PUT/GET]CMAP ioctls. 1559 1.2 jandberg * Just handle the copying of data to/from userspace and 1560 1.2 jandberg * let the functions amidisplaycc_setcmap and amidisplaycc_putcmap 1561 1.2 jandberg * do the real work. 1562 1.2 jandberg */ 1563 1.2 jandberg 1564 1.2 jandberg static int 1565 1.3 aymeric amidisplaycc_cmapioctl(view_t *view, u_long cmd, struct wsdisplay_cmap *cmap) 1566 1.2 jandberg { 1567 1.2 jandberg struct wsdisplay_cmap tmpcmap; 1568 1.2 jandberg u_char cmred[MAXCOLORS]; 1569 1.2 jandberg u_char cmgrn[MAXCOLORS]; 1570 1.2 jandberg u_char cmblu[MAXCOLORS]; 1571 1.2 jandberg 1572 1.2 jandberg int err; 1573 1.2 jandberg 1574 1.2 jandberg if (cmap->index >= MAXCOLORS || 1575 1.2 jandberg cmap->count > MAXCOLORS || 1576 1.2 jandberg cmap->index + cmap->count > MAXCOLORS) 1577 1.36 rin return EINVAL; 1578 1.2 jandberg 1579 1.2 jandberg if (cmap->count == 0) 1580 1.36 rin return 0; 1581 1.3 aymeric 1582 1.2 jandberg tmpcmap.index = cmap->index; 1583 1.2 jandberg tmpcmap.count = cmap->count; 1584 1.2 jandberg tmpcmap.red = cmred; 1585 1.2 jandberg tmpcmap.green = cmgrn; 1586 1.2 jandberg tmpcmap.blue = cmblu; 1587 1.2 jandberg 1588 1.2 jandberg if (cmd == WSDISPLAYIO_PUTCMAP) { 1589 1.2 jandberg /* copy the color data to kernel space */ 1590 1.2 jandberg 1591 1.2 jandberg err = copyin(cmap->red, cmred, cmap->count); 1592 1.2 jandberg if (err) 1593 1.36 rin return err; 1594 1.2 jandberg 1595 1.2 jandberg err = copyin(cmap->green, cmgrn, cmap->count); 1596 1.2 jandberg if (err) 1597 1.36 rin return err; 1598 1.2 jandberg 1599 1.2 jandberg err = copyin(cmap->blue, cmblu, cmap->count); 1600 1.2 jandberg if (err) 1601 1.36 rin return err; 1602 1.2 jandberg 1603 1.2 jandberg return amidisplaycc_setcmap(view, &tmpcmap); 1604 1.3 aymeric 1605 1.2 jandberg } else if (cmd == WSDISPLAYIO_GETCMAP) { 1606 1.2 jandberg 1607 1.2 jandberg err = amidisplaycc_getcmap(view, &tmpcmap); 1608 1.2 jandberg if (err) 1609 1.36 rin return err; 1610 1.2 jandberg 1611 1.2 jandberg /* copy data to user space */ 1612 1.2 jandberg 1613 1.2 jandberg err = copyout(cmred, cmap->red, cmap->count); 1614 1.2 jandberg if (err) 1615 1.36 rin return err; 1616 1.2 jandberg 1617 1.2 jandberg err = copyout(cmgrn, cmap->green, cmap->count); 1618 1.2 jandberg if (err) 1619 1.36 rin return err; 1620 1.2 jandberg 1621 1.2 jandberg err = copyout(cmblu, cmap->blue, cmap->count); 1622 1.2 jandberg if (err) 1623 1.36 rin return err; 1624 1.2 jandberg 1625 1.36 rin return 0; 1626 1.3 aymeric 1627 1.2 jandberg } else 1628 1.36 rin return EPASSTHROUGH; 1629 1.2 jandberg } 1630 1.2 jandberg 1631 1.2 jandberg /* 1632 1.2 jandberg * Set the palette of a emulation screen. 1633 1.2 jandberg * Here we do only color remapping and then call 1634 1.2 jandberg * amidisplaycc_setcmap to do the work. 1635 1.2 jandberg */ 1636 1.2 jandberg 1637 1.2 jandberg static int 1638 1.3 aymeric amidisplaycc_setemulcmap(struct amidisplaycc_screen *scr, 1639 1.3 aymeric struct wsdisplay_cmap *cmap) 1640 1.2 jandberg { 1641 1.2 jandberg struct wsdisplay_cmap tmpcmap; 1642 1.2 jandberg 1643 1.2 jandberg u_char red [MAXCOLORS]; 1644 1.2 jandberg u_char grn [MAXCOLORS]; 1645 1.2 jandberg u_char blu [MAXCOLORS]; 1646 1.2 jandberg 1647 1.2 jandberg int rc; 1648 1.2 jandberg int i; 1649 1.2 jandberg 1650 1.2 jandberg /* 1651 1.3 aymeric * Get old palette first. 1652 1.2 jandberg * Because of the color mapping going on in the emulation 1653 1.2 jandberg * screen the color range may not be contiguous in the real 1654 1.2 jandberg * palette. 1655 1.2 jandberg * So get the whole palette, insert the new colors 1656 1.2 jandberg * at the appropriate places and then set the whole 1657 1.2 jandberg * palette back. 1658 1.2 jandberg */ 1659 1.2 jandberg 1660 1.2 jandberg tmpcmap.index = 0; 1661 1.2 jandberg tmpcmap.count = 1 << scr->depth; 1662 1.2 jandberg tmpcmap.red = red; 1663 1.2 jandberg tmpcmap.green = grn; 1664 1.2 jandberg tmpcmap.blue = blu; 1665 1.2 jandberg 1666 1.2 jandberg rc = amidisplaycc_getcmap(scr->view, &tmpcmap); 1667 1.2 jandberg if (rc) 1668 1.36 rin return rc; 1669 1.2 jandberg 1670 1.2 jandberg for (i = cmap->index ; i < cmap->index + cmap->count ; i++) { 1671 1.2 jandberg 1672 1.2 jandberg tmpcmap.red [ scr->colormap[ i ] ] = cmap->red [ i ]; 1673 1.2 jandberg tmpcmap.green [ scr->colormap[ i ] ] = cmap->green [ i ]; 1674 1.2 jandberg tmpcmap.blue [ scr->colormap[ i ] ] = cmap->blue [ i ]; 1675 1.2 jandberg } 1676 1.2 jandberg 1677 1.2 jandberg rc = amidisplaycc_setcmap(scr->view, &tmpcmap); 1678 1.2 jandberg if (rc) 1679 1.36 rin return rc; 1680 1.3 aymeric 1681 1.36 rin return 0; 1682 1.2 jandberg } 1683 1.2 jandberg 1684 1.2 jandberg 1685 1.2 jandberg /* 1686 1.3 aymeric * Set the colormap for the given screen. 1687 1.2 jandberg */ 1688 1.2 jandberg 1689 1.2 jandberg static int 1690 1.3 aymeric amidisplaycc_setcmap(view_t *view, struct wsdisplay_cmap *cmap) 1691 1.2 jandberg { 1692 1.2 jandberg u_long cmentries [MAXCOLORS]; 1693 1.2 jandberg 1694 1.2 jandberg u_int colors; 1695 1.2 jandberg int index; 1696 1.2 jandberg int count; 1697 1.2 jandberg int err; 1698 1.2 jandberg colormap_t cm; 1699 1.2 jandberg 1700 1.2 jandberg if (view == NULL) 1701 1.36 rin return EINVAL; 1702 1.2 jandberg 1703 1.2 jandberg if (!cmap || !cmap->red || !cmap->green || !cmap->blue) { 1704 1.2 jandberg dprintf("amidisplaycc_setcmap: other==NULL\n"); 1705 1.36 rin return EINVAL; 1706 1.2 jandberg } 1707 1.2 jandberg 1708 1.2 jandberg index = cmap->index; 1709 1.2 jandberg count = cmap->count; 1710 1.2 jandberg colors = (1 << view->bitmap->depth); 1711 1.2 jandberg 1712 1.2 jandberg if (count > colors || index >= colors || index + count > colors) 1713 1.36 rin return EINVAL; 1714 1.2 jandberg 1715 1.2 jandberg if (count == 0) 1716 1.36 rin return 0; 1717 1.2 jandberg 1718 1.2 jandberg cm.entry = cmentries; 1719 1.2 jandberg cm.first = index; 1720 1.2 jandberg cm.size = count; 1721 1.2 jandberg 1722 1.3 aymeric /* 1723 1.2 jandberg * Get the old colormap. We need to do this at least to know 1724 1.2 jandberg * how many bits to use with the color values. 1725 1.2 jandberg */ 1726 1.2 jandberg 1727 1.2 jandberg err = grf_get_colormap(view, &cm); 1728 1.2 jandberg if (err) 1729 1.36 rin return err; 1730 1.2 jandberg 1731 1.3 aymeric /* 1732 1.2 jandberg * The palette entries from wscons contain 8 bits per gun. 1733 1.2 jandberg * We need to convert them to the number of bits the view 1734 1.3 aymeric * expects. That is typically 4 or 8. Here we calculate the 1735 1.2 jandberg * conversion constants with which we divide the color values. 1736 1.2 jandberg */ 1737 1.2 jandberg 1738 1.2 jandberg if (cm.type == CM_COLOR) { 1739 1.13 jandberg int c, green_div, blue_div, red_div; 1740 1.13 jandberg 1741 1.2 jandberg red_div = 256 / (cm.red_mask + 1); 1742 1.2 jandberg green_div = 256 / (cm.green_mask + 1); 1743 1.2 jandberg blue_div = 256 / (cm.blue_mask + 1); 1744 1.13 jandberg 1745 1.13 jandberg for (c = 0 ; c < count ; c++) 1746 1.2 jandberg cm.entry[c + index] = MAKE_COLOR_ENTRY( 1747 1.2 jandberg cmap->red[c] / red_div, 1748 1.2 jandberg cmap->green[c] / green_div, 1749 1.2 jandberg cmap->blue[c] / blue_div); 1750 1.2 jandberg 1751 1.13 jandberg } else if (cm.type == CM_GREYSCALE) { 1752 1.13 jandberg int c, grey_div; 1753 1.2 jandberg 1754 1.13 jandberg grey_div = 256 / (cm.grey_mask + 1); 1755 1.2 jandberg 1756 1.13 jandberg /* Generate grey from average of r-g-b (?) */ 1757 1.13 jandberg for (c = 0 ; c < count ; c++) 1758 1.2 jandberg cm.entry[c + index] = MAKE_COLOR_ENTRY( 1759 1.2 jandberg 0, 1760 1.2 jandberg 0, 1761 1.3 aymeric (cmap->red[c] + 1762 1.3 aymeric cmap->green[c] + 1763 1.2 jandberg cmap->blue[c]) / 3 / grey_div); 1764 1.13 jandberg } else 1765 1.36 rin return EINVAL; /* Hmhh */ 1766 1.3 aymeric 1767 1.3 aymeric /* 1768 1.2 jandberg * Now we have a new colormap that contains all the entries. Set 1769 1.2 jandberg * it to the view. 1770 1.2 jandberg */ 1771 1.2 jandberg 1772 1.2 jandberg err = grf_use_colormap(view, &cm); 1773 1.2 jandberg if (err) 1774 1.2 jandberg return err; 1775 1.2 jandberg 1776 1.36 rin return 0; 1777 1.2 jandberg } 1778 1.2 jandberg 1779 1.2 jandberg /* 1780 1.2 jandberg * Return the colormap of the given screen. 1781 1.2 jandberg */ 1782 1.2 jandberg 1783 1.2 jandberg static int 1784 1.3 aymeric amidisplaycc_getcmap(view_t *view, struct wsdisplay_cmap *cmap) 1785 1.2 jandberg { 1786 1.2 jandberg u_long cmentries [MAXCOLORS]; 1787 1.2 jandberg 1788 1.2 jandberg u_int colors; 1789 1.2 jandberg int index; 1790 1.2 jandberg int count; 1791 1.2 jandberg int err; 1792 1.2 jandberg colormap_t cm; 1793 1.2 jandberg 1794 1.2 jandberg if (view == NULL) 1795 1.36 rin return EINVAL; 1796 1.2 jandberg 1797 1.2 jandberg if (!cmap || !cmap->red || !cmap->green || !cmap->blue) 1798 1.36 rin return EINVAL; 1799 1.2 jandberg 1800 1.2 jandberg index = cmap->index; 1801 1.2 jandberg count = cmap->count; 1802 1.2 jandberg colors = (1 << view->bitmap->depth); 1803 1.2 jandberg 1804 1.2 jandberg if (count > colors || index >= colors || index + count > colors) 1805 1.36 rin return EINVAL; 1806 1.2 jandberg 1807 1.2 jandberg if (count == 0) 1808 1.36 rin return 0; 1809 1.2 jandberg 1810 1.2 jandberg cm.entry = cmentries; 1811 1.2 jandberg cm.first = index; 1812 1.2 jandberg cm.size = count; 1813 1.2 jandberg 1814 1.2 jandberg err = grf_get_colormap(view, &cm); 1815 1.2 jandberg if (err) 1816 1.36 rin return err; 1817 1.2 jandberg 1818 1.13 jandberg /* 1819 1.13 jandberg * Copy color data to wscons-style structure. Translate to 1820 1.13 jandberg * 8 bits/gun from whatever resolution the color natively is. 1821 1.13 jandberg */ 1822 1.2 jandberg if (cm.type == CM_COLOR) { 1823 1.13 jandberg int c, red_mul, green_mul, blue_mul; 1824 1.13 jandberg 1825 1.2 jandberg red_mul = 256 / (cm.red_mask + 1); 1826 1.2 jandberg green_mul = 256 / (cm.green_mask + 1); 1827 1.2 jandberg blue_mul = 256 / (cm.blue_mask + 1); 1828 1.13 jandberg 1829 1.13 jandberg for (c = 0 ; c < count ; c++) { 1830 1.13 jandberg cmap->red[c] = red_mul * 1831 1.13 jandberg CM_GET_RED(cm.entry[index+c]); 1832 1.13 jandberg cmap->green[c] = green_mul * 1833 1.13 jandberg CM_GET_GREEN(cm.entry[index+c]); 1834 1.13 jandberg cmap->blue[c] = blue_mul * 1835 1.13 jandberg CM_GET_BLUE(cm.entry[index+c]); 1836 1.13 jandberg } 1837 1.2 jandberg } else if (cm.type == CM_GREYSCALE) { 1838 1.13 jandberg int c, grey_mul; 1839 1.2 jandberg 1840 1.13 jandberg grey_mul = 256 / (cm.grey_mask + 1); 1841 1.2 jandberg 1842 1.13 jandberg for (c = 0 ; c < count ; c++) { 1843 1.13 jandberg cmap->red[c] = grey_mul * 1844 1.13 jandberg CM_GET_GREY(cm.entry[index+c]); 1845 1.13 jandberg cmap->green[c] = grey_mul * 1846 1.13 jandberg CM_GET_GREY(cm.entry[index+c]); 1847 1.13 jandberg cmap->blue[c] = grey_mul * 1848 1.13 jandberg CM_GET_GREY(cm.entry[index+c]); 1849 1.2 jandberg } 1850 1.13 jandberg } else 1851 1.36 rin return EINVAL; 1852 1.2 jandberg 1853 1.36 rin return 0; 1854 1.2 jandberg } 1855 1.2 jandberg 1856 1.15 jandberg /* 1857 1.15 jandberg * Find and set a font for the given screen. 1858 1.15 jandberg * 1859 1.15 jandberg * If fontname is given, a font with that name and suitable 1860 1.15 jandberg * size (determined by the screen) is searched for. 1861 1.15 jandberg * If fontname is NULL, a font with suitable size is searched. 1862 1.15 jandberg * 1863 1.15 jandberg * On success, the found font is assigned to the screen and possible 1864 1.15 jandberg * old font is freed. 1865 1.15 jandberg */ 1866 1.15 jandberg static int 1867 1.15 jandberg amidisplaycc_setfont(struct amidisplaycc_screen *scr, const char *fontname) 1868 1.15 jandberg { 1869 1.15 jandberg struct wsdisplay_font *wsfont; 1870 1.15 jandberg int wsfontcookie; 1871 1.15 jandberg 1872 1.15 jandberg KASSERT(scr); 1873 1.15 jandberg 1874 1.15 jandberg wsfontcookie = wsfont_find(fontname, 1875 1.15 jandberg scr->fontwidth, 1876 1.15 jandberg scr->fontheight, 1877 1.15 jandberg 1, 1878 1.15 jandberg WSDISPLAY_FONTORDER_L2R, 1879 1.25 macallan WSDISPLAY_FONTORDER_L2R, 1880 1.25 macallan WSFONT_FIND_BITMAP); 1881 1.15 jandberg 1882 1.15 jandberg if (wsfontcookie == -1) 1883 1.36 rin return EINVAL; 1884 1.15 jandberg 1885 1.15 jandberg /* Suitable font found. Now lock it. */ 1886 1.15 jandberg if (wsfont_lock(wsfontcookie, &wsfont)) 1887 1.36 rin return EINVAL; 1888 1.15 jandberg 1889 1.15 jandberg KASSERT(wsfont); 1890 1.15 jandberg 1891 1.15 jandberg if (scr->wsfont && scr->wsfontcookie != -1) 1892 1.15 jandberg wsfont_unlock(scr->wsfontcookie); 1893 1.15 jandberg 1894 1.15 jandberg scr->wsfont = wsfont; 1895 1.15 jandberg scr->wsfontcookie = wsfontcookie; 1896 1.39 jandberg 1897 1.36 rin return 0; 1898 1.15 jandberg } 1899 1.15 jandberg 1900 1.15 jandberg /* 1901 1.15 jandberg * Return a font that is guaranteed to exist. 1902 1.15 jandberg */ 1903 1.15 jandberg static const struct wsdisplay_font * 1904 1.15 jandberg amidisplaycc_getbuiltinfont(void) 1905 1.15 jandberg { 1906 1.15 jandberg static struct wsdisplay_font font; 1907 1.15 jandberg 1908 1.15 jandberg extern unsigned char kernel_font_width_8x8; 1909 1.15 jandberg extern unsigned char kernel_font_height_8x8; 1910 1.15 jandberg extern unsigned char kernel_font_lo_8x8; 1911 1.15 jandberg extern unsigned char kernel_font_hi_8x8; 1912 1.15 jandberg extern unsigned char kernel_font_8x8[]; 1913 1.15 jandberg 1914 1.15 jandberg font.name = "kf8x8"; 1915 1.15 jandberg font.firstchar = kernel_font_lo_8x8; 1916 1.15 jandberg font.numchars = kernel_font_hi_8x8 - kernel_font_lo_8x8 + 1; 1917 1.15 jandberg font.fontwidth = kernel_font_width_8x8; 1918 1.15 jandberg font.stride = 1; 1919 1.15 jandberg font.fontheight = kernel_font_height_8x8; 1920 1.15 jandberg font.data = kernel_font_8x8; 1921 1.15 jandberg 1922 1.15 jandberg /* these values aren't really used for anything */ 1923 1.15 jandberg font.encoding = WSDISPLAY_FONTENC_ISO; 1924 1.15 jandberg font.bitorder = WSDISPLAY_FONTORDER_KNOWN; 1925 1.15 jandberg font.byteorder = WSDISPLAY_FONTORDER_KNOWN; 1926 1.15 jandberg 1927 1.15 jandberg return &font; 1928 1.15 jandberg } 1929 1.15 jandberg 1930 1.2 jandberg /* ARGSUSED */ 1931 1.3 aymeric void 1932 1.3 aymeric amidisplaycc_pollc(void *cookie, int on) 1933 1.1 is { 1934 1.31 jandberg if (amidisplaycc_consolescreen.isconsole) 1935 1.31 jandberg { 1936 1.31 jandberg if (on) 1937 1.31 jandberg { 1938 1.31 jandberg /* About to use console, so make it visible */ 1939 1.31 jandberg grf_display_view(amidisplaycc_consolescreen.view); 1940 1.31 jandberg } 1941 1.31 jandberg if (!on && 1942 1.31 jandberg amidisplaycc_consolescreen.isconsole && 1943 1.31 jandberg amidisplaycc_consolescreen.device != NULL && 1944 1.31 jandberg amidisplaycc_consolescreen.device->currentscreen != NULL) 1945 1.31 jandberg { 1946 1.31 jandberg /* Restore the correct view after done with console use */ 1947 1.31 jandberg grf_display_view(amidisplaycc_consolescreen.device->currentscreen->view); 1948 1.31 jandberg } 1949 1.31 jandberg } 1950 1.1 is } 1951 1.1 is 1952 1.3 aymeric /* 1953 1.1 is * These dummy functions are here just so that we can compete of 1954 1.1 is * the console at init. 1955 1.1 is * If we win the console then the wscons system will provide the 1956 1.38 andvar * real ones which in turn will call the appropriate wskbd device. 1957 1.1 is * These should never be called. 1958 1.1 is */ 1959 1.1 is 1960 1.2 jandberg /* ARGSUSED */ 1961 1.1 is void 1962 1.3 aymeric amidisplaycc_cnputc(dev_t cd, int ch) 1963 1.1 is { 1964 1.1 is } 1965 1.1 is 1966 1.2 jandberg /* ARGSUSED */ 1967 1.1 is int 1968 1.3 aymeric amidisplaycc_cngetc(dev_t cd) 1969 1.1 is { 1970 1.36 rin return 0; 1971 1.1 is } 1972 1.1 is 1973 1.2 jandberg /* ARGSUSED */ 1974 1.3 aymeric void 1975 1.3 aymeric amidisplaycc_cnpollc(dev_t cd, int on) 1976 1.1 is { 1977 1.1 is } 1978 1.1 is 1979 1.2 jandberg 1980 1.2 jandberg /* 1981 1.2 jandberg * Prints stuff if DEBUG is turned on. 1982 1.2 jandberg */ 1983 1.2 jandberg 1984 1.2 jandberg /* ARGSUSED */ 1985 1.2 jandberg static void 1986 1.3 aymeric dprintf(const char *fmt, ...) 1987 1.2 jandberg { 1988 1.2 jandberg #ifdef DEBUG 1989 1.2 jandberg va_list ap; 1990 1.2 jandberg 1991 1.2 jandberg va_start(ap, fmt); 1992 1.2 jandberg vprintf(fmt, ap); 1993 1.2 jandberg va_end(ap); 1994 1.2 jandberg #endif 1995 1.2 jandberg } 1996 1.2 jandberg 1997 1.1 is #endif /* AMIDISPLAYCC */ 1998