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