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