1 /* $NetBSD: grfabs_cc.c,v 1.6 1994/10/26 02:03:23 cgd Exp $ */ 2 3 /* 4 * Copyright (c) 1994 Christian E. Hopps 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Christian E. Hopps. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * abstract interface for custom chips to the amiga abstract graphics driver. 35 * 36 */ 37 38 #include <sys/param.h> 39 #include <sys/errno.h> 40 #include <sys/cdefs.h> 41 #include <sys/queue.h> 42 43 #include <amiga/amiga/custom.h> 44 #include <amiga/amiga/cc.h> 45 46 #include <amiga/dev/grfabs_reg.h> 47 #include <amiga/dev/grfabs_ccreg.h> 48 49 monitor_t *m_this; 50 mdata_t *m_this_data; 51 char *monitor_name = "CCMONITOR"; 52 monitor_t monitor; 53 mdata_t monitor_data; 54 cop_t *null_mode_copper_list; 55 56 #if defined (GRF_PAL) 57 # if defined (GRF_A2024) 58 dmode_t pal_a2024_mode; 59 dmdata_t pal_a2024_mode_data; 60 cop_t *pal_a2024_frames[F_QD_TOTAL]; 61 u_char *hedley_init; /* init bitplane. */ 62 dmode_t *p24_this; 63 dmdata_t *p24_this_data; 64 65 dmode_t pal_hires_dlace_mode; 66 dmdata_t pal_hires_dlace_mode_data; 67 cop_t *pal_hires_dlace_frames[F_LACE_TOTAL]; 68 dmode_t *phdl_this; 69 dmdata_t *phdl_this_data; 70 # endif /* GRF_A2024 */ 71 72 dmode_t pal_hires_lace_mode; 73 dmdata_t pal_hires_lace_mode_data; 74 cop_t *pal_hires_lace_frames[F_LACE_TOTAL]; 75 dmode_t *phl_this; 76 dmdata_t *phl_this_data; 77 78 dmode_t pal_hires_mode; 79 dmdata_t pal_hires_mode_data; 80 cop_t *pal_hires_frames[F_TOTAL]; 81 dmode_t *ph_this; 82 dmdata_t *ph_this_data; 83 #endif /* PAL */ 84 85 #if defined (GRF_NTSC) 86 # if defined (GRF_A2024) 87 dmode_t a2024_mode; 88 dmdata_t a2024_mode_data; 89 cop_t *a2024_frames[F_QD_TOTAL]; 90 u_char *hedley_init; /* init bitplane. */ 91 dmode_t *a24_this; 92 dmdata_t *a24_this_data; 93 94 dmode_t hires_dlace_mode; 95 dmdata_t hires_dlace_mode_data; 96 cop_t *hires_dlace_frames[F_LACE_TOTAL]; 97 dmode_t *hdl_this; 98 dmdata_t *hdl_this_data; 99 # endif /* GRF_A2024 */ 100 101 # if defined (GRF_AGA) 102 dmode_t aga_mode; 103 dmdata_t aga_mode_data; 104 cop_t *aga_frames[F_TOTAL]; 105 dmode_t *aga_this; 106 dmdata_t *aga_this_data; 107 # endif /* GRF_AGA */ 108 109 dmode_t hires_lace_mode; 110 dmdata_t hires_lace_mode_data; 111 cop_t *hires_lace_frames[F_LACE_TOTAL]; 112 dmode_t *hl_this; 113 dmdata_t *hl_this_data; 114 115 void display_hires_view(view_t * v); 116 dmode_t hires_mode; 117 dmdata_t hires_mode_data; 118 cop_t *hires_frames[F_TOTAL]; 119 dmode_t *h_this; 120 dmdata_t *h_this_data; 121 #endif /* GRF_NTSC */ 122 123 #ifdef GRF_AGA 124 #define AGA_ENABLE 0x0001 125 #define AGA_ENABLE2 0x0002 126 #define AGA_TRACE 0x0004 127 #define AGA_TRACE2 0x0008 128 #define AGA_VGAONLY 0x0010 129 #define AGA_VGA31KHZ 0x0020 130 131 int aga_enable = 0; /* set by start_c(), or can be patched */ 132 #endif 133 134 /* monitor functions. */ 135 monitor_t * 136 cc_init_monitor() 137 { 138 cop_t *cp; 139 140 if (m_this) 141 return(m_this); 142 143 cc_monitor = m_this = &monitor; 144 /* turn sprite DMA off. we don't support them yet. */ 145 custom.dmacon = DMAF_SPRITE; 146 147 m_this->name = monitor_name; 148 m_this_data = m_this->data = &monitor_data; 149 150 m_this->get_current_mode = get_current_mode; 151 m_this->vbl_handler = (vbl_handler_func *) monitor_vbl_handler; 152 m_this->get_next_mode = get_next_mode; 153 m_this->get_best_mode = get_best_mode; 154 155 m_this->alloc_bitmap = alloc_bitmap; 156 m_this->free_bitmap = free_bitmap; 157 158 m_this_data->current_mode = NULL; 159 LIST_INIT(&m_this_data->modes); 160 161 cp = null_mode_copper_list = alloc_chipmem(sizeof(cop_t) * 4); 162 if (!cp) 163 panic("no chipmem for grf."); 164 165 CMOVE(cp, R_COLOR00, 0x0000); /* background is black */ 166 CMOVE(cp, R_BPLCON0, 0x0000); /* no planes to fetch from */ 167 CWAIT(cp, 255, 255); /* COPEND */ 168 CWAIT(cp, 255, 255); /* COPEND really */ 169 170 /* install this list and turn DMA on */ 171 custom.cop1lc = PREP_DMA_MEM(null_mode_copper_list); 172 custom.copjmp1 = 0; 173 custom.dmacon = DMAF_SETCLR | DMAF_MASTER | DMAF_RASTER \ 174 |DMAF_COPPER; 175 176 cc_init_modes(); 177 LIST_INSERT_HEAD(monitors, m_this, link); 178 return (m_this); 179 } 180 181 void 182 monitor_vbl_handler(m) 183 monitor_t *m; 184 { 185 dmdata_t *dmd; 186 187 if (m_this_data->current_mode == NULL) 188 return; 189 190 dmd = DMDATA(m_this_data->current_mode); 191 if (dmd) 192 dmd->vbl_handler(m_this_data->current_mode); 193 } 194 195 dmode_t * 196 get_current_mode() 197 { 198 if (m_this_data->current_mode) 199 return(m_this_data->current_mode); 200 else 201 return(NULL); 202 } 203 204 dmode_t * 205 get_next_mode(d) 206 dmode_t *d; 207 { 208 if (d) 209 return(d->link.le_next); 210 return(m_this_data->modes.lh_first); 211 } 212 213 /* XXX needs to have more control attributes */ 214 dmode_t * 215 get_best_mode(size, depth) 216 dimen_t *size; 217 u_char depth; 218 { 219 dmode_t *save; 220 dmode_t *dm; 221 long dt, dx, dy, ct; 222 dmdata_t *dmd; 223 224 save = NULL; 225 dm = m_this_data->modes.lh_first; 226 while (dm != NULL) { 227 dmd = dm->data; 228 if (depth > dmd->max_depth || depth < dmd->min_depth) { 229 dm = dm->link.le_next; 230 continue; 231 } else if (size->width > dmd->max_size.width || 232 size->height > dmd->max_size.height) { 233 dm = dm->link.le_next; 234 continue; 235 } else if (size->width < dmd->min_size.width || 236 size->height < dmd->min_size.height) { 237 dm = dm->link.le_next; 238 continue; 239 } 240 dx = abs(dm->nominal_size.width - size->width); 241 dy = abs(dm->nominal_size.height - size->height); 242 ct = dx + dy; 243 244 if (ct < dt || save == NULL) { 245 save = dm; 246 dt = ct; 247 } 248 dm = dm->link.le_next; 249 } 250 return (save); 251 } 252 /* bitmap functions */ 253 bmap_t * 254 alloc_bitmap(width, height, depth, flags) 255 u_short width, height, depth, flags; 256 { 257 int i; 258 u_long total_size; 259 #ifdef GRF_AGA 260 u_short lwpr = (flags & BMF_ALIGN64) ? ((width + 63) / 64) * 2 : 261 (width + 31) / 32; /* AGA needs 64 bit align */ 262 #else 263 u_short lwpr = (width + 31) / 32; 264 #endif 265 u_short wpr = lwpr << 1; 266 u_short bpr = wpr << 1; 267 u_short array_size = sizeof(u_char *) * depth; 268 u_long plane_size = bpr * height; 269 u_short temp_size = bpr + sizeof(u_long); 270 bmap_t *bm; 271 272 /* note the next allocation will give everything, also note that all 273 * the stuff we want (including bitmaps) will be long short aligned. 274 * This is a function of the data being allocated and the fact that 275 * alloc_chipmem() returns long short aligned data. note also that 276 * each row of the bitmap is long word aligned and made of exactly n 277 * longwords. -ch */ 278 279 /* Sigh, it seems for mapping to work we need the bitplane data to 1: 280 * be aligned on a page boundry. 2: be n pages large. 281 * 282 * why? becuase the user gets a page aligned address, if this is before 283 * your allocation, too bad. Also it seems that the mapping routines 284 * do not watch to closely to the allowable length. so if you go over 285 * n pages by less than another page, the user gets to write all over 286 * the entire page. Since you did not allocate up to a page boundry 287 * (or more) the user writes into someone elses memory. -ch */ 288 total_size = amiga_round_page(plane_size * depth) + /* for length */ 289 (temp_size) + (array_size) + sizeof(bmap_t) + 290 NBPG; /* for alignment */ 291 bm = alloc_chipmem(total_size); 292 if (bm) { 293 if (flags & BMF_CLEAR) { 294 bzero(bm, total_size); 295 } 296 bm->bytes_per_row = bpr; 297 bm->rows = height; 298 bm->depth = depth; 299 bm->flags = flags; 300 bm->plane = (u_char **) & bm[1]; 301 bm->blit_temp = ((u_char *) bm->plane) + array_size; 302 bm->plane[0] = (u_char *) amiga_round_page((u_long) (bm->blit_temp + temp_size)); 303 if (flags & BMF_INTERLEAVED) { 304 bm->row_mod = bm->bytes_per_row * (depth - 1); 305 for (i = 1; i < depth; i++) { 306 bm->plane[i] = bm->plane[i - 1] + bpr; 307 } 308 } else { 309 bm->row_mod = 0; 310 for (i = 1; i < depth; i++) { 311 bm->plane[i] = bm->plane[i - 1] + plane_size; 312 } 313 } 314 bm->hardware_address = PREP_DMA_MEM(bm->plane[0]); 315 return (bm); 316 } 317 return (NULL); 318 } 319 320 321 void 322 free_bitmap(bm) 323 bmap_t *bm; 324 { 325 if (bm) 326 free_chipmem(bm); 327 } 328 /* load a new mode into the current display, if NULL shut display off. */ 329 void 330 cc_load_mode(d) 331 dmode_t *d; 332 { 333 if (d) { 334 m_this_data->current_mode = d; 335 return; 336 } 337 /* turn off display */ 338 m_this_data->current_mode = NULL; 339 wait_tof(); 340 wait_tof(); 341 custom.cop1lc = PREP_DMA_MEM(null_mode_copper_list); 342 } 343 /* 344 * CC Mode Stuff. 345 */ 346 347 dmode_t *(*mode_init_funcs[]) (void) = { 348 #if defined (GRF_NTSC) 349 #if defined (GRF_A2024) 350 cc_init_ntsc_a2024, 351 cc_init_ntsc_hires_dlace, 352 #endif /* GRF_A2024 */ 353 cc_init_ntsc_hires_lace, 354 cc_init_ntsc_hires, 355 #if defined (GRF_AGA) 356 cc_init_ntsc_aga, 357 #endif /* GRF_AGA */ 358 #endif /* GRF_NTSC */ 359 #if defined (GRF_PAL) 360 #if defined (GRF_A2024) 361 cc_init_pal_a2024, 362 cc_init_pal_hires_dlace, 363 #endif /* GRF_A2024 */ 364 cc_init_pal_hires_lace, 365 cc_init_pal_hires, 366 #endif /* GRF_PAL */ 367 NULL 368 }; 369 370 int 371 cc_init_modes() 372 { 373 int i = 0; 374 int error = 0; 375 while (mode_init_funcs[i]) { 376 mode_init_funcs[i] (); 377 i++; 378 } 379 return (error); 380 } 381 382 monitor_t * 383 cc_get_monitor(d) 384 dmode_t *d; 385 { 386 return (DMDATA(d)->monitor); 387 } 388 389 view_t * 390 cc_get_current_view(d) 391 dmode_t *d; 392 { 393 return (DMDATA(d)->current_view); 394 } 395 396 397 view_t * 398 cc_alloc_view(mode, dim, depth) 399 dmode_t *mode; 400 dimen_t *dim; 401 u_char depth; 402 { 403 view_t *v = alloc_chipmem(sizeof(*v) + sizeof(vdata_t)); 404 if (v) { 405 bmap_t *bm = cc_monitor->alloc_bitmap(dim->width, dim->height, 406 depth, BMF_CLEAR | (DMDATA(mode)->max_depth == 8 ? BMF_ALIGN64 : 0)); 407 if (bm) { 408 int i; 409 box_t box; 410 411 v->data = &v[1]; /* at the end of view */ 412 VDATA(v)->colormap = DMDATA(mode)->alloc_colormap(depth); 413 if (VDATA(v)->colormap) { 414 INIT_BOX(&box, 0, 0, dim->width, dim->height); 415 cc_init_view(v, bm, mode, &box); 416 return (v); 417 } 418 cc_monitor->free_bitmap(bm); 419 } 420 free_chipmem(v); 421 } 422 return (NULL); 423 } 424 425 colormap_t * 426 cc_alloc_colormap(depth) 427 int depth; 428 { 429 u_long size = 1U << depth, i; 430 colormap_t *cm = alloc_chipmem(sizeof(u_long) * size + sizeof(*cm)); 431 432 if (cm) { 433 cm->type = CM_COLOR; 434 cm->red_mask = 0x0F; 435 cm->green_mask = 0x0F; 436 cm->blue_mask = 0x0F; 437 cm->first = 0; 438 cm->size = size; 439 cm->entry = (u_long *) & cm[1]; /* table directly after. */ 440 for (i = 0; i < size; i++) { 441 cm->entry[i] = CM_WTOL(cc_default_colors[i&31]); 442 } 443 return (cm); 444 } 445 return (NULL); 446 } 447 448 #ifdef GRF_AGA 449 colormap_t * 450 cc_alloc_aga_colormap(depth) 451 int depth; 452 { 453 u_long size = 1U << depth, i; 454 colormap_t *cm = alloc_chipmem(sizeof(u_long) * size + sizeof(*cm)); 455 456 if (cm) { 457 cm->type = CM_COLOR; 458 cm->red_mask = 0x0FF; 459 cm->green_mask = 0x0FF; 460 cm->blue_mask = 0x0FF; 461 cm->first = 0; 462 cm->size = size; 463 cm->entry = (u_long *) & cm[1]; /* table directly after. */ 464 for (i = 0; i < size; i++) { 465 cm->entry[i] = CM_WTOL(cc_default_colors[i&31]) | 466 (CM_WTOL(cc_default_colors[i&31]) << 4); 467 } 468 return (cm); 469 } 470 return (NULL); 471 } 472 #endif 473 474 int 475 cc_colormap_checkvals(vcm, cm, use) 476 colormap_t *vcm, *cm; 477 int use; 478 { 479 if (use) { 480 /* check to see if its the view's colormap, if so just do 481 * update. */ 482 if (vcm != cm) { 483 if (cm->first >= vcm->size || (cm->first + cm->size) > (cm->first + vcm->size) || 484 cm->type != vcm->type) { 485 return (0); 486 } 487 switch (vcm->type) { 488 case CM_COLOR: 489 if (cm->red_mask != vcm->red_mask || 490 cm->green_mask != vcm->green_mask || 491 cm->blue_mask != vcm->blue_mask) { 492 return (0); 493 } 494 break; 495 case CM_GREYSCALE: 496 if (cm->grey_mask != vcm->grey_mask) { 497 return (0); 498 } 499 break; 500 } 501 } 502 } else { 503 if (cm->first >= vcm->size || (cm->first + cm->size) > (cm->first + vcm->size)) { 504 return (0); 505 } 506 } 507 return (1); 508 } 509 /* does sanity check on values */ 510 int 511 cc_get_colormap(v, cm) 512 view_t *v; 513 colormap_t *cm; 514 { 515 colormap_t *vcm = VDATA(v)->colormap; 516 int i; 517 518 if (!cc_colormap_checkvals(vcm, cm, 0)) { 519 return (EINVAL); 520 } 521 cm->type = vcm->type; 522 523 switch (vcm->type) { 524 case CM_COLOR: 525 cm->red_mask = vcm->red_mask; 526 cm->green_mask = vcm->green_mask; 527 cm->blue_mask = vcm->blue_mask; 528 break; 529 case CM_GREYSCALE: 530 cm->grey_mask = vcm->grey_mask; 531 break; 532 } 533 534 /* copy entries into colormap. */ 535 for (i = cm->first; i < (cm->first + cm->size); i++) { 536 cm->entry[i] = vcm->entry[i]; 537 } 538 return (0); 539 } 540 541 /* does sanity check on values */ 542 int 543 cc_use_colormap(v, cm) 544 view_t *v; 545 colormap_t *cm; 546 { 547 colormap_t *vcm = VDATA(v)->colormap; 548 int s, i; 549 550 if (!cc_colormap_checkvals(vcm, cm, 1)) { 551 return (EINVAL); 552 } 553 /* check to see if its the view's colormap, if so just do update. */ 554 if (vcm != cm) { 555 /* copy entries into colormap. */ 556 for (i = cm->first; i < (cm->first + cm->size); i++) { 557 vcm->entry[i] = cm->entry[i]; 558 } 559 } 560 s = spltty(); 561 562 /* is view currently being displayed? */ 563 if (VDATA(v)->flags & VF_DISPLAY) { 564 /* yes, update the copper lists */ 565 cop_t *tmp, *cp; 566 int nframes = 1, j; 567 568 if (DMDATA(VDATA(v)->mode)->flags & DMF_INTERLACE) { 569 nframes = 2; 570 } 571 for (i = 0; i < nframes; i++) { 572 cp = DMDATA(VDATA(v)->mode)->frames[i]; 573 574 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR07)); 575 tmp -= 7; 576 577 for (j = 0; j < 32; j++) { 578 CMOVE(tmp, R_COLOR00 + (j << 1), CM_LTOW(vcm->entry[j])); 579 } 580 } 581 } 582 splx(s); 583 return (0); 584 } 585 586 #ifdef GRF_AGA 587 /* does sanity check on values */ 588 int 589 cc_use_aga_colormap(v, cm) 590 view_t *v; 591 colormap_t *cm; 592 { 593 colormap_t *vcm = VDATA(v)->colormap; 594 int s, i; 595 596 if (!cc_colormap_checkvals(vcm, cm, 1)) { 597 return (EINVAL); 598 } 599 /* check to see if its the view's colormap, if so just do update. */ 600 if (vcm != cm) { 601 /* copy entries into colormap. */ 602 for (i = cm->first; i < (cm->first + cm->size); i++) { 603 vcm->entry[i] = cm->entry[i]; 604 } 605 } 606 s = spltty(); 607 608 /* is view currently being displayed? */ 609 if (VDATA(v)->flags & VF_DISPLAY) { 610 /* yes, update the copper lists */ 611 cop_t *tmp, *cp; 612 int nframes = 1, j; 613 614 if (DMDATA(VDATA(v)->mode)->flags & DMF_INTERLACE) { 615 nframes = 2; 616 } 617 for (i = 0; i < nframes; i++) { 618 cp = DMDATA(VDATA(v)->mode)->frames[i]; 619 620 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR00)); 621 for (j = 0; j < vcm->size; j += 32) { 622 int k; 623 624 for (k = 0; k < 32; k++) { 625 int ce = vcm->entry[j + k] >> 4; 626 CMOVE(tmp, R_COLOR00 + (k << 1), CM_LTOW(ce)); 627 } 628 tmp++; 629 for (k = 0; k < 32; k++) { 630 int ce =vcm->entry[j + k]; 631 CMOVE(tmp, R_COLOR00 + (k << 1), CM_LTOW(ce)); 632 } 633 tmp++; 634 } 635 } 636 } 637 splx(s); 638 return (0); 639 } 640 #endif 641 642 #if defined (GRF_A2024) 643 colormap_t * 644 cc_a2024_alloc_colormap(depth) 645 int depth; 646 { 647 u_long size = 1U << depth, i; 648 colormap_t *cm = alloc_chipmem(sizeof(u_long) * size + sizeof(*cm)); 649 650 if (cm) { 651 cm->type = CM_GREYSCALE; 652 cm->grey_mask = 0x03; 653 cm->first = 0; 654 cm->size = size; 655 cm->entry = (u_long *) & cm[1]; /* table directly after. */ 656 for (i = 0; i < size; i++) { 657 cm->entry[i] = CM_WTOL(cc_a2024_default_colors[i]); 658 } 659 return (cm); 660 } 661 return (NULL); 662 } 663 664 int 665 cc_a2024_get_colormap(v, cm) 666 view_t *v; 667 colormap_t *cm; 668 { 669 /* there are no differences (yet) in the way the cm's are stored */ 670 return (cc_get_colormap(v, cm)); 671 } 672 673 int 674 cc_a2024_use_colormap(v, cm) 675 view_t *v; 676 colormap_t *cm; 677 { 678 colormap_t *vcm = VDATA(v)->colormap; 679 int s, i; 680 681 if (!cc_colormap_checkvals(vcm, cm, 1)) { 682 return (EINVAL); 683 } 684 /* check to see if its the view's colormap, if so just do update. */ 685 if (vcm != cm) { 686 /* copy entries into colormap. */ 687 for (i = cm->first; i < (cm->first + cm->size); i++) { 688 vcm->entry[i] = cm->entry[i]; 689 } 690 } 691 s = spltty(); 692 693 /* is view currently being displayed? */ 694 if (VDATA(v)->flags & VF_DISPLAY) { 695 /* yes, update the copper lists */ 696 cop_t *tmp, *cp; 697 int nframes = 2, nregs = cm->size == 4 ? 16 : 8, j; 698 699 if (DMDATA(VDATA(v)->mode)->flags & DMF_HEDLEY_EXP) { 700 nframes = 4; 701 } 702 for (i = 0; i < nframes; i++) { 703 cp = DMDATA(VDATA(v)->mode)->frames[i]; 704 705 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR07)); 706 tmp -= 7; 707 708 for (j = 0; j < nregs; j++) { 709 CMOVE(tmp, R_COLOR00 + (j << 1), A2024_CM_TO_CR(vcm, j)); 710 } 711 } 712 } 713 splx(s); 714 return (0); 715 } 716 #endif /* GRF_A2024 */ 717 718 719 /* 720 * CC View stuff. 721 */ 722 723 void 724 cc_init_view(v, bm, mode, dbox) 725 view_t *v; 726 bmap_t *bm; 727 dmode_t *mode; 728 box_t *dbox; 729 { 730 vdata_t *vd = VDATA(v); 731 v->bitmap = bm; 732 vd->mode = mode; 733 bcopy(dbox, &v->display, sizeof(box_t)); 734 735 v->display_view = DMDATA(vd->mode)->display_view; 736 v->use_colormap = DMDATA(vd->mode)->use_colormap; 737 v->get_colormap = DMDATA(vd->mode)->get_colormap; 738 v->free_view = cc_free_view; 739 v->get_display_mode = cc_get_display_mode; 740 v->remove_view = cc_remove_view; 741 } 742 743 void 744 cc_free_view(v) 745 view_t *v; 746 { 747 if (v) { 748 vdata_t *vd = VDATA(v); 749 dmode_t *md = vd->mode; 750 v->remove_view(v); 751 free_chipmem(VDATA(v)->colormap); 752 cc_monitor->free_bitmap(v->bitmap); 753 free_chipmem(v); 754 } 755 } 756 757 void 758 cc_remove_view(v) 759 view_t *v; 760 { 761 dmode_t *mode = VDATA(v)->mode; 762 763 if (MDATA(cc_monitor)->current_mode == mode) { 764 if (DMDATA(mode)->current_view == v) { 765 cc_load_mode(NULL); 766 } 767 } 768 if (DMDATA(mode)->current_view == v) { 769 DMDATA(mode)->current_view = NULL; 770 } 771 VDATA(v)->flags &= ~VF_DISPLAY; 772 } 773 774 dmode_t * 775 cc_get_display_mode(v) 776 view_t *v; 777 { 778 return (VDATA(v)->mode); 779 } 780 781 void 782 cc_mode_vbl_handler(d) 783 dmode_t *d; 784 { 785 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8); 786 787 if (vp < 12) { 788 custom.cop1lc = PREP_DMA_MEM(DMDATA(d)->frames[F_LONG]); 789 custom.copjmp1 = 0; 790 } 791 } 792 793 void 794 cc_lace_mode_vbl_handler(d) 795 dmode_t *d; 796 { 797 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8); 798 799 if (vp < 12) { 800 if (custom.vposr & 0x8000) { 801 custom.cop1lc = PREP_DMA_MEM(DMDATA(d)->frames[F_LACE_LONG]); 802 } else { 803 custom.cop1lc = PREP_DMA_MEM(DMDATA(d)->frames[F_LACE_SHORT]); 804 } 805 custom.copjmp1 = 0; 806 } 807 } 808 809 /* 810 * Modes. (ick) 811 */ 812 813 /* 814 * NTSC Modes 815 */ 816 817 #if defined (GRF_NTSC) 818 819 dmode_t * 820 cc_init_ntsc_hires() 821 { 822 /* this function should only be called once. */ 823 if (!h_this) { 824 u_short len = std_copper_list_len; 825 cop_t *cp; 826 827 h_this = &hires_mode; 828 h_this_data = &hires_mode_data; 829 bzero(h_this, sizeof(dmode_t)); 830 bzero(h_this_data, sizeof(dmdata_t)); 831 832 h_this->name = "ntsc: hires"; 833 h_this->nominal_size.width = 640; 834 h_this->nominal_size.height = 200; 835 h_this_data->max_size.width = 724; 836 h_this_data->max_size.height = 242; 837 h_this_data->min_size.width = 320; 838 h_this_data->min_size.height = 100; 839 h_this_data->min_depth = 1; 840 h_this_data->max_depth = 4; 841 h_this->data = h_this_data; 842 843 h_this->get_monitor = cc_get_monitor; 844 h_this->alloc_view = cc_alloc_view; 845 h_this->get_current_view = cc_get_current_view; 846 847 h_this_data->use_colormap = cc_use_colormap; 848 h_this_data->get_colormap = cc_get_colormap; 849 h_this_data->alloc_colormap = cc_alloc_colormap; 850 h_this_data->display_view = display_hires_view; 851 h_this_data->monitor = cc_monitor; 852 853 h_this_data->frames = hires_frames; 854 h_this_data->frames[F_LONG] = alloc_chipmem(std_copper_list_size * F_TOTAL); 855 if (!h_this_data->frames[F_LONG]) { 856 panic("couldn't get chipmem for copper list"); 857 } 858 h_this_data->frames[F_STORE_LONG] = &h_this_data->frames[F_LONG][len]; 859 860 bcopy(std_copper_list, h_this_data->frames[F_STORE_LONG], std_copper_list_size); 861 bcopy(std_copper_list, h_this_data->frames[F_LONG], std_copper_list_size); 862 863 h_this_data->bplcon0 = 0x8200 | USE_CON3; /* hires, color 864 * composite enable */ 865 h_this_data->std_start_x = STANDARD_VIEW_X; 866 h_this_data->std_start_y = STANDARD_VIEW_Y; 867 h_this_data->vbl_handler = (vbl_handler_func *) cc_mode_vbl_handler; 868 #if defined (GRF_ECS) 869 h_this_data->beamcon0 = STANDARD_NTSC_BEAMCON; 870 #endif 871 872 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, h_this, link); 873 } 874 return (h_this); 875 } 876 877 void 878 display_hires_view(v) 879 view_t *v; 880 { 881 if (h_this_data->current_view != v) { 882 vdata_t *vd = VDATA(v); 883 monitor_t *monitor = h_this_data->monitor; 884 cop_t *cp = h_this_data->frames[F_STORE_LONG], *tmp; 885 int depth = v->bitmap->depth, i; 886 int hstart, hstop, vstart, vstop, j; 887 int x, y, w = v->display.width, h = v->display.height; 888 u_short ddfstart, ddfwidth, con1; 889 890 /* round down to nearest even width */ 891 /* w &= 0xfffe; */ 892 /* calculate datafetch width. */ 893 894 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2; 895 896 /* This will center the any overscanned display */ 897 /* and allow user to modify. */ 898 x = v->display.x + h_this_data->std_start_x - ((w - 640) >> 2); 899 y = v->display.y + h_this_data->std_start_y - ((h - 200) >> 1); 900 901 if (y & 1) 902 y--; 903 904 if (!(x & 1)) 905 x--; 906 907 hstart = x; 908 hstop = x + (w >> 1); 909 vstart = y; 910 vstop = y + h; 911 ddfstart = (hstart - 9) >> 1; 912 913 /* check for hardware limits, AGA may allow more..? */ 914 /* anyone got a 4000 I can borrow :^) -ch */ 915 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 916 int d = 0; 917 918 /* XXX anyone know the equality properties of 919 * intermixed logial AND's */ 920 /* XXX and arithmetic operators? */ 921 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 922 d++; 923 } 924 925 ddfstart -= d; 926 hstart -= d << 1; 927 hstop -= d << 1; 928 } 929 /* correct the datafetch to proper limits. */ 930 /* delay the actual display of the data until we need it. */ 931 ddfstart &= 0xfffc; 932 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 933 934 if (h_this_data->current_view) { 935 VDATA(h_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 936 /* displayed. */ 937 } 938 h_this_data->current_view = v; 939 940 cp = h_this_data->frames[F_STORE_LONG]; 941 #if defined GRF_ECS 942 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON3)); 943 tmp->cp.inst.operand = 0x0020; 944 #if defined GRF_AGA 945 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE)); 946 tmp->cp.inst.operand = 0; 947 #endif 948 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 949 tmp->cp.inst.operand = h_this_data->beamcon0; 950 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 951 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 952 #endif /* ECS */ 953 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 954 tmp->cp.inst.operand = h_this_data->bplcon0 | ((depth & 0x7) << 12); 955 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 956 tmp->cp.inst.operand = con1; 957 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 958 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 959 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 960 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 961 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 962 tmp->cp.inst.operand = ddfstart; 963 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 964 tmp->cp.inst.operand = ddfstart + ddfwidth; 965 966 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 967 for (i = 0, j = 0; i < depth; j += 2, i++) { 968 /* update the plane pointers */ 969 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 970 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 971 } 972 973 /* set mods correctly. */ 974 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 975 tmp[0].cp.inst.operand = v->bitmap->row_mod; 976 tmp[1].cp.inst.operand = v->bitmap->row_mod; 977 978 /* set next pointers correctly */ 979 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 980 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(h_this_data->frames[F_STORE_LONG])); 981 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(h_this_data->frames[F_STORE_LONG])); 982 983 cp = h_this_data->frames[F_LONG]; 984 h_this_data->frames[F_LONG] = h_this_data->frames[F_STORE_LONG]; 985 h_this_data->frames[F_STORE_LONG] = cp; 986 987 vd->flags |= VF_DISPLAY; 988 989 cc_use_colormap(v, vd->colormap); 990 } 991 cc_load_mode(h_this); 992 } 993 994 dmode_t * 995 cc_init_ntsc_hires_lace() 996 { 997 /* this function should only be called once. */ 998 if (!hl_this) { 999 u_short len = std_copper_list_len; 1000 cop_t *cp; 1001 1002 hl_this = &hires_lace_mode; 1003 hl_this_data = &hires_lace_mode_data; 1004 bzero(hl_this, sizeof(dmode_t)); 1005 bzero(hl_this_data, sizeof(dmdata_t)); 1006 1007 hl_this->name = "ntsc: hires interlace"; 1008 hl_this->nominal_size.width = 640; 1009 hl_this->nominal_size.height = 400; 1010 hl_this_data->max_size.width = 724; 1011 hl_this_data->max_size.height = 482; 1012 hl_this_data->min_size.width = 320; 1013 hl_this_data->min_size.height = 200; 1014 hl_this_data->min_depth = 1; 1015 hl_this_data->max_depth = 4; 1016 hl_this->data = hl_this_data; 1017 1018 hl_this->get_monitor = cc_get_monitor; 1019 hl_this->alloc_view = cc_alloc_view; 1020 hl_this->get_current_view = cc_get_current_view; 1021 1022 hl_this_data->use_colormap = cc_use_colormap; 1023 hl_this_data->get_colormap = cc_get_colormap; 1024 hl_this_data->alloc_colormap = cc_alloc_colormap; 1025 hl_this_data->display_view = display_hires_lace_view; 1026 hl_this_data->monitor = cc_monitor; 1027 1028 hl_this_data->flags |= DMF_INTERLACE; 1029 1030 hl_this_data->frames = hires_lace_frames; 1031 hl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_copper_list_size * F_LACE_TOTAL); 1032 if (!hl_this_data->frames[F_LACE_LONG]) { 1033 panic("couldn't get chipmem for copper list"); 1034 } 1035 hl_this_data->frames[F_LACE_SHORT] = &hl_this_data->frames[F_LACE_LONG][len]; 1036 hl_this_data->frames[F_LACE_STORE_LONG] = &hl_this_data->frames[F_LACE_SHORT][len]; 1037 hl_this_data->frames[F_LACE_STORE_SHORT] = &hl_this_data->frames[F_LACE_STORE_LONG][len]; 1038 1039 bcopy(std_copper_list, hl_this_data->frames[F_LACE_STORE_LONG], std_copper_list_size); 1040 bcopy(std_copper_list, hl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size); 1041 bcopy(std_copper_list, hl_this_data->frames[F_LACE_LONG], std_copper_list_size); 1042 bcopy(std_copper_list, hl_this_data->frames[F_LACE_SHORT], std_copper_list_size); 1043 1044 hl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color 1045 * composite enable, 1046 * lace. */ 1047 hl_this_data->std_start_x = STANDARD_VIEW_X; 1048 hl_this_data->std_start_y = STANDARD_VIEW_Y; 1049 hl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler; 1050 #if defined (GRF_ECS) 1051 hl_this_data->beamcon0 = STANDARD_NTSC_BEAMCON; 1052 #endif 1053 1054 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, hl_this, link); 1055 } 1056 return (hl_this); 1057 } 1058 1059 void 1060 display_hires_lace_view(v) 1061 view_t *v; 1062 { 1063 if (hl_this_data->current_view != v) { 1064 vdata_t *vd = VDATA(v); 1065 monitor_t *monitor = hl_this_data->monitor; 1066 cop_t *cp = hl_this_data->frames[F_LACE_STORE_LONG], *tmp; 1067 int depth = v->bitmap->depth, i; 1068 int hstart, hstop, vstart, vstop, j; 1069 int x, y, w = v->display.width, h = v->display.height; 1070 u_short ddfstart, ddfwidth, con1; 1071 1072 /* round down to nearest even width */ 1073 /* w &= 0xfffe; */ 1074 1075 1076 /* calculate datafetch width. */ 1077 1078 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2; 1079 1080 /* This will center the any overscanned display */ 1081 /* and allow user to modify. */ 1082 x = v->display.x + hl_this_data->std_start_x - ((w - 640) >> 2); 1083 y = v->display.y + hl_this_data->std_start_y - ((h - 400) >> 2); 1084 1085 if (y & 1) 1086 y--; 1087 1088 if (!(x & 1)) 1089 x--; 1090 1091 hstart = x; 1092 hstop = x + (w >> 1); 1093 vstart = y; 1094 vstop = y + (h >> 1); 1095 ddfstart = (hstart - 9) >> 1; 1096 1097 /* check for hardware limits, AGA may allow more..? */ 1098 /* anyone got a 4000 I can borrow :^) -ch */ 1099 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 1100 int d = 0; 1101 1102 /* XXX anyone know the equality properties of 1103 * intermixed logial AND's */ 1104 /* XXX and arithmetic operators? */ 1105 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 1106 d++; 1107 } 1108 1109 ddfstart -= d; 1110 hstart -= d << 1; 1111 hstop -= d << 1; 1112 } 1113 /* correct the datafetch to proper limits. */ 1114 /* delay the actual display of the data until we need it. */ 1115 ddfstart &= 0xfffc; 1116 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 1117 1118 if (hl_this_data->current_view) { 1119 VDATA(hl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 1120 /* displayed. */ 1121 } 1122 hl_this_data->current_view = v; 1123 1124 cp = hl_this_data->frames[F_LACE_STORE_LONG]; 1125 #if defined GRF_ECS 1126 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON3)); 1127 tmp->cp.inst.operand = 0x0020; 1128 #if defined GRF_AGA 1129 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE)); 1130 tmp->cp.inst.operand = 0; 1131 #endif 1132 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 1133 tmp->cp.inst.operand = hl_this_data->beamcon0; 1134 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 1135 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 1136 #endif /* ECS */ 1137 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 1138 tmp->cp.inst.operand = hl_this_data->bplcon0 | ((depth & 0x7) << 12); 1139 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 1140 tmp->cp.inst.operand = con1; 1141 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 1142 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 1143 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 1144 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 1145 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 1146 tmp->cp.inst.operand = ddfstart; 1147 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 1148 tmp->cp.inst.operand = ddfstart + ddfwidth; 1149 1150 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 1151 for (i = 0, j = 0; i < depth; j += 2, i++) { 1152 /* update the plane pointers */ 1153 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 1154 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 1155 } 1156 1157 /* set mods correctly. */ 1158 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 1159 tmp[0].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod; 1160 tmp[1].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod; 1161 1162 /* set next pointers correctly */ 1163 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 1164 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hl_this_data->frames[F_LACE_STORE_SHORT])); 1165 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hl_this_data->frames[F_LACE_STORE_SHORT])); 1166 1167 1168 bcopy(hl_this_data->frames[F_LACE_STORE_LONG], hl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size); 1169 1170 /* these are the only ones that are different from long frame. */ 1171 cp = hl_this_data->frames[F_LACE_STORE_SHORT]; 1172 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 1173 for (i = 0, j = 0; i < depth; j += 2, i++) { 1174 u_short mod = v->bitmap->bytes_per_row + v->bitmap->row_mod; 1175 /* update plane pointers. high and low. */ 1176 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod])); 1177 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod])); 1178 } 1179 1180 /* set next pointers correctly */ 1181 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 1182 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hl_this_data->frames[F_LACE_STORE_LONG])); 1183 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hl_this_data->frames[F_LACE_STORE_LONG])); 1184 1185 1186 cp = hl_this_data->frames[F_LACE_LONG]; 1187 hl_this_data->frames[F_LACE_LONG] = hl_this_data->frames[F_LACE_STORE_LONG]; 1188 hl_this_data->frames[F_LACE_STORE_LONG] = cp; 1189 1190 cp = hl_this_data->frames[F_LACE_SHORT]; 1191 hl_this_data->frames[F_LACE_SHORT] = hl_this_data->frames[F_LACE_STORE_SHORT]; 1192 hl_this_data->frames[F_LACE_STORE_SHORT] = cp; 1193 1194 vd->flags |= VF_DISPLAY; 1195 1196 cc_use_colormap(v, vd->colormap); 1197 } 1198 cc_load_mode(hl_this); 1199 } 1200 #if defined (GRF_A2024) 1201 1202 dmode_t * 1203 cc_init_ntsc_hires_dlace() 1204 { 1205 /* this function should only be called once. */ 1206 if (!hdl_this) { 1207 u_short len = std_dlace_copper_list_len; 1208 cop_t *cp; 1209 1210 hdl_this = &hires_dlace_mode; 1211 hdl_this_data = &hires_dlace_mode_data; 1212 bzero(hdl_this, sizeof(dmode_t)); 1213 bzero(hdl_this_data, sizeof(dmdata_t)); 1214 1215 hdl_this->name = "ntsc: hires double interlace"; 1216 hdl_this->nominal_size.width = 640; 1217 hdl_this->nominal_size.height = 800; 1218 hdl_this_data->max_size.width = 724; 1219 hdl_this_data->max_size.height = 800; 1220 hdl_this_data->min_size.width = 320; 1221 hdl_this_data->min_size.height = 400; 1222 hdl_this_data->min_depth = 1; 1223 hdl_this_data->max_depth = 2; 1224 hdl_this->data = hdl_this_data; 1225 1226 hdl_this->get_monitor = cc_get_monitor; 1227 hdl_this->alloc_view = cc_alloc_view; 1228 hdl_this->get_current_view = cc_get_current_view; 1229 1230 hdl_this_data->use_colormap = cc_a2024_use_colormap; 1231 hdl_this_data->get_colormap = cc_a2024_get_colormap; 1232 hdl_this_data->alloc_colormap = cc_a2024_alloc_colormap; 1233 hdl_this_data->display_view = display_hires_dlace_view; 1234 hdl_this_data->monitor = cc_monitor; 1235 1236 hdl_this_data->flags |= DMF_INTERLACE; 1237 1238 hdl_this_data->frames = hires_dlace_frames; 1239 hdl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_dlace_copper_list_size * F_LACE_TOTAL); 1240 if (!hdl_this_data->frames[F_LACE_LONG]) { 1241 panic("couldn't get chipmem for copper list"); 1242 } 1243 hdl_this_data->frames[F_LACE_SHORT] = &hdl_this_data->frames[F_LACE_LONG][len]; 1244 hdl_this_data->frames[F_LACE_STORE_LONG] = &hdl_this_data->frames[F_LACE_SHORT][len]; 1245 hdl_this_data->frames[F_LACE_STORE_SHORT] = &hdl_this_data->frames[F_LACE_STORE_LONG][len]; 1246 1247 bcopy(std_dlace_copper_list, hdl_this_data->frames[F_LACE_STORE_LONG], std_dlace_copper_list_size); 1248 bcopy(std_dlace_copper_list, hdl_this_data->frames[F_LACE_STORE_SHORT], std_dlace_copper_list_size); 1249 bcopy(std_dlace_copper_list, hdl_this_data->frames[F_LACE_LONG], std_dlace_copper_list_size); 1250 bcopy(std_dlace_copper_list, hdl_this_data->frames[F_LACE_SHORT], std_dlace_copper_list_size); 1251 1252 hdl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color 1253 * composite enable, 1254 * dlace. */ 1255 hdl_this_data->std_start_x = STANDARD_VIEW_X; 1256 hdl_this_data->std_start_y = STANDARD_VIEW_Y; 1257 hdl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler; 1258 #if defined (GRF_ECS) 1259 hdl_this_data->beamcon0 = STANDARD_NTSC_BEAMCON; 1260 #endif 1261 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, hdl_this, link); 1262 } 1263 return (hdl_this); 1264 } 1265 1266 void 1267 display_hires_dlace_view(v) 1268 view_t *v; 1269 { 1270 if (hdl_this_data->current_view != v) { 1271 vdata_t *vd = VDATA(v); 1272 monitor_t *monitor = hdl_this_data->monitor; 1273 cop_t *cp = hdl_this_data->frames[F_LACE_STORE_LONG], *tmp; 1274 int depth = v->bitmap->depth, i; 1275 int hstart, hstop, vstart, vstop, j; 1276 int x, y, w = v->display.width, h = v->display.height; 1277 u_short ddfstart, ddfwidth, con1; 1278 u_short mod1l, mod2l; 1279 1280 /* round down to nearest even width */ 1281 /* w &= 0xfffe; */ 1282 1283 /* calculate datafetch width. */ 1284 1285 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2; 1286 1287 /* This will center the any overscanned display */ 1288 /* and allow user to modify. */ 1289 x = v->display.x + hdl_this_data->std_start_x - ((w - 640) >> 2); 1290 y = v->display.y + hdl_this_data->std_start_y - ((h - 800) >> 3); 1291 1292 if (y & 1) 1293 y--; 1294 1295 if (!(x & 1)) 1296 x--; 1297 1298 hstart = x; 1299 hstop = x + (w >> 1); 1300 vstart = y; 1301 vstop = y + (h >> 2); 1302 1303 ddfstart = (hstart - 9) >> 1; 1304 1305 /* check for hardware limits, AGA may allow more..? */ 1306 /* anyone got a 4000 I can borrow :^) -ch */ 1307 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 1308 int d = 0; 1309 1310 /* XXX anyone know the equality properties of 1311 * intermixed logial AND's */ 1312 /* XXX and arithmetic operators? */ 1313 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 1314 d++; 1315 } 1316 1317 ddfstart -= d; 1318 hstart -= d << 1; 1319 hstop -= d << 1; 1320 } 1321 /* correct the datafetch to proper limits. */ 1322 /* delay the actual display of the data until we need it. */ 1323 ddfstart &= 0xfffc; 1324 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 1325 1326 if (hdl_this_data->current_view) { 1327 VDATA(hdl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 1328 /* displayed. */ 1329 } 1330 hdl_this_data->current_view = v; 1331 1332 cp = hdl_this_data->frames[F_LACE_STORE_LONG]; 1333 #if defined GRF_ECS 1334 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON3)); 1335 tmp->cp.inst.operand = 0x0020; 1336 #if defined GRF_AGA 1337 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE)); 1338 tmp->cp.inst.operand = 0; 1339 #endif 1340 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 1341 tmp->cp.inst.operand = hdl_this_data->beamcon0; 1342 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 1343 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 1344 #endif /* ECS */ 1345 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 1346 tmp->cp.inst.operand = hdl_this_data->bplcon0 | ((depth & 0x7) << 13); /* times two. */ 1347 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 1348 tmp->cp.inst.operand = con1; 1349 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 1350 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 1351 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 1352 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 1353 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 1354 tmp->cp.inst.operand = ddfstart; 1355 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 1356 tmp->cp.inst.operand = ddfstart + ddfwidth; 1357 1358 mod1l = v->bitmap->bytes_per_row + v->bitmap->row_mod; 1359 mod2l = mod1l << 1; 1360 1361 /* update plane pointers. */ 1362 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 1363 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0])); 1364 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0])); 1365 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l])); 1366 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l])); 1367 if (depth == 2) { 1368 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0])); 1369 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0])); 1370 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l])); 1371 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l])); 1372 } 1373 /* set modulos. */ 1374 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 1375 tmp[0].cp.inst.operand = mod2l + mod1l; 1376 tmp[1].cp.inst.operand = mod2l + mod1l; 1377 1378 1379 /* set next coper list pointers */ 1380 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 1381 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hdl_this_data->frames[F_LACE_STORE_SHORT])); 1382 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hdl_this_data->frames[F_LACE_STORE_SHORT])); 1383 1384 bcopy(hdl_this_data->frames[F_LACE_STORE_LONG], hdl_this_data->frames[F_LACE_STORE_SHORT], 1385 std_dlace_copper_list_size); 1386 1387 /* these are the only ones that are different from long frame. */ 1388 cp = hdl_this_data->frames[F_LACE_STORE_SHORT]; 1389 /* update plane pointers. */ 1390 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 1391 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l])); 1392 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l])); 1393 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l])); 1394 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l])); 1395 if (depth == 2) { 1396 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l])); 1397 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l])); 1398 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l])); 1399 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l])); 1400 } 1401 /* set next copper list pointers */ 1402 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 1403 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hdl_this_data->frames[F_LACE_STORE_LONG])); 1404 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hdl_this_data->frames[F_LACE_STORE_LONG])); 1405 1406 cp = hdl_this_data->frames[F_LACE_LONG]; 1407 hdl_this_data->frames[F_LACE_LONG] = hdl_this_data->frames[F_LACE_STORE_LONG]; 1408 hdl_this_data->frames[F_LACE_STORE_LONG] = cp; 1409 1410 cp = hdl_this_data->frames[F_LACE_SHORT]; 1411 hdl_this_data->frames[F_LACE_SHORT] = hdl_this_data->frames[F_LACE_STORE_SHORT]; 1412 hdl_this_data->frames[F_LACE_STORE_SHORT] = cp; 1413 1414 vd->flags |= VF_DISPLAY; 1415 cc_a2024_use_colormap(v, vd->colormap); 1416 } 1417 cc_load_mode(hdl_this); 1418 } 1419 1420 1421 dmode_t * 1422 cc_init_ntsc_a2024() 1423 { 1424 /* this function should only be called once. */ 1425 if (!a24_this) { 1426 int i; 1427 u_short len = std_a2024_copper_list_len; 1428 cop_t *cp; 1429 1430 a24_this = &a2024_mode; 1431 a24_this_data = &a2024_mode_data; 1432 bzero(a24_this, sizeof(dmode_t)); 1433 bzero(a24_this_data, sizeof(dmdata_t)); 1434 1435 a24_this->name = "ntsc: A2024 15khz"; 1436 a24_this->nominal_size.width = 1024; 1437 a24_this->nominal_size.height = 800; 1438 a24_this_data->max_size.width = 1024; 1439 a24_this_data->max_size.height = 800; 1440 a24_this_data->min_size.width = 1024; 1441 a24_this_data->min_size.height = 800; 1442 a24_this_data->min_depth = 1; 1443 a24_this_data->max_depth = 2; 1444 a24_this->data = a24_this_data; 1445 1446 a24_this->get_monitor = cc_get_monitor; 1447 a24_this->alloc_view = cc_alloc_view; 1448 a24_this->get_current_view = cc_get_current_view; 1449 1450 a24_this_data->use_colormap = cc_a2024_use_colormap; 1451 a24_this_data->get_colormap = cc_a2024_get_colormap; 1452 a24_this_data->display_view = display_a2024_view; 1453 a24_this_data->alloc_colormap = cc_a2024_alloc_colormap; 1454 a24_this_data->monitor = cc_monitor; 1455 1456 a24_this_data->flags |= DMF_HEDLEY_EXP; 1457 1458 a24_this_data->frames = a2024_frames; 1459 a24_this_data->frames[F_QD_QUAD0] = alloc_chipmem(std_a2024_copper_list_size * F_QD_TOTAL); 1460 if (!a24_this_data->frames[F_QD_QUAD0]) { 1461 panic("couldn't get chipmem for copper list"); 1462 } 1463 /* setup the hedley init bitplane. */ 1464 hedley_init = alloc_chipmem(128); 1465 if (!hedley_init) { 1466 panic("couldn't get chipmem for hedley init bitplane"); 1467 } 1468 for (i = 1; i < 128; i++) 1469 hedley_init[i] = 0xff; 1470 hedley_init[0] = 0x03; 1471 1472 /* copy image of standard copper list. */ 1473 bcopy(std_a2024_copper_list, a24_this_data->frames[0], std_a2024_copper_list_size); 1474 1475 /* set the init plane pointer. */ 1476 cp = find_copper_inst(a24_this_data->frames[F_QD_QUAD0], CI_MOVE(R_BPL0PTH)); 1477 cp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hedley_init)); 1478 cp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hedley_init)); 1479 1480 for (i = 1; i < F_QD_TOTAL; i++) { 1481 a24_this_data->frames[i] = &a24_this_data->frames[i - 1][len]; 1482 bcopy(a24_this_data->frames[0], a24_this_data->frames[i], std_a2024_copper_list_size); 1483 } 1484 1485 a24_this_data->bplcon0 = 0x8200; /* hires */ 1486 a24_this_data->vbl_handler = (vbl_handler_func *) a2024_mode_vbl_handler; 1487 1488 1489 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, a24_this, link); 1490 } 1491 return (a24_this); 1492 } 1493 1494 void 1495 display_a2024_view(v) 1496 view_t *v; 1497 { 1498 if (a24_this_data->current_view != v) { 1499 vdata_t *vd = VDATA(v); 1500 monitor_t *monitor = a24_this_data->monitor; 1501 cop_t *cp, *tmp; 1502 u_char *inst_plane[2]; 1503 u_char **plane = inst_plane; 1504 u_long full_line = v->bitmap->bytes_per_row + v->bitmap->row_mod; 1505 u_long half_plane = full_line * v->bitmap->rows / 2; 1506 1507 int line_mod = 0xbc; /* standard 2024 15khz mod. */ 1508 int depth = v->bitmap->depth, i, j; 1509 1510 plane[0] = v->bitmap->plane[0]; 1511 if (depth == 2) { 1512 plane[1] = v->bitmap->plane[1]; 1513 } 1514 if (a24_this_data->current_view) { 1515 VDATA(a24_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer 1516 * displayed. */ 1517 } 1518 cp = a24_this_data->frames[F_QD_STORE_QUAD0]; 1519 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR1F)); 1520 tmp = find_copper_inst(tmp, CI_MOVE(R_BPLCON0)); /* grab third one. */ 1521 tmp->cp.inst.operand = a24_this_data->bplcon0 | ((depth & 0x7) << 13); /* times 2 */ 1522 1523 bcopy(a24_this_data->frames[F_QD_STORE_QUAD0], a24_this_data->frames[F_QD_STORE_QUAD1], std_a2024_copper_list_size); 1524 bcopy(a24_this_data->frames[F_QD_STORE_QUAD0], a24_this_data->frames[F_QD_STORE_QUAD2], std_a2024_copper_list_size); 1525 bcopy(a24_this_data->frames[F_QD_STORE_QUAD0], a24_this_data->frames[F_QD_STORE_QUAD3], std_a2024_copper_list_size); 1526 1527 /* 1528 * Mark Id's 1529 */ 1530 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD1], CI_WAIT(126, 21)); 1531 CBUMP(tmp); 1532 CMOVE(tmp, R_COLOR01, QUAD1_ID); 1533 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD2], CI_WAIT(126, 21)); 1534 CBUMP(tmp); 1535 CMOVE(tmp, R_COLOR01, QUAD2_ID); 1536 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD3], CI_WAIT(126, 21)); 1537 CBUMP(tmp); 1538 CMOVE(tmp, R_COLOR01, QUAD3_ID); 1539 1540 plane[0]--; 1541 plane[0]--; 1542 if (depth == 2) { 1543 plane[1]--; 1544 plane[1]--; 1545 } 1546 /* 1547 * Set bitplane pointers. 1548 */ 1549 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD0], CI_MOVE(R_BPLMOD2)); 1550 CBUMP(tmp); 1551 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][0]))); 1552 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][0]))); 1553 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line]))); 1554 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line]))); 1555 if (depth == 2) { 1556 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][0]))); 1557 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][0]))); 1558 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line]))); 1559 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line]))); 1560 } 1561 #if defined (GRF_ECS) 1562 CMOVE(tmp, R_DIWHIGH, 0x2000); 1563 #endif 1564 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD1]))); 1565 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD1]))); 1566 CEND(tmp); 1567 CEND(tmp); 1568 1569 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD1], CI_MOVE(R_BPLMOD2)); 1570 CBUMP(tmp); 1571 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE]))); 1572 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE]))); 1573 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE]))); 1574 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE]))); 1575 if (depth == 2) { 1576 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE]))); 1577 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE]))); 1578 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE]))); 1579 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE]))); 1580 } 1581 #if defined (GRF_ECS) 1582 CMOVE(tmp, R_DIWHIGH, 0x2000); 1583 #endif 1584 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD2]))); 1585 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD2]))); 1586 CEND(tmp); 1587 CEND(tmp); 1588 1589 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD2], CI_MOVE(R_BPLMOD2)); 1590 CBUMP(tmp); 1591 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane]))); 1592 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane]))); 1593 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line]))); 1594 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line]))); 1595 if (depth == 2) { 1596 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane]))); 1597 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane]))); 1598 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line]))); 1599 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line]))); 1600 } 1601 #if defined (GRF_ECS) 1602 CMOVE(tmp, R_DIWHIGH, 0x2000); 1603 #endif 1604 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD3]))); 1605 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD3]))); 1606 CEND(tmp); 1607 CEND(tmp); 1608 1609 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD3], CI_MOVE(R_BPLMOD2)); 1610 CBUMP(tmp); 1611 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE]))); 1612 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE]))); 1613 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE]))); 1614 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE]))); 1615 if (depth == 2) { 1616 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE]))); 1617 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE]))); 1618 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE]))); 1619 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE]))); 1620 } 1621 #if defined (GRF_ECS) 1622 CMOVE(tmp, R_DIWHIGH, 0x2000); 1623 #endif 1624 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD0]))); 1625 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD0]))); 1626 CEND(tmp); 1627 CEND(tmp); 1628 1629 /* swap new pointers in. */ 1630 for (i = F_QD_STORE_QUAD0, j = F_QD_QUAD0; 1631 i <= F_QD_STORE_QUAD3; i++, j++) { 1632 cp = a24_this_data->frames[j]; 1633 a24_this_data->frames[j] = a24_this_data->frames[i]; 1634 a24_this_data->frames[i] = cp; 1635 } 1636 1637 a24_this_data->current_view = v; 1638 vd->flags |= VF_DISPLAY; 1639 1640 cc_a2024_use_colormap(v, vd->colormap); 1641 } 1642 cc_load_mode(a24_this); 1643 } 1644 1645 void 1646 a2024_mode_vbl_handler(d) 1647 dmode_t *d; 1648 { 1649 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8); 1650 1651 if (vp < 12) { 1652 custom.cop1lc = PREP_DMA_MEM(a24_this_data->frames[a24_this_data->hedley_current]); 1653 custom.copjmp1 = 0; 1654 } 1655 a24_this_data->hedley_current++; 1656 a24_this_data->hedley_current &= 0x3; /* if 4 then 0. */ 1657 } 1658 #endif /* GRF_A2024 */ 1659 1660 #if defined (GRF_AGA) 1661 1662 dmode_t * 1663 cc_init_ntsc_aga() 1664 { 1665 /* this function should only be called once. */ 1666 if (!aga_this && (custom.deniseid & 0xff) == 0xf8 && 1667 aga_enable & AGA_ENABLE) { 1668 u_short len = aga_copper_list_len; 1669 cop_t *cp; 1670 1671 aga_this = &aga_mode; 1672 aga_this_data = &aga_mode_data; 1673 bzero(aga_this, sizeof(dmode_t)); 1674 bzero(aga_this_data, sizeof(dmdata_t)); 1675 1676 aga_this->name = "ntsc: AGA dbl"; 1677 aga_this->nominal_size.width = 640; 1678 aga_this->nominal_size.height = 400; 1679 aga_this_data->max_size.width = 724; 1680 aga_this_data->max_size.height = 482; 1681 aga_this_data->min_size.width = 320; 1682 aga_this_data->min_size.height = 200; 1683 aga_this_data->min_depth = 1; 1684 aga_this_data->max_depth = 8; 1685 aga_this->data = aga_this_data; 1686 1687 aga_this->get_monitor = cc_get_monitor; 1688 aga_this->alloc_view = cc_alloc_view; 1689 aga_this->get_current_view = cc_get_current_view; 1690 1691 aga_this_data->use_colormap = cc_use_aga_colormap; 1692 aga_this_data->get_colormap = cc_get_colormap; 1693 aga_this_data->alloc_colormap = cc_alloc_aga_colormap; 1694 aga_this_data->display_view = display_aga_view; 1695 aga_this_data->monitor = cc_monitor; 1696 1697 aga_this_data->frames = aga_frames; 1698 aga_this_data->frames[F_LONG] = alloc_chipmem(aga_copper_list_size * F_TOTAL); 1699 if (!aga_this_data->frames[F_LONG]) { 1700 panic("couldn't get chipmem for copper list"); 1701 } 1702 aga_this_data->frames[F_STORE_LONG] = &aga_this_data->frames[F_LONG][len]; 1703 1704 bcopy(aga_copper_list, aga_this_data->frames[F_STORE_LONG], aga_copper_list_size); 1705 bcopy(aga_copper_list, aga_this_data->frames[F_LONG], aga_copper_list_size); 1706 1707 aga_this_data->bplcon0 = 0x0240 | USE_CON3; /* color composite 1708 * enable, 1709 * shres. */ 1710 aga_this_data->std_start_x = 0x4f /*STANDARD_VIEW_X*/; 1711 aga_this_data->std_start_y = 0x2b /*STANDARD_VIEW_Y*/; 1712 aga_this_data->vbl_handler = (vbl_handler_func *) cc_mode_vbl_handler; 1713 aga_this_data->beamcon0 = SPECIAL_BEAMCON ^ VSYNCTRUE; 1714 1715 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, 1716 aga_this, link); 1717 } 1718 return (aga_this); 1719 } 1720 1721 /* static, so I can patch and play */ 1722 1723 int AGA_htotal = 0x79; 1724 int AGA_hsstrt = 0xe; 1725 int AGA_hsstop = 0x1c; 1726 int AGA_hbstrt = 0x8; 1727 int AGA_hbstop = 0x1e; 1728 int AGA_vtotal = 0x1ec; 1729 int AGA_vsstrt = 0x3; 1730 int AGA_vsstop = 0x6; 1731 int AGA_vbstrt = 0x0; 1732 int AGA_vbstop = 0x19; 1733 int AGA_hcenter = 0x4a; 1734 1735 void 1736 display_aga_view(v) 1737 view_t *v; 1738 { 1739 if (aga_this_data->current_view != v) { 1740 vdata_t *vd = VDATA(v); 1741 monitor_t *monitor = aga_this_data->monitor; 1742 cop_t *cp = aga_this_data->frames[F_STORE_LONG], *tmp; 1743 int depth = v->bitmap->depth, i; 1744 int hstart, hstop, vstart, vstop, j; 1745 int x, y, w = v->display.width, h = v->display.height; 1746 u_short ddfstart, ddfwidth, con1; 1747 1748 #ifdef DEBUG 1749 if (aga_enable & AGA_TRACE) 1750 printf("display_aga_view(%dx%dx%d) %x\n", w, h, 1751 depth, v); 1752 #endif 1753 /* round down to nearest even width */ 1754 /* w &= 0xfffe; */ 1755 /* calculate datafetch width. */ 1756 1757 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 4) << 1; 1758 1759 /* this will center the any overscanned display */ 1760 /* and allow user to modify. */ 1761 x = v->display.x + aga_this_data->std_start_x - ((w - 640) >> 3); 1762 y = v->display.y + aga_this_data->std_start_y - ((h - 400) >> 1); 1763 1764 if (y & 1) 1765 y--; 1766 1767 if (!(x & 1)) 1768 x--; 1769 1770 hstart = x; 1771 hstop = x + (w >> 2); 1772 vstart = y; 1773 vstop = y + (h >> 0); 1774 ddfstart = (hstart >> 1) - 8; 1775 1776 #ifdef DEBUG 1777 if (aga_enable & AGA_TRACE2) { 1778 printf (" ddfwidth %04x x %04x y %04x", ddfwidth, 1779 x, y); 1780 printf (" hstart %04x hstop %04x vstart %04x vstop %04x ddfstart %04x\n", 1781 hstart, hstop, vstart, vstop, ddfstart); 1782 } 1783 #endif 1784 /* check for hardware limits, AGA may allow more..? */ 1785 /* anyone got a 4000 I can borrow :^) -ch */ 1786 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 1787 int d = 0; 1788 1789 /* XXX anyone know the equality properties of 1790 * intermixed logial AND's */ 1791 /* XXX and arithmetic operators? */ 1792 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 1793 d++; 1794 } 1795 1796 ddfstart -= d; 1797 hstart -= d << 1; 1798 hstop -= d << 1; 1799 } 1800 /* correct the datafetch to proper limits. */ 1801 /* delay the actual display of the data until we need it. */ 1802 ddfstart &= 0xfffc; 1803 #ifdef DEBUG 1804 if (aga_enable & AGA_TRACE2) { 1805 printf (" ddfwidth %04x x %04x y %04x", ddfwidth, 1806 x, y); 1807 printf (" hstart %04x hstop %04x vstart %04x vstop %04x ddfstart %04x\n", 1808 hstart, hstop, vstart, vstop, ddfstart); 1809 } 1810 #endif 1811 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 1812 1813 if (aga_this_data->current_view) { 1814 VDATA(aga_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 1815 /* displayed. */ 1816 } 1817 aga_this_data->current_view = v; 1818 1819 cp = aga_this_data->frames[F_STORE_LONG]; 1820 tmp = cp; 1821 for (i = 0; i < 8; ++i) { 1822 if (tmp == NULL) 1823 break; 1824 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3)); 1825 if (tmp == NULL) 1826 break; 1827 tmp->cp.inst.operand = 0x0ca1 | (i << 13); 1828 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3)); 1829 if (tmp == NULL) 1830 break; 1831 tmp->cp.inst.operand = 0x0ea1 | (i << 13); 1832 } 1833 if (tmp) 1834 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3)); 1835 if (tmp) 1836 tmp->cp.inst.operand = 0x0ca1; 1837 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE)); 1838 tmp->cp.inst.operand = 0x8003; 1839 tmp = find_copper_inst(cp, CI_MOVE(R_HTOTAL)); 1840 tmp->cp.inst.operand = AGA_htotal; /* 81/71/73/79? */ 1841 tmp = find_copper_inst(cp, CI_MOVE(R_HBSTRT)); 1842 tmp->cp.inst.operand = AGA_hbstrt; /* 0x0008 */ 1843 tmp = find_copper_inst(cp, CI_MOVE(R_HSSTRT)); 1844 tmp->cp.inst.operand = AGA_hsstrt; /* 0x000e */ 1845 tmp = find_copper_inst(cp, CI_MOVE(R_HSSTOP)); 1846 tmp->cp.inst.operand = AGA_hsstop; /* 0x001c */ 1847 tmp = find_copper_inst(cp, CI_MOVE(R_HBSTOP)); 1848 tmp->cp.inst.operand = AGA_hsstop; /* 0x001e */ 1849 tmp = find_copper_inst(cp, CI_MOVE(R_HCENTER)); 1850 tmp->cp.inst.operand = AGA_hcenter; /*AGA_htotal / 2 + AGA_hsstrt */ 1851 tmp = find_copper_inst(cp, CI_MOVE(R_VBSTRT)); 1852 tmp->cp.inst.operand = AGA_vbstrt; /* 0x0000 */ 1853 tmp = find_copper_inst(cp, CI_MOVE(R_VSSTRT)); 1854 tmp->cp.inst.operand = AGA_vsstrt; /* 0x016b / AGA_htotal */ 1855 tmp = find_copper_inst(cp, CI_MOVE(R_VSSTOP)); 1856 tmp->cp.inst.operand = AGA_vsstop; /* 0x02d6 / AGA_htotal */ 1857 tmp = find_copper_inst(cp, CI_MOVE(R_VBSTOP)); 1858 tmp->cp.inst.operand = AGA_vbstop; /* 0x0bd1 / AGA_htotal */ 1859 tmp = find_copper_inst(cp, CI_MOVE(R_VTOTAL)); 1860 tmp->cp.inst.operand = AGA_vtotal; 1861 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 1862 tmp->cp.inst.operand = aga_this_data->beamcon0; 1863 #ifdef DEBUG 1864 if (aga_enable & AGA_TRACE2) 1865 printf(" beamcon0 %04x", tmp->cp.inst.operand); 1866 #endif 1867 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 1868 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 1869 #ifdef DEBUG 1870 if (aga_enable & AGA_TRACE2) 1871 printf(" diwhigh %04x>", tmp->cp.inst.operand); 1872 #endif 1873 #if 0 1874 tmp->cp.inst.operand = (vstop & 0x0700) | ((hstop & 0x0100) << 5); 1875 #endif 1876 #ifdef DEBUG 1877 if (aga_enable & AGA_TRACE2) 1878 printf("%04x", tmp->cp.inst.operand); 1879 #endif 1880 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 1881 tmp->cp.inst.operand = aga_this_data->bplcon0 | 1882 ((depth & 0x7) << 12) | ((depth & 0x8) << 1); 1883 #ifdef DEBUG 1884 if (aga_enable & AGA_TRACE2) 1885 printf(" bplcon0 %04x", tmp->cp.inst.operand); 1886 #endif 1887 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 1888 tmp->cp.inst.operand = con1; 1889 #ifdef DEBUG 1890 if (aga_enable & AGA_TRACE2) 1891 printf(" bplcon1 %04x>0000\n", con1); 1892 #endif 1893 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 1894 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 1895 #ifdef DEBUG 1896 if (aga_enable & AGA_TRACE2) 1897 printf(" diwstart %04x", tmp->cp.inst.operand); 1898 #endif 1899 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 1900 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 1901 #ifdef DEBUG 1902 if (aga_enable & AGA_TRACE2) 1903 printf(" diwstop %04x", tmp->cp.inst.operand); 1904 #endif 1905 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 1906 tmp->cp.inst.operand = ddfstart; 1907 #ifdef DEBUG 1908 if (aga_enable & AGA_TRACE2) 1909 printf(" ddfstart %04x", tmp->cp.inst.operand); 1910 #endif 1911 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 1912 tmp->cp.inst.operand = ddfstart + ddfwidth; 1913 #ifdef DEBUG 1914 if (aga_enable & AGA_TRACE2) 1915 printf(" ddfstop %04x", tmp->cp.inst.operand); 1916 #endif 1917 1918 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 1919 for (i = 0, j = 0; i < depth; j += 2, i++) { 1920 /* update the plane pointers */ 1921 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 1922 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 1923 #ifdef DEBUG 1924 if (aga_enable & AGA_TRACE2) 1925 printf (" bpl%dpth %08x", i, v->bitmap->plane[i]); 1926 #endif 1927 } 1928 1929 /* set mods correctly. */ 1930 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 1931 tmp[0].cp.inst.operand = v->bitmap->row_mod; 1932 tmp[1].cp.inst.operand = v->bitmap->row_mod; 1933 #ifdef DEBUG 1934 if (aga_enable & AGA_TRACE2) 1935 printf(" bplxmod %04x\n", v->bitmap->row_mod); 1936 #endif 1937 1938 /* set next pointers correctly */ 1939 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 1940 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(aga_this_data->frames[F_STORE_LONG])); 1941 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(aga_this_data->frames[F_STORE_LONG])); 1942 1943 cp = aga_this_data->frames[F_LONG]; 1944 aga_this_data->frames[F_LONG] = aga_this_data->frames[F_STORE_LONG]; 1945 aga_this_data->frames[F_STORE_LONG] = cp; 1946 1947 vd->flags |= VF_DISPLAY; 1948 1949 cc_use_aga_colormap(v, vd->colormap); 1950 } 1951 cc_load_mode(aga_this); 1952 #ifdef DEBUG 1953 if (aga_enable & AGA_TRACE) 1954 aga_enable |= AGA_TRACE2; /* XXXX */ 1955 #endif 1956 } 1957 1958 #endif /* GRF_AGA */ 1959 #endif /* GRF_NTSC */ 1960 1961 /* 1962 * PAL modes. 1963 */ 1964 1965 #if defined (GRF_PAL) 1966 1967 dmode_t * 1968 cc_init_pal_hires() 1969 { 1970 /* this function should only be called once. */ 1971 if (!ph_this) { 1972 u_short len = std_copper_list_len; 1973 cop_t *cp; 1974 1975 ph_this = &pal_hires_mode; 1976 ph_this_data = &pal_hires_mode_data; 1977 bzero(ph_this, sizeof(dmode_t)); 1978 bzero(ph_this_data, sizeof(dmdata_t)); 1979 1980 ph_this->name = "pal: pal_hires interlace"; 1981 ph_this->nominal_size.width = 640; 1982 ph_this->nominal_size.height = 256; 1983 ph_this_data->max_size.width = 724; 1984 ph_this_data->max_size.height = 289; 1985 ph_this_data->min_size.width = 320; 1986 ph_this_data->min_size.height = 244; 1987 ph_this_data->min_depth = 1; 1988 ph_this_data->max_depth = 4; 1989 ph_this->data = ph_this_data; 1990 1991 ph_this->get_monitor = cc_get_monitor; 1992 ph_this->alloc_view = cc_alloc_view; 1993 ph_this->get_current_view = cc_get_current_view; 1994 1995 ph_this_data->use_colormap = cc_use_colormap; 1996 ph_this_data->get_colormap = cc_get_colormap; 1997 ph_this_data->alloc_colormap = cc_alloc_colormap; 1998 ph_this_data->display_view = display_pal_hires_view; 1999 ph_this_data->monitor = cc_monitor; 2000 2001 ph_this_data->frames = pal_hires_frames; 2002 ph_this_data->frames[F_LONG] = alloc_chipmem(std_copper_list_size * F_TOTAL); 2003 if (!ph_this_data->frames[F_LONG]) { 2004 panic("couldn't get chipmem for copper list"); 2005 } 2006 ph_this_data->frames[F_STORE_LONG] = &ph_this_data->frames[F_LONG][len]; 2007 2008 bcopy(std_copper_list, ph_this_data->frames[F_STORE_LONG], std_copper_list_size); 2009 bcopy(std_copper_list, ph_this_data->frames[F_LONG], std_copper_list_size); 2010 2011 ph_this_data->bplcon0 = 0x8200 | USE_CON3; /* pal_hires, color 2012 * composite enable, 2013 * lace. */ 2014 ph_this_data->std_start_x = STANDARD_VIEW_X; 2015 ph_this_data->std_start_y = STANDARD_VIEW_Y; 2016 ph_this_data->vbl_handler = (vbl_handler_func *) cc_mode_vbl_handler; 2017 #if defined (GRF_ECS) 2018 ph_this_data->beamcon0 = STANDARD_PAL_BEAMCON; 2019 #endif 2020 2021 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, ph_this, link); 2022 } 2023 return (ph_this); 2024 } 2025 2026 void 2027 display_pal_hires_view(v) 2028 view_t *v; 2029 { 2030 if (ph_this_data->current_view != v) { 2031 vdata_t *vd = VDATA(v); 2032 monitor_t *monitor = ph_this_data->monitor; 2033 cop_t *cp = ph_this_data->frames[F_STORE_LONG], *tmp; 2034 int depth = v->bitmap->depth, i; 2035 int hstart, hstop, vstart, vstop, j; 2036 int x, y, w = v->display.width, h = v->display.height; 2037 u_short ddfstart, ddfwidth, con1; 2038 2039 /* round down to nearest even width */ 2040 /* w &= 0xfffe; */ 2041 2042 /* calculate datafetch width. */ 2043 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2; 2044 2045 /* This will center the any overscanned display */ 2046 /* and allow user to modify. */ 2047 x = v->display.x + ph_this_data->std_start_x - ((w - 640) >> 2); 2048 y = v->display.y + ph_this_data->std_start_y - ((h - 256) >> 1); 2049 2050 if (y & 1) 2051 y--; 2052 2053 if (!(x & 1)) 2054 x--; 2055 2056 hstart = x; 2057 hstop = x + (w >> 1); 2058 vstart = y; 2059 vstop = y + h; 2060 ddfstart = (hstart - 9) >> 1; 2061 /* check for hardware limits, AGA may allow more..? */ 2062 /* anyone got a 4000 I can borrow :^) -ch */ 2063 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 2064 int d = 0; 2065 2066 /* XXX anyone know the equality properties of 2067 * intermixed logial AND's */ 2068 /* XXX and arithmetic operators? */ 2069 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 2070 d++; 2071 } 2072 2073 ddfstart -= d; 2074 hstart -= d << 1; 2075 hstop -= d << 1; 2076 } 2077 /* correct the datafetch to proper limits. */ 2078 /* delay the actual display of the data until we need it. */ 2079 ddfstart &= 0xfffc; 2080 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 2081 2082 if (ph_this_data->current_view) { 2083 VDATA(ph_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 2084 /* displayed. */ 2085 } 2086 ph_this_data->current_view = v; 2087 2088 cp = ph_this_data->frames[F_STORE_LONG]; 2089 #if defined GRF_ECS 2090 #if defined GRF_AGA 2091 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE)); 2092 tmp->cp.inst.operand = 0; 2093 #endif 2094 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 2095 tmp->cp.inst.operand = ph_this_data->beamcon0; 2096 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 2097 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 2098 #endif /* ECS */ 2099 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 2100 tmp->cp.inst.operand = ph_this_data->bplcon0 | ((depth & 0x7) << 12); 2101 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 2102 tmp->cp.inst.operand = con1; 2103 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 2104 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 2105 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 2106 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 2107 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 2108 tmp->cp.inst.operand = ddfstart; 2109 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 2110 tmp->cp.inst.operand = ddfstart + ddfwidth; 2111 2112 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 2113 for (i = 0, j = 0; i < depth; j += 2, i++) { 2114 /* update the plane pointers */ 2115 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 2116 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 2117 } 2118 2119 /* set mods correctly. */ 2120 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 2121 tmp[0].cp.inst.operand = v->bitmap->row_mod; 2122 tmp[1].cp.inst.operand = v->bitmap->row_mod; 2123 2124 /* set next pointers correctly */ 2125 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 2126 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(ph_this_data->frames[F_STORE_LONG])); 2127 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(ph_this_data->frames[F_STORE_LONG])); 2128 2129 cp = ph_this_data->frames[F_LONG]; 2130 ph_this_data->frames[F_LONG] = ph_this_data->frames[F_STORE_LONG]; 2131 ph_this_data->frames[F_STORE_LONG] = cp; 2132 2133 vd->flags |= VF_DISPLAY; 2134 cc_use_colormap(v, vd->colormap); 2135 } 2136 cc_load_mode(ph_this); 2137 } 2138 2139 dmode_t * 2140 cc_init_pal_hires_lace() 2141 { 2142 /* this function should only be called once. */ 2143 if (!phl_this) { 2144 u_short len = std_copper_list_len; 2145 cop_t *cp; 2146 2147 phl_this = &pal_hires_lace_mode; 2148 phl_this_data = &pal_hires_lace_mode_data; 2149 bzero(phl_this, sizeof(dmode_t)); 2150 bzero(phl_this_data, sizeof(dmdata_t)); 2151 2152 phl_this->name = "pal: hires interlace"; 2153 phl_this->nominal_size.width = 640; 2154 phl_this->nominal_size.height = 512; 2155 phl_this_data->max_size.width = 724; 2156 phl_this_data->max_size.height = 578; 2157 phl_this_data->min_size.width = 320; 2158 phl_this_data->min_size.height = 484; 2159 phl_this_data->min_depth = 1; 2160 phl_this_data->max_depth = 4; 2161 phl_this->data = phl_this_data; 2162 2163 phl_this->get_monitor = cc_get_monitor; 2164 phl_this->alloc_view = cc_alloc_view; 2165 phl_this->get_current_view = cc_get_current_view; 2166 2167 phl_this_data->use_colormap = cc_use_colormap; 2168 phl_this_data->get_colormap = cc_get_colormap; 2169 phl_this_data->alloc_colormap = cc_alloc_colormap; 2170 phl_this_data->display_view = display_pal_hires_lace_view; 2171 phl_this_data->monitor = cc_monitor; 2172 2173 phl_this_data->flags |= DMF_INTERLACE; 2174 2175 phl_this_data->frames = pal_hires_lace_frames; 2176 phl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_copper_list_size * F_LACE_TOTAL); 2177 if (!phl_this_data->frames[F_LACE_LONG]) { 2178 panic("couldn't get chipmem for copper list"); 2179 } 2180 phl_this_data->frames[F_LACE_SHORT] = &phl_this_data->frames[F_LACE_LONG][len]; 2181 phl_this_data->frames[F_LACE_STORE_LONG] = &phl_this_data->frames[F_LACE_SHORT][len]; 2182 phl_this_data->frames[F_LACE_STORE_SHORT] = &phl_this_data->frames[F_LACE_STORE_LONG][len]; 2183 2184 bcopy(std_copper_list, phl_this_data->frames[F_LACE_STORE_LONG], std_copper_list_size); 2185 bcopy(std_copper_list, phl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size); 2186 bcopy(std_copper_list, phl_this_data->frames[F_LACE_LONG], std_copper_list_size); 2187 bcopy(std_copper_list, phl_this_data->frames[F_LACE_SHORT], std_copper_list_size); 2188 2189 phl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color 2190 * composite enable, 2191 * lace. */ 2192 phl_this_data->std_start_x = STANDARD_VIEW_X; 2193 phl_this_data->std_start_y = STANDARD_VIEW_Y; 2194 phl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler; 2195 #if defined (GRF_ECS) 2196 phl_this_data->beamcon0 = STANDARD_PAL_BEAMCON; 2197 #endif 2198 2199 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, phl_this, link); 2200 } 2201 return (phl_this); 2202 } 2203 2204 void 2205 display_pal_hires_lace_view(v) 2206 view_t *v; 2207 { 2208 if (phl_this_data->current_view != v) { 2209 vdata_t *vd = VDATA(v); 2210 monitor_t *monitor = phl_this_data->monitor; 2211 cop_t *cp = phl_this_data->frames[F_LACE_STORE_LONG], *tmp; 2212 int depth = v->bitmap->depth, i; 2213 int hstart, hstop, vstart, vstop, j; 2214 int x, y, w = v->display.width, h = v->display.height; 2215 u_short ddfstart, ddfwidth, con1; 2216 2217 /* round down to nearest even width */ 2218 /* w &= 0xfffe; */ 2219 2220 /* calculate datafetch width. */ 2221 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2; 2222 2223 /* This will center the any overscanned display */ 2224 /* and allow user to modify. */ 2225 x = v->display.x + phl_this_data->std_start_x - ((w - 640) >> 2); 2226 y = v->display.y + phl_this_data->std_start_y - ((h - 512) >> 2); 2227 2228 if (y & 1) 2229 y--; 2230 2231 if (!(x & 1)) 2232 x--; 2233 2234 hstart = x; 2235 hstop = x + (w >> 1); 2236 vstart = y; 2237 vstop = y + (h >> 1); 2238 ddfstart = (hstart - 9) >> 1; 2239 2240 /* check for hardware limits, AGA may allow more..? */ 2241 /* anyone got a 4000 I can borrow :^) -ch */ 2242 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 2243 int d = 0; 2244 2245 /* XXX anyone know the equality properties of 2246 * intermixed logial AND's */ 2247 /* XXX and arithmetic operators? */ 2248 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 2249 d++; 2250 } 2251 2252 ddfstart -= d; 2253 hstart -= d << 1; 2254 hstop -= d << 1; 2255 } 2256 /* correct the datafetch to proper limits. */ 2257 /* delay the actual display of the data until we need it. */ 2258 ddfstart &= 0xfffc; 2259 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 2260 2261 if (phl_this_data->current_view) { 2262 VDATA(phl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 2263 /* displayed. */ 2264 } 2265 phl_this_data->current_view = v; 2266 2267 cp = phl_this_data->frames[F_LACE_STORE_LONG]; 2268 #if defined GRF_ECS 2269 #if defined GRF_AGA 2270 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE)); 2271 tmp->cp.inst.operand = 0; 2272 #endif 2273 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 2274 tmp->cp.inst.operand = phl_this_data->beamcon0; 2275 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 2276 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 2277 #endif /* ECS */ 2278 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 2279 tmp->cp.inst.operand = phl_this_data->bplcon0 | ((depth & 0x7) << 12); 2280 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 2281 tmp->cp.inst.operand = con1; 2282 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 2283 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 2284 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 2285 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 2286 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 2287 tmp->cp.inst.operand = ddfstart; 2288 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 2289 tmp->cp.inst.operand = ddfstart + ddfwidth; 2290 2291 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 2292 for (i = 0, j = 0; i < depth; j += 2, i++) { 2293 /* update the plane pointers */ 2294 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 2295 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 2296 } 2297 2298 /* set mods correctly. */ 2299 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 2300 tmp[0].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod; 2301 tmp[1].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod; 2302 2303 /* set next pointers correctly */ 2304 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 2305 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_SHORT])); 2306 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_SHORT])); 2307 2308 2309 bcopy(phl_this_data->frames[F_LACE_STORE_LONG], phl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size); 2310 2311 /* these are the only ones that are different from long frame. */ 2312 cp = phl_this_data->frames[F_LACE_STORE_SHORT]; 2313 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 2314 for (i = 0, j = 0; i < depth; j += 2, i++) { 2315 u_short mod = v->bitmap->bytes_per_row + v->bitmap->row_mod; 2316 /* update plane pointers. high and low. */ 2317 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod])); 2318 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod])); 2319 } 2320 2321 /* set next pointers correctly */ 2322 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 2323 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_LONG])); 2324 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_LONG])); 2325 2326 2327 cp = phl_this_data->frames[F_LACE_LONG]; 2328 phl_this_data->frames[F_LACE_LONG] = phl_this_data->frames[F_LACE_STORE_LONG]; 2329 phl_this_data->frames[F_LACE_STORE_LONG] = cp; 2330 2331 cp = phl_this_data->frames[F_LACE_SHORT]; 2332 phl_this_data->frames[F_LACE_SHORT] = phl_this_data->frames[F_LACE_STORE_SHORT]; 2333 phl_this_data->frames[F_LACE_STORE_SHORT] = cp; 2334 2335 vd->flags |= VF_DISPLAY; 2336 cc_use_colormap(v, vd->colormap); 2337 } 2338 cc_load_mode(phl_this); 2339 } 2340 #if defined (GRF_A2024) 2341 2342 dmode_t * 2343 cc_init_pal_hires_dlace() 2344 { 2345 /* this function should only be called once. */ 2346 if (!phdl_this) { 2347 u_short len = std_dlace_copper_list_len; 2348 cop_t *cp; 2349 2350 phdl_this = &pal_hires_dlace_mode; 2351 phdl_this_data = &pal_hires_dlace_mode_data; 2352 bzero(phdl_this, sizeof(dmode_t)); 2353 bzero(phdl_this_data, sizeof(dmdata_t)); 2354 2355 phdl_this->name = "pal: hires double interlace"; 2356 phdl_this->nominal_size.width = 640; 2357 phdl_this->nominal_size.height = 1024; 2358 phdl_this_data->max_size.width = 724; 2359 phdl_this_data->max_size.height = 1024; 2360 phdl_this_data->min_size.width = 320; 2361 phdl_this_data->min_size.height = 512; 2362 phdl_this_data->min_depth = 1; 2363 phdl_this_data->max_depth = 2; 2364 phdl_this->data = phdl_this_data; 2365 2366 phdl_this->get_monitor = cc_get_monitor; 2367 phdl_this->alloc_view = cc_alloc_view; 2368 phdl_this->get_current_view = cc_get_current_view; 2369 2370 phdl_this_data->use_colormap = cc_a2024_use_colormap; 2371 phdl_this_data->get_colormap = cc_a2024_get_colormap; 2372 phdl_this_data->alloc_colormap = cc_a2024_alloc_colormap; 2373 phdl_this_data->display_view = display_pal_hires_dlace_view; 2374 phdl_this_data->monitor = cc_monitor; 2375 2376 phdl_this_data->flags |= DMF_INTERLACE; 2377 2378 phdl_this_data->frames = pal_hires_dlace_frames; 2379 phdl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_dlace_copper_list_size * F_LACE_TOTAL); 2380 if (!phdl_this_data->frames[F_LACE_LONG]) { 2381 panic("couldn't get chipmem for copper list"); 2382 } 2383 phdl_this_data->frames[F_LACE_SHORT] = &phdl_this_data->frames[F_LACE_LONG][len]; 2384 phdl_this_data->frames[F_LACE_STORE_LONG] = &phdl_this_data->frames[F_LACE_SHORT][len]; 2385 phdl_this_data->frames[F_LACE_STORE_SHORT] = &phdl_this_data->frames[F_LACE_STORE_LONG][len]; 2386 2387 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_STORE_LONG], std_dlace_copper_list_size); 2388 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_STORE_SHORT], std_dlace_copper_list_size); 2389 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_LONG], std_dlace_copper_list_size); 2390 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_SHORT], std_dlace_copper_list_size); 2391 2392 phdl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color 2393 * composite enable, 2394 * dlace. */ 2395 phdl_this_data->std_start_x = STANDARD_VIEW_X; 2396 phdl_this_data->std_start_y = STANDARD_VIEW_Y; 2397 phdl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler; 2398 #if defined (GRF_ECS) 2399 phdl_this_data->beamcon0 = STANDARD_PAL_BEAMCON; 2400 #endif 2401 2402 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, phdl_this, link); 2403 } 2404 return (phdl_this); 2405 } 2406 2407 void 2408 display_pal_hires_dlace_view(v) 2409 view_t *v; 2410 { 2411 if (phdl_this_data->current_view != v) { 2412 vdata_t *vd = VDATA(v); 2413 monitor_t *monitor = phdl_this_data->monitor; 2414 cop_t *cp = phdl_this_data->frames[F_LACE_STORE_LONG], *tmp; 2415 int depth = v->bitmap->depth, i; 2416 int hstart, hstop, vstart, vstop, j; 2417 int x, y, w = v->display.width, h = v->display.height; 2418 u_short ddfstart, ddfwidth, con1; 2419 u_short mod1l, mod2l; 2420 2421 /* round down to nearest even width */ 2422 /* w &= 0xfffe; */ 2423 2424 /* calculate datafetch width. */ 2425 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2; 2426 2427 /* This will center the any overscanned display */ 2428 /* and allow user to modify. */ 2429 x = v->display.x + phdl_this_data->std_start_x - ((w - 640) >> 2); 2430 y = v->display.y + phdl_this_data->std_start_y - ((h - 1024) >> 3); 2431 2432 if (y & 1) 2433 y--; 2434 2435 if (!(x & 1)) 2436 x--; 2437 2438 hstart = x; 2439 hstop = x + (w >> 1); 2440 vstart = y; 2441 vstop = y + (h >> 2); 2442 ddfstart = (hstart - 9) >> 1; 2443 2444 /* check for hardware limits, AGA may allow more..? */ 2445 /* anyone got a 4000 I can borrow :^) -ch */ 2446 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 2447 int d = 0; 2448 2449 /* XXX anyone know the equality properties of 2450 * intermixed logial AND's */ 2451 /* XXX and arithmetic operators? */ 2452 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 2453 d++; 2454 } 2455 2456 ddfstart -= d; 2457 hstart -= d << 1; 2458 hstop -= d << 1; 2459 } 2460 /* correct the datafetch to proper limits. */ 2461 /* delay the actual display of the data until we need it. */ 2462 ddfstart &= 0xfffc; 2463 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 2464 2465 if (phdl_this_data->current_view) { 2466 VDATA(phdl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 2467 /* displayed. */ 2468 } 2469 phdl_this_data->current_view = v; 2470 2471 cp = phdl_this_data->frames[F_LACE_STORE_LONG]; 2472 #if defined GRF_ECS 2473 #if defined GRF_AGA 2474 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE)); 2475 tmp->cp.inst.operand = 0; 2476 #endif 2477 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 2478 tmp->cp.inst.operand = phdl_this_data->beamcon0; 2479 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 2480 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 2481 #endif /* ECS */ 2482 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 2483 tmp->cp.inst.operand = phdl_this_data->bplcon0 | ((depth & 0x7) << 13); /* times two. */ 2484 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 2485 tmp->cp.inst.operand = con1; 2486 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 2487 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 2488 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 2489 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 2490 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 2491 tmp->cp.inst.operand = ddfstart; 2492 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 2493 tmp->cp.inst.operand = ddfstart + ddfwidth; 2494 2495 mod1l = v->bitmap->bytes_per_row + v->bitmap->row_mod; 2496 mod2l = mod1l << 1; 2497 2498 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 2499 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0])); /* update plane 2500 * pointers. */ 2501 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0])); /* high and low. */ 2502 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l])); /* update plane 2503 * pointers. */ 2504 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l])); /* high and low. */ 2505 if (depth == 2) { 2506 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0])); /* update plane 2507 * pointers. */ 2508 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0])); /* high and low. */ 2509 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l])); /* update plane 2510 * pointers. */ 2511 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l])); /* high and low. */ 2512 } 2513 /* set mods correctly. */ 2514 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 2515 tmp[0].cp.inst.operand = mod2l + mod1l; 2516 tmp[1].cp.inst.operand = mod2l + mod1l; 2517 2518 /* set next pointers correctly */ 2519 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 2520 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_SHORT])); 2521 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_SHORT])); 2522 2523 bcopy(phdl_this_data->frames[F_LACE_STORE_LONG], phdl_this_data->frames[F_LACE_STORE_SHORT], std_dlace_copper_list_size); 2524 2525 /* these are the only ones that are different from long frame. */ 2526 cp = phdl_this_data->frames[F_LACE_STORE_SHORT]; 2527 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 2528 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l])); /* update plane 2529 * pointers. */ 2530 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l])); /* high and low. */ 2531 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l])); /* update plane 2532 * pointers. */ 2533 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l])); /* high and low. */ 2534 if (depth == 2) { 2535 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l])); /* update plane 2536 * pointers. */ 2537 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l])); /* high and low. */ 2538 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l])); /* update plane 2539 * pointers. */ 2540 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l])); /* high and low. */ 2541 } 2542 /* set next pointers correctly */ 2543 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 2544 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_LONG])); 2545 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_LONG])); 2546 2547 cp = phdl_this_data->frames[F_LACE_LONG]; 2548 phdl_this_data->frames[F_LACE_LONG] = phdl_this_data->frames[F_LACE_STORE_LONG]; 2549 phdl_this_data->frames[F_LACE_STORE_LONG] = cp; 2550 2551 cp = phdl_this_data->frames[F_LACE_SHORT]; 2552 phdl_this_data->frames[F_LACE_SHORT] = phdl_this_data->frames[F_LACE_STORE_SHORT]; 2553 phdl_this_data->frames[F_LACE_STORE_SHORT] = cp; 2554 2555 vd->flags |= VF_DISPLAY; 2556 2557 cc_a2024_use_colormap(v, vd->colormap); 2558 } 2559 cc_load_mode(phdl_this); 2560 } 2561 2562 dmode_t * 2563 cc_init_pal_a2024() 2564 { 2565 /* this function should only be called once. */ 2566 if (!p24_this) { 2567 int i; 2568 u_short len = std_pal_a2024_copper_list_len; 2569 cop_t *cp; 2570 2571 p24_this = &pal_a2024_mode; 2572 p24_this_data = &pal_a2024_mode_data; 2573 bzero(p24_this, sizeof(dmode_t)); 2574 bzero(p24_this_data, sizeof(dmdata_t)); 2575 2576 p24_this->name = "pal: A2024 15khz"; 2577 p24_this->nominal_size.width = 1024; 2578 p24_this->nominal_size.height = 1024; 2579 p24_this_data->max_size.width = 1024; 2580 p24_this_data->max_size.height = 1024; 2581 p24_this_data->min_size.width = 1024; 2582 p24_this_data->min_size.height = 1024; 2583 p24_this_data->min_depth = 1; 2584 p24_this_data->max_depth = 2; 2585 p24_this->data = p24_this_data; 2586 2587 p24_this->get_monitor = cc_get_monitor; 2588 p24_this->alloc_view = cc_alloc_view; 2589 p24_this->get_current_view = cc_get_current_view; 2590 2591 p24_this_data->use_colormap = cc_a2024_use_colormap; 2592 p24_this_data->get_colormap = cc_a2024_get_colormap; 2593 p24_this_data->display_view = display_pal_a2024_view; 2594 p24_this_data->alloc_colormap = cc_a2024_alloc_colormap; 2595 p24_this_data->monitor = cc_monitor; 2596 2597 p24_this_data->flags |= DMF_HEDLEY_EXP; 2598 2599 p24_this_data->frames = pal_a2024_frames; 2600 p24_this_data->frames[F_QD_QUAD0] = alloc_chipmem(std_pal_a2024_copper_list_size * F_QD_TOTAL); 2601 if (!p24_this_data->frames[F_QD_QUAD0]) { 2602 panic("couldn't get chipmem for copper list"); 2603 } 2604 /* setup the hedley init bitplane. */ 2605 hedley_init = alloc_chipmem(128); 2606 if (!hedley_init) { 2607 panic("couldn't get chipmem for hedley init bitplane"); 2608 } 2609 for (i = 1; i < 128; i++) 2610 hedley_init[i] = 0xff; 2611 hedley_init[0] = 0x03; 2612 2613 /* copy image of standard copper list. */ 2614 bcopy(std_pal_a2024_copper_list, p24_this_data->frames[0], std_pal_a2024_copper_list_size); 2615 2616 /* set the init plane pointer. */ 2617 cp = find_copper_inst(p24_this_data->frames[F_QD_QUAD0], CI_MOVE(R_BPL0PTH)); 2618 cp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hedley_init)); 2619 cp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hedley_init)); 2620 2621 for (i = 1; i < F_QD_TOTAL; i++) { 2622 p24_this_data->frames[i] = &p24_this_data->frames[i - 1][len]; 2623 bcopy(p24_this_data->frames[0], p24_this_data->frames[i], std_pal_a2024_copper_list_size); 2624 } 2625 2626 p24_this_data->bplcon0 = 0x8200; /* hires */ 2627 p24_this_data->vbl_handler = (vbl_handler_func *) pal_a2024_mode_vbl_handler; 2628 2629 2630 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, p24_this, link); 2631 } 2632 return (p24_this); 2633 } 2634 2635 void 2636 display_pal_a2024_view(v) 2637 view_t *v; 2638 { 2639 if (p24_this_data->current_view != v) { 2640 vdata_t *vd = VDATA(v); 2641 monitor_t *monitor = p24_this_data->monitor; 2642 cop_t *cp, *tmp; 2643 u_char *inst_plane[2]; 2644 u_char **plane = inst_plane; 2645 u_long full_line = v->bitmap->bytes_per_row + v->bitmap->row_mod; 2646 u_long half_plane = full_line * v->bitmap->rows / 2; 2647 2648 int line_mod = 0xbc; /* standard 2024 15khz mod. */ 2649 int depth = v->bitmap->depth, i, j; 2650 2651 plane[0] = v->bitmap->plane[0]; 2652 if (depth == 2) { 2653 plane[1] = v->bitmap->plane[1]; 2654 } 2655 if (p24_this_data->current_view) { 2656 VDATA(p24_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer 2657 * displayed. */ 2658 } 2659 cp = p24_this_data->frames[F_QD_STORE_QUAD0]; 2660 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR1F)); 2661 tmp = find_copper_inst(tmp, CI_MOVE(R_BPLCON0)); /* grab third one. */ 2662 tmp->cp.inst.operand = p24_this_data->bplcon0 | ((depth & 0x7) << 13); /* times 2 */ 2663 2664 bcopy(p24_this_data->frames[F_QD_STORE_QUAD0], p24_this_data->frames[F_QD_STORE_QUAD1], std_pal_a2024_copper_list_size); 2665 bcopy(p24_this_data->frames[F_QD_STORE_QUAD0], p24_this_data->frames[F_QD_STORE_QUAD2], std_pal_a2024_copper_list_size); 2666 bcopy(p24_this_data->frames[F_QD_STORE_QUAD0], p24_this_data->frames[F_QD_STORE_QUAD3], std_pal_a2024_copper_list_size); 2667 2668 /* 2669 * Mark Id's 2670 */ 2671 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD1], CI_WAIT(126, 29)); 2672 CBUMP(tmp); 2673 CMOVE(tmp, R_COLOR01, QUAD1_ID); 2674 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD2], CI_WAIT(126, 29)); 2675 CBUMP(tmp); 2676 CMOVE(tmp, R_COLOR01, QUAD2_ID); 2677 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD3], CI_WAIT(126, 29)); 2678 CBUMP(tmp); 2679 CMOVE(tmp, R_COLOR01, QUAD3_ID); 2680 2681 plane[0]--; 2682 plane[0]--; 2683 if (depth == 2) { 2684 plane[1]--; 2685 plane[1]--; 2686 } 2687 /* 2688 * Set bitplane pointers. 2689 */ 2690 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD0], CI_MOVE(R_BPLMOD2)); 2691 CBUMP(tmp); 2692 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][0]))); 2693 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][0]))); 2694 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line]))); 2695 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line]))); 2696 if (depth == 2) { 2697 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][0]))); 2698 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][0]))); 2699 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line]))); 2700 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line]))); 2701 } 2702 #if defined (GRF_ECS) 2703 CMOVE(tmp, R_DIWHIGH, 0x2100); 2704 #endif 2705 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD1]))); 2706 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD1]))); 2707 CEND(tmp); 2708 CEND(tmp); 2709 2710 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD1], CI_MOVE(R_BPLMOD2)); 2711 CBUMP(tmp); 2712 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE]))); 2713 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE]))); 2714 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE]))); 2715 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE]))); 2716 if (depth == 2) { 2717 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE]))); 2718 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE]))); 2719 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE]))); 2720 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE]))); 2721 } 2722 #if defined (GRF_ECS) 2723 CMOVE(tmp, R_DIWHIGH, 0x2100); 2724 #endif 2725 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD2]))); 2726 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD2]))); 2727 CEND(tmp); 2728 CEND(tmp); 2729 2730 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD2], CI_MOVE(R_BPLMOD2)); 2731 CBUMP(tmp); 2732 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane]))); 2733 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane]))); 2734 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line]))); 2735 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line]))); 2736 if (depth == 2) { 2737 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane]))); 2738 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane]))); 2739 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line]))); 2740 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line]))); 2741 } 2742 #if defined (GRF_ECS) 2743 CMOVE(tmp, R_DIWHIGH, 0x2100); 2744 #endif 2745 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD3]))); 2746 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD3]))); 2747 CEND(tmp); 2748 CEND(tmp); 2749 2750 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD3], CI_MOVE(R_BPLMOD2)); 2751 CBUMP(tmp); 2752 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE]))); 2753 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE]))); 2754 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE]))); 2755 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE]))); 2756 if (depth == 2) { 2757 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE]))); 2758 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE]))); 2759 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE]))); 2760 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE]))); 2761 } 2762 #if defined (GRF_ECS) 2763 CMOVE(tmp, R_DIWHIGH, 0x2100); 2764 #endif 2765 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD0]))); 2766 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD0]))); 2767 CEND(tmp); 2768 CEND(tmp); 2769 2770 /* swap new pointers in. */ 2771 for (i = F_QD_STORE_QUAD0, j = F_QD_QUAD0; 2772 i <= F_QD_STORE_QUAD3; i++, j++) { 2773 cp = p24_this_data->frames[j]; 2774 p24_this_data->frames[j] = p24_this_data->frames[i]; 2775 p24_this_data->frames[i] = cp; 2776 } 2777 2778 p24_this_data->current_view = v; 2779 vd->flags |= VF_DISPLAY; 2780 2781 cc_a2024_use_colormap(v, vd->colormap); 2782 } 2783 cc_load_mode(p24_this); 2784 } 2785 2786 void 2787 pal_a2024_mode_vbl_handler(d) 2788 dmode_t *d; 2789 { 2790 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8); 2791 2792 if (vp < 20) { 2793 custom.cop1lc = PREP_DMA_MEM(p24_this_data->frames[p24_this_data->hedley_current]); 2794 custom.copjmp1 = 0; 2795 } 2796 p24_this_data->hedley_current++; 2797 p24_this_data->hedley_current &= 0x3; /* if 4 then 0. */ 2798 } 2799 #endif /* GRF_PAL */ 2800 #endif /* GRF_A2024 */ 2801