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