1 /* $NetBSD: grfabs_cc.c,v 1.15 1996/10/13 03:07:09 christos 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 #ifdef GRF_AGA_VGA 1846 aga_this_data->std_start_x = 0x40 /*STANDARD_VIEW_X*/; 1847 #else 1848 aga_this_data->std_start_x = 0x4f /*STANDARD_VIEW_X*/; 1849 #endif 1850 aga_this_data->std_start_y = 0x2b /*STANDARD_VIEW_Y*/; 1851 aga_this_data->vbl_handler = (vbl_handler_func *) cc_mode_vbl_handler; 1852 aga_this_data->beamcon0 = SPECIAL_BEAMCON ^ VSYNCTRUE; 1853 1854 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, 1855 aga_this, link); 1856 } 1857 return (aga_this); 1858 } 1859 1860 /* static, so I can patch and play */ 1861 1862 #ifdef GRF_AGA_VGA 1863 int AGA_htotal = 0x71; 1864 int AGA_hsstrt = 0xc; 1865 int AGA_hsstop = 0x16; 1866 int AGA_hbstrt = 0x5; 1867 #else 1868 int AGA_htotal = 0x79; 1869 int AGA_hsstrt = 0xe; 1870 int AGA_hsstop = 0x1c; 1871 int AGA_hbstrt = 0x8; 1872 #endif 1873 int AGA_hbstop = 0x1e; 1874 #ifdef GRF_AGA_VGA 1875 int AGA_vtotal = 0x1c1; 1876 #else 1877 int AGA_vtotal = 0x1ec; 1878 #endif 1879 int AGA_vsstrt = 0x3; 1880 int AGA_vsstop = 0x6; 1881 int AGA_vbstrt = 0x0; 1882 int AGA_vbstop = 0x19; 1883 int AGA_hcenter = 0x4a; 1884 1885 void 1886 display_aga_view(v) 1887 view_t *v; 1888 { 1889 if (aga_this_data->current_view != v) { 1890 vdata_t *vd = VDATA(v); 1891 cop_t *cp = aga_this_data->frames[F_STORE_LONG], *tmp; 1892 int depth = v->bitmap->depth, i; 1893 int hstart, hstop, vstart, vstop, j; 1894 int x, y, w = v->display.width, h = v->display.height; 1895 u_short ddfstart, ddfwidth, con1; 1896 1897 #ifdef DEBUG 1898 if (aga_enable & AGA_TRACE) 1899 printf("display_aga_view(%dx%dx%d) %p\n", w, h, 1900 depth, v); 1901 #endif 1902 /* round down to nearest even width */ 1903 /* w &= 0xfffe; */ 1904 /* calculate datafetch width. */ 1905 1906 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 4) << 1; 1907 1908 /* this will center the any overscanned display */ 1909 /* and allow user to modify. */ 1910 x = v->display.x + aga_this_data->std_start_x - ((w - 640) >> 3); 1911 y = v->display.y + aga_this_data->std_start_y - ((h - 400) >> 1); 1912 1913 if (y & 1) 1914 y--; 1915 1916 if (!(x & 1)) 1917 x--; 1918 1919 hstart = x; 1920 hstop = x + (w >> 2); 1921 vstart = y; 1922 vstop = y + (h >> 0); 1923 ddfstart = (hstart >> 1) - 8; 1924 1925 #ifdef DEBUG 1926 if (aga_enable & AGA_TRACE2) { 1927 printf (" ddfwidth %04x x %04x y %04x", ddfwidth, 1928 x, y); 1929 printf (" hstart %04x hstop %04x vstart %04x vstop %04x ddfstart %04x\n", 1930 hstart, hstop, vstart, vstop, ddfstart); 1931 } 1932 #endif 1933 /* check for hardware limits, AGA may allow more..? */ 1934 /* anyone got a 4000 I can borrow :^) -ch */ 1935 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 1936 int d = 0; 1937 1938 /* XXX anyone know the equality properties of 1939 * intermixed logial AND's */ 1940 /* XXX and arithmetic operators? */ 1941 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 1942 d++; 1943 } 1944 1945 ddfstart -= d; 1946 hstart -= d << 1; 1947 hstop -= d << 1; 1948 } 1949 /* correct the datafetch to proper limits. */ 1950 /* delay the actual display of the data until we need it. */ 1951 ddfstart &= 0xfffc; 1952 #ifdef DEBUG 1953 if (aga_enable & AGA_TRACE2) { 1954 printf (" ddfwidth %04x x %04x y %04x", ddfwidth, 1955 x, y); 1956 printf (" hstart %04x hstop %04x vstart %04x vstop %04x ddfstart %04x\n", 1957 hstart, hstop, vstart, vstop, ddfstart); 1958 } 1959 #endif 1960 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 1961 1962 if (aga_this_data->current_view) { 1963 VDATA(aga_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 1964 /* displayed. */ 1965 } 1966 aga_this_data->current_view = v; 1967 1968 cp = aga_this_data->frames[F_STORE_LONG]; 1969 tmp = cp; 1970 for (i = 0; i < 8; ++i) { 1971 if (tmp == NULL) 1972 break; 1973 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3)); 1974 if (tmp == NULL) 1975 break; 1976 tmp->cp.inst.operand = 0x0ca1 | (i << 13); 1977 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3)); 1978 if (tmp == NULL) 1979 break; 1980 tmp->cp.inst.operand = 0x0ea1 | (i << 13); 1981 } 1982 if (tmp) 1983 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3)); 1984 if (tmp) 1985 tmp->cp.inst.operand = 0x0ca1; 1986 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE)); 1987 tmp->cp.inst.operand = 0x8003; 1988 tmp = find_copper_inst(cp, CI_MOVE(R_HTOTAL)); 1989 tmp->cp.inst.operand = AGA_htotal; /* 81/71/73/79? */ 1990 tmp = find_copper_inst(cp, CI_MOVE(R_HBSTRT)); 1991 tmp->cp.inst.operand = AGA_hbstrt; /* 0x0008 */ 1992 tmp = find_copper_inst(cp, CI_MOVE(R_HSSTRT)); 1993 tmp->cp.inst.operand = AGA_hsstrt; /* 0x000e */ 1994 tmp = find_copper_inst(cp, CI_MOVE(R_HSSTOP)); 1995 tmp->cp.inst.operand = AGA_hsstop; /* 0x001c */ 1996 tmp = find_copper_inst(cp, CI_MOVE(R_HBSTOP)); 1997 tmp->cp.inst.operand = AGA_hsstop; /* 0x001e */ 1998 tmp = find_copper_inst(cp, CI_MOVE(R_HCENTER)); 1999 tmp->cp.inst.operand = AGA_hcenter; /*AGA_htotal / 2 + AGA_hsstrt */ 2000 tmp = find_copper_inst(cp, CI_MOVE(R_VBSTRT)); 2001 tmp->cp.inst.operand = AGA_vbstrt; /* 0x0000 */ 2002 tmp = find_copper_inst(cp, CI_MOVE(R_VSSTRT)); 2003 tmp->cp.inst.operand = AGA_vsstrt; /* 0x016b / AGA_htotal */ 2004 tmp = find_copper_inst(cp, CI_MOVE(R_VSSTOP)); 2005 tmp->cp.inst.operand = AGA_vsstop; /* 0x02d6 / AGA_htotal */ 2006 tmp = find_copper_inst(cp, CI_MOVE(R_VBSTOP)); 2007 tmp->cp.inst.operand = AGA_vbstop; /* 0x0bd1 / AGA_htotal */ 2008 tmp = find_copper_inst(cp, CI_MOVE(R_VTOTAL)); 2009 tmp->cp.inst.operand = AGA_vtotal; 2010 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 2011 tmp->cp.inst.operand = aga_this_data->beamcon0; 2012 #ifdef DEBUG 2013 if (aga_enable & AGA_TRACE2) 2014 printf(" beamcon0 %04x", tmp->cp.inst.operand); 2015 #endif 2016 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 2017 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 2018 #ifdef DEBUG 2019 if (aga_enable & AGA_TRACE2) 2020 printf(" diwhigh %04x>", tmp->cp.inst.operand); 2021 #endif 2022 #if 0 2023 tmp->cp.inst.operand = (vstop & 0x0700) | ((hstop & 0x0100) << 5); 2024 #endif 2025 #ifdef DEBUG 2026 if (aga_enable & AGA_TRACE2) 2027 printf("%04x", tmp->cp.inst.operand); 2028 #endif 2029 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 2030 tmp->cp.inst.operand = aga_this_data->bplcon0 | 2031 ((depth & 0x7) << 12) | ((depth & 0x8) << 1); 2032 #ifdef DEBUG 2033 if (aga_enable & AGA_TRACE2) 2034 printf(" bplcon0 %04x", tmp->cp.inst.operand); 2035 #endif 2036 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 2037 tmp->cp.inst.operand = con1; 2038 #ifdef DEBUG 2039 if (aga_enable & AGA_TRACE2) 2040 printf(" bplcon1 %04x>0000\n", con1); 2041 #endif 2042 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 2043 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 2044 #ifdef DEBUG 2045 if (aga_enable & AGA_TRACE2) 2046 printf(" diwstart %04x", tmp->cp.inst.operand); 2047 #endif 2048 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 2049 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 2050 #ifdef DEBUG 2051 if (aga_enable & AGA_TRACE2) 2052 printf(" diwstop %04x", tmp->cp.inst.operand); 2053 #endif 2054 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 2055 tmp->cp.inst.operand = ddfstart; 2056 #ifdef DEBUG 2057 if (aga_enable & AGA_TRACE2) 2058 printf(" ddfstart %04x", tmp->cp.inst.operand); 2059 #endif 2060 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 2061 tmp->cp.inst.operand = ddfstart + ddfwidth; 2062 #ifdef DEBUG 2063 if (aga_enable & AGA_TRACE2) 2064 printf(" ddfstop %04x", tmp->cp.inst.operand); 2065 #endif 2066 2067 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 2068 for (i = 0, j = 0; i < depth; j += 2, i++) { 2069 /* update the plane pointers */ 2070 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 2071 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 2072 #ifdef DEBUG 2073 if (aga_enable & AGA_TRACE2) 2074 printf (" bpl%dpth %p", i, v->bitmap->plane[i]); 2075 #endif 2076 } 2077 2078 /* set mods correctly. */ 2079 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 2080 tmp[0].cp.inst.operand = v->bitmap->row_mod; 2081 tmp[1].cp.inst.operand = v->bitmap->row_mod; 2082 #ifdef DEBUG 2083 if (aga_enable & AGA_TRACE2) 2084 printf(" bplxmod %04x\n", v->bitmap->row_mod); 2085 #endif 2086 2087 /* set next pointers correctly */ 2088 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 2089 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(aga_this_data->frames[F_STORE_LONG])); 2090 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(aga_this_data->frames[F_STORE_LONG])); 2091 2092 cp = aga_this_data->frames[F_LONG]; 2093 aga_this_data->frames[F_LONG] = aga_this_data->frames[F_STORE_LONG]; 2094 aga_this_data->frames[F_STORE_LONG] = cp; 2095 2096 vd->flags |= VF_DISPLAY; 2097 2098 cc_use_aga_colormap(v, vd->colormap); 2099 } 2100 cc_load_mode(aga_this); 2101 #ifdef DEBUG 2102 if (aga_enable & AGA_TRACE) 2103 aga_enable |= AGA_TRACE2; /* XXXX */ 2104 #endif 2105 } 2106 2107 #endif /* GRF_AGA */ 2108 #endif /* GRF_NTSC */ 2109 2110 /* 2111 * PAL modes. 2112 */ 2113 2114 #if defined (GRF_PAL) 2115 2116 dmode_t * 2117 cc_init_pal_hires() 2118 { 2119 /* this function should only be called once. */ 2120 if (!ph_this) { 2121 u_short len = std_copper_list_len; 2122 2123 ph_this = &pal_hires_mode; 2124 ph_this_data = &pal_hires_mode_data; 2125 bzero(ph_this, sizeof(dmode_t)); 2126 bzero(ph_this_data, sizeof(dmdata_t)); 2127 2128 ph_this->name = "pal: hires"; 2129 ph_this->nominal_size.width = 640; 2130 ph_this->nominal_size.height = 256; 2131 ph_this_data->max_size.width = 724; 2132 ph_this_data->max_size.height = 289; 2133 ph_this_data->min_size.width = 320; 2134 ph_this_data->min_size.height = 244; 2135 ph_this_data->min_depth = 1; 2136 ph_this_data->max_depth = 4; 2137 ph_this->data = ph_this_data; 2138 2139 ph_this->get_monitor = cc_get_monitor; 2140 ph_this->alloc_view = cc_alloc_view; 2141 ph_this->get_current_view = cc_get_current_view; 2142 2143 ph_this_data->use_colormap = cc_use_colormap; 2144 ph_this_data->get_colormap = cc_get_colormap; 2145 ph_this_data->alloc_colormap = cc_alloc_colormap; 2146 ph_this_data->display_view = display_pal_hires_view; 2147 ph_this_data->monitor = cc_monitor; 2148 2149 ph_this_data->frames = pal_hires_frames; 2150 ph_this_data->frames[F_LONG] = alloc_chipmem(std_copper_list_size * F_TOTAL); 2151 if (!ph_this_data->frames[F_LONG]) { 2152 panic("couldn't get chipmem for copper list"); 2153 } 2154 ph_this_data->frames[F_STORE_LONG] = &ph_this_data->frames[F_LONG][len]; 2155 2156 bcopy(std_copper_list, ph_this_data->frames[F_STORE_LONG], std_copper_list_size); 2157 bcopy(std_copper_list, ph_this_data->frames[F_LONG], std_copper_list_size); 2158 2159 ph_this_data->bplcon0 = 0x8200 | USE_CON3; /* pal_hires, color 2160 * composite enable, 2161 * lace. */ 2162 ph_this_data->std_start_x = STANDARD_VIEW_X; 2163 ph_this_data->std_start_y = STANDARD_VIEW_Y; 2164 ph_this_data->vbl_handler = (vbl_handler_func *) cc_mode_vbl_handler; 2165 #if defined (GRF_ECS) || defined (GRF_AGA) 2166 ph_this_data->beamcon0 = STANDARD_PAL_BEAMCON; 2167 #endif 2168 2169 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, ph_this, link); 2170 } 2171 return (ph_this); 2172 } 2173 2174 void 2175 display_pal_hires_view(v) 2176 view_t *v; 2177 { 2178 if (ph_this_data->current_view != v) { 2179 vdata_t *vd = VDATA(v); 2180 cop_t *cp = ph_this_data->frames[F_STORE_LONG], *tmp; 2181 int depth = v->bitmap->depth, i; 2182 int hstart, hstop, vstart, vstop, j; 2183 int x, y, w = v->display.width, h = v->display.height; 2184 u_short ddfstart, ddfwidth, con1; 2185 2186 /* round down to nearest even width */ 2187 /* w &= 0xfffe; */ 2188 2189 /* calculate datafetch width. */ 2190 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2; 2191 2192 /* This will center the any overscanned display */ 2193 /* and allow user to modify. */ 2194 x = v->display.x + ph_this_data->std_start_x - ((w - 640) >> 2); 2195 y = v->display.y + ph_this_data->std_start_y - ((h - 256) >> 1); 2196 2197 if (y & 1) 2198 y--; 2199 2200 if (!(x & 1)) 2201 x--; 2202 2203 hstart = x; 2204 hstop = x + (w >> 1); 2205 vstart = y; 2206 vstop = y + h; 2207 ddfstart = (hstart - 9) >> 1; 2208 /* check for hardware limits, AGA may allow more..? */ 2209 /* anyone got a 4000 I can borrow :^) -ch */ 2210 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 2211 int d = 0; 2212 2213 /* XXX anyone know the equality properties of 2214 * intermixed logial AND's */ 2215 /* XXX and arithmetic operators? */ 2216 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 2217 d++; 2218 } 2219 2220 ddfstart -= d; 2221 hstart -= d << 1; 2222 hstop -= d << 1; 2223 } 2224 /* correct the datafetch to proper limits. */ 2225 /* delay the actual display of the data until we need it. */ 2226 ddfstart &= 0xfffc; 2227 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 2228 2229 if (ph_this_data->current_view) { 2230 VDATA(ph_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 2231 /* displayed. */ 2232 } 2233 ph_this_data->current_view = v; 2234 2235 cp = ph_this_data->frames[F_STORE_LONG]; 2236 #if defined (GRF_ECS) || defined (GRF_AGA) 2237 #if defined GRF_AGA 2238 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE)); 2239 tmp->cp.inst.operand = 0; 2240 #endif 2241 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 2242 tmp->cp.inst.operand = ph_this_data->beamcon0; 2243 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 2244 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 2245 #endif /* ECS */ 2246 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 2247 tmp->cp.inst.operand = ph_this_data->bplcon0 | ((depth & 0x7) << 12); 2248 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 2249 tmp->cp.inst.operand = con1; 2250 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 2251 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 2252 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 2253 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 2254 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 2255 tmp->cp.inst.operand = ddfstart; 2256 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 2257 tmp->cp.inst.operand = ddfstart + ddfwidth; 2258 2259 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 2260 for (i = 0, j = 0; i < depth; j += 2, i++) { 2261 /* update the plane pointers */ 2262 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 2263 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 2264 } 2265 2266 /* set mods correctly. */ 2267 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 2268 tmp[0].cp.inst.operand = v->bitmap->row_mod; 2269 tmp[1].cp.inst.operand = v->bitmap->row_mod; 2270 2271 /* set next pointers correctly */ 2272 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 2273 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(ph_this_data->frames[F_STORE_LONG])); 2274 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(ph_this_data->frames[F_STORE_LONG])); 2275 2276 cp = ph_this_data->frames[F_LONG]; 2277 ph_this_data->frames[F_LONG] = ph_this_data->frames[F_STORE_LONG]; 2278 ph_this_data->frames[F_STORE_LONG] = cp; 2279 2280 vd->flags |= VF_DISPLAY; 2281 cc_use_colormap(v, vd->colormap); 2282 } 2283 cc_load_mode(ph_this); 2284 } 2285 2286 dmode_t * 2287 cc_init_pal_hires_lace() 2288 { 2289 /* this function should only be called once. */ 2290 if (!phl_this) { 2291 u_short len = std_copper_list_len; 2292 2293 phl_this = &pal_hires_lace_mode; 2294 phl_this_data = &pal_hires_lace_mode_data; 2295 bzero(phl_this, sizeof(dmode_t)); 2296 bzero(phl_this_data, sizeof(dmdata_t)); 2297 2298 phl_this->name = "pal: hires interlace"; 2299 phl_this->nominal_size.width = 640; 2300 phl_this->nominal_size.height = 512; 2301 phl_this_data->max_size.width = 724; 2302 phl_this_data->max_size.height = 578; 2303 phl_this_data->min_size.width = 320; 2304 phl_this_data->min_size.height = 484; 2305 phl_this_data->min_depth = 1; 2306 phl_this_data->max_depth = 4; 2307 phl_this->data = phl_this_data; 2308 2309 phl_this->get_monitor = cc_get_monitor; 2310 phl_this->alloc_view = cc_alloc_view; 2311 phl_this->get_current_view = cc_get_current_view; 2312 2313 phl_this_data->use_colormap = cc_use_colormap; 2314 phl_this_data->get_colormap = cc_get_colormap; 2315 phl_this_data->alloc_colormap = cc_alloc_colormap; 2316 phl_this_data->display_view = display_pal_hires_lace_view; 2317 phl_this_data->monitor = cc_monitor; 2318 2319 phl_this_data->flags |= DMF_INTERLACE; 2320 2321 phl_this_data->frames = pal_hires_lace_frames; 2322 phl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_copper_list_size * F_LACE_TOTAL); 2323 if (!phl_this_data->frames[F_LACE_LONG]) { 2324 panic("couldn't get chipmem for copper list"); 2325 } 2326 phl_this_data->frames[F_LACE_SHORT] = &phl_this_data->frames[F_LACE_LONG][len]; 2327 phl_this_data->frames[F_LACE_STORE_LONG] = &phl_this_data->frames[F_LACE_SHORT][len]; 2328 phl_this_data->frames[F_LACE_STORE_SHORT] = &phl_this_data->frames[F_LACE_STORE_LONG][len]; 2329 2330 bcopy(std_copper_list, phl_this_data->frames[F_LACE_STORE_LONG], std_copper_list_size); 2331 bcopy(std_copper_list, phl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size); 2332 bcopy(std_copper_list, phl_this_data->frames[F_LACE_LONG], std_copper_list_size); 2333 bcopy(std_copper_list, phl_this_data->frames[F_LACE_SHORT], std_copper_list_size); 2334 2335 phl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color 2336 * composite enable, 2337 * lace. */ 2338 phl_this_data->std_start_x = STANDARD_VIEW_X; 2339 phl_this_data->std_start_y = STANDARD_VIEW_Y; 2340 phl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler; 2341 #if defined (GRF_ECS) || defined (GRF_AGA) 2342 phl_this_data->beamcon0 = STANDARD_PAL_BEAMCON; 2343 #endif 2344 2345 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, phl_this, link); 2346 } 2347 return (phl_this); 2348 } 2349 2350 void 2351 display_pal_hires_lace_view(v) 2352 view_t *v; 2353 { 2354 if (phl_this_data->current_view != v) { 2355 vdata_t *vd = VDATA(v); 2356 cop_t *cp = phl_this_data->frames[F_LACE_STORE_LONG], *tmp; 2357 int depth = v->bitmap->depth, i; 2358 int hstart, hstop, vstart, vstop, j; 2359 int x, y, w = v->display.width, h = v->display.height; 2360 u_short ddfstart, ddfwidth, con1; 2361 2362 /* round down to nearest even width */ 2363 /* w &= 0xfffe; */ 2364 2365 /* calculate datafetch width. */ 2366 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2; 2367 2368 /* This will center the any overscanned display */ 2369 /* and allow user to modify. */ 2370 x = v->display.x + phl_this_data->std_start_x - ((w - 640) >> 2); 2371 y = v->display.y + phl_this_data->std_start_y - ((h - 512) >> 2); 2372 2373 if (y & 1) 2374 y--; 2375 2376 if (!(x & 1)) 2377 x--; 2378 2379 hstart = x; 2380 hstop = x + (w >> 1); 2381 vstart = y; 2382 vstop = y + (h >> 1); 2383 ddfstart = (hstart - 9) >> 1; 2384 2385 /* check for hardware limits, AGA may allow more..? */ 2386 /* anyone got a 4000 I can borrow :^) -ch */ 2387 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 2388 int d = 0; 2389 2390 /* XXX anyone know the equality properties of 2391 * intermixed logial AND's */ 2392 /* XXX and arithmetic operators? */ 2393 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 2394 d++; 2395 } 2396 2397 ddfstart -= d; 2398 hstart -= d << 1; 2399 hstop -= d << 1; 2400 } 2401 /* correct the datafetch to proper limits. */ 2402 /* delay the actual display of the data until we need it. */ 2403 ddfstart &= 0xfffc; 2404 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 2405 2406 if (phl_this_data->current_view) { 2407 VDATA(phl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 2408 /* displayed. */ 2409 } 2410 phl_this_data->current_view = v; 2411 2412 cp = phl_this_data->frames[F_LACE_STORE_LONG]; 2413 #if defined (GRF_ECS) || defined (GRF_AGA) 2414 #if defined GRF_AGA 2415 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE)); 2416 tmp->cp.inst.operand = 0; 2417 #endif 2418 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 2419 tmp->cp.inst.operand = phl_this_data->beamcon0; 2420 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 2421 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 2422 #endif /* ECS */ 2423 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 2424 tmp->cp.inst.operand = phl_this_data->bplcon0 | ((depth & 0x7) << 12); 2425 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 2426 tmp->cp.inst.operand = con1; 2427 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 2428 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 2429 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 2430 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 2431 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 2432 tmp->cp.inst.operand = ddfstart; 2433 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 2434 tmp->cp.inst.operand = ddfstart + ddfwidth; 2435 2436 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 2437 for (i = 0, j = 0; i < depth; j += 2, i++) { 2438 /* update the plane pointers */ 2439 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 2440 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 2441 } 2442 2443 /* set mods correctly. */ 2444 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 2445 tmp[0].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod; 2446 tmp[1].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod; 2447 2448 /* set next pointers correctly */ 2449 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 2450 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_SHORT])); 2451 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_SHORT])); 2452 2453 2454 bcopy(phl_this_data->frames[F_LACE_STORE_LONG], phl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size); 2455 2456 /* these are the only ones that are different from long frame. */ 2457 cp = phl_this_data->frames[F_LACE_STORE_SHORT]; 2458 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 2459 for (i = 0, j = 0; i < depth; j += 2, i++) { 2460 u_short mod = v->bitmap->bytes_per_row + v->bitmap->row_mod; 2461 /* update plane pointers. high and low. */ 2462 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod])); 2463 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod])); 2464 } 2465 2466 /* set next pointers correctly */ 2467 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 2468 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_LONG])); 2469 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_LONG])); 2470 2471 2472 cp = phl_this_data->frames[F_LACE_LONG]; 2473 phl_this_data->frames[F_LACE_LONG] = phl_this_data->frames[F_LACE_STORE_LONG]; 2474 phl_this_data->frames[F_LACE_STORE_LONG] = cp; 2475 2476 cp = phl_this_data->frames[F_LACE_SHORT]; 2477 phl_this_data->frames[F_LACE_SHORT] = phl_this_data->frames[F_LACE_STORE_SHORT]; 2478 phl_this_data->frames[F_LACE_STORE_SHORT] = cp; 2479 2480 vd->flags |= VF_DISPLAY; 2481 cc_use_colormap(v, vd->colormap); 2482 } 2483 cc_load_mode(phl_this); 2484 } 2485 #if defined (GRF_A2024) 2486 2487 dmode_t * 2488 cc_init_pal_hires_dlace() 2489 { 2490 /* this function should only be called once. */ 2491 if (!phdl_this) { 2492 u_short len = std_dlace_copper_list_len; 2493 2494 phdl_this = &pal_hires_dlace_mode; 2495 phdl_this_data = &pal_hires_dlace_mode_data; 2496 bzero(phdl_this, sizeof(dmode_t)); 2497 bzero(phdl_this_data, sizeof(dmdata_t)); 2498 2499 phdl_this->name = "pal: hires double interlace"; 2500 phdl_this->nominal_size.width = 640; 2501 phdl_this->nominal_size.height = 1024; 2502 phdl_this_data->max_size.width = 724; 2503 phdl_this_data->max_size.height = 1024; 2504 phdl_this_data->min_size.width = 320; 2505 phdl_this_data->min_size.height = 512; 2506 phdl_this_data->min_depth = 1; 2507 phdl_this_data->max_depth = 2; 2508 phdl_this->data = phdl_this_data; 2509 2510 phdl_this->get_monitor = cc_get_monitor; 2511 phdl_this->alloc_view = cc_alloc_view; 2512 phdl_this->get_current_view = cc_get_current_view; 2513 2514 phdl_this_data->use_colormap = cc_a2024_use_colormap; 2515 phdl_this_data->get_colormap = cc_a2024_get_colormap; 2516 phdl_this_data->alloc_colormap = cc_a2024_alloc_colormap; 2517 phdl_this_data->display_view = display_pal_hires_dlace_view; 2518 phdl_this_data->monitor = cc_monitor; 2519 2520 phdl_this_data->flags |= DMF_INTERLACE; 2521 2522 phdl_this_data->frames = pal_hires_dlace_frames; 2523 phdl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_dlace_copper_list_size * F_LACE_TOTAL); 2524 if (!phdl_this_data->frames[F_LACE_LONG]) { 2525 panic("couldn't get chipmem for copper list"); 2526 } 2527 phdl_this_data->frames[F_LACE_SHORT] = &phdl_this_data->frames[F_LACE_LONG][len]; 2528 phdl_this_data->frames[F_LACE_STORE_LONG] = &phdl_this_data->frames[F_LACE_SHORT][len]; 2529 phdl_this_data->frames[F_LACE_STORE_SHORT] = &phdl_this_data->frames[F_LACE_STORE_LONG][len]; 2530 2531 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_STORE_LONG], std_dlace_copper_list_size); 2532 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_STORE_SHORT], std_dlace_copper_list_size); 2533 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_LONG], std_dlace_copper_list_size); 2534 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_SHORT], std_dlace_copper_list_size); 2535 2536 phdl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color 2537 * composite enable, 2538 * dlace. */ 2539 phdl_this_data->std_start_x = STANDARD_VIEW_X; 2540 phdl_this_data->std_start_y = STANDARD_VIEW_Y; 2541 phdl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler; 2542 #if defined (GRF_ECS) || defined (GRF_AGA) 2543 phdl_this_data->beamcon0 = STANDARD_PAL_BEAMCON; 2544 #endif 2545 2546 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, phdl_this, link); 2547 } 2548 return (phdl_this); 2549 } 2550 2551 void 2552 display_pal_hires_dlace_view(v) 2553 view_t *v; 2554 { 2555 if (phdl_this_data->current_view != v) { 2556 vdata_t *vd = VDATA(v); 2557 cop_t *cp = phdl_this_data->frames[F_LACE_STORE_LONG], *tmp; 2558 int depth = v->bitmap->depth; 2559 int hstart, hstop, vstart, vstop; 2560 int x, y, w = v->display.width, h = v->display.height; 2561 u_short ddfstart, ddfwidth, con1; 2562 u_short mod1l, mod2l; 2563 2564 /* round down to nearest even width */ 2565 /* w &= 0xfffe; */ 2566 2567 /* calculate datafetch width. */ 2568 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2; 2569 2570 /* This will center the any overscanned display */ 2571 /* and allow user to modify. */ 2572 x = v->display.x + phdl_this_data->std_start_x - ((w - 640) >> 2); 2573 y = v->display.y + phdl_this_data->std_start_y - ((h - 1024) >> 3); 2574 2575 if (y & 1) 2576 y--; 2577 2578 if (!(x & 1)) 2579 x--; 2580 2581 hstart = x; 2582 hstop = x + (w >> 1); 2583 vstart = y; 2584 vstop = y + (h >> 2); 2585 ddfstart = (hstart - 9) >> 1; 2586 2587 /* check for hardware limits, AGA may allow more..? */ 2588 /* anyone got a 4000 I can borrow :^) -ch */ 2589 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 2590 int d = 0; 2591 2592 /* XXX anyone know the equality properties of 2593 * intermixed logial AND's */ 2594 /* XXX and arithmetic operators? */ 2595 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 2596 d++; 2597 } 2598 2599 ddfstart -= d; 2600 hstart -= d << 1; 2601 hstop -= d << 1; 2602 } 2603 /* correct the datafetch to proper limits. */ 2604 /* delay the actual display of the data until we need it. */ 2605 ddfstart &= 0xfffc; 2606 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 2607 2608 if (phdl_this_data->current_view) { 2609 VDATA(phdl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 2610 /* displayed. */ 2611 } 2612 phdl_this_data->current_view = v; 2613 2614 cp = phdl_this_data->frames[F_LACE_STORE_LONG]; 2615 #if defined (GRF_ECS) || defined (GRF_AGA) 2616 #if defined GRF_AGA 2617 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE)); 2618 tmp->cp.inst.operand = 0; 2619 #endif 2620 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 2621 tmp->cp.inst.operand = phdl_this_data->beamcon0; 2622 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 2623 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 2624 #endif /* ECS */ 2625 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 2626 tmp->cp.inst.operand = phdl_this_data->bplcon0 | ((depth & 0x7) << 13); /* times two. */ 2627 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 2628 tmp->cp.inst.operand = con1; 2629 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 2630 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 2631 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 2632 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 2633 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 2634 tmp->cp.inst.operand = ddfstart; 2635 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 2636 tmp->cp.inst.operand = ddfstart + ddfwidth; 2637 2638 mod1l = v->bitmap->bytes_per_row + v->bitmap->row_mod; 2639 mod2l = mod1l << 1; 2640 2641 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 2642 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0])); /* update plane 2643 * pointers. */ 2644 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0])); /* high and low. */ 2645 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l])); /* update plane 2646 * pointers. */ 2647 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l])); /* high and low. */ 2648 if (depth == 2) { 2649 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0])); /* update plane 2650 * pointers. */ 2651 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0])); /* high and low. */ 2652 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l])); /* update plane 2653 * pointers. */ 2654 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l])); /* high and low. */ 2655 } 2656 /* set mods correctly. */ 2657 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 2658 tmp[0].cp.inst.operand = mod2l + mod1l; 2659 tmp[1].cp.inst.operand = mod2l + mod1l; 2660 2661 /* set next pointers correctly */ 2662 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 2663 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_SHORT])); 2664 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_SHORT])); 2665 2666 bcopy(phdl_this_data->frames[F_LACE_STORE_LONG], phdl_this_data->frames[F_LACE_STORE_SHORT], std_dlace_copper_list_size); 2667 2668 /* these are the only ones that are different from long frame. */ 2669 cp = phdl_this_data->frames[F_LACE_STORE_SHORT]; 2670 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 2671 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l])); /* update plane 2672 * pointers. */ 2673 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l])); /* high and low. */ 2674 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l])); /* update plane 2675 * pointers. */ 2676 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l])); /* high and low. */ 2677 if (depth == 2) { 2678 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l])); /* update plane 2679 * pointers. */ 2680 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l])); /* high and low. */ 2681 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l])); /* update plane 2682 * pointers. */ 2683 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l])); /* high and low. */ 2684 } 2685 /* set next pointers correctly */ 2686 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 2687 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_LONG])); 2688 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_LONG])); 2689 2690 cp = phdl_this_data->frames[F_LACE_LONG]; 2691 phdl_this_data->frames[F_LACE_LONG] = phdl_this_data->frames[F_LACE_STORE_LONG]; 2692 phdl_this_data->frames[F_LACE_STORE_LONG] = cp; 2693 2694 cp = phdl_this_data->frames[F_LACE_SHORT]; 2695 phdl_this_data->frames[F_LACE_SHORT] = phdl_this_data->frames[F_LACE_STORE_SHORT]; 2696 phdl_this_data->frames[F_LACE_STORE_SHORT] = cp; 2697 2698 vd->flags |= VF_DISPLAY; 2699 2700 cc_a2024_use_colormap(v, vd->colormap); 2701 } 2702 cc_load_mode(phdl_this); 2703 } 2704 2705 dmode_t * 2706 cc_init_pal_a2024() 2707 { 2708 /* this function should only be called once. */ 2709 if (!p24_this) { 2710 int i; 2711 u_short len = std_pal_a2024_copper_list_len; 2712 cop_t *cp; 2713 2714 p24_this = &pal_a2024_mode; 2715 p24_this_data = &pal_a2024_mode_data; 2716 bzero(p24_this, sizeof(dmode_t)); 2717 bzero(p24_this_data, sizeof(dmdata_t)); 2718 2719 p24_this->name = "pal: A2024 15khz"; 2720 p24_this->nominal_size.width = 1024; 2721 p24_this->nominal_size.height = 1024; 2722 p24_this_data->max_size.width = 1024; 2723 p24_this_data->max_size.height = 1024; 2724 p24_this_data->min_size.width = 1024; 2725 p24_this_data->min_size.height = 1024; 2726 p24_this_data->min_depth = 1; 2727 p24_this_data->max_depth = 2; 2728 p24_this->data = p24_this_data; 2729 2730 p24_this->get_monitor = cc_get_monitor; 2731 p24_this->alloc_view = cc_alloc_view; 2732 p24_this->get_current_view = cc_get_current_view; 2733 2734 p24_this_data->use_colormap = cc_a2024_use_colormap; 2735 p24_this_data->get_colormap = cc_a2024_get_colormap; 2736 p24_this_data->display_view = display_pal_a2024_view; 2737 p24_this_data->alloc_colormap = cc_a2024_alloc_colormap; 2738 p24_this_data->monitor = cc_monitor; 2739 2740 p24_this_data->flags |= DMF_HEDLEY_EXP; 2741 2742 p24_this_data->frames = pal_a2024_frames; 2743 p24_this_data->frames[F_QD_QUAD0] = alloc_chipmem(std_pal_a2024_copper_list_size * F_QD_TOTAL); 2744 if (!p24_this_data->frames[F_QD_QUAD0]) { 2745 panic("couldn't get chipmem for copper list"); 2746 } 2747 /* setup the hedley init bitplane. */ 2748 hedley_init = alloc_chipmem(128); 2749 if (!hedley_init) { 2750 panic("couldn't get chipmem for hedley init bitplane"); 2751 } 2752 for (i = 1; i < 128; i++) 2753 hedley_init[i] = 0xff; 2754 hedley_init[0] = 0x03; 2755 2756 /* copy image of standard copper list. */ 2757 bcopy(std_pal_a2024_copper_list, p24_this_data->frames[0], std_pal_a2024_copper_list_size); 2758 2759 /* set the init plane pointer. */ 2760 cp = find_copper_inst(p24_this_data->frames[F_QD_QUAD0], CI_MOVE(R_BPL0PTH)); 2761 cp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hedley_init)); 2762 cp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hedley_init)); 2763 2764 for (i = 1; i < F_QD_TOTAL; i++) { 2765 p24_this_data->frames[i] = &p24_this_data->frames[i - 1][len]; 2766 bcopy(p24_this_data->frames[0], p24_this_data->frames[i], std_pal_a2024_copper_list_size); 2767 } 2768 2769 p24_this_data->bplcon0 = 0x8200; /* hires */ 2770 p24_this_data->vbl_handler = (vbl_handler_func *) pal_a2024_mode_vbl_handler; 2771 2772 2773 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, p24_this, link); 2774 } 2775 return (p24_this); 2776 } 2777 2778 void 2779 display_pal_a2024_view(v) 2780 view_t *v; 2781 { 2782 if (p24_this_data->current_view != v) { 2783 vdata_t *vd = VDATA(v); 2784 cop_t *cp, *tmp; 2785 u_char *inst_plane[2]; 2786 u_char **plane = inst_plane; 2787 u_long full_line = v->bitmap->bytes_per_row + v->bitmap->row_mod; 2788 u_long half_plane = full_line * v->bitmap->rows / 2; 2789 2790 int depth = v->bitmap->depth, i, j; 2791 2792 plane[0] = v->bitmap->plane[0]; 2793 if (depth == 2) { 2794 plane[1] = v->bitmap->plane[1]; 2795 } 2796 if (p24_this_data->current_view) { 2797 VDATA(p24_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer 2798 * displayed. */ 2799 } 2800 cp = p24_this_data->frames[F_QD_STORE_QUAD0]; 2801 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR1F)); 2802 tmp = find_copper_inst(tmp, CI_MOVE(R_BPLCON0)); /* grab third one. */ 2803 tmp->cp.inst.operand = p24_this_data->bplcon0 | ((depth & 0x7) << 13); /* times 2 */ 2804 2805 bcopy(p24_this_data->frames[F_QD_STORE_QUAD0], p24_this_data->frames[F_QD_STORE_QUAD1], std_pal_a2024_copper_list_size); 2806 bcopy(p24_this_data->frames[F_QD_STORE_QUAD0], p24_this_data->frames[F_QD_STORE_QUAD2], std_pal_a2024_copper_list_size); 2807 bcopy(p24_this_data->frames[F_QD_STORE_QUAD0], p24_this_data->frames[F_QD_STORE_QUAD3], std_pal_a2024_copper_list_size); 2808 2809 /* 2810 * Mark Id's 2811 */ 2812 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD1], CI_WAIT(126, 29)); 2813 CBUMP(tmp); 2814 CMOVE(tmp, R_COLOR01, QUAD1_ID); 2815 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD2], CI_WAIT(126, 29)); 2816 CBUMP(tmp); 2817 CMOVE(tmp, R_COLOR01, QUAD2_ID); 2818 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD3], CI_WAIT(126, 29)); 2819 CBUMP(tmp); 2820 CMOVE(tmp, R_COLOR01, QUAD3_ID); 2821 2822 plane[0]--; 2823 plane[0]--; 2824 if (depth == 2) { 2825 plane[1]--; 2826 plane[1]--; 2827 } 2828 /* 2829 * Set bitplane pointers. 2830 */ 2831 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD0], CI_MOVE(R_BPLMOD2)); 2832 CBUMP(tmp); 2833 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][0]))); 2834 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][0]))); 2835 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line]))); 2836 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line]))); 2837 if (depth == 2) { 2838 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][0]))); 2839 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][0]))); 2840 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line]))); 2841 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line]))); 2842 } 2843 #if defined (GRF_ECS) || defined (GRF_AGA) 2844 CMOVE(tmp, R_DIWHIGH, 0x2100); 2845 #endif 2846 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD1]))); 2847 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD1]))); 2848 CEND(tmp); 2849 CEND(tmp); 2850 2851 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD1], CI_MOVE(R_BPLMOD2)); 2852 CBUMP(tmp); 2853 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE]))); 2854 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE]))); 2855 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE]))); 2856 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE]))); 2857 if (depth == 2) { 2858 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE]))); 2859 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE]))); 2860 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE]))); 2861 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE]))); 2862 } 2863 #if defined (GRF_ECS) || defined (GRF_AGA) 2864 CMOVE(tmp, R_DIWHIGH, 0x2100); 2865 #endif 2866 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD2]))); 2867 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD2]))); 2868 CEND(tmp); 2869 CEND(tmp); 2870 2871 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD2], CI_MOVE(R_BPLMOD2)); 2872 CBUMP(tmp); 2873 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane]))); 2874 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane]))); 2875 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line]))); 2876 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line]))); 2877 if (depth == 2) { 2878 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane]))); 2879 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane]))); 2880 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line]))); 2881 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line]))); 2882 } 2883 #if defined (GRF_ECS) || defined (GRF_AGA) 2884 CMOVE(tmp, R_DIWHIGH, 0x2100); 2885 #endif 2886 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD3]))); 2887 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD3]))); 2888 CEND(tmp); 2889 CEND(tmp); 2890 2891 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD3], CI_MOVE(R_BPLMOD2)); 2892 CBUMP(tmp); 2893 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE]))); 2894 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE]))); 2895 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE]))); 2896 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE]))); 2897 if (depth == 2) { 2898 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE]))); 2899 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE]))); 2900 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE]))); 2901 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE]))); 2902 } 2903 #if defined (GRF_ECS) || defined (GRF_AGA) 2904 CMOVE(tmp, R_DIWHIGH, 0x2100); 2905 #endif 2906 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD0]))); 2907 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD0]))); 2908 CEND(tmp); 2909 CEND(tmp); 2910 2911 /* swap new pointers in. */ 2912 for (i = F_QD_STORE_QUAD0, j = F_QD_QUAD0; 2913 i <= F_QD_STORE_QUAD3; i++, j++) { 2914 cp = p24_this_data->frames[j]; 2915 p24_this_data->frames[j] = p24_this_data->frames[i]; 2916 p24_this_data->frames[i] = cp; 2917 } 2918 2919 p24_this_data->current_view = v; 2920 vd->flags |= VF_DISPLAY; 2921 2922 cc_a2024_use_colormap(v, vd->colormap); 2923 } 2924 cc_load_mode(p24_this); 2925 } 2926 2927 void 2928 pal_a2024_mode_vbl_handler(d) 2929 dmode_t *d; 2930 { 2931 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8); 2932 2933 if (vp < 20) { 2934 custom.cop1lc = PREP_DMA_MEM(p24_this_data->frames[p24_this_data->hedley_current]); 2935 custom.copjmp1 = 0; 2936 } 2937 p24_this_data->hedley_current++; 2938 p24_this_data->hedley_current &= 0x3; /* if 4 then 0. */ 2939 } 2940 #endif /* GRF_A2024 */ 2941 2942 #if defined (GRF_AGA) 2943 2944 dmode_t * 2945 cc_init_pal_aga() 2946 { 2947 /* this function should only be called once. */ 2948 if (!paga_this && (custom.deniseid & 0xff) == 0xf8 && 2949 aga_enable & AGA_ENABLE) { 2950 u_short len = aga_copper_list_len; 2951 2952 paga_this = &paga_mode; 2953 paga_this_data = &paga_mode_data; 2954 bzero(paga_this, sizeof(dmode_t)); 2955 bzero(paga_this_data, sizeof(dmdata_t)); 2956 2957 paga_this->name = "pal: AGA dbl"; 2958 paga_this->nominal_size.width = 640; 2959 paga_this->nominal_size.height = 512; 2960 paga_this_data->max_size.width = 720; 2961 paga_this_data->max_size.height = 564; 2962 paga_this_data->min_size.width = 320; 2963 paga_this_data->min_size.height = 200; 2964 paga_this_data->min_depth = 1; 2965 paga_this_data->max_depth = 8; 2966 paga_this->data = paga_this_data; 2967 2968 paga_this->get_monitor = cc_get_monitor; 2969 paga_this->alloc_view = cc_alloc_view; 2970 paga_this->get_current_view = cc_get_current_view; 2971 2972 paga_this_data->use_colormap = cc_use_aga_colormap; 2973 paga_this_data->get_colormap = cc_get_colormap; 2974 paga_this_data->alloc_colormap = cc_alloc_aga_colormap; 2975 paga_this_data->display_view = display_pal_aga_view; 2976 paga_this_data->monitor = cc_monitor; 2977 2978 paga_this_data->frames = paga_frames; 2979 paga_this_data->frames[F_LONG] = alloc_chipmem(aga_copper_list_size * F_TOTAL); 2980 if (!paga_this_data->frames[F_LONG]) { 2981 panic("couldn't get chipmem for copper list"); 2982 } 2983 paga_this_data->frames[F_STORE_LONG] = &paga_this_data->frames[F_LONG][len]; 2984 2985 bcopy(aga_copper_list, paga_this_data->frames[F_STORE_LONG], aga_copper_list_size); 2986 bcopy(aga_copper_list, paga_this_data->frames[F_LONG], aga_copper_list_size); 2987 2988 paga_this_data->bplcon0 = 0x0240 | USE_CON3; /* color composite 2989 * enable, 2990 * shres. */ 2991 paga_this_data->std_start_x = 0x4f /*STANDARD_VIEW_X*/; 2992 paga_this_data->std_start_y = 0x2b /*STANDARD_VIEW_Y*/; 2993 paga_this_data->vbl_handler = (vbl_handler_func *) cc_mode_vbl_handler; 2994 paga_this_data->beamcon0 = STANDARD_PAL_BEAMCON | (SPECIAL_BEAMCON ^ VSYNCTRUE); 2995 2996 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, 2997 paga_this, link); 2998 } 2999 return (paga_this); 3000 } 3001 3002 /* static, so I can patch and play (VGAOnly is commented-out) */ 3003 3004 int pAGA_htotal = 0x081; /* 0x079 */ 3005 int pAGA_hsstrt = 0x00f; /* 0x00f */ 3006 int pAGA_hsstop = 0x019; /* 0x019 */ 3007 int pAGA_hbstrt = 0x001; /* 0x001 */ 3008 int pAGA_hbstop = 0x021; /* 0x021 */ 3009 int pAGA_vtotal = 0x23d; /* 0x24d */ 3010 int pAGA_vsstrt = 0x001; /* 0x001 */ 3011 int pAGA_vsstop = 0x008; /* 0x008 */ 3012 int pAGA_vbstrt = 0x000; /* 0x000 */ 3013 int pAGA_vbstop = 0x017; /* 0x019 */ 3014 int pAGA_hcenter = 0x04f; /* 0x04b */ 3015 3016 void 3017 display_pal_aga_view(v) 3018 view_t *v; 3019 { 3020 if (paga_this_data->current_view != v) { 3021 vdata_t *vd = VDATA(v); 3022 cop_t *cp = paga_this_data->frames[F_STORE_LONG], *tmp; 3023 int depth = v->bitmap->depth, i; 3024 int hstart, hstop, vstart, vstop, j; 3025 int x, y, w = v->display.width, h = v->display.height; 3026 u_short ddfstart, ddfwidth, con1; 3027 3028 #ifdef DEBUG 3029 if (aga_enable & AGA_TRACE) 3030 printf("display_aga_view(%dx%dx%d) %p\n", w, h, 3031 depth, v); 3032 #endif 3033 /* round down to nearest even width */ 3034 /* w &= 0xfffe; */ 3035 /* calculate datafetch width. */ 3036 3037 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 4) << 1; 3038 3039 /* this will center the any overscanned display */ 3040 /* and allow user to modify. */ 3041 x = v->display.x + paga_this_data->std_start_x - ((w - 640) >> 3); 3042 y = v->display.y + paga_this_data->std_start_y - ((h - 512) >> 1); 3043 3044 if (y & 1) 3045 y--; 3046 3047 if (!(x & 1)) 3048 x--; 3049 3050 hstart = x; 3051 hstop = x + (w >> 2); 3052 vstart = y; 3053 vstop = y + (h >> 0); 3054 ddfstart = (hstart >> 1) - 8; 3055 3056 #ifdef DEBUG 3057 if (aga_enable & AGA_TRACE2) { 3058 printf (" ddfwidth %04x x %04x y %04x", ddfwidth, 3059 x, y); 3060 printf (" hstart %04x hstop %04x vstart %04x vstop %04x ddfstart %04x\n", 3061 hstart, hstop, vstart, vstop, ddfstart); 3062 } 3063 #endif 3064 /* check for hardware limits, AGA may allow more..? */ 3065 /* anyone got a 4000 I can borrow :^) -ch */ 3066 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 3067 int d = 0; 3068 3069 /* XXX anyone know the equality properties of 3070 * intermixed logial AND's */ 3071 /* XXX and arithmetic operators? */ 3072 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 3073 d++; 3074 } 3075 3076 ddfstart -= d; 3077 hstart -= d << 1; 3078 hstop -= d << 1; 3079 } 3080 /* correct the datafetch to proper limits. */ 3081 /* delay the actual display of the data until we need it. */ 3082 ddfstart &= 0xfffc; 3083 #ifdef DEBUG 3084 if (aga_enable & AGA_TRACE2) { 3085 printf (" ddfwidth %04x x %04x y %04x", ddfwidth, 3086 x, y); 3087 printf (" hstart %04x hstop %04x vstart %04x vstop %04x ddfstart %04x\n", 3088 hstart, hstop, vstart, vstop, ddfstart); 3089 } 3090 #endif 3091 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 3092 3093 if (paga_this_data->current_view) { 3094 VDATA(paga_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 3095 /* displayed. */ 3096 } 3097 paga_this_data->current_view = v; 3098 3099 cp = paga_this_data->frames[F_STORE_LONG]; 3100 tmp = cp; 3101 for (i = 0; i < 8; ++i) { 3102 if (tmp == NULL) 3103 break; 3104 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3)); 3105 if (tmp == NULL) 3106 break; 3107 tmp->cp.inst.operand = 0x0ca1 | (i << 13); 3108 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3)); 3109 if (tmp == NULL) 3110 break; 3111 tmp->cp.inst.operand = 0x0ea1 | (i << 13); 3112 } 3113 if (tmp) 3114 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3)); 3115 if (tmp) 3116 tmp->cp.inst.operand = 0x0ca1; 3117 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE)); 3118 tmp->cp.inst.operand = 0x8003; 3119 tmp = find_copper_inst(cp, CI_MOVE(R_HTOTAL)); 3120 tmp->cp.inst.operand = pAGA_htotal; /* 81/71/73/79? */ 3121 tmp = find_copper_inst(cp, CI_MOVE(R_HBSTRT)); 3122 tmp->cp.inst.operand = pAGA_hbstrt; /* 0x0008 */ 3123 tmp = find_copper_inst(cp, CI_MOVE(R_HSSTRT)); 3124 tmp->cp.inst.operand = pAGA_hsstrt; /* 0x000e */ 3125 tmp = find_copper_inst(cp, CI_MOVE(R_HSSTOP)); 3126 tmp->cp.inst.operand = pAGA_hsstop; /* 0x001c */ 3127 tmp = find_copper_inst(cp, CI_MOVE(R_HBSTOP)); 3128 tmp->cp.inst.operand = pAGA_hsstop; /* 0x001e */ 3129 tmp = find_copper_inst(cp, CI_MOVE(R_HCENTER)); 3130 tmp->cp.inst.operand = pAGA_hcenter; /*AGA_htotal / 2 + AGA_hsstrt */ 3131 tmp = find_copper_inst(cp, CI_MOVE(R_VBSTRT)); 3132 tmp->cp.inst.operand = pAGA_vbstrt; /* 0x0000 */ 3133 tmp = find_copper_inst(cp, CI_MOVE(R_VSSTRT)); 3134 tmp->cp.inst.operand = pAGA_vsstrt; /* 0x016b / AGA_htotal */ 3135 tmp = find_copper_inst(cp, CI_MOVE(R_VSSTOP)); 3136 tmp->cp.inst.operand = pAGA_vsstop; /* 0x02d6 / AGA_htotal */ 3137 tmp = find_copper_inst(cp, CI_MOVE(R_VBSTOP)); 3138 tmp->cp.inst.operand = pAGA_vbstop; /* 0x0bd1 / AGA_htotal */ 3139 tmp = find_copper_inst(cp, CI_MOVE(R_VTOTAL)); 3140 tmp->cp.inst.operand = pAGA_vtotal; 3141 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 3142 tmp->cp.inst.operand = paga_this_data->beamcon0; 3143 #ifdef DEBUG 3144 if (aga_enable & AGA_TRACE2) 3145 printf(" beamcon0 %04x", tmp->cp.inst.operand); 3146 #endif 3147 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 3148 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 3149 #ifdef DEBUG 3150 if (aga_enable & AGA_TRACE2) 3151 printf(" diwhigh %04x>", tmp->cp.inst.operand); 3152 #endif 3153 #if 0 3154 tmp->cp.inst.operand = (vstop & 0x0700) | ((hstop & 0x0100) << 5); 3155 #endif 3156 #ifdef DEBUG 3157 if (aga_enable & AGA_TRACE2) 3158 printf("%04x", tmp->cp.inst.operand); 3159 #endif 3160 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 3161 tmp->cp.inst.operand = paga_this_data->bplcon0 | 3162 ((depth & 0x7) << 12) | ((depth & 0x8) << 1); 3163 #ifdef DEBUG 3164 if (aga_enable & AGA_TRACE2) 3165 printf(" bplcon0 %04x", tmp->cp.inst.operand); 3166 #endif 3167 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 3168 tmp->cp.inst.operand = con1; 3169 #ifdef DEBUG 3170 if (aga_enable & AGA_TRACE2) 3171 printf(" bplcon1 %04x>0000\n", con1); 3172 #endif 3173 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 3174 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 3175 #ifdef DEBUG 3176 if (aga_enable & AGA_TRACE2) 3177 printf(" diwstart %04x", tmp->cp.inst.operand); 3178 #endif 3179 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 3180 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 3181 #ifdef DEBUG 3182 if (aga_enable & AGA_TRACE2) 3183 printf(" diwstop %04x", tmp->cp.inst.operand); 3184 #endif 3185 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 3186 tmp->cp.inst.operand = ddfstart; 3187 #ifdef DEBUG 3188 if (aga_enable & AGA_TRACE2) 3189 printf(" ddfstart %04x", tmp->cp.inst.operand); 3190 #endif 3191 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 3192 tmp->cp.inst.operand = ddfstart + ddfwidth; 3193 #ifdef DEBUG 3194 if (aga_enable & AGA_TRACE2) 3195 printf(" ddfstop %04x", tmp->cp.inst.operand); 3196 #endif 3197 3198 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 3199 for (i = 0, j = 0; i < depth; j += 2, i++) { 3200 /* update the plane pointers */ 3201 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 3202 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 3203 #ifdef DEBUG 3204 if (aga_enable & AGA_TRACE2) 3205 printf (" bpl%dpth %p", i, v->bitmap->plane[i]); 3206 #endif 3207 } 3208 3209 /* set mods correctly. */ 3210 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 3211 tmp[0].cp.inst.operand = v->bitmap->row_mod; 3212 tmp[1].cp.inst.operand = v->bitmap->row_mod; 3213 #ifdef DEBUG 3214 if (aga_enable & AGA_TRACE2) 3215 printf(" bplxmod %04x\n", v->bitmap->row_mod); 3216 #endif 3217 3218 /* set next pointers correctly */ 3219 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 3220 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(paga_this_data->frames[F_STORE_LONG])); 3221 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(paga_this_data->frames[F_STORE_LONG])); 3222 3223 cp = paga_this_data->frames[F_LONG]; 3224 paga_this_data->frames[F_LONG] = paga_this_data->frames[F_STORE_LONG]; 3225 paga_this_data->frames[F_STORE_LONG] = cp; 3226 3227 vd->flags |= VF_DISPLAY; 3228 3229 cc_use_aga_colormap(v, vd->colormap); 3230 } 3231 cc_load_mode(paga_this); 3232 #ifdef DEBUG 3233 if (aga_enable & AGA_TRACE) 3234 aga_enable |= AGA_TRACE2; /* XXXX */ 3235 #endif 3236 } 3237 3238 #endif /* GRF_AGA */ 3239 #endif /* GRF_PAL */ 3240