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