|
|
1.1 ! root 1: /******************************Module*Header*******************************\ ! 2: * Module Name: S3Sup.c ! 3: * ! 4: * S3 support routines. ! 5: * ! 6: * Copyright (c) 1992 Microsoft Corporation ! 7: * ! 8: \**************************************************************************/ ! 9: ! 10: #include "driver.h" ! 11: ! 12: #define TOP_CLIP 0x1 ! 13: #define LEFT_CLIP 0x2 ! 14: #define RIGHT_CLIP 0x4 ! 15: #define BOTTOM_CLIP 0x8 ! 16: ! 17: #if CATCHIT ! 18: ! 19: ULONG nOutpAccesses, ! 20: nOutpwAccesses, ! 21: nInpAccesses, ! 22: nInpwAccesses; ! 23: ! 24: #define CHIP_STATE_TEST \ ! 25: byte = inp(0x3d4); \ ! 26: outp(0x3d4, 0x39); \ ! 27: if ((inp(0x3d5) & 0xA0) != 0xA0) \ ! 28: RIP("S3.DLL! Invalid Reg 39\n"); \ ! 29: outp(0x3d4, 0x40); \ ! 30: if (!(inp(0x3d5) & 0x1)) \ ! 31: RIP("S3.DLL! Invalid Reg 40 bit 0\n"); \ ! 32: outp(0x3d4, byte); ! 33: ! 34: #else ! 35: ! 36: #if LOG_OUTS ! 37: ! 38: #define MAX_LOG 256 ! 39: ! 40: typedef struct _logentry { ! 41: WORD port, ! 42: val ; ! 43: } LOGENTRY; ! 44: ! 45: LOGENTRY aLogEntries[MAX_LOG]; ! 46: INT iCurrentLogEntry = 0; ! 47: ! 48: ! 49: #define LOG_OUTPUT \ ! 50: aLogEntries[iCurrentLogEntry].port = (WORD) port; \ ! 51: aLogEntries[iCurrentLogEntry].val = (WORD) val; \ ! 52: iCurrentLogEntry = ++iCurrentLogEntry % MAX_LOG; ! 53: ! 54: ! 55: #endif ! 56: #endif ! 57: ! 58: ! 59: BYTE Rop2ToS3Rop[] = { ! 60: LOGICAL_0, /* 0 1 */ ! 61: NOT_SCREEN_AND_NOT_NEW, /* DPon 2 */ ! 62: SCREEN_AND_NOT_NEW, /* DPna 3 */ ! 63: NOT_NEW, /* Pn 4 */ ! 64: NOT_SCREEN_AND_NEW, /* PDna 5 */ ! 65: NOT_SCREEN, /* Dn 6 */ ! 66: SCREEN_XOR_NEW, /* DPx 7 */ ! 67: NOT_SCREEN_OR_NOT_NEW, /* DPan 8 */ ! 68: SCREEN_AND_NEW, /* DPa 9 */ ! 69: NOT_SCREEN_XOR_NEW, /* DPxn 10 */ ! 70: LEAVE_ALONE, /* D 11 */ ! 71: SCREEN_OR_NOT_NEW, /* DPno 12 */ ! 72: OVERPAINT, /* P 13 */ ! 73: NOT_SCREEN_OR_NEW, /* PDno 14 */ ! 74: SCREEN_OR_NEW, /* DPo 15 */ ! 75: LOGICAL_1 /* 1 16 */ ! 76: }; ! 77: ! 78: #if defined(i386) ! 79: ! 80: /****************************************************************************\ ! 81: * vDataPortInB ! 82: \****************************************************************************/ ! 83: VOID vDataPortInB(PPDEV ppdev, PBYTE pb, UINT count) ! 84: { ! 85: ULONG pixtrans = (ULONG) (PIXEL_TRANSFER); ! 86: ! 87: _asm { ! 88: cld ! 89: ! 90: mov ecx, count ! 91: mov edi, pb ! 92: mov edx, pixtrans ! 93: ! 94: rep insb ! 95: } ! 96: } ! 97: ! 98: /***************************************************************************** ! 99: * vDataPortIn ! 100: ****************************************************************************/ ! 101: VOID vDataPortIn(PPDEV ppdev, PWORD pw, UINT count) ! 102: { ! 103: ULONG pixtrans = (ULONG) (PIXEL_TRANSFER); ! 104: ! 105: ! 106: _asm { ! 107: cld ! 108: ! 109: mov ecx, count ! 110: mov edi, pw ! 111: mov edx, pixtrans ! 112: ! 113: rep insw ! 114: } ! 115: } ! 116: ! 117: ! 118: /***************************************************************************** ! 119: * vDataPortOutB ! 120: ****************************************************************************/ ! 121: VOID vDataPortOutB(PPDEV ppdev, PBYTE pb, UINT count) ! 122: { ! 123: ULONG pixtrans = (ULONG) (PIXEL_TRANSFER); ! 124: ! 125: _asm { ! 126: cld ! 127: ! 128: mov ecx, count ! 129: mov esi, pb ! 130: mov edx, pixtrans ! 131: ! 132: rep outsb ! 133: } ! 134: } ! 135: ! 136: /***************************************************************************** ! 137: * vDataPortOut ! 138: ****************************************************************************/ ! 139: VOID vDataPortOut(PPDEV ppdev, PWORD pw, UINT count) ! 140: { ! 141: ULONG pixtrans = (ULONG) (PIXEL_TRANSFER); ! 142: ! 143: _asm { ! 144: cld ! 145: ! 146: mov ecx, count ! 147: mov esi, pw ! 148: mov edx, pixtrans ! 149: ! 150: rep outsw ! 151: } ! 152: } ! 153: ! 154: #else ! 155: ! 156: /****************************************************************************\ ! 157: * vDataPortInB ! 158: \****************************************************************************/ ! 159: VOID vDataPortInB(PPDEV ppdev, PBYTE pb, UINT count) ! 160: { ! 161: while (count-- > 0) { ! 162: *((PUCHAR)pb)++ = READ_PORT_UCHAR (gpucCsrBase + PIXEL_TRANSFER); ! 163: } ! 164: } ! 165: ! 166: /***************************************************************************** ! 167: * vDataPortIn ! 168: ****************************************************************************/ ! 169: VOID vDataPortIn(PPDEV ppdev, PWORD pw, UINT count) ! 170: { ! 171: while (count-- > 0) { ! 172: *((USHORT UNALIGNED *)pw)++ = READ_PORT_USHORT ((PUSHORT)(gpucCsrBase + PIXEL_TRANSFER)); ! 173: } ! 174: } ! 175: ! 176: ! 177: /***************************************************************************** ! 178: * vDataPortOutB ! 179: ****************************************************************************/ ! 180: VOID vDataPortOutB(PPDEV ppdev, PBYTE pb, UINT count) ! 181: { ! 182: while (count-- > 0) { ! 183: WRITE_PORT_UCHAR (gpucCsrBase + PIXEL_TRANSFER, *((PUCHAR)pb)++); ! 184: } ! 185: } ! 186: ! 187: /***************************************************************************** ! 188: * vDataPortOut ! 189: ****************************************************************************/ ! 190: VOID vDataPortOut(PPDEV ppdev, PWORD pw, UINT count) ! 191: { ! 192: while (count-- > 0) { ! 193: WRITE_PORT_USHORT ((PUSHORT)(gpucCsrBase + PIXEL_TRANSFER), *((USHORT UNALIGNED *)pw)++); ! 194: } ! 195: ! 196: } ! 197: ! 198: #endif //i386 ! 199: ! 200: /***************************************************************************** ! 201: * bIntersectTest - ! 202: ****************************************************************************/ ! 203: BOOL bIntersectTest(PRECTL prcl1, PRECTL prcl2) ! 204: { ! 205: ! 206: if ( (prcl1->left > prcl2->right) || ! 207: (prcl1->right < prcl2->left) || ! 208: (prcl1->top > prcl2->bottom) || ! 209: (prcl1->bottom < prcl2->top) ) ! 210: return(FALSE); ! 211: ! 212: return(TRUE); ! 213: } ! 214: ! 215: ! 216: /***************************************************************************** ! 217: * bTrivialAccept - Test for a trivial accept rect 1 being inside or ! 218: * coincident with rect 2. ! 219: ****************************************************************************/ ! 220: BOOL bTrivialAcceptTest(PRECTL prcl1, PRECTL prcl2) ! 221: { ! 222: ! 223: if ( (prcl1->left < prcl2->left) || ! 224: (prcl1->right > prcl2->right) || ! 225: (prcl1->top < prcl2->top) || ! 226: (prcl1->bottom > prcl2->bottom) ) ! 227: return(FALSE); ! 228: ! 229: return(TRUE); ! 230: } ! 231: ! 232: ! 233: /***************************************************************************** ! 234: * vResetS3Clipping ! 235: *****************************************************************************/ ! 236: VOID vResetS3Clipping(PPDEV ppdev) ! 237: { ! 238: RECTL rcl; ! 239: ! 240: rcl.top = 0; ! 241: rcl.left = 0; ! 242: rcl.right = S3_MAX_RAM_WIDTH; ! 243: rcl.bottom = S3_MAX_RAM_HEIGHT; ! 244: ! 245: vSetS3ClipRect(ppdev, &rcl); ! 246: } ! 247: ! 248: /***************************************************************************** ! 249: * vSetS3ClipRect ! 250: * ! 251: * Important note: GDI is inclusive/exclusive, ! 252: * the chip is inclusive/inclusive, ! 253: * and this routine does the mapping. ! 254: *****************************************************************************/ ! 255: VOID vSetS3ClipRect(PPDEV ppdev, PRECTL prclClip) ! 256: { ! 257: ULONG fl; ! 258: WORD clipcount; ! 259: ! 260: fl = 0; ! 261: clipcount = 0; ! 262: ! 263: if (ppdev->ClipTop != prclClip->top) { ! 264: fl |= TOP_CLIP; ! 265: ppdev->ClipTop = prclClip->top; ! 266: clipcount++; ! 267: } ! 268: ! 269: if (ppdev->ClipLeft != prclClip->left) { ! 270: fl |= LEFT_CLIP; ! 271: ppdev->ClipLeft = prclClip->left; ! 272: clipcount++; ! 273: } ! 274: ! 275: if (ppdev->ClipRight != prclClip->right) { ! 276: fl |= RIGHT_CLIP; ! 277: ppdev->ClipRight = prclClip->right; ! 278: clipcount++; ! 279: } ! 280: ! 281: if (ppdev->ClipBottom != prclClip->bottom) { ! 282: fl |= BOTTOM_CLIP; ! 283: ppdev->ClipBottom = prclClip->bottom; ! 284: clipcount++; ! 285: } ! 286: ! 287: if (fl == 0) ! 288: return; ! 289: #if 1 ! 290: ! 291: if (ppdev->cxScreen == ppdev->cxMaxRam) ! 292: { ! 293: if (ppdev->ClipRight > ( (LONG)(ppdev->cxScreen))) ! 294: { ! 295: RIP("S3.DLL!vSetS3ClipRect - (ppdev->ClipRight > ppdev->cxScreen)\n"); ! 296: } ! 297: } ! 298: ! 299: DISPDBG((1, "S3.DLL!vSetS3ClipRect - New Clipping %d, %d %d, %d\n", ! 300: ppdev->ClipTop, ppdev->ClipLeft, ! 301: ppdev->ClipRight, ppdev->ClipBottom)); ! 302: ! 303: #endif ! 304: ! 305: // ! 306: // Wait for the minium amount of queue entries needed ! 307: // ! 308: ! 309: clipcount = (FIFO_1_EMPTY << 1) >> clipcount; ! 310: ! 311: FIFOWAIT(clipcount); ! 312: ! 313: if (fl & TOP_CLIP) ! 314: OUTPW (MULTIFUNC_CNTL, (CLIP_TOP | ppdev->ClipTop)); ! 315: ! 316: if (fl & LEFT_CLIP) ! 317: OUTPW (MULTIFUNC_CNTL, (CLIP_LEFT | ppdev->ClipLeft)); ! 318: ! 319: if (fl & RIGHT_CLIP) ! 320: OUTPW (MULTIFUNC_CNTL, (CLIP_RIGHT | (ppdev->ClipRight - 1))); ! 321: ! 322: if (fl & BOTTOM_CLIP) ! 323: OUTPW (MULTIFUNC_CNTL, (CLIP_BOTTOM | (ppdev->ClipBottom - 1))); ! 324: } ! 325: ! 326: ! 327: #if CATCHIT ! 328: ! 329: VOID outpw_test(unsigned port , unsigned val) ! 330: { ! 331: BYTE byte; ! 332: ! 333: CHIP_STATE_TEST; ! 334: ! 335: LOGDBG((9, "Ow %lx: %lx\n", port, val)); ! 336: ! 337: nOutpwAccesses++; ! 338: ! 339: outpw(port, val); ! 340: return; ! 341: } ! 342: ! 343: ! 344: VOID outp_test(unsigned port, int val) ! 345: { ! 346: BYTE byte; ! 347: ! 348: CHIP_STATE_TEST; ! 349: ! 350: LOGDBG((9, "Ob %lx: %lx\n", port, val)); ! 351: ! 352: nOutpAccesses++; ! 353: ! 354: outp(port, val); ! 355: return; ! 356: } ! 357: ! 358: ! 359: BYTE inp_test(WORD port) ! 360: { ! 361: BYTE byte; ! 362: ! 363: CHIP_STATE_TEST; ! 364: ! 365: nInpAccesses++; ! 366: ! 367: return(inp(port)); ! 368: } ! 369: ! 370: ! 371: WORD inpw_test(WORD port) ! 372: { ! 373: BYTE byte; ! 374: ! 375: CHIP_STATE_TEST; ! 376: ! 377: nInpwAccesses++; ! 378: ! 379: return(inpw(port)); ! 380: } ! 381: ! 382: VOID vCheckDataReady(PPDEV ppdev) ! 383: { ! 384: ASSERTS3((INPW(GP_STAT) & HARDWARE_BUSY), ! 385: "S3.DLL - S3 not ready for data transfer\n"); ! 386: } ! 387: ! 388: VOID vCheckDataComplete(PPDEV ppdev) ! 389: { ! 390: LONG i; ! 391: ! 392: // We loop because it may take a while for the hardware to finish ! 393: // digesting all the data we transferred: ! 394: ! 395: for (i = 1000; i > 0; i--) ! 396: { ! 397: if (!(INPW(GP_STAT) & HARDWARE_BUSY)) ! 398: return; ! 399: } ! 400: ! 401: RIP("S3.DLL - S3 data transfer not complete\n"); ! 402: } ! 403: ! 404: #endif ! 405: ! 406: #if LOG_OUTS ! 407: ! 408: VOID outpw_log(unsigned port , unsigned val) ! 409: { ! 410: BYTE byte; ! 411: ! 412: LOG_OUTPUT; ! 413: ! 414: LOGDBG((9, "Ow %lx: %lx\n", port, val)); ! 415: ! 416: return (outpw(port, val)); ! 417: } ! 418: ! 419: ! 420: VOID outp_log(unsigned port, int val) ! 421: { ! 422: BYTE byte; ! 423: ! 424: LOG_OUTPUT; ! 425: ! 426: LOGDBG((9, "Ob %lx: %lx\n", port, val)); ! 427: ! 428: return (outp(port, val)); ! 429: } ! 430: ! 431: ! 432: #endif ! 433: ! 434: ! 435: ! 436: ! 437: #if !defined(_X86_) && !defined(i386) ! 438: ! 439: /****************************************************************************** ! 440: * vPuntGetBits - Get the bits from the device surface onto the "punt" bitmap. ! 441: *****************************************************************************/ ! 442: VOID vPuntGetBits(PPDEV ppdev, SURFOBJ *psoTrg, RECTL *prclTrg) ! 443: { ! 444: UINT i, j ; ! 445: ! 446: LONG lDestDelta, ! 447: xTrg, yTrg, ! 448: cxTrg, cyTrg ; ! 449: ! 450: PBYTE pbScan0, ! 451: pbDestRect ; ! 452: ! 453: PWORD pw ; ! 454: ! 455: WORD s3Cmd ; ! 456: ! 457: RECTL rclClip ; ! 458: ! 459: ! 460: // Default the clipping to the entire screen to get the data. ! 461: // we can over write portions of the host dest bitmap ! 462: // because we never display it, we only use this dest bitmap ! 463: // as work surface for the engine. ! 464: ! 465: rclClip.left = 0 ; ! 466: rclClip.top = 0 ; ! 467: rclClip.right = S3BM_WIDTH; ! 468: rclClip.bottom = S3BM_HEIGHT; ! 469: ! 470: vSetS3ClipRect(ppdev, &rclClip) ; ! 471: ! 472: // Calculate the size of the target rectangle, and pick up ! 473: // some convienent locals. ! 474: ! 475: pbScan0 = (PBYTE) ppdev->psoTemp->pvScan0 ; ! 476: ! 477: // The source rectangle passed into DrvCopyBits/DrvBitBlt might ! 478: // not be clipped to the visible surface (because the clip object ! 479: // would take care of that), so we have to be careful that we don't ! 480: // overwrite anything outside the visible surface: ! 481: ! 482: xTrg = max(prclTrg->left, 0) ; ! 483: yTrg = max(prclTrg->top, 0) ; ! 484: ! 485: cxTrg = min(prclTrg->right, (LONG) ppdev->cxScreen) - xTrg ; ! 486: cyTrg = min(prclTrg->bottom, (LONG) ppdev->cyScreen) - yTrg ; ! 487: ! 488: lDestDelta = ppdev->psoTemp->lDelta ; ! 489: ! 490: // Copy the target rectangle from the real screen to the ! 491: // bitmap we are telling the engine is the screen. ! 492: ! 493: // Calculate the location of the dest rect. ! 494: ! 495: pbDestRect = pbScan0 + (yTrg * lDestDelta) + xTrg ; ! 496: ! 497: // Set the S3 chip up for the copy. ! 498: ! 499: s3Cmd = RECTANGLE_FILL | BYTE_SWAP | BUS_SIZE_16 | ! 500: DRAWING_DIR_TBLRXM | DIR_TYPE_XY | WAIT | ! 501: DRAW | LAST_PIXEL_ON | READ ; ! 502: ! 503: FIFOWAIT(FIFO_6_EMPTY) ; ! 504: ! 505: outpw (MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)) ; ! 506: outpw (CUR_X, xTrg) ; ! 507: outpw (CUR_Y, yTrg) ; ! 508: outpw (RECT_WIDTH, cxTrg - 1) ; ! 509: outpw (MULTIFUNC_CNTL, (RECT_HEIGHT | (cyTrg - 1))) ; ! 510: outpw (CMD, s3Cmd) ; ! 511: ! 512: // Wait for the Data Available. ! 513: ! 514: while (!(inpw(GP_STAT) & READ_DATA_AVAILABLE)) ; ! 515: ! 516: // Now transfer the data from the screen to the host memory bitmap. ! 517: ! 518: pw = (PWORD) pbDestRect ; ! 519: j = (cxTrg + 1) / 2 ; ! 520: ! 521: for (i = 0 ; i < (UINT) cyTrg ; i++) ! 522: { ! 523: vDataPortIn(ppdev, pw, j) ; ! 524: ((PBYTE) pw) += lDestDelta ; ! 525: } ! 526: ! 527: } ! 528: ! 529: /****************************************************************************** ! 530: * vPuntPutBits - Put the bits from the "punt" bitmap to the device surface. ! 531: *****************************************************************************/ ! 532: VOID vPuntPutBits(PPDEV ppdev, SURFOBJ *psoTrg, RECTL *prclTrg) ! 533: { ! 534: UINT i, j ; ! 535: ! 536: LONG lDestDelta, ! 537: xTrg, yTrg, ! 538: cxTrg, cyTrg ; ! 539: ! 540: PBYTE pbScan0, ! 541: pbDestRect ; ! 542: ! 543: PWORD pw ; ! 544: ! 545: WORD s3Cmd ; ! 546: ! 547: // Set the clipping to exactly what we need on the destination. ! 548: ! 549: vSetS3ClipRect(ppdev, prclTrg) ; ! 550: ! 551: // Recalculate the target position(s) and extent(s) ! 552: ! 553: // The target rectangle passed into DrvCopyBits/DrvBitBlt might ! 554: // not be clipped to the visible surface (because the clip object ! 555: // would take care of that), so we have to be careful that we don't ! 556: // overwrite anything outside the visible surface: ! 557: ! 558: xTrg = max(prclTrg->left, 0) ; ! 559: yTrg = max(prclTrg->top, 0) ; ! 560: ! 561: cxTrg = min(prclTrg->right, (LONG) ppdev->cxScreen) - xTrg ; ! 562: cyTrg = min(prclTrg->bottom, (LONG) ppdev->cyScreen) - yTrg ; ! 563: ! 564: pbScan0 = (PBYTE) (ppdev->psoTemp->pvScan0) ; ! 565: lDestDelta = ppdev->psoTemp->lDelta ; ! 566: pbDestRect = pbScan0 + (yTrg * lDestDelta) + xTrg ; ! 567: ! 568: // Put the bits back on the screen. ! 569: ! 570: s3Cmd = RECTANGLE_FILL | BUS_SIZE_16 | BYTE_SWAP | WAIT | ! 571: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY | ! 572: LAST_PIXEL_ON | SINGLE_PIXEL | WRITE ; ! 573: ! 574: FIFOWAIT(FIFO_7_EMPTY) ; ! 575: ! 576: outpw(FRGD_MIX, (SRC_CPU_DATA | OVERPAINT)) ; ! 577: outpw(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)) ; ! 578: outpw (CUR_X, xTrg) ; ! 579: outpw (CUR_Y, yTrg) ; ! 580: outpw (RECT_WIDTH, cxTrg - 1) ; ! 581: outpw (MULTIFUNC_CNTL, (RECT_HEIGHT | (cyTrg - 1))) ; ! 582: outpw(CMD, s3Cmd) ; ! 583: ! 584: // Now transfer the data, from the host memory bitmap to the screen. ! 585: ! 586: pw = (PWORD) pbDestRect ; ! 587: j = (cxTrg + 1) / 2 ; ! 588: ! 589: for (i = 0 ; i < (UINT) cyTrg ; i++) ! 590: { ! 591: vDataPortOut(ppdev, pw, j) ; ! 592: ((PBYTE) pw) += lDestDelta ; ! 593: } ! 594: ! 595: return ; ! 596: } ! 597: ! 598: #endif // !defined(_X86_) && !defined(i386) ! 599:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.