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.3 1994/03/27 06:23:30 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 dmode_t hires_lace_mode; 100 dmdata_t hires_lace_mode_data; 101 cop_t *hires_lace_frames[F_LACE_TOTAL]; 102 dmode_t *hl_this; 103 dmdata_t *hl_this_data; 104 105 void display_hires_view(view_t * v); 106 dmode_t hires_mode; 107 dmdata_t hires_mode_data; 108 cop_t *hires_frames[F_TOTAL]; 109 dmode_t *h_this; 110 dmdata_t *h_this_data; 111 #endif /* GRF_NTSC */ 112 113 114 /* monitor functions. */ 115 monitor_t * 116 cc_init_monitor() 117 { 118 cop_t *cp; 119 120 if (m_this) 121 return(m_this); 122 123 cc_monitor = m_this = &monitor; 124 /* turn sprite DMA off. we don't support them yet. */ 125 custom.dmacon = DMAF_SPRITE; 126 127 m_this->name = monitor_name; 128 m_this_data = m_this->data = &monitor_data; 129 130 m_this->get_current_mode = get_current_mode; 131 m_this->vbl_handler = (vbl_handler_func *) monitor_vbl_handler; 132 m_this->get_next_mode = get_next_mode; 133 m_this->get_best_mode = get_best_mode; 134 135 m_this->alloc_bitmap = alloc_bitmap; 136 m_this->free_bitmap = free_bitmap; 137 138 m_this_data->current_mode = NULL; 139 LIST_INIT(&m_this_data->modes); 140 141 cp = null_mode_copper_list = alloc_chipmem(sizeof(cop_t) * 4); 142 if (!cp) 143 panic("no chipmem for grf."); 144 145 CMOVE(cp, R_COLOR00, 0x0000); /* background is black */ 146 CMOVE(cp, R_BPLCON0, 0x0000); /* no planes to fetch from */ 147 CWAIT(cp, 255, 255); /* COPEND */ 148 CWAIT(cp, 255, 255); /* COPEND really */ 149 150 /* install m_this list and turn DMA on */ 151 custom.cop1lc = PREP_DMA_MEM(null_mode_copper_list); 152 custom.copjmp1 = 0; 153 custom.dmacon = DMAF_SETCLR | DMAF_MASTER | DMAF_RASTER \ 154 |DMAF_COPPER; 155 156 cc_init_modes(); 157 LIST_INSERT_HEAD(monitors, m_this, link); 158 return (m_this); 159 } 160 161 void 162 monitor_vbl_handler(m) 163 monitor_t *m; 164 { 165 dmdata_t *dmd; 166 167 if (m_this_data->current_mode == NULL) 168 return; 169 170 dmd = DMDATA(m_this_data->current_mode); 171 if (dmd) 172 dmd->vbl_handler(m_this_data->current_mode); 173 } 174 175 dmode_t * 176 get_current_mode() 177 { 178 if (m_this_data->current_mode) 179 return(m_this_data->current_mode); 180 else 181 return(NULL); 182 } 183 184 dmode_t * 185 get_next_mode(d) 186 dmode_t *d; 187 { 188 if (d) 189 return(d->link.le_next); 190 return(m_this_data->modes.lh_first); 191 } 192 193 /* XXX needs to have more control attributes */ 194 dmode_t * 195 get_best_mode(size, depth) 196 dimen_t *size; 197 u_char depth; 198 { 199 dmode_t *save; 200 dmode_t *dm; 201 long dt, dx, dy, ct; 202 dmdata_t *dmd; 203 204 save = NULL; 205 dm = m_this_data->modes.lh_first; 206 while (dm != NULL) { 207 dmd = dm->data; 208 if (depth > dmd->max_depth || depth < dmd->min_depth) { 209 dm = dm->link.le_next; 210 continue; 211 } else if (size->width > dmd->max_size.width || 212 size->height > dmd->max_size.height) { 213 dm = dm->link.le_next; 214 continue; 215 } else if (size->width < dmd->min_size.width || 216 size->height < dmd->min_size.height) { 217 dm = dm->link.le_next; 218 continue; 219 } 220 dx = abs(dm->nominal_size.width - size->width); 221 dy = abs(dm->nominal_size.height - size->height); 222 ct = dx + dy; 223 224 if (ct < dt || save == NULL) { 225 save = dm; 226 dt = ct; 227 } 228 dm = dm->link.le_next; 229 } 230 return (save); 231 } 232 /* bitmap functions */ 233 bmap_t * 234 alloc_bitmap(width, height, depth, flags) 235 u_short width, height, depth, flags; 236 { 237 int i; 238 u_long total_size; 239 u_short lwpr = (width + 31) / 32; 240 u_short wpr = lwpr << 1; 241 u_short bpr = wpr << 1; 242 u_short array_size = sizeof(u_char *) * depth; 243 u_long plane_size = bpr * height; 244 u_short temp_size = bpr + sizeof(u_long); 245 bmap_t *bm; 246 247 /* note the next allocation will give everything, also note that all 248 * the stuff we want (including bitmaps) will be long short aligned. 249 * M_This is a function of the data being allocated and the fact that 250 * alloc_chipmem() returns long short aligned data. note also that 251 * each row of the bitmap is long word aligned and made of exactly n 252 * longwords. -ch */ 253 254 /* Sigh, it seems for mapping to work we need the bitplane data to 1: 255 * be aligned on a page boundry. 2: be n pages large. 256 * 257 * why? becuase the user gets a page aligned address, if m_this is before 258 * your allocation, too bad. Also it seems that the mapping routines 259 * do not watch to closely to the allowable length. so if you go over 260 * n pages by less than another page, the user gets to write all over 261 * the entire page. Since you did not allocate up to a page boundry 262 * (or more) the user writes into someone elses memory. -ch */ 263 total_size = amiga_round_page(plane_size * depth) + /* for length */ 264 (temp_size) + (array_size) + sizeof(bmap_t) + 265 NBPG; /* for alignment */ 266 bm = alloc_chipmem(total_size); 267 if (bm) { 268 if (flags & BMF_CLEAR) { 269 bzero(bm, total_size); 270 } 271 bm->bytes_per_row = bpr; 272 bm->rows = height; 273 bm->depth = depth; 274 bm->flags = flags; 275 bm->plane = (u_char **) & bm[1]; 276 bm->blit_temp = ((u_char *) bm->plane) + array_size; 277 bm->plane[0] = (u_char *) amiga_round_page((u_long) (bm->blit_temp + temp_size)); 278 if (flags & BMF_INTERLEAVED) { 279 bm->row_mod = bm->bytes_per_row * (depth - 1); 280 for (i = 1; i < depth; i++) { 281 bm->plane[i] = bm->plane[i - 1] + bpr; 282 } 283 } else { 284 bm->row_mod = 0; 285 for (i = 1; i < depth; i++) { 286 bm->plane[i] = bm->plane[i - 1] + plane_size; 287 } 288 } 289 bm->hardware_address = PREP_DMA_MEM(bm->plane[0]); 290 return (bm); 291 } 292 return (NULL); 293 } 294 295 296 void 297 free_bitmap(bm) 298 bmap_t *bm; 299 { 300 if (bm) 301 free_chipmem(bm); 302 } 303 /* load a new mode into the current display, if NULL shut display off. */ 304 void 305 cc_load_mode(d) 306 dmode_t *d; 307 { 308 if (d) { 309 m_this_data->current_mode = d; 310 return; 311 } 312 /* turn off display */ 313 m_this_data->current_mode = NULL; 314 wait_tof(); 315 wait_tof(); 316 custom.cop1lc = PREP_DMA_MEM(null_mode_copper_list); 317 } 318 /* 319 * CC Mode Stuff. 320 */ 321 322 dmode_t *(*mode_init_funcs[]) (void) = { 323 #if defined (GRF_NTSC) 324 #if defined (GRF_A2024) 325 cc_init_ntsc_a2024, 326 cc_init_ntsc_hires_dlace, 327 #endif /* GRF_A2024 */ 328 cc_init_ntsc_hires_lace, 329 cc_init_ntsc_hires, 330 #endif /* GRF_NTSC */ 331 #if defined (GRF_PAL) 332 #if defined (GRF_A2024) 333 cc_init_pal_a2024, 334 cc_init_pal_hires_dlace, 335 #endif /* GRF_A2024 */ 336 cc_init_pal_hires_lace, 337 cc_init_pal_hires, 338 #endif /* GRF_PAL */ 339 NULL 340 }; 341 342 int 343 cc_init_modes() 344 { 345 int i = 0; 346 int error = 0; 347 while (mode_init_funcs[i]) { 348 mode_init_funcs[i] (); 349 i++; 350 } 351 return (error); 352 } 353 354 monitor_t * 355 cc_get_monitor(d) 356 dmode_t *d; 357 { 358 return (DMDATA(d)->monitor); 359 } 360 361 view_t * 362 cc_get_current_view(d) 363 dmode_t *d; 364 { 365 return (DMDATA(d)->current_view); 366 } 367 368 369 view_t * 370 cc_alloc_view(mode, dim, depth) 371 dmode_t *mode; 372 dimen_t *dim; 373 u_char depth; 374 { 375 view_t *v = alloc_chipmem(sizeof(*v) + sizeof(vdata_t)); 376 if (v) { 377 bmap_t *bm = cc_monitor->alloc_bitmap(dim->width, dim->height, depth, BMF_CLEAR); 378 if (bm) { 379 int i; 380 box_t box; 381 382 v->data = &v[1]; /* at the end of view */ 383 VDATA(v)->colormap = DMDATA(mode)->alloc_colormap(depth); 384 if (VDATA(v)->colormap) { 385 INIT_BOX(&box, 0, 0, dim->width, dim->height); 386 cc_init_view(v, bm, mode, &box); 387 return (v); 388 } 389 cc_monitor->free_bitmap(bm); 390 } 391 free_chipmem(v); 392 } 393 return (NULL); 394 } 395 396 colormap_t * 397 cc_alloc_colormap(depth) 398 int depth; 399 { 400 u_long size = 1U << depth, i; 401 colormap_t *cm = alloc_chipmem(sizeof(u_long) * size + sizeof(*cm)); 402 403 if (cm) { 404 cm->type = CM_COLOR; 405 cm->red_mask = 0x0F; 406 cm->green_mask = 0x0F; 407 cm->blue_mask = 0x0F; 408 cm->first = 0; 409 cm->size = size; 410 cm->entry = (u_long *) & cm[1]; /* table directly after. */ 411 for (i = 0; i < min(size, 32); i++) { 412 cm->entry[i] = CM_WTOL(cc_default_colors[i]); 413 } 414 return (cm); 415 } 416 return (NULL); 417 } 418 419 int 420 cc_colormap_checkvals(vcm, cm, use) 421 colormap_t *vcm, *cm; 422 int use; 423 { 424 if (use) { 425 /* check to see if its the view's colormap, if so just do 426 * update. */ 427 if (vcm != cm) { 428 if (cm->first >= vcm->size || (cm->first + cm->size) > (cm->first + vcm->size) || 429 cm->type != vcm->type) { 430 return (0); 431 } 432 switch (vcm->type) { 433 case CM_COLOR: 434 if (cm->red_mask != vcm->red_mask || 435 cm->green_mask != vcm->green_mask || 436 cm->blue_mask != vcm->blue_mask) { 437 return (0); 438 } 439 break; 440 case CM_GREYSCALE: 441 if (cm->grey_mask != vcm->grey_mask) { 442 return (0); 443 } 444 break; 445 } 446 } 447 } else { 448 if (cm->first >= vcm->size || (cm->first + cm->size) > (cm->first + vcm->size)) { 449 return (0); 450 } 451 } 452 return (1); 453 } 454 /* does sanity check on values */ 455 int 456 cc_get_colormap(v, cm) 457 view_t *v; 458 colormap_t *cm; 459 { 460 colormap_t *vcm = VDATA(v)->colormap; 461 int i; 462 463 if (!cc_colormap_checkvals(vcm, cm, 0)) { 464 return (EINVAL); 465 } 466 cm->type = vcm->type; 467 468 switch (vcm->type) { 469 case CM_COLOR: 470 cm->red_mask = vcm->red_mask; 471 cm->green_mask = vcm->green_mask; 472 cm->blue_mask = vcm->blue_mask; 473 break; 474 case CM_GREYSCALE: 475 cm->grey_mask = vcm->grey_mask; 476 break; 477 } 478 479 /* copy entries into colormap. */ 480 for (i = cm->first; i < (cm->first + cm->size); i++) { 481 cm->entry[i] = vcm->entry[i]; 482 } 483 return (0); 484 } 485 486 /* does sanity check on values */ 487 int 488 cc_use_colormap(v, cm) 489 view_t *v; 490 colormap_t *cm; 491 { 492 colormap_t *vcm = VDATA(v)->colormap; 493 int s, i; 494 495 if (!cc_colormap_checkvals(vcm, cm, 1)) { 496 return (EINVAL); 497 } 498 /* check to see if its the view's colormap, if so just do update. */ 499 if (vcm != cm) { 500 /* copy entries into colormap. */ 501 for (i = cm->first; i < (cm->first + cm->size); i++) { 502 vcm->entry[i] = cm->entry[i]; 503 } 504 } 505 s = spltty(); 506 507 /* is view currently being displayed? */ 508 if (VDATA(v)->flags & VF_DISPLAY) { 509 /* yes, update the copper lists */ 510 cop_t *tmp, *cp; 511 int nframes = 1, j; 512 513 if (DMDATA(VDATA(v)->mode)->flags & DMF_INTERLACE) { 514 nframes = 2; 515 } 516 for (i = 0; i < nframes; i++) { 517 cp = DMDATA(VDATA(v)->mode)->frames[i]; 518 519 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR07)); 520 tmp -= 7; 521 522 for (j = 0; j < 16; j++) { 523 CMOVE(tmp, R_COLOR00 + (j << 1), CM_LTOW(vcm->entry[j])); 524 } 525 } 526 } 527 splx(s); 528 return (0); 529 } 530 #if defined (GRF_A2024) 531 colormap_t * 532 cc_a2024_alloc_colormap(depth) 533 int depth; 534 { 535 u_long size = 1U << depth, i; 536 colormap_t *cm = alloc_chipmem(sizeof(u_long) * size + sizeof(*cm)); 537 538 if (cm) { 539 cm->type = CM_GREYSCALE; 540 cm->grey_mask = 0x03; 541 cm->first = 0; 542 cm->size = size; 543 cm->entry = (u_long *) & cm[1]; /* table directly after. */ 544 for (i = 0; i < size; i++) { 545 cm->entry[i] = CM_WTOL(cc_a2024_default_colors[i]); 546 } 547 return (cm); 548 } 549 return (NULL); 550 } 551 552 int 553 cc_a2024_get_colormap(v, cm) 554 view_t *v; 555 colormap_t *cm; 556 { 557 /* there are no differences (yet) in the way the cm's are stored */ 558 return (cc_get_colormap(v, cm)); 559 } 560 561 int 562 cc_a2024_use_colormap(v, cm) 563 view_t *v; 564 colormap_t *cm; 565 { 566 colormap_t *vcm = VDATA(v)->colormap; 567 int s, i; 568 569 if (!cc_colormap_checkvals(vcm, cm, 1)) { 570 return (EINVAL); 571 } 572 /* check to see if its the view's colormap, if so just do update. */ 573 if (vcm != cm) { 574 /* copy entries into colormap. */ 575 for (i = cm->first; i < (cm->first + cm->size); i++) { 576 vcm->entry[i] = cm->entry[i]; 577 } 578 } 579 s = spltty(); 580 581 /* is view currently being displayed? */ 582 if (VDATA(v)->flags & VF_DISPLAY) { 583 /* yes, update the copper lists */ 584 cop_t *tmp, *cp; 585 int nframes = 2, nregs = cm->size == 4 ? 16 : 8, j; 586 587 if (DMDATA(VDATA(v)->mode)->flags & DMF_HEDLEY_EXP) { 588 nframes = 4; 589 } 590 for (i = 0; i < nframes; i++) { 591 cp = DMDATA(VDATA(v)->mode)->frames[i]; 592 593 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR07)); 594 tmp -= 7; 595 596 for (j = 0; j < nregs; j++) { 597 CMOVE(tmp, R_COLOR00 + (j << 1), A2024_CM_TO_CR(vcm, j)); 598 } 599 } 600 } 601 splx(s); 602 return (0); 603 } 604 #endif /* GRF_A2024 */ 605 606 607 /* 608 * CC View stuff. 609 */ 610 611 void 612 cc_init_view(v, bm, mode, dbox) 613 view_t *v; 614 bmap_t *bm; 615 dmode_t *mode; 616 box_t *dbox; 617 { 618 vdata_t *vd = VDATA(v); 619 v->bitmap = bm; 620 vd->mode = mode; 621 bcopy(dbox, &v->display, sizeof(box_t)); 622 623 v->display_view = DMDATA(vd->mode)->display_view; 624 v->use_colormap = DMDATA(vd->mode)->use_colormap; 625 v->get_colormap = DMDATA(vd->mode)->get_colormap; 626 v->free_view = cc_free_view; 627 v->get_display_mode = cc_get_display_mode; 628 v->remove_view = cc_remove_view; 629 } 630 631 void 632 cc_free_view(v) 633 view_t *v; 634 { 635 if (v) { 636 vdata_t *vd = VDATA(v); 637 dmode_t *md = vd->mode; 638 v->remove_view(v); 639 cc_monitor->free_bitmap(v->bitmap); 640 free_chipmem(v); 641 } 642 } 643 644 void 645 cc_remove_view(v) 646 view_t *v; 647 { 648 dmode_t *mode = VDATA(v)->mode; 649 650 if (MDATA(cc_monitor)->current_mode == mode) { 651 if (DMDATA(mode)->current_view == v) { 652 cc_load_mode(NULL); 653 } 654 } 655 if (DMDATA(mode)->current_view == v) { 656 DMDATA(mode)->current_view = NULL; 657 } 658 VDATA(v)->flags &= ~VF_DISPLAY; 659 } 660 661 dmode_t * 662 cc_get_display_mode(v) 663 view_t *v; 664 { 665 return (VDATA(v)->mode); 666 } 667 668 void 669 cc_mode_vbl_handler(d) 670 dmode_t *d; 671 { 672 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8); 673 674 if (vp < 12) { 675 custom.cop1lc = PREP_DMA_MEM(DMDATA(d)->frames[F_LONG]); 676 custom.copjmp1 = 0; 677 } 678 } 679 680 void 681 cc_lace_mode_vbl_handler(d) 682 dmode_t *d; 683 { 684 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8); 685 686 if (vp < 12) { 687 if (custom.vposr & 0x8000) { 688 custom.cop1lc = PREP_DMA_MEM(DMDATA(d)->frames[F_LACE_LONG]); 689 } else { 690 custom.cop1lc = PREP_DMA_MEM(DMDATA(d)->frames[F_LACE_SHORT]); 691 } 692 custom.copjmp1 = 0; 693 } 694 } 695 696 /* 697 * Modes. (ick) 698 */ 699 700 /* 701 * NTSC Modes 702 */ 703 704 #if defined (GRF_NTSC) 705 706 dmode_t * 707 cc_init_ntsc_hires() 708 { 709 /* h_this function should only be called once. */ 710 if (!h_this) { 711 u_short len = std_copper_list_len; 712 cop_t *cp; 713 714 h_this = &hires_mode; 715 h_this_data = &hires_mode_data; 716 bzero(h_this, sizeof(dmode_t)); 717 bzero(h_this_data, sizeof(dmdata_t)); 718 719 h_this->name = "ntsc: hires interlace"; 720 h_this->nominal_size.width = 640; 721 h_this->nominal_size.height = 200; 722 h_this_data->max_size.width = 724; 723 h_this_data->max_size.height = 242; 724 h_this_data->min_size.width = 320; 725 h_this_data->min_size.height = 100; 726 h_this_data->min_depth = 1; 727 h_this_data->max_depth = 4; 728 h_this->data = h_this_data; 729 730 h_this->get_monitor = cc_get_monitor; 731 h_this->alloc_view = cc_alloc_view; 732 h_this->get_current_view = cc_get_current_view; 733 734 h_this_data->use_colormap = cc_use_colormap; 735 h_this_data->get_colormap = cc_get_colormap; 736 h_this_data->alloc_colormap = cc_alloc_colormap; 737 h_this_data->display_view = display_hires_view; 738 h_this_data->monitor = cc_monitor; 739 740 h_this_data->frames = hires_frames; 741 h_this_data->frames[F_LONG] = alloc_chipmem(std_copper_list_size * F_TOTAL); 742 if (!h_this_data->frames[F_LONG]) { 743 panic("couldn't get chipmem for copper list"); 744 } 745 h_this_data->frames[F_STORE_LONG] = &h_this_data->frames[F_LONG][len]; 746 747 bcopy(std_copper_list, h_this_data->frames[F_STORE_LONG], std_copper_list_size); 748 bcopy(std_copper_list, h_this_data->frames[F_LONG], std_copper_list_size); 749 750 h_this_data->bplcon0 = 0x8200 | USE_CON3; /* hires, color 751 * composite enable, 752 * lace. */ 753 h_this_data->std_start_x = STANDARD_VIEW_X; 754 h_this_data->std_start_y = STANDARD_VIEW_Y; 755 h_this_data->vbl_handler = (vbl_handler_func *) cc_mode_vbl_handler; 756 #if defined (GRF_ECS) 757 h_this_data->beamcon0 = STANDARD_NTSC_BEAMCON; 758 #endif 759 760 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, h_this, link); 761 } 762 return (h_this); 763 } 764 765 void 766 display_hires_view(v) 767 view_t *v; 768 { 769 if (h_this_data->current_view != v) { 770 vdata_t *vd = VDATA(v); 771 monitor_t *monitor = h_this_data->monitor; 772 cop_t *cp = h_this_data->frames[F_STORE_LONG], *tmp; 773 int depth = v->bitmap->depth, i; 774 int hstart, hstop, vstart, vstop, j; 775 int x, y, w = v->display.width, h = v->display.height; 776 u_short ddfstart, ddfwidth, con1; 777 778 /* round down to nearest even width */ 779 /* w &= 0xfffe; */ 780 /* calculate datafetch width. */ 781 782 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2; 783 784 /* H_This will center the any overscanned display */ 785 /* and allow user to modify. */ 786 x = v->display.x + h_this_data->std_start_x - ((w - 640) >> 2); 787 y = v->display.y + h_this_data->std_start_y - ((h - 200) >> 1); 788 789 if (y & 1) 790 y--; 791 792 if (!(x & 1)) 793 x--; 794 795 hstart = x; 796 hstop = x + (w >> 1); 797 vstart = y; 798 vstop = y + h; 799 ddfstart = (hstart - 9) >> 1; 800 801 /* check for hardware limits, AGA may allow more..? */ 802 /* anyone got a 4000 I can borrow :^) -ch */ 803 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 804 int d = 0; 805 806 /* XXX anyone know the equality properties of 807 * intermixed logial AND's */ 808 /* XXX and arithmetic operators? */ 809 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 810 d++; 811 } 812 813 ddfstart -= d; 814 hstart -= d << 1; 815 hstop -= d << 1; 816 } 817 /* correct the datafetch to proper limits. */ 818 /* delay the actual display of the data until we need it. */ 819 ddfstart &= 0xfffc; 820 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 821 822 if (h_this_data->current_view) { 823 VDATA(h_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 824 /* displayed. */ 825 } 826 h_this_data->current_view = v; 827 828 cp = h_this_data->frames[F_STORE_LONG]; 829 #if defined GRF_ECS 830 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 831 tmp->cp.inst.operand = h_this_data->beamcon0; 832 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 833 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 834 #endif /* ECS */ 835 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 836 tmp->cp.inst.operand = h_this_data->bplcon0 | ((depth & 0x7) << 12); 837 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 838 tmp->cp.inst.operand = con1; 839 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 840 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 841 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 842 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 843 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 844 tmp->cp.inst.operand = ddfstart; 845 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 846 tmp->cp.inst.operand = ddfstart + ddfwidth; 847 848 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 849 for (i = 0, j = 0; i < depth; j += 2, i++) { 850 /* update the plane pointers */ 851 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 852 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 853 } 854 855 /* set mods correctly. */ 856 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 857 tmp[0].cp.inst.operand = v->bitmap->row_mod; 858 tmp[1].cp.inst.operand = v->bitmap->row_mod; 859 860 /* set next pointers correctly */ 861 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 862 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(h_this_data->frames[F_STORE_LONG])); 863 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(h_this_data->frames[F_STORE_LONG])); 864 865 cp = h_this_data->frames[F_LONG]; 866 h_this_data->frames[F_LONG] = h_this_data->frames[F_STORE_LONG]; 867 h_this_data->frames[F_STORE_LONG] = cp; 868 869 vd->flags |= VF_DISPLAY; 870 871 cc_use_colormap(v, vd->colormap); 872 } 873 cc_load_mode(h_this); 874 } 875 876 dmode_t * 877 cc_init_ntsc_hires_lace() 878 { 879 /* hl_this function should only be called once. */ 880 if (!hl_this) { 881 u_short len = std_copper_list_len; 882 cop_t *cp; 883 884 hl_this = &hires_lace_mode; 885 hl_this_data = &hires_lace_mode_data; 886 bzero(hl_this, sizeof(dmode_t)); 887 bzero(hl_this_data, sizeof(dmdata_t)); 888 889 hl_this->name = "ntsc: hires interlace"; 890 hl_this->nominal_size.width = 640; 891 hl_this->nominal_size.height = 400; 892 hl_this_data->max_size.width = 724; 893 hl_this_data->max_size.height = 482; 894 hl_this_data->min_size.width = 320; 895 hl_this_data->min_size.height = 200; 896 hl_this_data->min_depth = 1; 897 hl_this_data->max_depth = 4; 898 hl_this->data = hl_this_data; 899 900 hl_this->get_monitor = cc_get_monitor; 901 hl_this->alloc_view = cc_alloc_view; 902 hl_this->get_current_view = cc_get_current_view; 903 904 hl_this_data->use_colormap = cc_use_colormap; 905 hl_this_data->get_colormap = cc_get_colormap; 906 hl_this_data->alloc_colormap = cc_alloc_colormap; 907 hl_this_data->display_view = display_hires_lace_view; 908 hl_this_data->monitor = cc_monitor; 909 910 hl_this_data->flags |= DMF_INTERLACE; 911 912 hl_this_data->frames = hires_lace_frames; 913 hl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_copper_list_size * F_LACE_TOTAL); 914 if (!hl_this_data->frames[F_LACE_LONG]) { 915 panic("couldn't get chipmem for copper list"); 916 } 917 hl_this_data->frames[F_LACE_SHORT] = &hl_this_data->frames[F_LACE_LONG][len]; 918 hl_this_data->frames[F_LACE_STORE_LONG] = &hl_this_data->frames[F_LACE_SHORT][len]; 919 hl_this_data->frames[F_LACE_STORE_SHORT] = &hl_this_data->frames[F_LACE_STORE_LONG][len]; 920 921 bcopy(std_copper_list, hl_this_data->frames[F_LACE_STORE_LONG], std_copper_list_size); 922 bcopy(std_copper_list, hl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size); 923 bcopy(std_copper_list, hl_this_data->frames[F_LACE_LONG], std_copper_list_size); 924 bcopy(std_copper_list, hl_this_data->frames[F_LACE_SHORT], std_copper_list_size); 925 926 hl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color 927 * composite enable, 928 * lace. */ 929 hl_this_data->std_start_x = STANDARD_VIEW_X; 930 hl_this_data->std_start_y = STANDARD_VIEW_Y; 931 hl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler; 932 #if defined (GRF_ECS) 933 hl_this_data->beamcon0 = STANDARD_NTSC_BEAMCON; 934 #endif 935 936 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, hl_this, link); 937 } 938 return (hl_this); 939 } 940 941 void 942 display_hires_lace_view(v) 943 view_t *v; 944 { 945 if (hl_this_data->current_view != v) { 946 vdata_t *vd = VDATA(v); 947 monitor_t *monitor = hl_this_data->monitor; 948 cop_t *cp = hl_this_data->frames[F_LACE_STORE_LONG], *tmp; 949 int depth = v->bitmap->depth, i; 950 int hstart, hstop, vstart, vstop, j; 951 int x, y, w = v->display.width, h = v->display.height; 952 u_short ddfstart, ddfwidth, con1; 953 954 /* round down to nearest even width */ 955 /* w &= 0xfffe; */ 956 957 958 /* calculate datafetch width. */ 959 960 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2; 961 962 /* Hl_This will center the any overscanned display */ 963 /* and allow user to modify. */ 964 x = v->display.x + hl_this_data->std_start_x - ((w - 640) >> 2); 965 y = v->display.y + hl_this_data->std_start_y - ((h - 400) >> 2); 966 967 if (y & 1) 968 y--; 969 970 if (!(x & 1)) 971 x--; 972 973 hstart = x; 974 hstop = x + (w >> 1); 975 vstart = y; 976 vstop = y + (h >> 1); 977 ddfstart = (hstart - 9) >> 1; 978 979 /* check for hardware limits, AGA may allow more..? */ 980 /* anyone got a 4000 I can borrow :^) -ch */ 981 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 982 int d = 0; 983 984 /* XXX anyone know the equality properties of 985 * intermixed logial AND's */ 986 /* XXX and arithmetic operators? */ 987 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 988 d++; 989 } 990 991 ddfstart -= d; 992 hstart -= d << 1; 993 hstop -= d << 1; 994 } 995 /* correct the datafetch to proper limits. */ 996 /* delay the actual display of the data until we need it. */ 997 ddfstart &= 0xfffc; 998 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 999 1000 if (hl_this_data->current_view) { 1001 VDATA(hl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 1002 /* displayed. */ 1003 } 1004 hl_this_data->current_view = v; 1005 1006 cp = hl_this_data->frames[F_LACE_STORE_LONG]; 1007 #if defined GRF_ECS 1008 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 1009 tmp->cp.inst.operand = hl_this_data->beamcon0; 1010 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 1011 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 1012 #endif /* ECS */ 1013 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 1014 tmp->cp.inst.operand = hl_this_data->bplcon0 | ((depth & 0x7) << 12); 1015 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 1016 tmp->cp.inst.operand = con1; 1017 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 1018 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 1019 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 1020 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 1021 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 1022 tmp->cp.inst.operand = ddfstart; 1023 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 1024 tmp->cp.inst.operand = ddfstart + ddfwidth; 1025 1026 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 1027 for (i = 0, j = 0; i < depth; j += 2, i++) { 1028 /* update the plane pointers */ 1029 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 1030 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 1031 } 1032 1033 /* set mods correctly. */ 1034 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 1035 tmp[0].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod; 1036 tmp[1].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod; 1037 1038 /* set next pointers correctly */ 1039 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 1040 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hl_this_data->frames[F_LACE_STORE_SHORT])); 1041 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hl_this_data->frames[F_LACE_STORE_SHORT])); 1042 1043 1044 bcopy(hl_this_data->frames[F_LACE_STORE_LONG], hl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size); 1045 1046 /* these are the only ones that are different from long frame. */ 1047 cp = hl_this_data->frames[F_LACE_STORE_SHORT]; 1048 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 1049 for (i = 0, j = 0; i < depth; j += 2, i++) { 1050 u_short mod = v->bitmap->bytes_per_row + v->bitmap->row_mod; 1051 /* update plane pointers. high and low. */ 1052 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod])); 1053 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod])); 1054 } 1055 1056 /* set next pointers correctly */ 1057 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 1058 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hl_this_data->frames[F_LACE_STORE_LONG])); 1059 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hl_this_data->frames[F_LACE_STORE_LONG])); 1060 1061 1062 cp = hl_this_data->frames[F_LACE_LONG]; 1063 hl_this_data->frames[F_LACE_LONG] = hl_this_data->frames[F_LACE_STORE_LONG]; 1064 hl_this_data->frames[F_LACE_STORE_LONG] = cp; 1065 1066 cp = hl_this_data->frames[F_LACE_SHORT]; 1067 hl_this_data->frames[F_LACE_SHORT] = hl_this_data->frames[F_LACE_STORE_SHORT]; 1068 hl_this_data->frames[F_LACE_STORE_SHORT] = cp; 1069 1070 vd->flags |= VF_DISPLAY; 1071 1072 cc_use_colormap(v, vd->colormap); 1073 } 1074 cc_load_mode(hl_this); 1075 } 1076 #if defined (GRF_A2024) 1077 1078 dmode_t * 1079 cc_init_ntsc_hires_dlace() 1080 { 1081 /* hdl_this function should only be called once. */ 1082 if (!hdl_this) { 1083 u_short len = std_dlace_copper_list_len; 1084 cop_t *cp; 1085 1086 hdl_this = &hires_dlace_mode; 1087 hdl_this_data = &hires_dlace_mode_data; 1088 bzero(hdl_this, sizeof(dmode_t)); 1089 bzero(hdl_this_data, sizeof(dmdata_t)); 1090 1091 hdl_this->name = "ntsc: hires double interlace"; 1092 hdl_this->nominal_size.width = 640; 1093 hdl_this->nominal_size.height = 800; 1094 hdl_this_data->max_size.width = 724; 1095 hdl_this_data->max_size.height = 800; 1096 hdl_this_data->min_size.width = 320; 1097 hdl_this_data->min_size.height = 400; 1098 hdl_this_data->min_depth = 1; 1099 hdl_this_data->max_depth = 2; 1100 hdl_this->data = hdl_this_data; 1101 1102 hdl_this->get_monitor = cc_get_monitor; 1103 hdl_this->alloc_view = cc_alloc_view; 1104 hdl_this->get_current_view = cc_get_current_view; 1105 1106 hdl_this_data->use_colormap = cc_a2024_use_colormap; 1107 hdl_this_data->get_colormap = cc_a2024_get_colormap; 1108 hdl_this_data->alloc_colormap = cc_a2024_alloc_colormap; 1109 hdl_this_data->display_view = display_hires_dlace_view; 1110 hdl_this_data->monitor = cc_monitor; 1111 1112 hdl_this_data->flags |= DMF_INTERLACE; 1113 1114 hdl_this_data->frames = hires_dlace_frames; 1115 hdl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_dlace_copper_list_size * F_LACE_TOTAL); 1116 if (!hdl_this_data->frames[F_LACE_LONG]) { 1117 panic("couldn't get chipmem for copper list"); 1118 } 1119 hdl_this_data->frames[F_LACE_SHORT] = &hdl_this_data->frames[F_LACE_LONG][len]; 1120 hdl_this_data->frames[F_LACE_STORE_LONG] = &hdl_this_data->frames[F_LACE_SHORT][len]; 1121 hdl_this_data->frames[F_LACE_STORE_SHORT] = &hdl_this_data->frames[F_LACE_STORE_LONG][len]; 1122 1123 bcopy(std_dlace_copper_list, hdl_this_data->frames[F_LACE_STORE_LONG], std_dlace_copper_list_size); 1124 bcopy(std_dlace_copper_list, hdl_this_data->frames[F_LACE_STORE_SHORT], std_dlace_copper_list_size); 1125 bcopy(std_dlace_copper_list, hdl_this_data->frames[F_LACE_LONG], std_dlace_copper_list_size); 1126 bcopy(std_dlace_copper_list, hdl_this_data->frames[F_LACE_SHORT], std_dlace_copper_list_size); 1127 1128 hdl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color 1129 * composite enable, 1130 * dlace. */ 1131 hdl_this_data->std_start_x = STANDARD_VIEW_X; 1132 hdl_this_data->std_start_y = STANDARD_VIEW_Y; 1133 hdl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler; 1134 #if defined (GRF_ECS) 1135 hdl_this_data->beamcon0 = STANDARD_NTSC_BEAMCON; 1136 #endif 1137 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, hdl_this, link); 1138 } 1139 return (hdl_this); 1140 } 1141 1142 void 1143 display_hires_dlace_view(v) 1144 view_t *v; 1145 { 1146 if (hdl_this_data->current_view != v) { 1147 vdata_t *vd = VDATA(v); 1148 monitor_t *monitor = hdl_this_data->monitor; 1149 cop_t *cp = hdl_this_data->frames[F_LACE_STORE_LONG], *tmp; 1150 int depth = v->bitmap->depth, i; 1151 int hstart, hstop, vstart, vstop, j; 1152 int x, y, w = v->display.width, h = v->display.height; 1153 u_short ddfstart, ddfwidth, con1; 1154 u_short mod1l, mod2l; 1155 1156 /* round down to nearest even width */ 1157 /* w &= 0xfffe; */ 1158 1159 /* calculate datafetch width. */ 1160 1161 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2; 1162 1163 /* Hdl_This will center the any overscanned display */ 1164 /* and allow user to modify. */ 1165 x = v->display.x + hdl_this_data->std_start_x - ((w - 640) >> 2); 1166 y = v->display.y + hdl_this_data->std_start_y - ((h - 800) >> 3); 1167 1168 if (y & 1) 1169 y--; 1170 1171 if (!(x & 1)) 1172 x--; 1173 1174 hstart = x; 1175 hstop = x + (w >> 1); 1176 vstart = y; 1177 vstop = y + (h >> 2); 1178 1179 ddfstart = (hstart - 9) >> 1; 1180 1181 /* check for hardware limits, AGA may allow more..? */ 1182 /* anyone got a 4000 I can borrow :^) -ch */ 1183 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 1184 int d = 0; 1185 1186 /* XXX anyone know the equality properties of 1187 * intermixed logial AND's */ 1188 /* XXX and arithmetic operators? */ 1189 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 1190 d++; 1191 } 1192 1193 ddfstart -= d; 1194 hstart -= d << 1; 1195 hstop -= d << 1; 1196 } 1197 /* correct the datafetch to proper limits. */ 1198 /* delay the actual display of the data until we need it. */ 1199 ddfstart &= 0xfffc; 1200 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 1201 1202 if (hdl_this_data->current_view) { 1203 VDATA(hdl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 1204 /* displayed. */ 1205 } 1206 hdl_this_data->current_view = v; 1207 1208 cp = hdl_this_data->frames[F_LACE_STORE_LONG]; 1209 #if defined GRF_ECS 1210 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 1211 tmp->cp.inst.operand = hdl_this_data->beamcon0; 1212 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 1213 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 1214 #endif /* ECS */ 1215 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 1216 tmp->cp.inst.operand = hdl_this_data->bplcon0 | ((depth & 0x7) << 13); /* times two. */ 1217 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 1218 tmp->cp.inst.operand = con1; 1219 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 1220 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 1221 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 1222 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 1223 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 1224 tmp->cp.inst.operand = ddfstart; 1225 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 1226 tmp->cp.inst.operand = ddfstart + ddfwidth; 1227 1228 mod1l = v->bitmap->bytes_per_row + v->bitmap->row_mod; 1229 mod2l = mod1l << 1; 1230 1231 /* update plane pointers. */ 1232 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 1233 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0])); 1234 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0])); 1235 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l])); 1236 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l])); 1237 if (depth == 2) { 1238 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0])); 1239 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0])); 1240 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l])); 1241 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l])); 1242 } 1243 /* set modulos. */ 1244 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 1245 tmp[0].cp.inst.operand = mod2l + mod1l; 1246 tmp[1].cp.inst.operand = mod2l + mod1l; 1247 1248 1249 /* set next coper list pointers */ 1250 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 1251 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hdl_this_data->frames[F_LACE_STORE_SHORT])); 1252 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hdl_this_data->frames[F_LACE_STORE_SHORT])); 1253 1254 bcopy(hdl_this_data->frames[F_LACE_STORE_LONG], hdl_this_data->frames[F_LACE_STORE_SHORT], 1255 std_dlace_copper_list_size); 1256 1257 /* these are the only ones that are different from long frame. */ 1258 cp = hdl_this_data->frames[F_LACE_STORE_SHORT]; 1259 /* update plane pointers. */ 1260 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 1261 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l])); 1262 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l])); 1263 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l])); 1264 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l])); 1265 if (depth == 2) { 1266 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l])); 1267 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l])); 1268 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l])); 1269 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l])); 1270 } 1271 /* set next copper list pointers */ 1272 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 1273 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hdl_this_data->frames[F_LACE_STORE_LONG])); 1274 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hdl_this_data->frames[F_LACE_STORE_LONG])); 1275 1276 cp = hdl_this_data->frames[F_LACE_LONG]; 1277 hdl_this_data->frames[F_LACE_LONG] = hdl_this_data->frames[F_LACE_STORE_LONG]; 1278 hdl_this_data->frames[F_LACE_STORE_LONG] = cp; 1279 1280 cp = hdl_this_data->frames[F_LACE_SHORT]; 1281 hdl_this_data->frames[F_LACE_SHORT] = hdl_this_data->frames[F_LACE_STORE_SHORT]; 1282 hdl_this_data->frames[F_LACE_STORE_SHORT] = cp; 1283 1284 vd->flags |= VF_DISPLAY; 1285 cc_a2024_use_colormap(v, vd->colormap); 1286 } 1287 cc_load_mode(hdl_this); 1288 } 1289 1290 1291 dmode_t * 1292 cc_init_ntsc_a2024() 1293 { 1294 /* a24_this function should only be called once. */ 1295 if (!a24_this) { 1296 int i; 1297 u_short len = std_a2024_copper_list_len; 1298 cop_t *cp; 1299 1300 a24_this = &a2024_mode; 1301 a24_this_data = &a2024_mode_data; 1302 bzero(a24_this, sizeof(dmode_t)); 1303 bzero(a24_this_data, sizeof(dmdata_t)); 1304 1305 a24_this->name = "ntsc: A2024 15khz"; 1306 a24_this->nominal_size.width = 1024; 1307 a24_this->nominal_size.height = 800; 1308 a24_this_data->max_size.width = 1024; 1309 a24_this_data->max_size.height = 800; 1310 a24_this_data->min_size.width = 1024; 1311 a24_this_data->min_size.height = 800; 1312 a24_this_data->min_depth = 1; 1313 a24_this_data->max_depth = 2; 1314 a24_this->data = a24_this_data; 1315 1316 a24_this->get_monitor = cc_get_monitor; 1317 a24_this->alloc_view = cc_alloc_view; 1318 a24_this->get_current_view = cc_get_current_view; 1319 1320 a24_this_data->use_colormap = cc_a2024_use_colormap; 1321 a24_this_data->get_colormap = cc_a2024_get_colormap; 1322 a24_this_data->display_view = display_a2024_view; 1323 a24_this_data->alloc_colormap = cc_a2024_alloc_colormap; 1324 a24_this_data->monitor = cc_monitor; 1325 1326 a24_this_data->flags |= DMF_HEDLEY_EXP; 1327 1328 a24_this_data->frames = a2024_frames; 1329 a24_this_data->frames[F_QD_QUAD0] = alloc_chipmem(std_a2024_copper_list_size * F_QD_TOTAL); 1330 if (!a24_this_data->frames[F_QD_QUAD0]) { 1331 panic("couldn't get chipmem for copper list"); 1332 } 1333 /* setup the hedley init bitplane. */ 1334 hedley_init = alloc_chipmem(128); 1335 if (!hedley_init) { 1336 panic("couldn't get chipmem for hedley init bitplane"); 1337 } 1338 for (i = 1; i < 128; i++) 1339 hedley_init[i] = 0xff; 1340 hedley_init[0] = 0x03; 1341 1342 /* copy image of standard copper list. */ 1343 bcopy(std_a2024_copper_list, a24_this_data->frames[0], std_a2024_copper_list_size); 1344 1345 /* set the init plane pointer. */ 1346 cp = find_copper_inst(a24_this_data->frames[F_QD_QUAD0], CI_MOVE(R_BPL0PTH)); 1347 cp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hedley_init)); 1348 cp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hedley_init)); 1349 1350 for (i = 1; i < F_QD_TOTAL; i++) { 1351 a24_this_data->frames[i] = &a24_this_data->frames[i - 1][len]; 1352 bcopy(a24_this_data->frames[0], a24_this_data->frames[i], std_a2024_copper_list_size); 1353 } 1354 1355 a24_this_data->bplcon0 = 0x8200; /* hires */ 1356 a24_this_data->vbl_handler = (vbl_handler_func *) a2024_mode_vbl_handler; 1357 1358 1359 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, a24_this, link); 1360 } 1361 return (a24_this); 1362 } 1363 1364 void 1365 display_a2024_view(v) 1366 view_t *v; 1367 { 1368 if (a24_this_data->current_view != v) { 1369 vdata_t *vd = VDATA(v); 1370 monitor_t *monitor = a24_this_data->monitor; 1371 cop_t *cp, *tmp; 1372 u_char *inst_plane[2]; 1373 u_char **plane = inst_plane; 1374 u_long full_line = v->bitmap->bytes_per_row + v->bitmap->row_mod; 1375 u_long half_plane = full_line * v->bitmap->rows / 2; 1376 1377 int line_mod = 0xbc; /* standard 2024 15khz mod. */ 1378 int depth = v->bitmap->depth, i, j; 1379 1380 plane[0] = v->bitmap->plane[0]; 1381 if (depth == 2) { 1382 plane[1] = v->bitmap->plane[1]; 1383 } 1384 if (a24_this_data->current_view) { 1385 VDATA(a24_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer 1386 * displayed. */ 1387 } 1388 cp = a24_this_data->frames[F_QD_STORE_QUAD0]; 1389 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR1F)); 1390 tmp = find_copper_inst(tmp, CI_MOVE(R_BPLCON0)); /* grab third one. */ 1391 tmp->cp.inst.operand = a24_this_data->bplcon0 | ((depth & 0x7) << 13); /* times 2 */ 1392 1393 bcopy(a24_this_data->frames[F_QD_STORE_QUAD0], a24_this_data->frames[F_QD_STORE_QUAD1], std_a2024_copper_list_size); 1394 bcopy(a24_this_data->frames[F_QD_STORE_QUAD0], a24_this_data->frames[F_QD_STORE_QUAD2], std_a2024_copper_list_size); 1395 bcopy(a24_this_data->frames[F_QD_STORE_QUAD0], a24_this_data->frames[F_QD_STORE_QUAD3], std_a2024_copper_list_size); 1396 1397 /* 1398 * Mark Id's 1399 */ 1400 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD1], CI_WAIT(126, 21)); 1401 CBUMP(tmp); 1402 CMOVE(tmp, R_COLOR01, QUAD1_ID); 1403 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD2], CI_WAIT(126, 21)); 1404 CBUMP(tmp); 1405 CMOVE(tmp, R_COLOR01, QUAD2_ID); 1406 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD3], CI_WAIT(126, 21)); 1407 CBUMP(tmp); 1408 CMOVE(tmp, R_COLOR01, QUAD3_ID); 1409 1410 plane[0]--; 1411 plane[0]--; 1412 if (depth == 2) { 1413 plane[1]--; 1414 plane[1]--; 1415 } 1416 /* 1417 * Set bitplane pointers. 1418 */ 1419 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD0], CI_MOVE(R_BPLMOD2)); 1420 CBUMP(tmp); 1421 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][0]))); 1422 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][0]))); 1423 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line]))); 1424 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line]))); 1425 if (depth == 2) { 1426 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][0]))); 1427 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][0]))); 1428 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line]))); 1429 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line]))); 1430 } 1431 #if defined (GRF_ECS) 1432 CMOVE(tmp, R_DIWHIGH, 0x2000); 1433 #endif 1434 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD1]))); 1435 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD1]))); 1436 CEND(tmp); 1437 CEND(tmp); 1438 1439 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD1], CI_MOVE(R_BPLMOD2)); 1440 CBUMP(tmp); 1441 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE]))); 1442 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE]))); 1443 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE]))); 1444 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE]))); 1445 if (depth == 2) { 1446 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE]))); 1447 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE]))); 1448 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE]))); 1449 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE]))); 1450 } 1451 #if defined (GRF_ECS) 1452 CMOVE(tmp, R_DIWHIGH, 0x2000); 1453 #endif 1454 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD2]))); 1455 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD2]))); 1456 CEND(tmp); 1457 CEND(tmp); 1458 1459 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD2], CI_MOVE(R_BPLMOD2)); 1460 CBUMP(tmp); 1461 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane]))); 1462 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane]))); 1463 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line]))); 1464 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line]))); 1465 if (depth == 2) { 1466 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane]))); 1467 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane]))); 1468 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line]))); 1469 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line]))); 1470 } 1471 #if defined (GRF_ECS) 1472 CMOVE(tmp, R_DIWHIGH, 0x2000); 1473 #endif 1474 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD3]))); 1475 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD3]))); 1476 CEND(tmp); 1477 CEND(tmp); 1478 1479 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD3], CI_MOVE(R_BPLMOD2)); 1480 CBUMP(tmp); 1481 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE]))); 1482 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE]))); 1483 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE]))); 1484 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE]))); 1485 if (depth == 2) { 1486 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE]))); 1487 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE]))); 1488 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE]))); 1489 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE]))); 1490 } 1491 #if defined (GRF_ECS) 1492 CMOVE(tmp, R_DIWHIGH, 0x2000); 1493 #endif 1494 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD0]))); 1495 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD0]))); 1496 CEND(tmp); 1497 CEND(tmp); 1498 1499 /* swap new pointers in. */ 1500 for (i = F_QD_STORE_QUAD0, j = F_QD_QUAD0; 1501 i <= F_QD_STORE_QUAD3; i++, j++) { 1502 cp = a24_this_data->frames[j]; 1503 a24_this_data->frames[j] = a24_this_data->frames[i]; 1504 a24_this_data->frames[i] = cp; 1505 } 1506 1507 a24_this_data->current_view = v; 1508 vd->flags |= VF_DISPLAY; 1509 1510 cc_a2024_use_colormap(v, vd->colormap); 1511 } 1512 cc_load_mode(a24_this); 1513 } 1514 1515 void 1516 a2024_mode_vbl_handler(d) 1517 dmode_t *d; 1518 { 1519 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8); 1520 1521 if (vp < 12) { 1522 custom.cop1lc = PREP_DMA_MEM(a24_this_data->frames[a24_this_data->hedley_current]); 1523 custom.copjmp1 = 0; 1524 } 1525 a24_this_data->hedley_current++; 1526 a24_this_data->hedley_current &= 0x3; /* if 4 then 0. */ 1527 } 1528 #endif /* GRF_A2024 */ 1529 #endif /* GRF_NTSC */ 1530 1531 /* 1532 * PAL modes. 1533 */ 1534 1535 #if defined (GRF_PAL) 1536 1537 dmode_t * 1538 cc_init_pal_hires() 1539 { 1540 /* ph_this function should only be called once. */ 1541 if (!ph_this) { 1542 u_short len = std_copper_list_len; 1543 cop_t *cp; 1544 1545 ph_this = &pal_hires_mode; 1546 ph_this_data = &pal_hires_mode_data; 1547 bzero(ph_this, sizeof(dmode_t)); 1548 bzero(ph_this_data, sizeof(dmdata_t)); 1549 1550 ph_this->name = "pal: pal_hires interlace"; 1551 ph_this->nominal_size.width = 640; 1552 ph_this->nominal_size.height = 256; 1553 ph_this_data->max_size.width = 724; 1554 ph_this_data->max_size.height = 289; 1555 ph_this_data->min_size.width = 320; 1556 ph_this_data->min_size.height = 244; 1557 ph_this_data->min_depth = 1; 1558 ph_this_data->max_depth = 4; 1559 ph_this->data = ph_this_data; 1560 1561 ph_this->get_monitor = cc_get_monitor; 1562 ph_this->alloc_view = cc_alloc_view; 1563 ph_this->get_current_view = cc_get_current_view; 1564 1565 ph_this_data->use_colormap = cc_use_colormap; 1566 ph_this_data->get_colormap = cc_get_colormap; 1567 ph_this_data->alloc_colormap = cc_alloc_colormap; 1568 ph_this_data->display_view = display_pal_hires_view; 1569 ph_this_data->monitor = cc_monitor; 1570 1571 ph_this_data->frames = pal_hires_frames; 1572 ph_this_data->frames[F_LONG] = alloc_chipmem(std_copper_list_size * F_TOTAL); 1573 if (!ph_this_data->frames[F_LONG]) { 1574 panic("couldn't get chipmem for copper list"); 1575 } 1576 ph_this_data->frames[F_STORE_LONG] = &ph_this_data->frames[F_LONG][len]; 1577 1578 bcopy(std_copper_list, ph_this_data->frames[F_STORE_LONG], std_copper_list_size); 1579 bcopy(std_copper_list, ph_this_data->frames[F_LONG], std_copper_list_size); 1580 1581 ph_this_data->bplcon0 = 0x8200 | USE_CON3; /* pal_hires, color 1582 * composite enable, 1583 * lace. */ 1584 ph_this_data->std_start_x = STANDARD_VIEW_X; 1585 ph_this_data->std_start_y = STANDARD_VIEW_Y; 1586 ph_this_data->vbl_handler = (vbl_handler_func *) cc_mode_vbl_handler; 1587 #if defined (GRF_ECS) 1588 ph_this_data->beamcon0 = STANDARD_PAL_BEAMCON; 1589 #endif 1590 1591 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, ph_this, link); 1592 } 1593 return (ph_this); 1594 } 1595 1596 void 1597 display_pal_hires_view(v) 1598 view_t *v; 1599 { 1600 if (ph_this_data->current_view != v) { 1601 vdata_t *vd = VDATA(v); 1602 monitor_t *monitor = ph_this_data->monitor; 1603 cop_t *cp = ph_this_data->frames[F_STORE_LONG], *tmp; 1604 int depth = v->bitmap->depth, i; 1605 int hstart, hstop, vstart, vstop, j; 1606 int x, y, w = v->display.width, h = v->display.height; 1607 u_short ddfstart, ddfwidth, con1; 1608 1609 /* round down to nearest even width */ 1610 /* w &= 0xfffe; */ 1611 1612 /* calculate datafetch width. */ 1613 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2; 1614 1615 /* Ph_This will center the any overscanned display */ 1616 /* and allow user to modify. */ 1617 x = v->display.x + ph_this_data->std_start_x - ((w - 640) >> 2); 1618 y = v->display.y + ph_this_data->std_start_y - ((h - 256) >> 1); 1619 1620 if (y & 1) 1621 y--; 1622 1623 if (!(x & 1)) 1624 x--; 1625 1626 hstart = x; 1627 hstop = x + (w >> 1); 1628 vstart = y; 1629 vstop = y + h; 1630 ddfstart = (hstart - 9) >> 1; 1631 /* check for hardware limits, AGA may allow more..? */ 1632 /* anyone got a 4000 I can borrow :^) -ch */ 1633 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 1634 int d = 0; 1635 1636 /* XXX anyone know the equality properties of 1637 * intermixed logial AND's */ 1638 /* XXX and arithmetic operators? */ 1639 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 1640 d++; 1641 } 1642 1643 ddfstart -= d; 1644 hstart -= d << 1; 1645 hstop -= d << 1; 1646 } 1647 /* correct the datafetch to proper limits. */ 1648 /* delay the actual display of the data until we need it. */ 1649 ddfstart &= 0xfffc; 1650 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 1651 1652 if (ph_this_data->current_view) { 1653 VDATA(ph_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 1654 /* displayed. */ 1655 } 1656 ph_this_data->current_view = v; 1657 1658 cp = ph_this_data->frames[F_STORE_LONG]; 1659 #if defined GRF_ECS 1660 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 1661 tmp->cp.inst.operand = ph_this_data->beamcon0; 1662 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 1663 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 1664 #endif /* ECS */ 1665 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 1666 tmp->cp.inst.operand = ph_this_data->bplcon0 | ((depth & 0x7) << 12); 1667 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 1668 tmp->cp.inst.operand = con1; 1669 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 1670 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 1671 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 1672 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 1673 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 1674 tmp->cp.inst.operand = ddfstart; 1675 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 1676 tmp->cp.inst.operand = ddfstart + ddfwidth; 1677 1678 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 1679 for (i = 0, j = 0; i < depth; j += 2, i++) { 1680 /* update the plane pointers */ 1681 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 1682 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 1683 } 1684 1685 /* set mods correctly. */ 1686 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 1687 tmp[0].cp.inst.operand = v->bitmap->row_mod; 1688 tmp[1].cp.inst.operand = v->bitmap->row_mod; 1689 1690 /* set next pointers correctly */ 1691 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 1692 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(ph_this_data->frames[F_STORE_LONG])); 1693 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(ph_this_data->frames[F_STORE_LONG])); 1694 1695 cp = ph_this_data->frames[F_LONG]; 1696 ph_this_data->frames[F_LONG] = ph_this_data->frames[F_STORE_LONG]; 1697 ph_this_data->frames[F_STORE_LONG] = cp; 1698 1699 vd->flags |= VF_DISPLAY; 1700 cc_use_colormap(v, vd->colormap); 1701 } 1702 cc_load_mode(ph_this); 1703 } 1704 1705 dmode_t * 1706 cc_init_pal_hires_lace() 1707 { 1708 /* phl_this function should only be called once. */ 1709 if (!phl_this) { 1710 u_short len = std_copper_list_len; 1711 cop_t *cp; 1712 1713 phl_this = &pal_hires_lace_mode; 1714 phl_this_data = &pal_hires_lace_mode_data; 1715 bzero(phl_this, sizeof(dmode_t)); 1716 bzero(phl_this_data, sizeof(dmdata_t)); 1717 1718 phl_this->name = "pal: hires interlace"; 1719 phl_this->nominal_size.width = 640; 1720 phl_this->nominal_size.height = 512; 1721 phl_this_data->max_size.width = 724; 1722 phl_this_data->max_size.height = 578; 1723 phl_this_data->min_size.width = 320; 1724 phl_this_data->min_size.height = 484; 1725 phl_this_data->min_depth = 1; 1726 phl_this_data->max_depth = 4; 1727 phl_this->data = phl_this_data; 1728 1729 phl_this->get_monitor = cc_get_monitor; 1730 phl_this->alloc_view = cc_alloc_view; 1731 phl_this->get_current_view = cc_get_current_view; 1732 1733 phl_this_data->use_colormap = cc_use_colormap; 1734 phl_this_data->get_colormap = cc_get_colormap; 1735 phl_this_data->alloc_colormap = cc_alloc_colormap; 1736 phl_this_data->display_view = display_pal_hires_lace_view; 1737 phl_this_data->monitor = cc_monitor; 1738 1739 phl_this_data->flags |= DMF_INTERLACE; 1740 1741 phl_this_data->frames = pal_hires_lace_frames; 1742 phl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_copper_list_size * F_LACE_TOTAL); 1743 if (!phl_this_data->frames[F_LACE_LONG]) { 1744 panic("couldn't get chipmem for copper list"); 1745 } 1746 phl_this_data->frames[F_LACE_SHORT] = &phl_this_data->frames[F_LACE_LONG][len]; 1747 phl_this_data->frames[F_LACE_STORE_LONG] = &phl_this_data->frames[F_LACE_SHORT][len]; 1748 phl_this_data->frames[F_LACE_STORE_SHORT] = &phl_this_data->frames[F_LACE_STORE_LONG][len]; 1749 1750 bcopy(std_copper_list, phl_this_data->frames[F_LACE_STORE_LONG], std_copper_list_size); 1751 bcopy(std_copper_list, phl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size); 1752 bcopy(std_copper_list, phl_this_data->frames[F_LACE_LONG], std_copper_list_size); 1753 bcopy(std_copper_list, phl_this_data->frames[F_LACE_SHORT], std_copper_list_size); 1754 1755 phl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color 1756 * composite enable, 1757 * lace. */ 1758 phl_this_data->std_start_x = STANDARD_VIEW_X; 1759 phl_this_data->std_start_y = STANDARD_VIEW_Y; 1760 phl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler; 1761 #if defined (GRF_ECS) 1762 phl_this_data->beamcon0 = STANDARD_PAL_BEAMCON; 1763 #endif 1764 1765 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, phl_this, link); 1766 } 1767 return (phl_this); 1768 } 1769 1770 void 1771 display_pal_hires_lace_view(v) 1772 view_t *v; 1773 { 1774 if (phl_this_data->current_view != v) { 1775 vdata_t *vd = VDATA(v); 1776 monitor_t *monitor = phl_this_data->monitor; 1777 cop_t *cp = phl_this_data->frames[F_LACE_STORE_LONG], *tmp; 1778 int depth = v->bitmap->depth, i; 1779 int hstart, hstop, vstart, vstop, j; 1780 int x, y, w = v->display.width, h = v->display.height; 1781 u_short ddfstart, ddfwidth, con1; 1782 1783 /* round down to nearest even width */ 1784 /* w &= 0xfffe; */ 1785 1786 /* calculate datafetch width. */ 1787 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2; 1788 1789 /* Phl_This will center the any overscanned display */ 1790 /* and allow user to modify. */ 1791 x = v->display.x + phl_this_data->std_start_x - ((w - 640) >> 2); 1792 y = v->display.y + phl_this_data->std_start_y - ((h - 512) >> 2); 1793 1794 if (y & 1) 1795 y--; 1796 1797 if (!(x & 1)) 1798 x--; 1799 1800 hstart = x; 1801 hstop = x + (w >> 1); 1802 vstart = y; 1803 vstop = y + (h >> 1); 1804 ddfstart = (hstart - 9) >> 1; 1805 1806 /* check for hardware limits, AGA may allow more..? */ 1807 /* anyone got a 4000 I can borrow :^) -ch */ 1808 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 1809 int d = 0; 1810 1811 /* XXX anyone know the equality properties of 1812 * intermixed logial AND's */ 1813 /* XXX and arithmetic operators? */ 1814 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 1815 d++; 1816 } 1817 1818 ddfstart -= d; 1819 hstart -= d << 1; 1820 hstop -= d << 1; 1821 } 1822 /* correct the datafetch to proper limits. */ 1823 /* delay the actual display of the data until we need it. */ 1824 ddfstart &= 0xfffc; 1825 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 1826 1827 if (phl_this_data->current_view) { 1828 VDATA(phl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 1829 /* displayed. */ 1830 } 1831 phl_this_data->current_view = v; 1832 1833 cp = phl_this_data->frames[F_LACE_STORE_LONG]; 1834 #if defined GRF_ECS 1835 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 1836 tmp->cp.inst.operand = phl_this_data->beamcon0; 1837 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 1838 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 1839 #endif /* ECS */ 1840 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 1841 tmp->cp.inst.operand = phl_this_data->bplcon0 | ((depth & 0x7) << 12); 1842 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 1843 tmp->cp.inst.operand = con1; 1844 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 1845 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 1846 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 1847 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 1848 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 1849 tmp->cp.inst.operand = ddfstart; 1850 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 1851 tmp->cp.inst.operand = ddfstart + ddfwidth; 1852 1853 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 1854 for (i = 0, j = 0; i < depth; j += 2, i++) { 1855 /* update the plane pointers */ 1856 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 1857 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i])); 1858 } 1859 1860 /* set mods correctly. */ 1861 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 1862 tmp[0].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod; 1863 tmp[1].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod; 1864 1865 /* set next pointers correctly */ 1866 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 1867 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_SHORT])); 1868 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_SHORT])); 1869 1870 1871 bcopy(phl_this_data->frames[F_LACE_STORE_LONG], phl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size); 1872 1873 /* these are the only ones that are different from long frame. */ 1874 cp = phl_this_data->frames[F_LACE_STORE_SHORT]; 1875 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 1876 for (i = 0, j = 0; i < depth; j += 2, i++) { 1877 u_short mod = v->bitmap->bytes_per_row + v->bitmap->row_mod; 1878 /* update plane pointers. high and low. */ 1879 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod])); 1880 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod])); 1881 } 1882 1883 /* set next pointers correctly */ 1884 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 1885 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_LONG])); 1886 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_LONG])); 1887 1888 1889 cp = phl_this_data->frames[F_LACE_LONG]; 1890 phl_this_data->frames[F_LACE_LONG] = phl_this_data->frames[F_LACE_STORE_LONG]; 1891 phl_this_data->frames[F_LACE_STORE_LONG] = cp; 1892 1893 cp = phl_this_data->frames[F_LACE_SHORT]; 1894 phl_this_data->frames[F_LACE_SHORT] = phl_this_data->frames[F_LACE_STORE_SHORT]; 1895 phl_this_data->frames[F_LACE_STORE_SHORT] = cp; 1896 1897 vd->flags |= VF_DISPLAY; 1898 cc_use_colormap(v, vd->colormap); 1899 } 1900 cc_load_mode(phl_this); 1901 } 1902 #if defined (GRF_A2024) 1903 1904 dmode_t * 1905 cc_init_pal_hires_dlace() 1906 { 1907 /* phdl_this function should only be called once. */ 1908 if (!phdl_this) { 1909 u_short len = std_dlace_copper_list_len; 1910 cop_t *cp; 1911 1912 phdl_this = &pal_hires_dlace_mode; 1913 phdl_this_data = &pal_hires_dlace_mode_data; 1914 bzero(phdl_this, sizeof(dmode_t)); 1915 bzero(phdl_this_data, sizeof(dmdata_t)); 1916 1917 phdl_this->name = "pal: hires double interlace"; 1918 phdl_this->nominal_size.width = 640; 1919 phdl_this->nominal_size.height = 1024; 1920 phdl_this_data->max_size.width = 724; 1921 phdl_this_data->max_size.height = 1024; 1922 phdl_this_data->min_size.width = 320; 1923 phdl_this_data->min_size.height = 512; 1924 phdl_this_data->min_depth = 1; 1925 phdl_this_data->max_depth = 2; 1926 phdl_this->data = phdl_this_data; 1927 1928 phdl_this->get_monitor = cc_get_monitor; 1929 phdl_this->alloc_view = cc_alloc_view; 1930 phdl_this->get_current_view = cc_get_current_view; 1931 1932 phdl_this_data->use_colormap = cc_a2024_use_colormap; 1933 phdl_this_data->get_colormap = cc_a2024_get_colormap; 1934 phdl_this_data->alloc_colormap = cc_a2024_alloc_colormap; 1935 phdl_this_data->display_view = display_pal_hires_dlace_view; 1936 phdl_this_data->monitor = cc_monitor; 1937 1938 phdl_this_data->flags |= DMF_INTERLACE; 1939 1940 phdl_this_data->frames = pal_hires_dlace_frames; 1941 phdl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_dlace_copper_list_size * F_LACE_TOTAL); 1942 if (!phdl_this_data->frames[F_LACE_LONG]) { 1943 panic("couldn't get chipmem for copper list"); 1944 } 1945 phdl_this_data->frames[F_LACE_SHORT] = &phdl_this_data->frames[F_LACE_LONG][len]; 1946 phdl_this_data->frames[F_LACE_STORE_LONG] = &phdl_this_data->frames[F_LACE_SHORT][len]; 1947 phdl_this_data->frames[F_LACE_STORE_SHORT] = &phdl_this_data->frames[F_LACE_STORE_LONG][len]; 1948 1949 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_STORE_LONG], std_dlace_copper_list_size); 1950 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_STORE_SHORT], std_dlace_copper_list_size); 1951 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_LONG], std_dlace_copper_list_size); 1952 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_SHORT], std_dlace_copper_list_size); 1953 1954 phdl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color 1955 * composite enable, 1956 * dlace. */ 1957 phdl_this_data->std_start_x = STANDARD_VIEW_X; 1958 phdl_this_data->std_start_y = STANDARD_VIEW_Y; 1959 phdl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler; 1960 #if defined (GRF_ECS) 1961 phdl_this_data->beamcon0 = STANDARD_PAL_BEAMCON; 1962 #endif 1963 1964 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, phdl_this, link); 1965 } 1966 return (phdl_this); 1967 } 1968 1969 void 1970 display_pal_hires_dlace_view(v) 1971 view_t *v; 1972 { 1973 if (phdl_this_data->current_view != v) { 1974 vdata_t *vd = VDATA(v); 1975 monitor_t *monitor = phdl_this_data->monitor; 1976 cop_t *cp = phdl_this_data->frames[F_LACE_STORE_LONG], *tmp; 1977 int depth = v->bitmap->depth, i; 1978 int hstart, hstop, vstart, vstop, j; 1979 int x, y, w = v->display.width, h = v->display.height; 1980 u_short ddfstart, ddfwidth, con1; 1981 u_short mod1l, mod2l; 1982 1983 /* round down to nearest even width */ 1984 /* w &= 0xfffe; */ 1985 1986 /* calculate datafetch width. */ 1987 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2; 1988 1989 /* Phdl_This will center the any overscanned display */ 1990 /* and allow user to modify. */ 1991 x = v->display.x + phdl_this_data->std_start_x - ((w - 640) >> 2); 1992 y = v->display.y + phdl_this_data->std_start_y - ((h - 1024) >> 3); 1993 1994 if (y & 1) 1995 y--; 1996 1997 if (!(x & 1)) 1998 x--; 1999 2000 hstart = x; 2001 hstop = x + (w >> 1); 2002 vstart = y; 2003 vstop = y + (h >> 2); 2004 ddfstart = (hstart - 9) >> 1; 2005 2006 /* check for hardware limits, AGA may allow more..? */ 2007 /* anyone got a 4000 I can borrow :^) -ch */ 2008 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) { 2009 int d = 0; 2010 2011 /* XXX anyone know the equality properties of 2012 * intermixed logial AND's */ 2013 /* XXX and arithmetic operators? */ 2014 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) { 2015 d++; 2016 } 2017 2018 ddfstart -= d; 2019 hstart -= d << 1; 2020 hstop -= d << 1; 2021 } 2022 /* correct the datafetch to proper limits. */ 2023 /* delay the actual display of the data until we need it. */ 2024 ddfstart &= 0xfffc; 2025 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4); 2026 2027 if (phdl_this_data->current_view) { 2028 VDATA(phdl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */ 2029 /* displayed. */ 2030 } 2031 phdl_this_data->current_view = v; 2032 2033 cp = phdl_this_data->frames[F_LACE_STORE_LONG]; 2034 #if defined GRF_ECS 2035 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0)); 2036 tmp->cp.inst.operand = phdl_this_data->beamcon0; 2037 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH)); 2038 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop); 2039 #endif /* ECS */ 2040 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0)); 2041 tmp->cp.inst.operand = phdl_this_data->bplcon0 | ((depth & 0x7) << 13); /* times two. */ 2042 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1)); 2043 tmp->cp.inst.operand = con1; 2044 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART)); 2045 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff); 2046 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP)); 2047 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff); 2048 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART)); 2049 tmp->cp.inst.operand = ddfstart; 2050 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP)); 2051 tmp->cp.inst.operand = ddfstart + ddfwidth; 2052 2053 mod1l = v->bitmap->bytes_per_row + v->bitmap->row_mod; 2054 mod2l = mod1l << 1; 2055 2056 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 2057 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0])); /* update plane 2058 * pointers. */ 2059 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0])); /* high and low. */ 2060 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l])); /* update plane 2061 * pointers. */ 2062 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l])); /* high and low. */ 2063 if (depth == 2) { 2064 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0])); /* update plane 2065 * pointers. */ 2066 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0])); /* high and low. */ 2067 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l])); /* update plane 2068 * pointers. */ 2069 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l])); /* high and low. */ 2070 } 2071 /* set mods correctly. */ 2072 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD)); 2073 tmp[0].cp.inst.operand = mod2l + mod1l; 2074 tmp[1].cp.inst.operand = mod2l + mod1l; 2075 2076 /* set next pointers correctly */ 2077 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 2078 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_SHORT])); 2079 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_SHORT])); 2080 2081 bcopy(phdl_this_data->frames[F_LACE_STORE_LONG], phdl_this_data->frames[F_LACE_STORE_SHORT], std_dlace_copper_list_size); 2082 2083 /* these are the only ones that are different from long frame. */ 2084 cp = phdl_this_data->frames[F_LACE_STORE_SHORT]; 2085 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH)); 2086 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l])); /* update plane 2087 * pointers. */ 2088 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l])); /* high and low. */ 2089 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l])); /* update plane 2090 * pointers. */ 2091 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l])); /* high and low. */ 2092 if (depth == 2) { 2093 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l])); /* update plane 2094 * pointers. */ 2095 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l])); /* high and low. */ 2096 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l])); /* update plane 2097 * pointers. */ 2098 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l])); /* high and low. */ 2099 } 2100 /* set next pointers correctly */ 2101 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH)); 2102 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_LONG])); 2103 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_LONG])); 2104 2105 cp = phdl_this_data->frames[F_LACE_LONG]; 2106 phdl_this_data->frames[F_LACE_LONG] = phdl_this_data->frames[F_LACE_STORE_LONG]; 2107 phdl_this_data->frames[F_LACE_STORE_LONG] = cp; 2108 2109 cp = phdl_this_data->frames[F_LACE_SHORT]; 2110 phdl_this_data->frames[F_LACE_SHORT] = phdl_this_data->frames[F_LACE_STORE_SHORT]; 2111 phdl_this_data->frames[F_LACE_STORE_SHORT] = cp; 2112 2113 vd->flags |= VF_DISPLAY; 2114 2115 cc_a2024_use_colormap(v, vd->colormap); 2116 } 2117 cc_load_mode(phdl_this); 2118 } 2119 2120 dmode_t * 2121 cc_init_pal_a2024() 2122 { 2123 /* p24_this function should only be called once. */ 2124 if (!p24_this) { 2125 int i; 2126 u_short len = std_pal_a2024_copper_list_len; 2127 cop_t *cp; 2128 2129 p24_this = &pal_a2024_mode; 2130 p24_this_data = &pal_a2024_mode_data; 2131 bzero(p24_this, sizeof(dmode_t)); 2132 bzero(p24_this_data, sizeof(dmdata_t)); 2133 2134 p24_this->name = "pal: A2024 15khz"; 2135 p24_this->nominal_size.width = 1024; 2136 p24_this->nominal_size.height = 1024; 2137 p24_this_data->max_size.width = 1024; 2138 p24_this_data->max_size.height = 1024; 2139 p24_this_data->min_size.width = 1024; 2140 p24_this_data->min_size.height = 1024; 2141 p24_this_data->min_depth = 1; 2142 p24_this_data->max_depth = 2; 2143 p24_this->data = p24_this_data; 2144 2145 p24_this->get_monitor = cc_get_monitor; 2146 p24_this->alloc_view = cc_alloc_view; 2147 p24_this->get_current_view = cc_get_current_view; 2148 2149 p24_this_data->use_colormap = cc_a2024_use_colormap; 2150 p24_this_data->get_colormap = cc_a2024_get_colormap; 2151 p24_this_data->display_view = display_pal_a2024_view; 2152 p24_this_data->alloc_colormap = cc_a2024_alloc_colormap; 2153 p24_this_data->monitor = cc_monitor; 2154 2155 p24_this_data->flags |= DMF_HEDLEY_EXP; 2156 2157 p24_this_data->frames = pal_a2024_frames; 2158 p24_this_data->frames[F_QD_QUAD0] = alloc_chipmem(std_pal_a2024_copper_list_size * F_QD_TOTAL); 2159 if (!p24_this_data->frames[F_QD_QUAD0]) { 2160 panic("couldn't get chipmem for copper list"); 2161 } 2162 /* setup the hedley init bitplane. */ 2163 hedley_init = alloc_chipmem(128); 2164 if (!hedley_init) { 2165 panic("couldn't get chipmem for hedley init bitplane"); 2166 } 2167 for (i = 1; i < 128; i++) 2168 hedley_init[i] = 0xff; 2169 hedley_init[0] = 0x03; 2170 2171 /* copy image of standard copper list. */ 2172 bcopy(std_pal_a2024_copper_list, p24_this_data->frames[0], std_pal_a2024_copper_list_size); 2173 2174 /* set the init plane pointer. */ 2175 cp = find_copper_inst(p24_this_data->frames[F_QD_QUAD0], CI_MOVE(R_BPL0PTH)); 2176 cp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hedley_init)); 2177 cp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hedley_init)); 2178 2179 for (i = 1; i < F_QD_TOTAL; i++) { 2180 p24_this_data->frames[i] = &p24_this_data->frames[i - 1][len]; 2181 bcopy(p24_this_data->frames[0], p24_this_data->frames[i], std_pal_a2024_copper_list_size); 2182 } 2183 2184 p24_this_data->bplcon0 = 0x8200; /* hires */ 2185 p24_this_data->vbl_handler = (vbl_handler_func *) pal_a2024_mode_vbl_handler; 2186 2187 2188 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, p24_this, link); 2189 } 2190 return (p24_this); 2191 } 2192 2193 void 2194 display_pal_a2024_view(v) 2195 view_t *v; 2196 { 2197 if (p24_this_data->current_view != v) { 2198 vdata_t *vd = VDATA(v); 2199 monitor_t *monitor = p24_this_data->monitor; 2200 cop_t *cp, *tmp; 2201 u_char *inst_plane[2]; 2202 u_char **plane = inst_plane; 2203 u_long full_line = v->bitmap->bytes_per_row + v->bitmap->row_mod; 2204 u_long half_plane = full_line * v->bitmap->rows / 2; 2205 2206 int line_mod = 0xbc; /* standard 2024 15khz mod. */ 2207 int depth = v->bitmap->depth, i, j; 2208 2209 plane[0] = v->bitmap->plane[0]; 2210 if (depth == 2) { 2211 plane[1] = v->bitmap->plane[1]; 2212 } 2213 if (p24_this_data->current_view) { 2214 VDATA(p24_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer 2215 * displayed. */ 2216 } 2217 cp = p24_this_data->frames[F_QD_STORE_QUAD0]; 2218 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR1F)); 2219 tmp = find_copper_inst(tmp, CI_MOVE(R_BPLCON0)); /* grab third one. */ 2220 tmp->cp.inst.operand = p24_this_data->bplcon0 | ((depth & 0x7) << 13); /* times 2 */ 2221 2222 bcopy(p24_this_data->frames[F_QD_STORE_QUAD0], p24_this_data->frames[F_QD_STORE_QUAD1], std_pal_a2024_copper_list_size); 2223 bcopy(p24_this_data->frames[F_QD_STORE_QUAD0], p24_this_data->frames[F_QD_STORE_QUAD2], std_pal_a2024_copper_list_size); 2224 bcopy(p24_this_data->frames[F_QD_STORE_QUAD0], p24_this_data->frames[F_QD_STORE_QUAD3], std_pal_a2024_copper_list_size); 2225 2226 /* 2227 * Mark Id's 2228 */ 2229 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD1], CI_WAIT(126, 29)); 2230 CBUMP(tmp); 2231 CMOVE(tmp, R_COLOR01, QUAD1_ID); 2232 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD2], CI_WAIT(126, 29)); 2233 CBUMP(tmp); 2234 CMOVE(tmp, R_COLOR01, QUAD2_ID); 2235 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD3], CI_WAIT(126, 29)); 2236 CBUMP(tmp); 2237 CMOVE(tmp, R_COLOR01, QUAD3_ID); 2238 2239 plane[0]--; 2240 plane[0]--; 2241 if (depth == 2) { 2242 plane[1]--; 2243 plane[1]--; 2244 } 2245 /* 2246 * Set bitplane pointers. 2247 */ 2248 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD0], CI_MOVE(R_BPLMOD2)); 2249 CBUMP(tmp); 2250 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][0]))); 2251 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][0]))); 2252 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line]))); 2253 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line]))); 2254 if (depth == 2) { 2255 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][0]))); 2256 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][0]))); 2257 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line]))); 2258 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line]))); 2259 } 2260 #if defined (GRF_ECS) 2261 CMOVE(tmp, R_DIWHIGH, 0x2100); 2262 #endif 2263 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD1]))); 2264 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD1]))); 2265 CEND(tmp); 2266 CEND(tmp); 2267 2268 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD1], CI_MOVE(R_BPLMOD2)); 2269 CBUMP(tmp); 2270 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE]))); 2271 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE]))); 2272 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE]))); 2273 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE]))); 2274 if (depth == 2) { 2275 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE]))); 2276 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE]))); 2277 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE]))); 2278 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE]))); 2279 } 2280 #if defined (GRF_ECS) 2281 CMOVE(tmp, R_DIWHIGH, 0x2100); 2282 #endif 2283 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD2]))); 2284 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD2]))); 2285 CEND(tmp); 2286 CEND(tmp); 2287 2288 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD2], CI_MOVE(R_BPLMOD2)); 2289 CBUMP(tmp); 2290 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane]))); 2291 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane]))); 2292 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line]))); 2293 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line]))); 2294 if (depth == 2) { 2295 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane]))); 2296 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane]))); 2297 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line]))); 2298 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line]))); 2299 } 2300 #if defined (GRF_ECS) 2301 CMOVE(tmp, R_DIWHIGH, 0x2100); 2302 #endif 2303 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD3]))); 2304 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD3]))); 2305 CEND(tmp); 2306 CEND(tmp); 2307 2308 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD3], CI_MOVE(R_BPLMOD2)); 2309 CBUMP(tmp); 2310 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE]))); 2311 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE]))); 2312 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE]))); 2313 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE]))); 2314 if (depth == 2) { 2315 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE]))); 2316 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE]))); 2317 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE]))); 2318 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE]))); 2319 } 2320 #if defined (GRF_ECS) 2321 CMOVE(tmp, R_DIWHIGH, 0x2100); 2322 #endif 2323 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD0]))); 2324 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD0]))); 2325 CEND(tmp); 2326 CEND(tmp); 2327 2328 /* swap new pointers in. */ 2329 for (i = F_QD_STORE_QUAD0, j = F_QD_QUAD0; 2330 i <= F_QD_STORE_QUAD3; i++, j++) { 2331 cp = p24_this_data->frames[j]; 2332 p24_this_data->frames[j] = p24_this_data->frames[i]; 2333 p24_this_data->frames[i] = cp; 2334 } 2335 2336 p24_this_data->current_view = v; 2337 vd->flags |= VF_DISPLAY; 2338 2339 cc_a2024_use_colormap(v, vd->colormap); 2340 } 2341 cc_load_mode(p24_this); 2342 } 2343 2344 void 2345 pal_a2024_mode_vbl_handler(d) 2346 dmode_t *d; 2347 { 2348 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8); 2349 2350 if (vp < 20) { 2351 custom.cop1lc = PREP_DMA_MEM(p24_this_data->frames[p24_this_data->hedley_current]); 2352 custom.copjmp1 = 0; 2353 } 2354 p24_this_data->hedley_current++; 2355 p24_this_data->hedley_current &= 0x3; /* if 4 then 0. */ 2356 } 2357 #endif /* GRF_PAL */ 2358 #endif /* GRF_A2024 */ 2359