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