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