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