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