1 /* $NetBSD: grfabs_fal.c,v 1.16 2003/04/01 23:47:02 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1995 Thomas Gerner. 5 * Copyright (c) 1995 Leo Weppelman. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Leo Weppelman. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #ifdef FALCON_VIDEO 35 /* 36 * atari abstract graphics driver: Falcon-interface 37 */ 38 #include <sys/param.h> 39 #include <sys/queue.h> 40 #include <sys/malloc.h> 41 #include <sys/device.h> 42 #include <sys/systm.h> 43 44 #include <uvm/uvm_extern.h> 45 46 #include <machine/iomap.h> 47 #include <machine/video.h> 48 #include <machine/mfp.h> 49 #include <atari/atari/device.h> 50 #include <atari/atari/stalloc.h> 51 #include <atari/dev/grfabs_reg.h> 52 #include <atari/dev/grfabs_fal.h> 53 54 /* 55 * Function decls 56 */ 57 static void init_view __P((view_t *, bmap_t *, dmode_t *, box_t *)); 58 static bmap_t *alloc_bitmap __P((u_long, u_long, u_char)); 59 static colormap_t *alloc_colormap __P((dmode_t *)); 60 static void free_bitmap __P((bmap_t *)); 61 static void falcon_display_view __P((view_t *)); 62 static view_t *falcon_alloc_view __P((dmode_t *, dimen_t *, u_char)); 63 static void falcon_free_view __P((view_t *)); 64 static void falcon_remove_view __P((view_t *)); 65 static void falcon_save_view __P((view_t *)); 66 static int falcon_use_colormap __P((view_t *, colormap_t *)); 67 static void falcon_detect __P((dmode_t *)); 68 static struct videl *falcon_getreg __P((u_short)); 69 70 /* 71 * Our function switch table 72 */ 73 struct grfabs_sw fal_vid_sw = { 74 falcon_display_view, 75 falcon_alloc_view, 76 falcon_free_view, 77 falcon_remove_view, 78 falcon_save_view, 79 falcon_use_colormap 80 }; 81 82 struct falcon_hwregs { 83 u_short fal_mode; /* falcon mode */ 84 struct videl *fal_regs; /* videl register values */ 85 }; 86 #define vm_mode(dm) (((struct falcon_hwregs*)(dm->data))->fal_mode) 87 #define vm_regs(dm) (((struct falcon_hwregs*)(dm->data))->fal_regs) 88 89 /* 90 * Note that the order of this table *must* match the order of 91 * the table below! 92 */ 93 static struct falcon_hwregs fal_hwregs[] = { 94 { RES_FALAUTO }, 95 { RES_FAL_STHIGH }, 96 { RES_FAL_STMID }, 97 { RES_FAL_STLOW }, 98 { RES_FAL_TTLOW }, 99 { RES_VGA2 }, 100 { RES_VGA4 }, 101 { RES_VGA16 }, 102 { RES_VGA256 }, 103 { RES_DIRECT } 104 }; 105 106 107 static dmode_t vid_modes[] = { 108 { {NULL,NULL}, "falauto", { 0, 0 }, 0, NULL, &fal_vid_sw}, 109 { {NULL,NULL}, "sthigh", { 640,400 }, 1, NULL, &fal_vid_sw}, 110 { {NULL,NULL}, "stmid", { 640,200 }, 2, NULL, &fal_vid_sw}, 111 { {NULL,NULL}, "stlow", { 320,200 }, 4, NULL, &fal_vid_sw}, 112 { {NULL,NULL}, "ttlow", { 320,480 }, 8, NULL, &fal_vid_sw}, 113 { {NULL,NULL}, "vga2", { 640,480 }, 1, NULL, &fal_vid_sw}, 114 { {NULL,NULL}, "vga4", { 640,480 }, 2, NULL, &fal_vid_sw}, 115 { {NULL,NULL}, "vga16", { 640,480 }, 4, NULL, &fal_vid_sw}, 116 { {NULL,NULL}, "vga256", { 640,480 }, 8, NULL, &fal_vid_sw}, 117 { {NULL,NULL}, "highcol", { 320,200 }, 16, NULL, &fal_vid_sw}, 118 { {NULL,NULL}, NULL, } 119 }; 120 121 /* 122 * The following table contains timing values for the various video modes. 123 * I have only a multisync display, therefore I can not say if this values 124 * are useful at other displays. 125 * Use other video modes at YOUR OWN RISK. 126 * THERE IS NO WARRENTY ABOUT THIS VALUES TO WORK WITH A PARTICULAR 127 * DISPLAY. -- Thomas 128 */ 129 static struct videl videlinit[] = { 130 { RES_FALAUTO, /* autodedect */ 131 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 132 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, 133 134 { FAL_VGA | RES_FAL_STHIGH, /* sthigh, 640x400, 2 colors */ 135 0x2, 0x0, 0x28, 0x0, 0x400, 0xc6, 0x8d, 0x15, 0x273, 0x50, 0x96, 0x0, 136 0x0, 0x419, 0x3af, 0x8f, 0x8f, 0x3af, 0x415, 0x186, 0x8 }, 137 138 #if 0 /* not yet */ 139 { FAL_SM | RES_FAL_STHIGH, /* sthigh, 640x400, 2 colors */ 140 0x0, 0x0, 0x28, 0x2, 0x0, 0x1a, 0x0, 0x0, 0x20f, 0xc, 0x14, 0x0, 141 0x0, 0x3e9, 0x0, 0x0, 0x43, 0x363, 0x3e7, 0x80, 0x8 }, 142 #endif 143 144 { FAL_VGA | RES_FAL_STMID, /* stmid, 640x200, 4 colors */ 145 0x2, 0x0, 0x50, 0x1, 0x0, 0x17, 0x12, 0x1, 0x20e, 0xd, 0x11, 0x0, 146 0x0, 0x419, 0x3af, 0x8f, 0x8f, 0x3af, 0x415, 0x186, 0x9 }, 147 148 { FAL_VGA | RES_FAL_STLOW, /* stlow, 320x200, 16 colors */ 149 0x2, 0x0, 0x50, 0x0, 0x0, 0x17, 0x12, 0x1, 0x20e, 0xd, 0x11, 0x0, 150 0x0, 0x419, 0x3af, 0x8f, 0x8f, 0x3af, 0x415, 0x186, 0x5 }, 151 152 { FAL_VGA | RES_FAL_TTLOW, /* ttlow, 320x480, 256 colors */ 153 0x2, 0x0, 0xa0, 0x0, 0x10, 0xc6, 0x8d, 0x15, 0x29a, 0x7b, 0x96, 0x0, 154 0x0, 0x419, 0x3ff, 0x3f, 0x3f, 0x3ff, 0x415, 0x186, 0x4 }, 155 156 { FAL_VGA | RES_VGA2, /* vga, 640x480, 2 colors */ 157 0x2, 0x0, 0x28, 0x0, 0x400, 0xc6, 0x8d, 0x15, 0x273, 0x50, 0x96, 0x0, 158 0x0, 0x419, 0x3ff, 0x3f, 0x3f, 0x3ff, 0x415, 0x186, 0x8 }, 159 160 { FAL_VGA | RES_VGA4, /* vga, 640x480, 4 colors */ 161 0x2, 0x0, 0x50, 0x1, 0x0, 0x17, 0x12, 0x1, 0x20e, 0xd, 0x11, 0x0, 162 0x0, 0x419, 0x3ff, 0x3f, 0x3f, 0x3ff, 0x415, 0x186, 0x8 }, 163 164 { FAL_VGA | RES_VGA16, /* vga, 640x480, 16 colors */ 165 0x2, 0x0, 0xa0, 0x1, 0x0, 0xc6, 0x8d, 0x15, 0x2a3, 0x7c, 0x96, 0x0, 166 0x0, 0x419, 0x3ff, 0x3f, 0x3f, 0x3ff, 0x415, 0x186, 0x8 }, 167 168 { FAL_VGA | RES_VGA256, /* vga, 640x480, 256 colors */ 169 0x2, 0x0, 0x140, 0x1, 0x10, 0xc6, 0x8d, 0x15, 0x2ab, 0x84, 0x96, 0x0, 170 0x0, 0x419, 0x3ff, 0x3f, 0x3f, 0x3ff, 0x415, 0x186, 0x8 }, 171 172 { FAL_VGA | RES_DIRECT, /* direct video, 320x200, 65536 colors */ 173 0x2, 0x0, 0x140, 0x0, 0x100, 0xc6, 0x8d, 0x15, 0x2ac, 0x91, 0x96, 0x0, 174 0x0, 0x419, 0x3ff, 0x3f, 0x3f, 0x3ff, 0x415, 0x186, 0x4 }, 175 176 { 0xffff } /* end of list */ 177 }; 178 179 static u_short mon_type; 180 /* 181 * XXX: called from ite console init routine. 182 * Initialize list of possible video modes. 183 */ 184 void 185 falcon_probe_video(modelp) 186 MODES *modelp; 187 { 188 dmode_t *dm; 189 struct videl *vregs; 190 int i; 191 192 mon_type = *(volatile unsigned char *)(AD_FAL_MON_TYPE); 193 mon_type = (mon_type & 0xc0) << 2; 194 195 /* 196 * get all possible modes 197 */ 198 199 for (i = 0; (dm = &vid_modes[i])->name != NULL; i++) { 200 dm->data = (void *)&fal_hwregs[i]; 201 if (vm_mode(dm) == RES_FALAUTO) { 202 vm_regs(dm) = falcon_getreg(RES_FALAUTO); 203 falcon_detect(dm); 204 LIST_INSERT_HEAD(modelp, dm, link); 205 } else { 206 vregs = falcon_getreg(vm_mode(dm) | mon_type); 207 if (vregs) { 208 vm_regs(dm) = vregs; 209 LIST_INSERT_HEAD(modelp, dm, link); 210 } 211 } 212 } 213 214 /* 215 * This seems to prevent bordered screens. 216 */ 217 for (i=0; i < 16; i++) 218 VIDEO->vd_fal_rgb[i] = CM_L2FAL(gra_def_color16[i]); 219 } 220 221 static struct videl * 222 falcon_getreg(mode) 223 u_short mode; 224 { 225 int i; 226 struct videl *vregs; 227 228 for (i = 0; (vregs = &videlinit[i])->video_mode != 0xffff; i++) 229 if ((vregs->video_mode) == mode) 230 return vregs; 231 232 return NULL; /* mode not found */ 233 } 234 235 static void 236 falcon_detect(dm) 237 dmode_t *dm; 238 { 239 u_short falshift, stshift; 240 struct videl *vregs = vm_regs(dm); 241 242 /* 243 * First get the videl register values 244 */ 245 246 vregs->vd_syncmode = VIDEO->vd_sync; 247 vregs->vd_line_wide = VIDEO->vd_line_wide; 248 vregs->vd_vert_wrap = VIDEO->vd_vert_wrap; 249 vregs->vd_st_res = VIDEO->vd_st_res; 250 vregs->vd_fal_res = VIDEO->vd_fal_res; 251 vregs->vd_h_hold_tim = VIDEO->vd_h_hold_tim; 252 vregs->vd_h_bord_beg = VIDEO->vd_h_bord_beg; 253 vregs->vd_h_bord_end = VIDEO->vd_h_bord_end; 254 vregs->vd_h_dis_beg = VIDEO->vd_h_dis_beg; 255 vregs->vd_h_dis_end = VIDEO->vd_h_dis_end; 256 vregs->vd_h_ss = VIDEO->vd_h_ss; 257 vregs->vd_h_fs = VIDEO->vd_h_fs; 258 vregs->vd_h_hh = VIDEO->vd_h_hh; 259 vregs->vd_v_freq_tim = VIDEO->vd_v_freq_tim; 260 vregs->vd_v_bord_beg = VIDEO->vd_v_bord_beg; 261 vregs->vd_v_bord_end = VIDEO->vd_v_bord_end; 262 vregs->vd_v_dis_beg = VIDEO->vd_v_dis_beg; 263 vregs->vd_v_dis_end = VIDEO->vd_v_dis_end; 264 vregs->vd_v_ss = VIDEO->vd_v_ss; 265 vregs->vd_fal_ctrl = VIDEO->vd_fal_ctrl; 266 vregs->vd_fal_mode = VIDEO->vd_fal_mode; 267 268 269 /* 270 * Calculate the depth of the screen 271 */ 272 273 falshift = vregs->vd_fal_res; 274 stshift = vregs->vd_st_res; 275 276 if (falshift & 0x400) /* 2 color */ 277 dm->depth = 1; 278 else if (falshift & 0x100) /* high color, direct */ 279 dm->depth = 16; 280 else if (falshift & 0x10) /* 256 color */ 281 dm->depth = 8; 282 else if (stshift == 0) /* 16 color */ 283 dm->depth = 4; 284 else if (stshift == 1) /* 4 color */ 285 dm->depth = 2; 286 else dm->depth = 1; /* 2 color */ 287 288 /* 289 * Now calculate the screen hight 290 */ 291 292 dm->size.height = vregs->vd_v_dis_end - vregs->vd_v_dis_beg; 293 if (!((vregs->vd_fal_mode & 0x2) >> 1)) /* if not interlaced */ 294 dm->size.height >>=1; 295 if (vregs->vd_fal_mode & 0x1) /* if doublescan */ 296 dm->size.height >>=1; 297 298 /* 299 * And the width 300 */ 301 302 dm->size.width = vregs->vd_vert_wrap * 16 / dm->depth; 303 304 } 305 306 u_long falcon_needs_vbl; 307 void falcon_display_switch __P((void)); 308 309 static void 310 falcon_display_view(v) 311 view_t *v; 312 { 313 dmode_t *dm = v->mode; 314 bmap_t *bm; 315 struct videl *vregs; 316 static u_short last_mode = 0xffff; 317 318 if (dm->current_view) { 319 /* 320 * Mark current view for this mode as no longer displayed 321 */ 322 dm->current_view->flags &= ~VF_DISPLAY; 323 } 324 dm->current_view = v; 325 v->flags |= VF_DISPLAY; 326 vregs = vm_regs(v->mode); 327 328 falcon_use_colormap(v, v->colormap); 329 330 bm = v->bitmap; 331 VIDEO->vd_ramh = ((u_long)bm->hw_address >> 16) & 0xff; 332 VIDEO->vd_ramm = ((u_long)bm->hw_address >> 8) & 0xff; 333 VIDEO->vd_raml = (u_long)bm->hw_address & 0xff; 334 335 if (last_mode != vregs->video_mode) { 336 last_mode = vregs->video_mode; 337 338 if (dm->depth == 1) { 339 /* 340 * Set the resolution registers to a mode, which guarantee 341 * no shifting when the register are written during vbl. 342 */ 343 VIDEO->vd_fal_res = 0; 344 VIDEO->vd_st_res = 0; 345 } 346 347 /* 348 * Arrange for them to be activated 349 * at the second vbl interrupt. 350 */ 351 falcon_needs_vbl = (u_long)v; 352 } 353 } 354 355 void 356 falcon_display_switch() 357 { 358 view_t *v; 359 struct videl *vregs; 360 static int vbl_count = 1; 361 362 if(vbl_count--) return; 363 364 v = (view_t*)falcon_needs_vbl; 365 366 vbl_count = 1; 367 falcon_needs_vbl = 0; 368 369 /* 370 * Write to videl registers only on VGA displays 371 * This is only a hack. Must be fixed soon. XXX -- Thomas 372 */ 373 if(mon_type != FAL_VGA) return; 374 375 vregs = vm_regs(v->mode); 376 377 VIDEO->vd_v_freq_tim = vregs->vd_v_freq_tim; 378 VIDEO->vd_v_ss = vregs->vd_v_ss; 379 VIDEO->vd_v_bord_beg = vregs->vd_v_bord_beg; 380 VIDEO->vd_v_bord_end = vregs->vd_v_bord_end; 381 VIDEO->vd_v_dis_beg = vregs->vd_v_dis_beg; 382 VIDEO->vd_v_dis_end = vregs->vd_v_dis_end; 383 VIDEO->vd_h_hold_tim = vregs->vd_h_hold_tim; 384 VIDEO->vd_h_ss = vregs->vd_h_ss; 385 VIDEO->vd_h_bord_beg = vregs->vd_h_bord_beg; 386 VIDEO->vd_h_bord_end = vregs->vd_h_bord_end; 387 VIDEO->vd_h_dis_beg = vregs->vd_h_dis_beg; 388 VIDEO->vd_h_dis_end = vregs->vd_h_dis_end; 389 #if 0 /* This seems not to be necessary -- Thomas */ 390 VIDEO->vd_h_fs = vregs->vd_h_fs; 391 VIDEO->vd_h_hh = vregs->vd_h_hh; 392 #endif 393 VIDEO->vd_sync = vregs->vd_syncmode; 394 VIDEO->vd_fal_res = 0; 395 if (v->mode->depth == 2) 396 VIDEO->vd_st_res = vregs->vd_st_res; 397 else { 398 VIDEO->vd_st_res = 0; 399 VIDEO->vd_fal_res = vregs->vd_fal_res; 400 } 401 VIDEO->vd_vert_wrap = vregs->vd_vert_wrap; 402 VIDEO->vd_line_wide = vregs->vd_line_wide; 403 VIDEO->vd_fal_ctrl = vregs->vd_fal_ctrl; 404 VIDEO->vd_fal_mode = vregs->vd_fal_mode; 405 } 406 407 static void 408 falcon_remove_view(v) 409 view_t *v; 410 { 411 dmode_t *mode = v->mode; 412 413 if (mode->current_view == v) { 414 #if 0 415 if (v->flags & VF_DISPLAY) 416 panic("Cannot shutdown display"); /* XXX */ 417 #endif 418 mode->current_view = NULL; 419 } 420 v->flags &= ~VF_DISPLAY; 421 } 422 423 void 424 falcon_save_view(v) 425 view_t *v; 426 { 427 } 428 429 static void 430 falcon_free_view(v) 431 view_t *v; 432 { 433 if (v) { 434 falcon_remove_view(v); 435 if (v->colormap != &gra_con_cmap) 436 free(v->colormap, M_DEVBUF); 437 free_bitmap(v->bitmap); 438 if (v != &gra_con_view) 439 free(v, M_DEVBUF); 440 } 441 } 442 443 static int 444 falcon_use_colormap(v, cm) 445 view_t *v; 446 colormap_t *cm; 447 { 448 dmode_t *dm; 449 volatile u_short *creg; 450 volatile u_long *fcreg; 451 u_long *src; 452 colormap_t *vcm; 453 u_long *vcreg; 454 u_short ncreg; 455 int last_streg; 456 int i; 457 458 dm = v->mode; 459 vcm = v->colormap; 460 461 /* 462 * I guess it seems reasonable to require the maps to be 463 * of the same type... 464 */ 465 if (cm->type != vcm->type) 466 return (EINVAL); 467 468 /* 469 * First get the colormap addresses an calculate 470 * howmany colors are in it. 471 */ 472 if (dm->depth == 16) /* direct color, no colormap; 473 but also not (yet) supported */ 474 return(0); 475 fcreg = &VIDEO->vd_fal_rgb[0]; 476 creg = &VIDEO->vd_st_rgb[0]; 477 ncreg = 1 << dm->depth; 478 479 /* If first entry specified beyond capabilities -> error */ 480 if (cm->first >= ncreg) 481 return (EINVAL); 482 483 /* 484 * A little tricky, the actual colormap pointer will be NULL 485 * when view is not displaying, valid otherwise. 486 */ 487 if (v->flags & VF_DISPLAY) { 488 creg = &creg[cm->first]; 489 fcreg = &fcreg[cm->first]; 490 } else { 491 creg = NULL; 492 fcreg = NULL; 493 } 494 495 vcreg = &vcm->entry[cm->first]; 496 ncreg -= cm->first; 497 last_streg = 16 - cm->first; 498 if (cm->size > ncreg) 499 return (EINVAL); 500 ncreg = cm->size; 501 502 for (i = 0, src = cm->entry; i < ncreg; i++, vcreg++) { 503 *vcreg = *src++; 504 505 /* 506 * If displaying, also update actual color register. 507 */ 508 if (fcreg != NULL) { 509 *fcreg++ = CM_L2FAL(*vcreg); 510 if (i < last_streg) 511 *creg++ = CM_L2ST(*vcreg); 512 } 513 } 514 return (0); 515 } 516 517 static view_t * 518 falcon_alloc_view(mode, dim, depth) 519 dmode_t *mode; 520 dimen_t *dim; 521 u_char depth; 522 { 523 view_t *v; 524 bmap_t *bm; 525 526 if (!atari_realconfig) 527 v = &gra_con_view; 528 else v = malloc(sizeof(*v), M_DEVBUF, M_NOWAIT); 529 if (v == NULL) 530 return(NULL); 531 532 bm = alloc_bitmap(mode->size.width, mode->size.height, mode->depth); 533 if (bm) { 534 box_t box; 535 536 v->colormap = alloc_colormap(mode); 537 if (v->colormap) { 538 INIT_BOX(&box,0,0,mode->size.width,mode->size.height); 539 init_view(v, bm, mode, &box); 540 return(v); 541 } 542 free_bitmap(bm); 543 } 544 if (v != &gra_con_view) 545 free(v, M_DEVBUF); 546 return (NULL); 547 } 548 549 static void 550 init_view(v, bm, mode, dbox) 551 view_t *v; 552 bmap_t *bm; 553 dmode_t *mode; 554 box_t *dbox; 555 { 556 v->bitmap = bm; 557 v->mode = mode; 558 v->flags = 0; 559 bcopy(dbox, &v->display, sizeof(box_t)); 560 } 561 562 /* bitmap functions */ 563 564 static bmap_t * 565 alloc_bitmap(width, height, depth) 566 u_long width, height; 567 u_char depth; 568 { 569 u_long total_size, bm_size; 570 void *hw_address; 571 bmap_t *bm; 572 573 /* 574 * Sigh, it seems for mapping to work we need the bitplane data to 575 * 1: be aligned on a page boundry. 576 * 2: be n pages large. 577 * 578 * why? because the user gets a page aligned address, if this is before 579 * your allocation, too bad. Also it seems that the mapping routines 580 * do not watch to closely to the allowable length. so if you go over 581 * n pages by less than another page, the user gets to write all over 582 * the entire page. Since you did not allocate up to a page boundry 583 * (or more) the user writes into someone elses memory. -ch 584 */ 585 bm_size = m68k_round_page((width * height * depth) / NBBY); 586 total_size = bm_size + sizeof(bmap_t) + PAGE_SIZE; 587 588 if ((bm = (bmap_t*)alloc_stmem(total_size, &hw_address)) == NULL) 589 return(NULL); 590 591 bm->plane = (u_char*)bm + sizeof(bmap_t); 592 bm->plane = (u_char*)m68k_round_page(bm->plane); 593 bm->hw_address = (u_char*)hw_address + sizeof(bmap_t); 594 bm->hw_address = (u_char*)m68k_round_page(bm->hw_address); 595 bm->bytes_per_row = (width * depth) / NBBY; 596 bm->rows = height; 597 bm->depth = depth; 598 bm->phys_mappable = (depth * width * height) / NBBY; 599 bm->regs = NULL; 600 bm->hw_regs = NULL; 601 bm->reg_size = 0; 602 bm->vga_address = NULL; 603 bm->vga_mappable = 0; 604 bm->lin_base = 0; 605 bm->vga_base = 0; 606 607 bzero(bm->plane, bm_size); 608 return (bm); 609 } 610 611 static void 612 free_bitmap(bm) 613 bmap_t *bm; 614 { 615 if (bm) 616 free_stmem(bm); 617 } 618 619 static colormap_t * 620 alloc_colormap(dm) 621 dmode_t *dm; 622 { 623 int nentries, i; 624 colormap_t *cm; 625 u_char type = CM_COLOR; 626 627 if (dm->depth == 16) /* direct color, no colormap; 628 not (yet) supported */ 629 nentries = 0; 630 else 631 nentries = 1 << dm->depth; 632 633 if (!atari_realconfig) { 634 cm = &gra_con_cmap; 635 cm->entry = gra_con_colors; 636 } 637 else { 638 int size; 639 640 size = sizeof(*cm) + (nentries * sizeof(cm->entry[0])); 641 cm = malloc(size, M_DEVBUF, M_NOWAIT); 642 if (cm == NULL) 643 return(NULL); 644 cm->entry = (long *)&cm[1]; 645 646 } 647 648 if ((cm->type = type) == CM_COLOR) 649 cm->red_mask = cm->green_mask = cm->blue_mask = 0x3f; 650 651 cm->first = 0; 652 cm->size = nentries; 653 654 for (i = 0; i < nentries; i++) 655 cm->entry[i] = gra_def_color16[i % 16]; 656 return (cm); 657 } 658 #endif /* FALCON_VIDEO */ 659