Annotation of ntddk/src/video/displays/s3/s3sup.c, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.