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