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