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