1 /* NeoMagic Back End Scaler functions */ 2 /* Written by Rudolf Cornelissen 05/2002-06/2003 */ 3 4 #define MODULE_BIT 0x00000200 5 6 #include "nm_std.h" 7 8 //fixme: implement: (used for virtual screens!) 9 //void move_overlay(uint16 hdisp_start, uint16 vdisp_start); 10 11 status_t nm_configure_bes 12 (const overlay_buffer *ob, const overlay_window *ow, const overlay_view *ov, int offset) 13 { 14 /* yuy2 (4:2:2) colorspace calculations */ 15 /* Note: Some calculations will have to be modified for other colorspaces if they are incorporated. */ 16 17 /* Note: 18 * in BeOS R5.0.3 and DANO: 19 * 'ow->offset_xxx' is always 0, so not used; 20 * 'ow->width' and 'ow->height' are the output window size: does not change 21 * if window is clipping; 22 * 'ow->h_start' and 'ow->v_start' are the left-top position of the output 23 * window. These values can be negative: this means the window is clipping 24 * at the left or the top of the display, respectively. */ 25 26 /* 'ov' is the view in the source bitmap, so which part of the bitmap is actually 27 * displayed on screen. This is used for the 'hardware zoom' function. */ 28 29 /* bes setup data */ 30 nm_bes_data bi; 31 /* misc used variables */ 32 uint16 temp1, temp2; 33 /* BES output coordinate system for virtual workspaces */ 34 uint16 crtc_hstart, crtc_vstart, crtc_hend, crtc_vend; 35 /* inverse scaling factor, used for source positioning */ 36 uint32 ifactor; 37 /* copy of overlay view which has checked valid values */ 38 overlay_view my_ov; 39 40 41 /************************************************************************************** 42 *** copy, check and limit if needed the user-specified view into the intput bitmap *** 43 **************************************************************************************/ 44 my_ov = *ov; 45 /* check for valid 'coordinates' */ 46 if (my_ov.width == 0) my_ov.width++; 47 if (my_ov.height == 0) my_ov.height++; 48 if (my_ov.h_start > ((ob->width - si->overlay.myBufInfo[offset].slopspace) - 1)) 49 my_ov.h_start = ((ob->width - si->overlay.myBufInfo[offset].slopspace) - 1); 50 if (((my_ov.h_start + my_ov.width) - 1) > ((ob->width - si->overlay.myBufInfo[offset].slopspace) - 1)) 51 my_ov.width = ((((ob->width - si->overlay.myBufInfo[offset].slopspace) - 1) - my_ov.h_start) + 1); 52 if (my_ov.v_start > (ob->height - 1)) 53 my_ov.v_start = (ob->height - 1); 54 if (((my_ov.v_start + my_ov.height) - 1) > (ob->height - 1)) 55 my_ov.height = (((ob->height - 1) - my_ov.v_start) + 1); 56 57 LOG(6,("Overlay: inputbuffer view (zoom) left %d, top %d, width %d, height %d\n", 58 my_ov.h_start, my_ov.v_start, my_ov.width, my_ov.height)); 59 60 /* the BES does not respect virtual_workspaces, but adheres to CRTC 61 * constraints only */ 62 crtc_hstart = si->dm.h_display_start; 63 /* horizontal end is the first position beyond the displayed range on the CRTC */ 64 crtc_hend = crtc_hstart + si->dm.timing.h_display; 65 crtc_vstart = si->dm.v_display_start; 66 /* vertical end is the first position beyond the displayed range on the CRTC */ 67 crtc_vend = crtc_vstart + si->dm.timing.v_display; 68 69 70 /**************************************** 71 *** setup all edges of output window *** 72 ****************************************/ 73 74 /* setup left and right edges of output window */ 75 bi.hcoordv = 0; 76 /* left edge coordinate of output window, must be inside desktop */ 77 /* clipping on the left side */ 78 if (ow->h_start < crtc_hstart) 79 { 80 temp1 = 0; 81 } 82 else 83 { 84 /* clipping on the right side */ 85 if (ow->h_start >= (crtc_hend - 1)) 86 { 87 /* width < 2 is not allowed */ 88 temp1 = (crtc_hend - crtc_hstart - 2); 89 } 90 else 91 /* no clipping here */ 92 { 93 temp1 = (ow->h_start - crtc_hstart); 94 } 95 } 96 bi.hcoordv |= temp1 << 16; 97 /* right edge coordinate of output window, must be inside desktop */ 98 /* width < 2 is not allowed */ 99 if (ow->width < 2) 100 { 101 temp2 = (temp1 + 1); 102 } 103 else 104 { 105 /* clipping on the right side */ 106 if ((ow->h_start + ow->width - 1) > (crtc_hend - 1)) 107 { 108 temp2 = (crtc_hend - crtc_hstart - 1); 109 } 110 else 111 { 112 /* clipping on the left side */ 113 if ((ow->h_start + ow->width - 1) < (crtc_hstart + 1)) 114 { 115 /* width < 2 is not allowed */ 116 temp2 = 1; 117 } 118 else 119 /* no clipping here */ 120 { 121 temp2 = ((uint16)(ow->h_start + ow->width - crtc_hstart - 1)); 122 } 123 } 124 } 125 bi.hcoordv |= temp2 << 0; 126 LOG(4,("Overlay: CRTC left-edge output %d, right-edge output %d\n",temp1, temp2)); 127 128 /* setup top and bottom edges of output window */ 129 bi.vcoordv = 0; 130 /* top edge coordinate of output window, must be inside desktop */ 131 /* clipping on the top side */ 132 if (ow->v_start < crtc_vstart) 133 { 134 temp1 = 0; 135 } 136 else 137 { 138 /* clipping on the bottom side */ 139 if (ow->v_start >= (crtc_vend - 1)) 140 { 141 /* height < 2 is not allowed */ 142 temp1 = (crtc_vend - crtc_vstart - 2); 143 } 144 else 145 /* no clipping here */ 146 { 147 temp1 = (ow->v_start - crtc_vstart); 148 } 149 } 150 bi.vcoordv |= temp1 << 16; 151 /* bottom edge coordinate of output window, must be inside desktop */ 152 /* height < 2 is not allowed */ 153 if (ow->height < 2) 154 { 155 temp2 = (temp1 + 1); 156 } 157 else 158 { 159 /* clipping on the bottom side */ 160 if ((ow->v_start + ow->height - 1) > (crtc_vend - 1)) 161 { 162 temp2 = (crtc_vend - crtc_vstart - 1); 163 } 164 else 165 { 166 /* clipping on the top side */ 167 if ((ow->v_start + ow->height - 1) < (crtc_vstart + 1)) 168 { 169 /* height < 2 is not allowed */ 170 temp2 = 1; 171 } 172 else 173 /* no clipping here */ 174 { 175 temp2 = ((uint16)(ow->v_start + ow->height - crtc_vstart - 1)); 176 } 177 } 178 } 179 bi.vcoordv |= temp2 << 0; 180 LOG(4,("Overlay: CRTC top-edge output %d, bottom-edge output %d\n",temp1, temp2)); 181 182 183 /********************************************* 184 *** setup horizontal scaling and clipping *** 185 *********************************************/ 186 187 LOG(6,("Overlay: total input picture width = %d, height = %d\n", 188 (ob->width - si->overlay.myBufInfo[offset].slopspace), ob->height)); 189 LOG(6,("Overlay: output picture width = %d, height = %d\n", ow->width, ow->height)); 190 191 /* calculate inverse horizontal scaling factor, taking zoom into account */ 192 ifactor = ((((uint32)my_ov.width) << 12) / ow->width); 193 194 /* correct factor to prevent most-right visible 'line' from distorting */ 195 ifactor -= 1; 196 bi.hiscalv = ifactor; 197 LOG(4,("Overlay: horizontal scaling factor is %f\n", (float)4096 / ifactor)); 198 199 /* check scaling factor (and modify if needed) to be within scaling limits */ 200 if (((((uint32)my_ov.width) << 12) / 1024) > bi.hiscalv) 201 { 202 /* (non-inverse) factor too large, set factor to max. valid value */ 203 bi.hiscalv = ((((uint32)my_ov.width) << 12) / 1024); 204 LOG(4,("Overlay: horizontal scaling factor too large, clamping at %f\n", (float)4096 / bi.hiscalv)); 205 } 206 /* horizontal downscaling cannot be done by NM BES hardware */ 207 if (bi.hiscalv > (1 << 12)) 208 { 209 /* (non-inverse) factor too small, set factor to min. valid value */ 210 bi.hiscalv = 0x1000; 211 LOG(4,("Overlay: horizontal scaling factor too small, clamping at %f\n", (float)4096 / bi.hiscalv)); 212 } 213 214 215 /* do horizontal clipping... */ 216 /* Setup horizontal source start: first (sub)pixel contributing to output picture */ 217 /* Note: 218 * The method is to calculate, based on 1:1 scaling, based on the output window. 219 * After this is done, include the scaling factor so you get a value based on the input bitmap. 220 * Then add the left starting position of the bitmap's view (zoom function) to get the final value needed. 221 * Note: The input bitmaps slopspace is automatically excluded from the calculations this way! */ 222 /* Note also: 223 * Even if the scaling factor is clamping we instruct the BES to use the correct source start pos.! */ 224 bi.hsrcstv = 0; 225 /* check for destination horizontal clipping at left side */ 226 if (ow->h_start < crtc_hstart) 227 { 228 /* check if entire destination picture is clipping left: 229 * (2 pixels will be clamped onscreen at least) */ 230 if ((ow->h_start + ow->width - 1) < (crtc_hstart + 1)) 231 { 232 /* increase 'first contributing pixel' with 'fixed value': (total dest. width - 2) */ 233 bi.hsrcstv += (ow->width - 2); 234 } 235 else 236 { 237 /* increase 'first contributing pixel' with actual number of dest. clipping pixels */ 238 bi.hsrcstv += (crtc_hstart - ow->h_start); 239 } 240 LOG(4,("Overlay: clipping left...\n")); 241 242 /* The calculated value is based on scaling = 1x. So we now compensate for scaling. 243 * Note that this also already takes care of aligning the value to the BES register! */ 244 bi.hsrcstv *= (ifactor << 4); 245 } 246 /* take zoom into account */ 247 bi.hsrcstv += ((uint32)my_ov.h_start) << 16; 248 /* AND below required by hardware */ 249 bi.hsrcstv &= 0x03fffffc; 250 LOG(4,("Overlay: first hor. (sub)pixel of input bitmap contributing %f\n", bi.hsrcstv / (float)65536)); 251 252 253 /* Setup horizontal source end: last (sub)pixel contributing to output picture */ 254 /* Note: 255 * The method is to calculate, based on 1:1 scaling, based on the output window. 256 * After this is done, include the scaling factor so you get a value based on the input bitmap. 257 * Then add the right ending position of the bitmap's view (zoom function) to get the final value needed. */ 258 /* Note also: 259 * Even if the scaling factor is clamping we instruct the BES to use the correct source end pos.! */ 260 261 bi.hsrcendv = 0; 262 /* check for destination horizontal clipping at right side */ 263 if ((ow->h_start + ow->width - 1) > (crtc_hend - 1)) 264 { 265 /* check if entire destination picture is clipping right: 266 * (2 pixels will be clamped onscreen at least) */ 267 if (ow->h_start > (crtc_hend - 2)) 268 { 269 /* increase 'number of clipping pixels' with 'fixed value': (total dest. width - 2) */ 270 bi.hsrcendv += (ow->width - 2); 271 } 272 else 273 { 274 /* increase 'number of clipping pixels' with actual number of dest. clipping pixels */ 275 bi.hsrcendv += ((ow->h_start + ow->width - 1) - (crtc_hend - 1)); 276 } 277 LOG(4,("Overlay: clipping right...\n")); 278 279 /* The calculated value is based on scaling = 1x. So we now compensate for scaling. 280 * Note that this also already takes care of aligning the value to the BES register! */ 281 bi.hsrcendv *= (ifactor << 4); 282 /* now subtract this value from the last used pixel in (zoomed) inputbuffer, aligned to BES */ 283 bi.hsrcendv = (((uint32)((my_ov.h_start + my_ov.width) - 1)) << 16) - bi.hsrcendv; 284 } 285 else 286 { 287 /* set last contributing pixel to last used pixel in (zoomed) inputbuffer, aligned to BES */ 288 bi.hsrcendv = (((uint32)((my_ov.h_start + my_ov.width) - 1)) << 16); 289 } 290 /* AND below required by hardware */ 291 bi.hsrcendv &= 0x03fffffc; 292 LOG(4,("Overlay: last horizontal (sub)pixel of input bitmap contributing %f\n", bi.hsrcendv / (float)65536)); 293 294 295 /* setup horizontal source last position excluding slopspace: 296 * this is the last pixel that will be used for calculating interpolated pixels */ 297 bi.hsrclstv = ((ob->width - 1) - si->overlay.myBufInfo[offset].slopspace) << 16; 298 /* AND below required by hardware */ 299 bi.hsrclstv &= 0x03ff0000; 300 301 302 /******************************************* 303 *** setup vertical scaling and clipping *** 304 *******************************************/ 305 306 /* calculate inverse vertical scaling factor, taking zoom into account */ 307 ifactor = ((((uint32)my_ov.height) << 12) / ow->height); 308 309 /* correct factor to prevent lowest visible line from distorting */ 310 ifactor -= 1; 311 LOG(4,("Overlay: vertical scaling factor is %f\n", (float)4096 / ifactor)); 312 313 /* preserve ifactor for source positioning calculations later on */ 314 bi.viscalv = ifactor; 315 316 /* check scaling factor (and modify if needed) to be within scaling limits */ 317 if (((((uint32)my_ov.height) << 12) / 1024) > bi.viscalv) 318 { 319 /* (non-inverse) factor too large, set factor to max. valid value */ 320 bi.viscalv = ((((uint32)my_ov.height) << 12) / 1024); 321 LOG(4,("Overlay: vertical scaling factor too large, clamping at %f\n", (float)4096 / bi.viscalv)); 322 } 323 /* vertical downscaling cannot be done by NM BES hardware */ 324 if (bi.viscalv > (1 << 12)) 325 { 326 /* (non-inverse) factor too small, set factor to min. valid value */ 327 bi.viscalv = 0x1000; 328 LOG(4,("Overlay: vertical scaling factor too small, clamping at %f\n", (float)4096 / bi.viscalv)); 329 } 330 331 332 /* do vertical clipping... */ 333 /* Setup vertical source start: first (sub)pixel contributing to output picture. 334 * Note: this exists of two parts: 335 * 1. setup fractional part (sign is always 'positive'); 336 * 2. setup relative base_adress, taking clipping on top (and zoom) into account. 337 * Both parts are done intertwined below. */ 338 /* Note: 339 * The method is to calculate, based on 1:1 scaling, based on the output window. 340 * 'After' this is done, include the scaling factor so you get a value based on the input bitmap. 341 * Then add the top starting position of the bitmap's view (zoom function) to get the final value needed. */ 342 /* Note also: 343 * Even if the scaling factor is clamping we instruct the BES to use the correct source start pos.! */ 344 345 /* calculate relative base_adress and 'vertical weight fractional part' */ 346 bi.weight = 0; 347 bi.a1orgv = (uint32)((vuint32 *)ob->buffer); 348 bi.a1orgv -= (uint32)((vuint32 *)si->framebuffer); 349 /* calculate origin adress */ 350 LOG(4,("Overlay: topleft corner of input bitmap (cardRAM offset) $%08x\n",bi.a1orgv)); 351 /* check for destination vertical clipping at top side */ 352 if (ow->v_start < crtc_vstart) 353 { 354 /* check if entire destination picture is clipping at top: 355 * (2 pixels will be clamped onscreen at least) */ 356 if ((ow->v_start + ow->height - 1) < (crtc_vstart + 1)) 357 { 358 /* increase source buffer origin with 'fixed value': 359 * (integer part of ('total height - 2' of dest. picture in pixels * inverse scaling factor)) * 360 * bytes per row source picture */ 361 bi.weight = (ow->height - 2) * (ifactor << 4); 362 bi.a1orgv += ((bi.weight >> 16) * ob->bytes_per_row); 363 } 364 else 365 { 366 /* increase source buffer origin with: 367 * (integer part of (number of destination picture clipping pixels * inverse scaling factor)) * 368 * bytes per row source picture */ 369 bi.weight = (crtc_vstart - ow->v_start) * (ifactor << 4); 370 bi.a1orgv += ((bi.weight >> 16) * ob->bytes_per_row); 371 } 372 LOG(4,("Overlay: clipping at top...\n")); 373 } 374 /* take zoom into account */ 375 bi.a1orgv += (my_ov.v_start * ob->bytes_per_row); 376 bi.weight += (((uint32)my_ov.v_start) << 16); 377 LOG(4,("Overlay: 'contributing part of buffer' origin is (cardRAM offset) $%08x\n",bi.a1orgv)); 378 LOG(4,("Overlay: first vert. (sub)pixel of input bitmap contributing %f\n", bi.weight / (float)65536)); 379 380 /* AND below is required by NM hardware. */ 381 /* Buffer A topleft corner of field 1 (origin)(field 1 contains our full frames) */ 382 bi.a1orgv &= 0x00fffff0; 383 384 /* field 1 weight: AND below required by hardware, also make sure 'sign' is always 'positive' */ 385 bi.v1wghtv = bi.weight & 0x0000fffc; 386 387 388 /* setup field 1 (is our complete frame) vertical source last position. 389 * this is the last pixel that will be used for calculating interpolated pixels */ 390 bi.v1srclstv = (ob->height - 1); 391 /* AND below required by hardware */ 392 bi.v1srclstv &= 0x000003ff; 393 394 395 /***************************** 396 *** log color keying info *** 397 *****************************/ 398 399 LOG(6,("Overlay: key_red %d, key_green %d, key_blue %d, key_alpha %d\n", 400 ow->red.value, ow->green.value, ow->blue.value, ow->alpha.value)); 401 LOG(6,("Overlay: mask_red %d, mask_green %d, mask_blue %d, mask_alpha %d\n", 402 ow->red.mask, ow->green.mask, ow->blue.mask, ow->alpha.mask)); 403 404 405 /************************* 406 *** setup BES control *** 407 *************************/ 408 409 /* BES global control: setup functions */ 410 bi.globctlv = 0; 411 412 /* enable BES */ 413 bi.globctlv |= 1 << 0; 414 /* enable colorkeying */ 415 bi.globctlv |= 1 << 1; 416 /* b3 = 1: distorts right-half of overlay output. Keeping it zero. */ 417 /* colorspace is YV12, I420 or YUY2 (no RV15 or RV16) */ 418 bi.globctlv |= 0 << 5; 419 420 /* enable auto-alternating hardware buffers if alternating buffers is enabled (NM2160) */ 421 bi.globctlv |= 1 << 8; 422 /* ??? */ 423 bi.globctlv |= 1 << 13; 424 /* display one buffer (no alternating buffers) (NM2160: no effect) */ 425 bi.globctlv |= 0 << 14; 426 /* display frame (no field) (NM2160: no effect) */ 427 bi.globctlv |= 0 << 15; 428 429 /* BTW: horizontal and vertical filtering are always turned on in NM hardware. */ 430 431 432 /************************************* 433 *** sync to BES (Back End Scaler) *** 434 *************************************/ 435 436 /* Make sure reprogramming the BES completes before the next retrace occurs, 437 * to prevent register-update glitches (double buffer feature). */ 438 439 //fixme... 440 441 // LOG(3,("Overlay: starting register programming beyond Vcount %d\n", CR1R(VCOUNT))); 442 /* Even at 1600x1200x90Hz, a single line still takes about 9uS to complete: 443 * this resolution will generate about 180Mhz pixelclock while we can do 444 * upto 360Mhz. So snooze about 4uS to prevent bus-congestion... 445 * Appr. 200 lines time will provide enough room even on a 100Mhz CPU if it's 446 * screen is set to the highest refreshrate/resolution possible. */ 447 // while (CR1R(VCOUNT) > (si->dm.timing.v_total - 200)) snooze(4); 448 449 450 /************************************** 451 *** actually program the registers *** 452 **************************************/ 453 454 if (si->ps.card_type >= NM2097) 455 { 456 /* PCI card */ 457 LOG(4,("Overlay: accelerant is programming BES\n")); 458 /* unlock card overlay sequencer registers (b5 = 1) */ 459 PCIGRPHW(GENLOCK, (PCIGRPHR(GENLOCK) | 0x20)); 460 /* destination rectangle */ 461 PCIGRPHW(HDCOORD1L, ((bi.hcoordv >> 16) & 0xff)); 462 PCIGRPHW(HDCOORD2L, (bi.hcoordv & 0xff)); 463 PCIGRPHW(HDCOORD21H, (((bi.hcoordv >> 4) & 0xf0) | ((bi.hcoordv >> 24) & 0x0f))); 464 PCIGRPHW(VDCOORD1L, ((bi.vcoordv >> 16) & 0xff)); 465 PCIGRPHW(VDCOORD2L, (bi.vcoordv & 0xff)); 466 PCIGRPHW(VDCOORD21H, (((bi.vcoordv >> 4) & 0xf0) | ((bi.vcoordv >> 24) & 0x0f))); 467 /* scaling */ 468 PCIGRPHW(XSCALEL, (bi.hiscalv & 0xff)); 469 PCIGRPHW(XSCALEH, ((bi.hiscalv >> 8) & 0xff)); 470 PCIGRPHW(YSCALEL, (bi.viscalv & 0xff)); 471 PCIGRPHW(YSCALEH, ((bi.viscalv >> 8) & 0xff)); 472 /* inputbuffer #1 origin */ 473 /* (we don't program buffer #2 as it's unused.) */ 474 /* first include 'pixel precise' left clipping... 475 * (subpixel precision is not supported by NeoMagic cards) */ 476 bi.a1orgv += ((bi.hsrcstv >> 16) * 2); 477 /* we need to step in 4-byte (2 pixel) granularity due to the nature of yuy2 */ 478 bi.a1orgv &= ~0x03; 479 /* now setup buffer startadress and horizontal source end (minimizes used bandwidth) */ 480 if (si->ps.card_type < NM2200) 481 { 482 bi.a1orgv >>= 1; 483 /* horizontal source end does not use subpixelprecision: granularity is 8 pixels */ 484 PCIGRPHW(0xbc, (((((bi.hsrcendv >> 16) + 7) & ~8) / 8) - 1)); 485 } 486 else 487 { 488 /* horizontal source end does not use subpixelprecision: granularity is 16 pixels */ 489 //fixme? divide by 16 instead of 8 (if >= NM2200 owners report trouble then use 8!) 490 //fixme? check if overlaybuffer width should also have granularity of 16 now! 491 PCIGRPHW(0xbc, (((((bi.hsrcendv >> 16) + 15) & ~16) / 16) - 1)); 492 } 493 PCIGRPHW(BUF1ORGL, (bi.a1orgv & 0xff)); 494 PCIGRPHW(BUF1ORGM, ((bi.a1orgv >> 8) & 0xff)); 495 PCIGRPHW(BUF1ORGH, ((bi.a1orgv >> 16) & 0xff)); 496 /* b2 = 0: don't use horizontal mirroring (NM2160) */ 497 /* other bits do ??? */ 498 PCIGRPHW(0xbf, 0x02); 499 /* ??? */ 500 PCIGRPHW(0xbd, 0x02); 501 PCIGRPHW(0xbe, 0x00); 502 /* (subpixel precise) source rect clipping is not supported on NeoMagic cards; 503 * so we do 'pixel precise' left clipping via modification of buffer 504 * startadress above instead. 505 * (pixel precise top clipping is also done this way..) */ 506 //fixme: checkout real pixel precise clipping on NM2200 and later cards!!! 507 /* 508 { 509 uint16 left = 0; 510 uint16 right = 128; 511 uint16 top = 0; 512 uint16 bottom = 128; 513 514 left = (bi.hsrcstv >> 16); 515 right = (bi.hsrclstv >> 16); 516 top = (bi.weight >> 16); 517 bottom = (bi.v1srclstv >> 16); 518 519 PCISEQW(HSCOORD1L, (left & 0xff)); 520 PCISEQW(HSCOORD2L, (right & 0xff)); 521 PCISEQW(HSCOORD21H, (((right >> 4) & 0xf0) | ((left >> 8) & 0x0f))); 522 PCISEQW(VSCOORD1L, (top & 0xff)); 523 PCISEQW(VSCOORD2L, (bottom & 0xff)); 524 PCISEQW(VSCOORD21H, (((bottom >> 4) & 0xf0) | ((top >> 8) & 0x0f))); 525 } 526 */ 527 /* ??? */ 528 PCISEQW(0x1c, 0xfb); 529 PCISEQW(0x1d, 0x00); 530 PCISEQW(0x1e, 0xe2); 531 PCISEQW(0x1f, 0x02); 532 /* b1 = 0: disable alternating hardware buffers (NM2160) */ 533 /* other bits do ??? */ 534 PCISEQW(0x09, 0x11); 535 /* ??? */ 536 PCISEQW(0x0a, 0x00); 537 /* global BES control */ 538 PCIGRPHW(BESCTRL1, (bi.globctlv & 0xff)); 539 PCISEQW(BESCTRL2, ((bi.globctlv >> 8) & 0xff)); 540 541 542 /************************** 543 *** setup color keying *** 544 **************************/ 545 546 PCIGRPHW(COLKEY_R, (ow->red.value & ow->red.mask)); 547 PCIGRPHW(COLKEY_G, (ow->green.value & ow->green.mask)); 548 PCIGRPHW(COLKEY_B, (ow->blue.value & ow->blue.mask)); 549 550 551 /************************* 552 *** setup misc. stuff *** 553 *************************/ 554 555 /* setup brightness to be 'neutral' (two's complement number) */ 556 PCIGRPHW(BRIGHTNESS, 0x00); 557 558 /* setup inputbuffer #1 pitch including slopspace (in pixels) */ 559 /* (we don't program the pitch for inputbuffer #2 as it's unused.) */ 560 PCIGRPHW(BUF1PITCHL, (ob->width & 0xff)); 561 PCIGRPHW(BUF1PITCHH, ((ob->width >> 8) & 0xff)); 562 } 563 else 564 { 565 /* ISA card. Speed required, so: 566 * program entire sequence in kerneldriver in one context switch! */ 567 LOG(4,("Overlay: kerneldriver programs BES\n")); 568 569 /* complete BES info struct... */ 570 bi.card_type = si->ps.card_type; 571 bi.colkey_r = (ow->red.value & ow->red.mask); 572 bi.colkey_g = (ow->green.value & ow->green.mask); 573 bi.colkey_b = (ow->blue.value & ow->blue.mask); 574 bi.ob_width = ob->width; 575 /* ... and call kerneldriver to program the BES */ 576 bi.magic = NM_PRIVATE_DATA_MAGIC; 577 ioctl(fd, NM_PGM_BES, &bi, sizeof(bi)); 578 } 579 580 /* on a 500Mhz P3 CPU just logging a line costs 400uS (18-19 vcounts at 1024x768x60Hz)! 581 * programming the registers above actually costs 180uS here */ 582 // LOG(3,("Overlay: completed at Vcount %d\n", CR1R(VCOUNT))); 583 584 return B_OK; 585 } 586 587 status_t nm_release_bes() 588 { 589 /* setup BES control: disable scaler */ 590 if (si->ps.card_type >= NM2097) 591 { 592 /* PCI card */ 593 PCIGRPHW(BESCTRL1, 0x02); 594 PCISEQW(BESCTRL2, 0xa0); 595 } 596 else 597 { 598 /* ISA card */ 599 ISAGRPHW(BESCTRL1, 0x02); 600 ISASEQW(BESCTRL2, 0xa0); 601 } 602 603 return B_OK; 604 } 605