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