Annotation of ntddk/src/video/displays/vga/i386/dibs.asm, revision 1.1.1.1

1.1       root        1:         page    ,132
                      2:        title   Dib Conversions
                      3: ;---------------------------Module-Header------------------------------;
                      4: ; Module Name: dibs.asm
                      5: ;
                      6: ; Copyright (c) 1992 Microsoft Corporation
                      7: ;-----------------------------------------------------------------------;
                      8: 
                      9:         .386
                     10: 
                     11: ifndef  DOS_PLATFORM
                     12:         .model  small,c
                     13: else
                     14: ifdef   STD_CALL
                     15:         .model  small,c
                     16: else
                     17:         .model  small,pascal
                     18: endif;  STD_CALL
                     19: endif;  DOS_PLATFORM
                     20: 
                     21: 
                     22:         .xlist
                     23:         include stdcall.inc             ;calling convention cmacros
                     24: 
                     25:         include i386\cmacFLAT.inc       ; FLATland cmacros
                     26:         include i386\display.inc        ; Display specific structures
                     27:         include i386\ppc.inc            ; Pack pel conversion structure
                     28:         include i386\bitblt.inc         ; General definitions
                     29:        include i386\egavga.inc
                     30:         .list
                     31: 
                     32:         assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
                     33:         assume fs:nothing,gs:nothing
                     34: 
                     35:         EXTRNP  comp_byte_interval
                     36: 
                     37: 
                     38: ; General equates
                     39: 
                     40: ; BUGBUG this should be dynamically calculated
                     41: 
                     42: CJ_PLANE    equ     (cj_max_scan+1)          ;Extra byte makes algorithm easier
                     43: 
                     44:         .data
                     45: 
                     46: ; Define the buffer for packed-pel to planer conversion.  !!! when we do
                     47: ; conversion to planer bitmaps, this will have to come from the extra scan
                     48: ; we'll allocate in our planer color bitmaps !!!
                     49: 
                     50: ; BUGBUG this should be allocated memory accessed via the DEVSURF, not static
                     51: 
                     52:         public  ajConvertBuffer
                     53: ajConvertBuffer db      (CJ_PLANE * 4) dup (0)
                     54: 
                     55:         .code
                     56: 
                     57: _TEXT$03   SEGMENT DWORD USE32 PUBLIC 'CODE'
                     58:            ASSUME  CS:FLAT, DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
                     59: 
                     60: ; Define the default pixel mapping table.  This table will be used when
                     61: ; converting from 4bpp to planer with no color translation.
                     62: 
                     63:         align   4
                     64: 
                     65:         public  aulDefBitMapping
                     66: aulDefBitMapping equ    this dword
                     67: 
                     68:         dd      00000000000000000000000000000000b   ;0000
                     69:         dd      00000000000000000000000000000001b   ;0001
                     70:         dd      00000000000000000000000100000000b   ;0010
                     71:         dd      00000000000000000000000100000001b   ;0011
                     72:         dd      00000000000000010000000000000000b   ;0100
                     73:         dd      00000000000000010000000000000001b   ;0101
                     74:         dd      00000000000000010000000100000000b   ;0110
                     75:         dd      00000000000000010000000100000001b   ;0111
                     76:         dd      00000001000000000000000000000000b   ;1000
                     77:         dd      00000001000000000000000000000001b   ;1001
                     78:         dd      00000001000000000000000100000000b   ;1010
                     79:         dd      00000001000000000000000100000001b   ;1011
                     80:         dd      00000001000000010000000000000000b   ;1100
                     81:         dd      00000001000000010000000000000001b   ;1101
                     82:         dd      00000001000000010000000100000000b   ;1110
                     83:         dd      00000001000000010000000100000001b   ;1111
                     84: 
                     85: 
                     86: ;-----------------------------------------------------------------------;
                     87: ; vDIB4n8ToPlaner
                     88: ;
                     89: ; Converts a scan of a 4bpp or 8bpp DIB into planer format for bitblt
                     90: ;
                     91: ; Entry:
                     92: ;   EBP --> ppc structure
                     93: ; Exit:
                     94: ;   ESI --> plane 0 of scan data
                     95: ; Registers Destroyed:
                     96: ;   EAX,EBX,EDX,EBP
                     97: ; Registers Preserved:
                     98: ;   ECX,EDI
                     99: ;-----------------------------------------------------------------------;
                    100: 
                    101: ppc         equ     [ebp]
                    102: 
                    103: vDIB4n8ToPlaner proc
                    104: 
                    105:        push    ecx
                    106:        push    edi
                    107: 
                    108: ; Load up the parameters for the blt
                    109: 
                    110:         mov     esi,ppc.pSrc                ;Source pointer
                    111:         mov     eax,ppc.iNextScan           ;Index to next scan
                    112:         add     eax,esi
                    113:         mov     ppc.pSrc,eax                ;Save next source pointer
                    114:         xor     eax,eax                     ;Creating a four bit index in eax
                    115: 
                    116: ; pulXlate must be zero for 4bpp conversion since we will be using
                    117: ; ebx for creating an index.  No problem since we don't need the
                    118: ; translation by the time we're in this code.
                    119: 
                    120:         mov     ebx,ppc.pulXlate            ;Color translation or zero
                    121:         lea     edi,ajConvertBuffer         ;Where to store results
                    122: 
                    123: ; Handle a partial first byte and all full bytes
                    124: 
                    125:         mov     ecx,ppc.cLeftMiddle         ;Get loop count for middle and left
                    126:         jecxz   vDIB4n8DoneFirst            ;No first/inner
                    127:        push    ebp
                    128:         push    offset FLAT:VDIB4n8FinishFirst   ;Set return address
                    129:         push    ppc.pfnLeftMiddle           ;Set proc for left partial byte
                    130:         mov     ebp,ppc.pulConvert          ;Base address of conversion table
                    131:         xor     edx,edx                     ;Init accumulated bits
                    132:         ret                                 ;To ppc.pfnLeftMiddle
                    133: VDIB4n8FinishFirst:                         ;It returns here
                    134:        pop     ebp
                    135: 
                    136: vDIB4n8DoneFirst:
                    137:         mov     ecx,ppc.pfnRight
                    138:         jecxz   short vDIB4n8DoneRightSide  ;No left side
                    139:         and     edx,01010101h               ;Carryover from a partial 4bpp byte
                    140:        push    ebp
                    141:         push    offset FLAT:VDIB4n8FinishLast    ;Set return address
                    142:         push    ecx                         ;Set function address
                    143:         mov     ecx,1                       ;No looping
                    144:         mov     ebp,ppc.pulConvert          ;Base address of conversion table
                    145:         ret                                 ;To ppc.pfnRight
                    146: VDIB4n8FinishLast:                          ;It returns here
                    147:        pop     ebp
                    148: 
                    149:         mov     cl,ppc.cLeftShift           ;Must align right side pels
                    150:        shl     edx,cl
                    151:        mov     [edi][CJ_PLANE*0][-1],dl
                    152:         mov     [edi][CJ_PLANE*1][-1],dh
                    153:        shr     edx,16
                    154:        mov     [edi][CJ_PLANE*2][-1],dl
                    155:        mov     [edi][CJ_PLANE*3][-1],dh
                    156: 
                    157: ; Load up the source pointer and exit
                    158: 
                    159: vDIB4n8DoneRightSide:
                    160:        pop     edi
                    161:        pop     ecx
                    162:         mov     esi,ppc.pjConverted
                    163:        ret
                    164: 
                    165: vDIB4n8ToPlaner endp
                    166: 
                    167: ppc     equ     <>
                    168: 
                    169: 
                    170: ;-----------------------------------------------------------------------;
                    171: ; vDIB4Convert*
                    172: ;
                    173: ; Converts the specified number of source 4 bpp bits into the
                    174: ; buffer.  These are support routines for vDIB4Planer, where a
                    175: ; source byte converts into two aligned bits
                    176: ;
                    177: ; Entry:
                    178: ;   EAX 31:8 = 0
                    179: ;   EBP --> Bit conversion table
                    180: ;   ESI --> Source bitmap
                    181: ;   EDI --> Planer destination
                    182: ;   ECX  =  Loop count
                    183: ; Exit:
                    184: ;   EBP --> Bit conversion table
                    185: ;   ESI --> Next source byte
                    186: ;   EDI --> Next planer destination
                    187: ;   EDX  =  Last planer byte accumulated
                    188: ; Registers Destroyed:
                    189: ;   EAX,ECX,EDX
                    190: ; Registers Preserved:
                    191: ;-----------------------------------------------------------------------;
                    192: 
                    193: vDIB4Convert8::
                    194:        lodsb
                    195:        mov     ebx,eax
                    196:        shr     eax,4
                    197:         and     ebx,00001111b
                    198:        mov     edx,[ebp][eax*4]
                    199:        shl     edx,1
                    200:        or      edx,[ebp][ebx*4]
                    201: vDIB4Convert6::
                    202:        lodsb
                    203:        shl     edx,1
                    204:        mov     ebx,eax
                    205:        shr     eax,4
                    206:         and     ebx,00001111b
                    207:        or      edx,[ebp][eax*4]
                    208:        shl     edx,1
                    209:        or      edx,[ebp][ebx*4]
                    210: vDIB4Convert4::
                    211:        lodsb
                    212:        shl     edx,1
                    213:        mov     ebx,eax
                    214:        shr     eax,4
                    215:         and     ebx,00001111b
                    216:        or      edx,[ebp][eax*4]
                    217:        shl     edx,1
                    218:        or      edx,[ebp][ebx*4]
                    219: vDIB4Convert2::
                    220:        lodsb
                    221:        shl     edx,1
                    222:        mov     ebx,eax
                    223:        shr     eax,4
                    224:         and     ebx,00001111b
                    225:        or      edx,[ebp][eax*4]
                    226:        shl     edx,1
                    227:        or      edx,[ebp][ebx*4]
                    228:        mov     [edi][CJ_PLANE*0],dl
                    229:         mov     [edi][CJ_PLANE*1],dh
                    230:         ror     edx,16
                    231:        mov     [edi][CJ_PLANE*2],dl
                    232:        mov     [edi][CJ_PLANE*3],dh
                    233:        inc     edi
                    234:        dec     ecx
                    235:         jnz     vDIB4Convert8
                    236:         rol     edx,16                  ;Incase alignment of last byte
                    237:        ret
                    238: 
                    239: 
                    240: ;-----------------------------------------------------------------------;
                    241: ; vDIB4NAConvert*
                    242: ;
                    243: ; Converts the specified number of source 4 bpp bits into the
                    244: ; buffer.  These are support routines for vDIB4Planer, where a
                    245: ; source byte converts into two non-aligned bytes (we have to carry
                    246: ; a bit over into the next destination byte).
                    247: ;
                    248: ; Entry:
                    249: ;   EAX 31:8 = 0
                    250: ;   EBP --> Bit conversion table
                    251: ;   ESI --> Source bitmap
                    252: ;   EDI --> Planer destination
                    253: ;   ECX  =  Loop count
                    254: ; Exit:
                    255: ;   EBP --> Bit conversion table
                    256: ;   ESI --> Next source byte
                    257: ;   EDI --> Next planer destination
                    258: ;   EDX  =  first pel of next destination
                    259: ; Registers Destroyed:
                    260: ;   EAX,ECX,EDX
                    261: ; Registers Preserved:
                    262: ;-----------------------------------------------------------------------;
                    263: 
                    264: vDIB4NAConvert7::
                    265:        lodsb
                    266:         shl     edx,1                   ;Carry over bit from last fetch
                    267:        mov     ebx,eax
                    268:        shr     eax,4
                    269:         and     ebx,00001111b
                    270:         or      edx,[ebp][eax*4]
                    271:        shl     edx,1
                    272:        or      edx,[ebp][ebx*4]
                    273: vDIB4NAConvert5::
                    274:        lodsb
                    275:        shl     edx,1
                    276:        mov     ebx,eax
                    277:        shr     eax,4
                    278:         and     ebx,00001111b
                    279:        or      edx,[ebp][eax*4]
                    280:        shl     edx,1
                    281:        or      edx,[ebp][ebx*4]
                    282: vDIB4NAConvert3::
                    283:        lodsb
                    284:        shl     edx,1
                    285:        mov     ebx,eax
                    286:        shr     eax,4
                    287:         and     ebx,00001111b
                    288:        or      edx,[ebp][eax*4]
                    289:        shl     edx,1
                    290:        or      edx,[ebp][ebx*4]
                    291: vDIB4NAConvert1::
                    292:        lodsb
                    293:        shl     edx,1
                    294:        mov     ebx,eax
                    295:        shr     eax,4
                    296:         and     ebx,00001111b
                    297:        or      edx,[ebp][eax*4]
                    298:        mov     [edi][CJ_PLANE*0],dl
                    299:         mov     [edi][CJ_PLANE*1],dh
                    300:         shr     edx,16
                    301:        mov     [edi][CJ_PLANE*2],dl
                    302:        mov     [edi][CJ_PLANE*3],dh
                    303:        inc     edi
                    304:         mov     edx,[ebp][ebx*4]            ;Start of next destination byte
                    305:        dec     ecx
                    306:         jnz     vDIB4NAConvert7
                    307:        ret
                    308: 
                    309: ;-----------------------------------------------------------------------;
                    310: ; vDIB4NAConvert0
                    311: ;
                    312: ; Last byte code for the 4bpp non-aligned case where the data already
                    313: ; exists in EDX, but we have to increment the destination pointer since
                    314: ; vDIB4n8ToPlaner assumes we stored the data and incremented the pointer
                    315: ;
                    316: ; Entry:
                    317: ;   EDI --> destination
                    318: ; Exit:
                    319: ;   EDI  =  EDI + 1
                    320: ; Registers Destroyed:
                    321: ;   None
                    322: ; Registers Preserved:
                    323: ;   All but EDI
                    324: ;-----------------------------------------------------------------------;
                    325: 
                    326: vDIB4NAConvert0 proc
                    327: 
                    328:         inc     edi
                    329: vNOP::
                    330:         ret
                    331: 
                    332: vDIB4NAConvert0 endp
                    333: 
                    334: 
                    335: 
                    336: ;-----------------------------------------------------------------------;
                    337: ; The following table is indexed into to get the address of where to
                    338: ; enter the 4bpp conversion loops
                    339: ;-----------------------------------------------------------------------;
                    340: 
                    341: apfn4bppConvert equ this dword
                    342: 
                    343:         dd      offset FLAT:vDIB4Convert8
                    344:         dd      offset FLAT:vDIB4NAConvert7
                    345:         dd      offset FLAT:vDIB4Convert6
                    346:         dd      offset FLAT:vDIB4NAConvert5
                    347:         dd      offset FLAT:vDIB4Convert4
                    348:         dd      offset FLAT:vDIB4NAConvert3
                    349:         dd      offset FLAT:vDIB4Convert2
                    350:         dd      offset FLAT:vDIB4NAConvert1
                    351: 
                    352: ;-----------------------------------------------------------------------;
                    353: ; The following table is indexed into to get the address of where to
                    354: ; enter the 4bpp conversion loops for a partial right hand side byte
                    355: ;-----------------------------------------------------------------------;
                    356: 
                    357: apfn4bppConvertRHS  equ this dword
                    358: 
                    359:         dd      offset FLAT:vNOP            ;Should never be called
                    360:         dd      offset FLAT:vDIB4Convert6   ;Convert three more source bytes
                    361:         dd      offset FLAT:vDIB4Convert6   ;Convert three      source bytes
                    362:         dd      offset FLAT:vDIB4Convert4   ;Convert two   more source bytes
                    363:         dd      offset FLAT:vDIB4Convert4   ;Convert two        source bytes
                    364:         dd      offset FLAT:vDIB4Convert2   ;Convert one   more source byte
                    365:         dd      offset FLAT:vDIB4Convert2   ;Convert one        source byte
                    366:         dd      offset FLAT:vDIB4NAConvert0 ;Non-aligned, data in EDX already
                    367: 
                    368: ;-----------------------------------------------------------------------;
                    369: ; vDIB8Convert*
                    370: ;
                    371: ; Converts the specified number of source 8 bpp bits into the
                    372: ; buffer.  These are support routines for vDIB8Planer.
                    373: ;
                    374: ; Entry:
                    375: ;   EAX 31:8 = 0
                    376: ;   EBP --> Bit conversion table
                    377: ;   EBX --> Color translation table
                    378: ;   ESI --> Source bitmap
                    379: ;   EDI --> Planer destination
                    380: ;   ECX  =  Loop count
                    381: ; Exit:
                    382: ;   EBP --> Bit conversion table
                    383: ;   EBX --> Color translation table
                    384: ;   ESI --> Next source byte
                    385: ;   EDI --> Next planer destination
                    386: ; Registers Destroyed:
                    387: ;   EAX,ECX,EDX
                    388: ; Registers Preserved:
                    389: ;   None
                    390: ;-----------------------------------------------------------------------;
                    391: 
                    392: vDIB8Convert8::
                    393:        lodsb                           ;Get pel 1
                    394:         mov     al,[ebx][eax*4]         ;Color translation into 4 bits
                    395:        mov     edx,[ebp][eax*4]
                    396: vDIB8Convert7::
                    397:        lodsb                           ;Get pel 2
                    398:        shl     edx,1
                    399:         mov     al,[ebx][eax*4]
                    400:        or      edx,[ebp][eax*4]
                    401: vDIB8Convert6::
                    402:        lodsb                           ;Get pel 2
                    403:        shl     edx,1
                    404:         mov     al,[ebx][eax*4]
                    405:        or      edx,[ebp][eax*4]
                    406: vDIB8Convert5::
                    407:        lodsb                           ;Get pel 2
                    408:        shl     edx,1
                    409:         mov     al,[ebx][eax*4]
                    410:        or      edx,[ebp][eax*4]
                    411: vDIB8Convert4::
                    412:        lodsb                           ;Get pel 2
                    413:        shl     edx,1
                    414:         mov     al,[ebx][eax*4]
                    415:        or      edx,[ebp][eax*4]
                    416: vDIB8Convert3::
                    417:        lodsb                           ;Get pel 2
                    418:        shl     edx,1
                    419:         mov     al,[ebx][eax*4]
                    420:        or      edx,[ebp][eax*4]
                    421: vDIB8Convert2::
                    422:        lodsb                           ;Get pel 2
                    423:        shl     edx,1
                    424:         mov     al,[ebx][eax*4]
                    425:        or      edx,[ebp][eax*4]
                    426: vDIB8Convert1::
                    427:        lodsb                           ;Get pel 7
                    428:        shl     edx,1
                    429:         mov     al,[ebx][eax*4]
                    430:        or      edx,[ebp][eax*4]
                    431:        mov     [edi][CJ_PLANE*0],dl
                    432:         mov     [edi][CJ_PLANE*1],dh
                    433:         ror     edx,16
                    434:        mov     [edi][CJ_PLANE*2],dl
                    435:        mov     [edi][CJ_PLANE*3],dh
                    436:        inc     edi
                    437:        dec     ecx
                    438:         jnz     vDIB8Convert8
                    439:         rol     edx,16                  ;Incase alignment of last byte
                    440:        ret
                    441: 
                    442: ;-----------------------------------------------------------------------;
                    443: ; The following table is indexed into to get the address of where to
                    444: ; enter the 8bpp conversion loop
                    445: ;-----------------------------------------------------------------------;
                    446: 
                    447: apfn8bppConvert equ this dword
                    448:         dd      offset FLAT:vDIB8Convert8
                    449:         dd      offset FLAT:vDIB8Convert7
                    450:         dd      offset FLAT:vDIB8Convert6
                    451:         dd      offset FLAT:vDIB8Convert5
                    452:         dd      offset FLAT:vDIB8Convert4
                    453:         dd      offset FLAT:vDIB8Convert3
                    454:         dd      offset FLAT:vDIB8Convert2
                    455:         dd      offset FLAT:vDIB8Convert1
                    456: 
                    457: 
                    458: ;-----------------------------------------------------------------------;
                    459: ; vDIB8Preprocess()
                    460: ;
                    461: ; Performs whatever processing is necessary to prepare for a blt from
                    462: ; a 8bpp DIB to a planer format bitmap.
                    463: ;
                    464: ; Entry:
                    465: ;   EBP --> Bitblt frame structure
                    466: ; Exit:
                    467: ;   None
                    468: ; Registers Destroyed:
                    469: ;   EAX,EBX,ECX,EDX,ESI,EDI
                    470: ; Registers Preserved:
                    471: ;   EBP,EBX
                    472: ;-----------------------------------------------------------------------;
                    473: 
                    474: fr      equ     [ebp]
                    475: 
                    476: cProc   vDIB8Preprocess
                    477: 
                    478:         push    ebx
                    479:         mov     fr.ppcBlt.pulConvert,offset FLAT:aulDefBitMapping
                    480: 
                    481: ; Align the blt so that the blt's phase will become 0.  Both origins are
                    482: ; guaranteed to be positive and < 16 bits !!!
                    483: 
                    484:         movzx   eax,fr.DestxOrg         ;Align source and dest X origins
                    485:         mov     edx,eax
                    486:         xchg    ax,fr.SrcxOrg           ;D31:16 is zero for both
                    487:         add     eax,fr.src.lp_bits
                    488:         mov     fr.ppcBlt.pSrc,eax      ;Save address of first source pel
                    489:         and     edx,7                   ;Always start in first byte of buffer
                    490:         push    edx                     ;Save for computing loop entry
                    491:         movzx   ebx,fr.xExt             ;Compute exclusive right hand side (rhs)
                    492:         add     ebx,edx
                    493:         push    ebx                     ;Save rhs for shift count computation
                    494: 
                    495: ; comp_byte_interval returns:
                    496: ;
                    497: ;   EDI = offset to first byte to be altered in the scan
                    498: ;   ESI = inner loop count (possibly 0)
                    499: ;   AL  = first byte mask (possibly 0)
                    500: ;   AH  = last  byte mask (possibly 0)
                    501: 
                    502:         cCall   comp_byte_interval
                    503:         pop     ebx                     ;Exclusive rhs
                    504:         pop     edx                     ;Inclusive lhs
                    505: 
                    506: ; If only a partial destination byte will be altered, the mask will have
                    507: ; been returned in AL with AH and ESI 0.
                    508: 
                    509:         or      ah,ah                   ;See if only a first byte
                    510:         jnz     short @f                ;More than one byte to alter
                    511:         or      esi,esi
                    512:         jnz     @F                      ;More than a partial byte
                    513: 
                    514: ; There will only be a partial byte.  The normal flow-o-control falls apart
                    515: ; so we have to special case it.
                    516: 
                    517:         mov     fr.ppcBlt.cLeftMiddle,esi   ;No first/inner loop
                    518:         mov     eax,8
                    519:         sub     eax,ebx
                    520:         mov     fr.ppcBlt.cLeftShift,al ;Set shift count to align last byte
                    521:         mov     eax,8
                    522:         sub     ebx,edx                 ;EBX = # pels needed (<8)
                    523:         sub     eax,ebx
                    524:         mov     eax,apfn8bppConvert[eax*4]
                    525:         jmp     short v8bpp_have_last
                    526: 
                    527: @@:
                    528: 
                    529: ; More than a single byte will be written for the destination.  Compute entry
                    530: ; into the convert loop based on the destination X origin.  If the X dest
                    531: ; origin was zero, the first byte will have been combined into the inner loop
                    532: ; count
                    533: 
                    534:         cmp     al,1                    ;If partial first byte we need to bump
                    535:         cmc                             ;  the loop count by 1
                    536:         adc     esi,0
                    537:         mov     edx,apfn8bppConvert[edx*4]
                    538:         mov     al,ah                       ;Set last byte mask
                    539:         mov     fr.ppcBlt.pfnLeftMiddle,edx
                    540: v8bpp_have_first_inner:
                    541:         mov     fr.ppcBlt.cLeftMiddle,esi   ;Save innerloop count (possibly 0)
                    542: 
                    543: ; Compute the function and shift count for the last byte (if one exists)
                    544: 
                    545:         movzx   eax,al
                    546:         or      eax,eax
                    547:         jz      short v8bpp_have_last   ;No last byte, set pfn = 0
                    548:         mov     al,8                    ;D31:8 set to 0 with above movzx
                    549:         sub     eax,ebx
                    550:         and     eax,00000111b
                    551:         mov     fr.ppcBlt.cLeftShift,al ;Set shift count to align last byte
                    552:         mov     eax,apfn8bppConvert[eax*4]
                    553: v8bpp_have_last:
                    554:         mov     fr.ppcBlt.pfnRight,eax
                    555: 
                    556: ; Set the address of routine which will be called from the compiled blt
                    557: 
                    558:         mov     fr.ppcBlt.pfnConvert,offset FLAT:vDIB4n8ToPlaner
                    559:         mov     fr.ppcBlt.pjConverted,offset FLAT:ajConvertBuffer
                    560:         pop     ebx
                    561:         cRet    vDIB8Preprocess
                    562: 
                    563: endProc vDIB8Preprocess
                    564: 
                    565: 
                    566: 
                    567: ;-----------------------------------------------------------------------;
                    568: ; vDIB4Preprocess()
                    569: ;
                    570: ; Performs whatever processing is necessary to prepare for a blt from
                    571: ; a 4bpp DIB to a planer format bitmap.
                    572: ;
                    573: ; Entry:
                    574: ;   EBP --> Bitblt frame structure
                    575: ; Exit:
                    576: ;   None
                    577: ; Registers Destroyed:
                    578: ;   EAX,EBX,ECX,EDX,ESI,EDI
                    579: ; Registers Preserved:
                    580: ;   EBP,EBX
                    581: ;-----------------------------------------------------------------------;
                    582: 
                    583: fr      equ     [ebp]
                    584: 
                    585: cProc   vDIB4Preprocess
                    586: 
                    587:         push    ebx
                    588: 
                    589: ; If a color translation vector was given, generate the new bit
                    590: ; conversion array
                    591: 
                    592:         mov     eax,offset FLAT:aulDefBitMapping
                    593:         cld
                    594:         mov     esi,fr.ppcBlt.pulXlate
                    595:         or      esi,esi
                    596:         jz      vDIB4_have_mapping_array
                    597:         lea     edi,fr.aulMap
                    598:         mov     ecx,16
                    599: create_next_bit_mapping:
                    600:         lodsd
                    601:         mov     eax,aulDefBitMapping[eax*4]
                    602:         stosd
                    603:         dec     ecx
                    604:         jnz     create_next_bit_mapping
                    605:         lea     eax,[edi][-16*4]
                    606: vDIB4_have_mapping_array:
                    607:         mov     fr.ppcBlt.pulConvert,eax
                    608: 
                    609: 
                    610: ; Align the blt so that the blt's phase will become 0.  Both origins are
                    611: ; guaranteed to be positive and < 16 bits !!!
                    612: 
                    613:         movzx   eax,fr.DestxOrg         ;Align source and dest X origins
                    614:         mov     edx,eax                 ;Save for later calculations
                    615:         xchg    ax,fr.SrcxOrg           ;D31:16 is zero for both
                    616: 
                    617: ; We never want to process a partial source byte.  We will move the source
                    618: ; left if necessary, and adjust the extent if necessary.  Note that if any
                    619: ; adjustments are made, we won't fetch past the end of the source nor
                    620: ; will we write beyond the end of our buffer (since we made it big enough
                    621: ; in the first place).
                    622: 
                    623: ; We don't worry about adjusting the source origin before we save it
                    624: ; since we will be shifting it right later to round it to a byte address
                    625: 
                    626:         mov     ecx,eax
                    627:         shr     ecx,1
                    628:         add     ecx,fr.src.lp_bits
                    629:         mov     fr.ppcBlt.pSrc,ecx      ;Save address of first pel
                    630:         and     eax,1                   ;EAX = 1 if source is odd pel
                    631:         movzx   ebx,fr.xExt
                    632:         sub     edx,eax                 ;Move dest left if necessary
                    633:         add     ebx,eax                 ;Also bump extent if moved
                    634:         and     edx,7                   ;Start dest in first byte of buffer
                    635:         inc     ebx                     ;Round extent to a multiple of 2
                    636:         and     bl,11111110b
                    637:         add     ebx,edx                 ;Exclusive right hand side
                    638: 
                    639: ; A problem:  When moving the source left a pel, we can encounter a situation
                    640: ; wherein the first pel written is in bit position 0.  However, it should be
                    641: ; noted that this pel is not part of the blt, so we have to skip over the
                    642: ; byte containing it to get to the correct first pel (which will be bit 7
                    643: ; of the next byte).
                    644: 
                    645:         cmp     dl,7
                    646:         je      @F
                    647:         xor     ax,ax
                    648: @@:
                    649:         add     eax,offset FLAT:ajConvertBuffer
                    650:         mov     fr.ppcBlt.pjConverted,eax
                    651: 
                    652: ; comp_byte_interval returns:
                    653: ;
                    654: ;   EDI = offset to first byte to be altered in the scan
                    655: ;   ESI = inner loop count (possibly 0)
                    656: ;   AL  = first byte mask (possibly 0)
                    657: ;   AH  = last  byte mask (possibly 0)
                    658: 
                    659:         push    edx                     ;Save for computing loop entry
                    660:         push    ebx                     ;Save rhs for shift count computation
                    661:         cCall   comp_byte_interval
                    662:         pop     ebx                     ;Exclusive rhs
                    663:         pop     edx                     ;Inclusive lhs
                    664: 
                    665: ; If only a partial destination byte will be altered, the mask will have
                    666: ; been returned in AL with AH and ESI 0.
                    667: 
                    668:         or      ah,ah                   ;See if only a first byte
                    669:         jnz     short @f                ;More than one byte to alter
                    670:         or      esi,esi
                    671:         jnz     short @f                ;More than one byte
                    672: 
                    673: ; There will only be a partial byte.  The normal flow-o-control falls apart
                    674: ; so we have to special case it.
                    675: 
                    676:         mov     fr.ppcBlt.cLeftMiddle,esi   ;No first/inner loop
                    677:         mov     eax,8
                    678:         sub     eax,ebx
                    679:         mov     fr.ppcBlt.cLeftShift,al ;Set shift count to align last byte
                    680:         mov     eax,8
                    681:         sub     ebx,edx                 ;EBX = # pels needed (<8)
                    682:         sub     eax,ebx
                    683:         mov     eax,apfn4bppConvertRHS[eax*4]
                    684:         jmp     short v4bpp_have_last
                    685: 
                    686: @@:
                    687: 
                    688: ; More than a single byte will be written for the destination.  Compute entry
                    689: ; into the convert loop based on the destination X origin.  If the X dest
                    690: ; origin was zero, the first byte will have been combined into the inner loop
                    691: ; count
                    692: 
                    693:         cmp     al,1                    ;If partial first byte we need to bump
                    694:         cmc                             ;  the loop count by 1
                    695:         adc     esi,0
                    696:         mov     ecx,apfn4bppConvert[edx*4]
                    697:         mov     al,ah                      ;Set last byte mask
                    698:         mov     fr.ppcBlt.pfnLeftMiddle,ecx
                    699: v4bpp_have_first_inner:
                    700:         mov     fr.ppcBlt.cLeftMiddle,esi   ;Save innerloop count (possibly 0)
                    701: 
                    702: ; Compute the function and shift count for the last byte (if one exists)
                    703: 
                    704:         movzx   eax,al
                    705:         or      eax,eax
                    706:         jz      short v4bpp_have_last   ;No last byte, set pfn = 0
                    707:         mov     al,8                    ;D31:8 set to 0 with above movzx
                    708:         sub     eax,ebx
                    709:         and     eax,00000111b
                    710:         mov     fr.ppcBlt.cLeftShift,al ;Set shift count to align last byte
                    711:         mov     eax,apfn4bppConvertRHS[eax*4]
                    712: v4bpp_have_last:
                    713:         mov     fr.ppcBlt.pfnRight,eax
                    714: 
                    715: ; Set the address of the routine which will be called from the compiled blt
                    716: 
                    717:         mov     fr.ppcBlt.pfnConvert,offset FLAT:vDIB4n8ToPlaner
                    718:         pop     ebx
                    719:         cRet    vDIB4Preprocess
                    720: 
                    721: endProc vDIB4Preprocess
                    722: 
                    723: 
                    724: ;----------------------------Private-Routine----------------------------;
                    725: ; packed_pel_comp_y
                    726: ;
                    727: ; Compute y-related parameters.
                    728: ;
                    729: ; The parameters related to the Y coordinate and BLT direction
                    730: ; are computed.  The parameters include:
                    731: ;
                    732: ;      a) Index to next scan line
                    733: ;      b) Starting Y address calculation
                    734: ;      d) Index to next plane
                    735: ;
                    736: ; Entry:
                    737: ;       EBP --> Blt frame
                    738: ;      AX  =  Y coordinate
                    739: ;       ECX =  BLT direction
                    740: ;             0000 = Y+
                    741: ;             FFFF = Y-
                    742: ;      BX  =  inclusive Y extent
                    743: ; Returns:
                    744: ;       None
                    745: ; Registers Preserved:
                    746: ;       EBP,ECX,EBX,EDX
                    747: ; Registers Destroyed:
                    748: ;       EAX,ESI,EDI,flags
                    749: ; Calls:
                    750: ;      None
                    751: ; History:
                    752: ;-----------------------------------------------------------------------;
                    753: 
                    754: fr      equ     [ebp]
                    755: 
                    756: cProc   packed_pel_comp_y
                    757: 
                    758:         push    edx
                    759:         mov     fr.src.next_plane,CJ_PLANE  ;Index to next plane of data
                    760:         movsx   esi,fr.src.width_b          ;Need bmWidthBytes couple-o-times
                    761:         movzx   eax,ax
                    762:         mul     esi                         ;Compute Y address
                    763:         add     fr.ppcBlt.pSrc,eax          ;Add to base address
                    764: 
                    765:         xor     esi,ecx                     ;1's complement if Y-
                    766:         sub     esi,ecx                     ;2's complement if Y-
                    767:         mov     fr.ppcBlt.iNextScan,esi     ;Set index to next scan line
                    768:         pop     edx
                    769:         cRet    packed_pel_comp_y
                    770: 
                    771: endProc packed_pel_comp_y
                    772: 
                    773: _TEXT$03   ends
                    774: 
                    775:         end
                    776: 
                    777: 

unix.superglobalmegacorp.com

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