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

1.1       root        1: ;!!! This is all temp crap to be replaced when the blinker is written
                      2: 
                      3: ;---------------------------Module-Header------------------------------;
                      4: ; Module Name: cpybits.asm
                      5: ;
                      6: ; Copyright (c) 1992 Microsoft Corporation
                      7: ;-----------------------------------------------------------------------;
                      8:         page    ,132
                      9:         title   DrvCopyBits Support
                     10:         .386
                     11: 
                     12: ifndef  DOS_PLATFORM
                     13:         .model  small,c
                     14: else
                     15: ifdef   STD_CALL
                     16:         .model  small,c
                     17: else
                     18:         .model  small,pascal
                     19: endif;  STD_CALL
                     20: endif;  DOS_PLATFORM
                     21: 
                     22:         assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
                     23:         assume fs:nothing,gs:nothing
                     24: 
                     25:         .xlist
                     26:         include stdcall.inc             ;calling convention cmacros
                     27:         include i386\egavga.inc         ;VGA register definitions
                     28:         include i386\strucs.inc
                     29:         .list
                     30: 
                     31: 
                     32:         .data
                     33: 
                     34: ; Reuse the work area from the dib conversion code.
                     35: 
                     36: ; BUGBUG this should be allocated memory accessed via the DEVSURF, not static
                     37: 
                     38:         extrn   ajConvertBuffer:byte    ;Buffer for converting to/from display
                     39: 
                     40: ; BUGBUG this should be dynamically calculated
                     41: 
                     42: CJ_WORK_PLANE   equ     cj_max_scan+1   ;Width of each plane in ajConvertBuffer
                     43: 
                     44:         .code
                     45: 
                     46: ; ausLo16 is used to convert the low nibble of a byte into 4bpp packed pel
                     47: 
                     48: ausLo16 equ this word
                     49: 
                     50:         dw          0000h                   ;0000
                     51:         dw          0100h                   ;0001
                     52:         dw          1000h                   ;0010
                     53:         dw          1100h                   ;0011
                     54:         dw          0001h                   ;0100
                     55:         dw          0101h                   ;0101
                     56:         dw          1001h                   ;0110
                     57:         dw          1101h                   ;0111
                     58:         dw          0010h                   ;1000
                     59:         dw          0110h                   ;1001
                     60:         dw          1010h                   ;1010
                     61:         dw          1110h                   ;1011
                     62:         dw          0011h                   ;1100
                     63:         dw          0111h                   ;1101
                     64:         dw          1011h                   ;1110
                     65:         dw          1111h                   ;1111
                     66: 
                     67: ; aulHi16 is used to convert the hi nibble of a byte into 4bpp packed pel
                     68: 
                     69: aulHi16 equ this dword
                     70: 
                     71:         dd          00000000h               ;0000
                     72:         dd          01000000h               ;0001
                     73:         dd          10000000h               ;0010
                     74:         dd          11000000h               ;0011
                     75:         dd          00010000h               ;0100
                     76:         dd          01010000h               ;0101
                     77:         dd          10010000h               ;0110
                     78:         dd          11010000h               ;0111
                     79:         dd          00100000h               ;1000
                     80:         dd          01100000h               ;1001
                     81:         dd          10100000h               ;1010
                     82:         dd          11100000h               ;1011
                     83:         dd          00110000h               ;1100
                     84:         dd          01110000h               ;1101
                     85:         dd          10110000h               ;1110
                     86:         dd          11110000h               ;1111
                     87: 
                     88: ; ajRightMasks turns an exclusive bit position (0-7) into a mask of bits
                     89: ; to alter for the right hand side of the blt
                     90: 
                     91: ajRightMasks equ this byte
                     92: 
                     93:         db          11111111b               ;0 should never be used
                     94:         db          01111111b               ;1
                     95:         db          00111111b               ;2
                     96:         db          00011111b               ;3
                     97:         db          00001111b               ;4
                     98:         db          00000111b               ;5
                     99:         db          00000011b               ;6
                    100:         db          00000001b               ;7
                    101: 
                    102: ; ajLeftMasks turns a bit position (0-7) into a mask of bits to alter for
                    103: ; the left hand side of the blt
                    104: 
                    105: ajLeftMasks equ this byte
                    106: 
                    107:         db          11111111b               ;0 should never be used
                    108:         db          10000000b               ;1
                    109:         db          11000000b               ;2
                    110:         db          11100000b               ;3
                    111:         db          11110000b               ;4
                    112:         db          11111000b               ;5
                    113:         db          11111100b               ;6
                    114:         db          11111110b               ;7
                    115: 
                    116: 
                    117: CB_4BPP_SCAN    equ (CX_SCREEN_MAX / 2)     ;# bytes for a 4bpp screen scan
                    118: 
                    119: ;-----------------------------Public-Routine----------------------------;
                    120: ; vConvertVGAScan
                    121: ;
                    122: ; Converts a VGA scan into a 4bpp format with a given phase alignment,
                    123: ; and returns a pointer to the converted buffer.
                    124: ;
                    125: ; pdsurfsrc - pointer to source surface (must be VGA display memory)
                    126: ; xSrc      - X origin of the source
                    127: ; ySrc      - Y origin of the source
                    128: ; pjDstBase - Base address of the destination
                    129: ; xDst      - X origin of the destination
                    130: ; yDst      - Y origin of the destination
                    131: ; cxPels    - Number of pels in X
                    132: ; cyTotalScans - Number of scans in overall operation
                    133: ; lDelta    - Width in bytes of a destination scan
                    134: ; iFormat   - Format of destination
                    135: ; pulXlate  - Color translation vector
                    136: ;-----------------------------------------------------------------------;
                    137: 
                    138: ProcName    xxxvConvertVGA2DIB,vConvertVGA2DIB,44
                    139: 
                    140: xxxvConvertVGA2DIB proc uses esi edi ebx,\
                    141:         pdsurfsrc       :ptr DEVSURF,   \
                    142:         xSrc            :dword,         \
                    143:         ySrc            :dword,         \
                    144:         pjDstBase       :dword,         \
                    145:         xDst            :dword,         \
                    146:         yDst            :dword,         \
                    147:         cxPels          :dword,         \
                    148:         cyTotalScans    :dword,         \
                    149:         lDelta          :dword,         \
                    150:         iFormat         :dword,         \
                    151:         pulXlate        :dword
                    152: 
                    153: ;-----------------------------------------------------------------------;
                    154: ; Local variables and their meaning
                    155: ;
                    156: ; cjScreenCopy      This is the number of bytes to copy from each scan
                    157: ;                   into ajConvertBuffer.
                    158: ; jLeftMask         This is the left-hand side (lhs) mask used when copying
                    159: ;                   the converted data to the destination
                    160: ; jRightMask        This is the right-hand side (lhs) mask used when copying
                    161: ;                   the converted data to the destination
                    162: ; cRightShift       This is the number of bits that the converted data needs
                    163: ;                   to be shifted right to align with the destination.
                    164: ; cjRightShift      This is the number of bytes which must be shifted right
                    165: ;                   by cRightShift
                    166: ; cCopy             This is the number of full (e.g. not masked) bytes which
                    167: ;                   must be copied to the destination
                    168: ; pjWork            Pointer to the work area where
                    169: ;                       a)  color converted data is written into
                    170: ;                       b)  bits are phase-aligned if needed
                    171: ;                       c)  data is read from for the final copy to the DIB
                    172: ; pjSrc             Address of scan 0 in memory
                    173: ; pjDst             Address of scan 0 in memory
                    174: ; cyScans           Number of scans to do in current bank
                    175: ; ulScanWidth       Offset from start of one scan to start of next
                    176: ; ulBottomSrcScan   Bottom scan line of source rectangle (non-inclusive)
                    177: ;-----------------------------------------------------------------------;
                    178: 
                    179:         local   cjScreenCopy    :dword
                    180:         local   jLeftMask       :byte
                    181:         local   jRightMask      :byte
                    182:         local   cRightShift     :byte
                    183:         local   cjRightShift    :dword
                    184:         local   cCopy           :dword
                    185:         local   pfnXlate        :ptr
                    186:         local   pjWork          :ptr
                    187:         local   cjSkip          :dword
                    188:         local   pjSrc           :dword
                    189:         local   pjDst           :dword
                    190:         local   cyScans         :dword
                    191:         local   ulScanWidth     :dword
                    192:         local   ulBottomSrcScan :dword
                    193: 
                    194:         local   ajColorConv[16]:byte
                    195:         local   ajWork[CB_4BPP_SCAN+4]:byte
                    196:         local   aj8bpp[CX_SCREEN_MAX+8]:byte
                    197: 
                    198: 
                    199: ;----------------------------------------------------------------------;
                    200: ; Loop through source banks, copying & converting one bank at a time.
                    201: 
                    202: ; Calculate the bottom scan line of the source rectangle (non-inclusive).
                    203: 
                    204:         mov     eax,ySrc
                    205:         add     eax,cyTotalScans
                    206:         mov     ulBottomSrcScan,eax
                    207: 
                    208:         mov     ecx,pdsurfsrc           ;point to source surface
                    209:         mov     eax,[ecx].dsurf_lNextScan
                    210:         mov     ulScanWidth,eax         ;local copy of scan line width
                    211: 
                    212: ; Map in the bank containing the top scan to fill, if it's not mapped in
                    213: ; already.
                    214: 
                    215:         mov     eax,ySrc                ;top scan line of source
                    216: 
                    217:         cmp     eax,[ecx].dsurf_rcl1WindowClip.yTop ;is fill top less than
                    218:                                                     ; current bank?
                    219:         jl      short map_init_bank             ;yes, map in proper bank
                    220:         cmp     eax,[ecx].dsurf_rcl1WindowClip.yBottom ;fill top greater than
                    221:                                                        ; current bank?
                    222:         jl      short init_bank_mapped          ;no, proper bank already mapped
                    223: map_init_bank:
                    224: 
                    225: ; Map in the bank containing the top scan line of the fill.
                    226: 
                    227:         ptrCall <dword ptr [ecx].dsurf_pfnBankControl>,<ecx,eax,JustifyTop>
                    228: 
                    229: init_bank_mapped:
                    230: 
                    231: bank_loop:
                    232: 
                    233: ; Set the start address of the source bitmap.
                    234: ; Note that the start of the bitmap will change each time through the
                    235: ; bank loop, because the start of the bitmap is varied to map the
                    236: ; desired scan line to the banking window.
                    237: 
                    238:         mov     eax,pdsurfsrc           ;point to source surface
                    239:         mov     ebx,[eax].dsurf_pvBitmapStart ;start of scan 0 in bitmap
                    240:         mov     pjSrc,ebx
                    241: 
                    242: ; Set the start address of the destination bitmap.
                    243: 
                    244:         mov     ebx,pjDstBase
                    245:         mov     pjDst,ebx
                    246: 
                    247: ; Figure out how many scan lines we'll fill in the current bank.
                    248: 
                    249:         mov     ebx,ulBottomSrcScan     ;bottom of destination rectangle
                    250:         cmp     ebx,[eax].dsurf_rcl1WindowClip.yBottom
                    251:                                         ;which comes first, the bottom of the
                    252:                                         ; dest rect or the bottom of the
                    253:                                         ; current bank?
                    254:         jl      short BottomScanSet     ;fill bottom comes first, so draw to
                    255:                                         ; that; this is the last bank in fill
                    256:         mov     ebx,[eax].dsurf_rcl1WindowClip.yBottom
                    257:                                         ;bank bottom comes first; draw to
                    258:                                         ; bottom of bank
                    259: BottomScanSet:
                    260:         sub     ebx,ySrc        ;# of scans to fill in bank
                    261:         mov     cyScans,ebx
                    262:         push    ebx             ;remember # of scans in bank
                    263: 
                    264:         call    DoOneBank       ;copy and convert within the current bank
                    265: 
                    266:         pop     ebx             ;restore # of scans in bank
                    267: 
                    268:         sub     cyTotalScans,ebx        ;count off this bank's scans from total
                    269:         jz      short banks_done        ;no more scans; done
                    270:         add     yDst,ebx                ;advance to the next destination scan
                    271:                                         ; to copy to
                    272:         mov     edi,pdsurfsrc
                    273:         mov     eax,[edi].dsurf_rcl1WindowClip.yBottom
                    274:         mov     ySrc,eax                ;remember where the top of the bank
                    275:                                         ; we're about to map in is (same as
                    276:                                         ; bottom of bank we just did)
                    277: 
                    278:         ptrCall <dword ptr [edi].dsurf_pfnBankControl>,<edi,eax,JustifyTop>
                    279:                                         ;map in the bank
                    280: 
                    281:         jmp     bank_loop               ;fill the next bank
                    282: 
                    283: 
                    284: ; Done.
                    285: 
                    286:         align   4
                    287: banks_done:
                    288: 
                    289:         cRet    vConvertVGA2DIB
                    290: 
                    291: ;----------------------------------------------------------------------;
                    292: ; Copies and converts bits within a single bank.
                    293: 
                    294:         align   4
                    295: DoOneBank:
                    296: 
                    297:         cld
                    298: 
                    299: ; Compute the number of bytes to copy from the screen, and the starting
                    300: ; address of the source
                    301: 
                    302:         mov     eax,ySrc                ;Compute addr of first source scan
                    303:         mov     ebx,xSrc
                    304:         imul    eax,ulScanWidth
                    305:         mov     ecx,ebx
                    306:         shr     ebx,3
                    307:         add     eax,ebx
                    308:         add     pjSrc,eax
                    309: 
                    310: ; Compute the number of bytes to actually transfer from the screen
                    311: 
                    312:         mov     eax,cxPels              ;Compute rhs
                    313:         add     eax,ecx
                    314:         dec     eax                     ;Make rhs inclusive
                    315:         shr     ecx,3                   ;Compute byte of lhs
                    316:         shr     eax,3                   ;Compute byte of rhs
                    317:         sub     eax,ecx                 ;Compute number of bytes for copy
                    318:         inc     eax                     ;(because rhs inclusive, always inc)
                    319:         mov     cjScreenCopy,eax
                    320: 
                    321: ; Compute the address of the starting destination scan.
                    322: 
                    323:         mov     eax,yDst
                    324:         imul    lDelta
                    325:         add     pjDst,eax
                    326: 
                    327: ; Set up for the preprocess loops and invoke the correct one.  First make
                    328: ; some assumptions about defaults
                    329: 
                    330:         xor     eax,eax
                    331:         mov     cRightShift,al          ;No shifting needed
                    332:         mov     jLeftMask,al            ;No left masking needed
                    333:         mov     jRightMask,al           ;No right masking needed
                    334:         lea     eax,ajWork              ;Intermediate work area
                    335:         mov     pjWork,eax
                    336: 
                    337:         mov     esi,cxPels
                    338:         mov     ebx,xSrc
                    339:         mov     edx,xDst
                    340: 
                    341:         mov     eax,iFormat
                    342:         dec     eax
                    343:         jz      preproc_1bpp
                    344:         dec     eax
                    345:         jz      preproc_4bpp
                    346:         .errnz  BMF_1BPP-1
                    347:         .errnz  BMF_4BPP-2
                    348:         .errnz  BMF_8BPP-3
                    349: 
                    350: ; Destination is 8bpp.  Copy will be phased aligned from the conversion buffer
                    351: ; to the destination.
                    352: 
                    353: preproc_8bpp:
                    354:         add     pjDst,edx               ;Offset to first pel in DIB
                    355:         and     ebx,7                   ;Offset to first pel for final copy
                    356:         mov     cjSkip,ebx
                    357:         mov     cCopy,esi               ;Number of bytes for final copy
                    358:         lea     eax,aj8bpp              ;Intermediate work area
                    359:         mov     pjWork,eax
                    360:         mov     pfnXlate,offset FLAT:cvt_to_8bpp
                    361:         jmp     preproc_done
                    362: 
                    363: 
                    364: ; Destination is 4bpp.  Copy will either be phase aligned or be off by 4 in
                    365: ; which case we will phase align the entire buffer before copying.
                    366: 
                    367: preproc_4bpp:
                    368:         lea     eax,[esi][edx]          ;Compute rhs for later
                    369:         test    dl,1                    ;Odd if left mask needed
                    370:         jz      @F
                    371:         mov     jLeftMask,11110000b
                    372:         dec     esi                     ;One less pel in inner loop
                    373: @@:
                    374:         test    al,1                    ;Odd if right mask needed
                    375:         jz      @F
                    376:         mov     jRightMask,00001111b
                    377:         dec     esi                     ;One less pel in inner loop
                    378: @@:
                    379: 
                    380:         and     ebx,7                   ;Offset for final copy is xSrc mod 8
                    381: 
                    382: ; If the source and destination have different alignments, we'll have to
                    383: ; compute phase alignment stuff.
                    384: 
                    385:         mov     eax,ebx
                    386:         xor     eax,edx
                    387:         shr     eax,1
                    388:         jnc     @F
                    389:         mov     eax,cjScreenCopy        ;* 4 for size of data in buffer
                    390:         shl     eax,2
                    391:         inc     eax                     ;+ 1 to shift into last byte!
                    392:         mov     cjRightShift,eax
                    393:         mov     cRightShift,4           ;Shift entire buffer right 4 pels
                    394:         inc     ebx                     ;First pel just moved right
                    395: @@:
                    396: 
                    397: ; Finish calculating the other parameters
                    398: 
                    399:         shr     edx,1                   ;Offset to first pel in DIB
                    400:         add     pjDst,edx
                    401:         shr     ebx,1
                    402:         mov     cjSkip,ebx
                    403:         shr     esi,1
                    404:         mov     cCopy,esi               ;# of inner bytes for final copy
                    405: 
                    406:         mov     eax,offset FLAT:copy_to_dest;Assume no color translation needed
                    407:         cmp     pulXlate,0
                    408:         je      @F
                    409:         mov     eax,offset FLAT:cvt_to_4bpp ;Addreess of color xlate routine
                    410: @@:
                    411:         mov     pfnXlate,eax
                    412:         jmp     preproc_done
                    413: 
                    414: 
                    415: ; Destination is 1bpp.  Copy most likely will require masking and phase
                    416: ; alignment.
                    417: 
                    418: preproc_1bpp:
                    419:         mov     edi,00000007h           ;A handy mask used a lot
                    420:         xor     ecx,ecx                 ;CL = lhs mask, CH = rhs mask
                    421:         lea     eax,[esi][edx]          ;Compute rhs for later
                    422:         test    edx,edi                 ;See if partial byte
                    423:         jz      preproc_1bpp_done_lhs   ;No partial lhs byte
                    424:         mov     ecx,edx
                    425:         neg     ecx
                    426:         and     ecx,edi                 ;CL = # bits in lhs, CH = 0
                    427:         sub     esi,ecx                 ;Compute # remaining bytes
                    428:         mov     cl,ajLeftMasks[ecx]     ;Get lhs mask
                    429:         jnc     preproc_1bpp_done_lhs   ;Didn't combine into one byte
                    430:         and     eax,edi                 ;Combine rhs mask with lhs mask
                    431:         and     cl,ajRightMasks[eax]
                    432:         xor     esi,esi                 ;No more bytes
                    433:         xor     eax,eax                 ;To show no rhs
                    434:         jmp     short preproc_1bpp_have_masks
                    435: 
                    436: preproc_1bpp_done_lhs:
                    437:         and     eax,edi                 ;See if partial rhs byte
                    438:         jz      preproc_1bpp_have_masks ;No partial rhs byte
                    439:         mov     ch,ajRightMasks[eax]
                    440:         sub     esi,eax                 ;Compute # remaining bytes
                    441: 
                    442: preproc_1bpp_have_masks:
                    443:         mov     jLeftMask,cl            ;Set left and right masks
                    444:         mov     jRightMask,ch
                    445:         shr     esi,3                   ;# of inner bytes for final copy
                    446:         mov     cCopy,esi
                    447: 
                    448: ; Compute offset to first byte in destination DIB
                    449: 
                    450:         mov     eax,edx
                    451:         shr     eax,3
                    452:         add     pjDst,eax
                    453: 
                    454: ; Compute phase alignment parameters
                    455: 
                    456:         xor     ecx,ecx                 ;Assume cjSkip is 0
                    457:         and     edx,edi
                    458:         and     ebx,edi
                    459:         sub     edx,ebx                 ;Determine phase alignment
                    460:         jz      preproc_finish_1bpp     ;No phase alignment needed
                    461: 
                    462: ; We're really shifting left, so we'll set it up to shift right a lot, and
                    463: ; get the first byte of the final move from byte 1 of the work area.
                    464: 
                    465:         adc     ecx,ecx                 ;Set cjSkip = 0 or 1
                    466:         and     edx,edi                 ;3 LSBs is shift count
                    467:         mov     cRightShift,dl          ;Phase for the shift
                    468:         mov     eax,cjScreenCopy        ;Size of data in buffer
                    469:         inc     eax                     ;+ 1 to shift into last byte!
                    470:         mov     cjRightShift,eax
                    471: preproc_finish_1bpp:
                    472:         mov     cjSkip,ecx              ;No skipping needed
                    473:         mov     esi,pulXlate            ;Copy color translation table to the
                    474:         lea     edi,ajColorConv         ;  frame because we are out of regs.
                    475:         mov     ecx,16
                    476: @@:
                    477:         lodsd
                    478:         stosb
                    479:         dec     ecx
                    480:         jnz     @B
                    481: 
                    482:         mov     pfnXlate,offset FLAT:cvt_to_1bpp
                    483: 
                    484: preproc_done:
                    485: 
                    486: process_next_scan:
                    487: 
                    488:         mov     edi,offset FLAT:ajConvertBuffer
                    489:         mov     edx,EGA_BASE + GRAF_ADDR
                    490:         mov     eax,GRAF_READ_MAP
                    491: copy_next_plane:
                    492:         mov     esi,pjSrc               ;ESI --> first Source byte
                    493:         out     dx,ax                   ;Set read plane
                    494:         mov     ecx,cjScreenCopy        ;Set number of bytes to read
                    495:         mov     ebx,edi
                    496:         rep     movsb
                    497:         lea     edi,[ebx][CJ_WORK_PLANE];EDI --> next scan in convert buf
                    498:         inc     ah                      ;Set next read plane
                    499:         cmp     ah,4
                    500:         jb      copy_next_plane
                    501: 
                    502: ; The scan has been read in from the VGA.  Convert it into 4bpp format which
                    503: ; will be needed for doing the color conversion.
                    504: 
                    505:         lea     edi,ajWork              ;Convert dwords into here
                    506:         mov     esi,offset FLAT:ajConvertBuffer
                    507:         mov     ecx,cjScreenCopy        ;# of source bytes to convert
                    508: 
                    509: cvt_next_src_byte:
                    510:         xor     eax,eax
                    511:         mov     al,[esi][CJ_WORK_PLANE*3]   ;Get data for plane C3
                    512:         mov     ebx,eax
                    513:         and     ebx,00001111b
                    514:         shr     eax,4
                    515:         mov     edx,aulHi16[ebx*4]
                    516:         or      dx,ausLo16[eax*2]
                    517:         shl     edx,1
                    518:         mov     al,[esi][CJ_WORK_PLANE*2]   ;Get data for plane C2
                    519:         mov     ebx,eax
                    520:         and     ebx,00001111b
                    521:         shr     eax,4
                    522:         or      edx,aulHi16[ebx*4]
                    523:         or      dx,ausLo16[eax*2]
                    524:         shl     edx,1
                    525:         mov     al,[esi][CJ_WORK_PLANE*1]   ;Get data for plane C1
                    526:         mov     ebx,eax
                    527:         and     ebx,00001111b
                    528:         shr     eax,4
                    529:         or      edx,aulHi16[ebx*4]
                    530:         or      dx,ausLo16[eax*2]
                    531:         shl     edx,1
                    532:         lodsb                               ;Get data for plane C0
                    533:         mov     ebx,eax
                    534:         and     ebx,00001111b
                    535:         shr     eax,4
                    536:         or      edx,aulHi16[ebx*4]
                    537:         or      dx,ausLo16[eax*2]
                    538:         mov     eax,edx
                    539:         stosd                               ;8 pels down!
                    540:         dec     ecx
                    541:         jnz     cvt_next_src_byte
                    542: 
                    543: 
                    544: ; Perform the format conversion
                    545:         mov     ecx,cjScreenCopy        ;Set lopp count
                    546:         lea     esi,ajWork              ;Set source pointer
                    547:         mov     edi,pjWork              ;Set destination pointer
                    548:         mov     ebx,pulXlate            ;Set color translate vector
                    549:         xor     eax,eax                 ;Init D31:D8 to 0
                    550:         jmp     pfnXlate                ;Invoke correct conversion routine
                    551: 
                    552: ; Convert from 4bpp to 8bpp with color translation
                    553: 
                    554: cvt_to_8bpp:
                    555:         lodsb                           ;Get two nibbles worth
                    556:         mov     edx,eax
                    557:         shr     eax,4
                    558:         and     edx,00001111b
                    559:         mov     al,[ebx][eax*4]
                    560:         stosb
                    561:         mov     al,[ebx][edx*4]
                    562:         stosb
                    563:         lodsb                           ;Get two nibbles worth
                    564:         mov     edx,eax
                    565:         shr     eax,4
                    566:         and     edx,00001111b
                    567:         mov     al,[ebx][eax*4]
                    568:         stosb
                    569:         mov     al,[ebx][edx*4]
                    570:         stosb
                    571:         lodsb                           ;Get two nibbles worth
                    572:         mov     edx,eax
                    573:         shr     eax,4
                    574:         and     edx,00001111b
                    575:         mov     al,[ebx][eax*4]
                    576:         stosb
                    577:         mov     al,[ebx][edx*4]
                    578:         stosb
                    579:         lodsb                           ;Get two nibbles worth
                    580:         mov     edx,eax
                    581:         shr     eax,4
                    582:         and     edx,00001111b
                    583:         mov     al,[ebx][eax*4]
                    584:         stosb
                    585:         mov     al,[ebx][edx*4]
                    586:         stosb
                    587:         dec     ecx
                    588:         jnz     cvt_to_8bpp
                    589:         jmp     copy_to_dest
                    590: 
                    591: ; Convert from 4bpp to 4bpp with color translation.
                    592: 
                    593: cvt_to_4bpp:
                    594:         lodsb                           ;Get two nibbles worth
                    595:         mov     edx,eax
                    596:         shr     eax,4
                    597:         and     edx,00001111b
                    598:         mov     al,[ebx][eax*4]
                    599:         shl     al,4
                    600:         or      al,[ebx][edx*4]
                    601:         stosb
                    602:         lodsb                           ;Get two nibbles worth
                    603:         mov     edx,eax
                    604:         shr     eax,4
                    605:         and     edx,00001111b
                    606:         mov     al,[ebx][eax*4]
                    607:         shl     al,4
                    608:         or      al,[ebx][edx*4]
                    609:         stosb
                    610:         lodsb                           ;Get two nibbles worth
                    611:         mov     edx,eax
                    612:         shr     eax,4
                    613:         and     edx,00001111b
                    614:         mov     al,[ebx][eax*4]
                    615:         shl     al,4
                    616:         or      al,[ebx][edx*4]
                    617:         stosb
                    618:         lodsb                           ;Get two nibbles worth
                    619:         mov     edx,eax
                    620:         shr     eax,4
                    621:         and     edx,00001111b
                    622:         mov     al,[ebx][eax*4]
                    623:         shl     al,4
                    624:         or      al,[ebx][edx*4]
                    625:         stosb
                    626:         dec     ecx
                    627:         jnz     cvt_to_4bpp
                    628:         jmp     copy_to_dest
                    629: 
                    630: 
                    631: ; Convert from 4bpp to 1bpp with color translation.
                    632: 
                    633: 
                    634: cvt_to_1bpp:
                    635:         lodsb                           ;Get two nibbles worth
                    636:         mov     edx,eax
                    637:         shr     eax,4
                    638:         and     edx,00001111b
                    639:         mov     bl,ajColorConv[eax]
                    640:         shl     bl,1
                    641:         or      bl,ajColorConv[edx]
                    642:         lodsb
                    643:         mov     edx,eax
                    644:         shr     eax,4
                    645:         and     edx,00001111b
                    646:         shl     bl,1
                    647:         or      bl,ajColorConv[eax]
                    648:         shl     bl,1
                    649:         or      bl,ajColorConv[edx]
                    650:         lodsb                           ;Get two nibbles worth
                    651:         mov     edx,eax
                    652:         shr     eax,4
                    653:         and     edx,00001111b
                    654:         shl     bl,1
                    655:         or      bl,ajColorConv[eax]
                    656:         shl     bl,1
                    657:         or      bl,ajColorConv[edx]
                    658:         lodsb                           ;Get two nibbles worth
                    659:         mov     edx,eax
                    660:         shr     eax,4
                    661:         and     edx,00001111b
                    662:         shl     bl,1
                    663:         or      bl,ajColorConv[eax]
                    664:         shl     bl,1
                    665:         or      bl,ajColorConv[edx]
                    666:         mov     al,bl
                    667:         stosb
                    668:         dec     ecx
                    669:         jnz     cvt_to_1bpp
                    670: 
                    671: 
                    672: ; Copy to the destination.  This unfortunately may involve phase alignment
                    673: 
                    674: copy_to_dest:
                    675:         movzx   ecx,cRightShift
                    676:         jecxz   copy_aligned_to_dest
                    677:         mov     edi,pjWork
                    678:         mov     ebx,cjRightShift
                    679: phase_align_it:
                    680:         mov     ah,dl                   ;Get previous unused bits
                    681:         mov     al,byte ptr [edi]
                    682:         mov     dl,al
                    683:         shr     eax,cl
                    684:         stosb
                    685:         dec     ebx
                    686:         jnz     phase_align_it
                    687: 
                    688: copy_aligned_to_dest:
                    689:         mov     esi,pjWork
                    690:         add     esi,cjSkip
                    691:         mov     edi,pjDst
                    692: 
                    693:         mov     dl,jLeftMask
                    694:         or      dl,dl
                    695:         jz      @F
                    696:         lodsb
                    697:         mov     ah,byte ptr [edi]
                    698:         xor     ah,al
                    699:         and     ah,dl
                    700:         xor     al,ah
                    701:         stosb
                    702: @@:
                    703:         mov     ecx,cCopy
                    704:         rep     movsb
                    705: 
                    706:         mov     dl,jRightMask
                    707:         or      dl,dl
                    708:         jz      @F
                    709:         lodsb
                    710:         mov     ah,byte ptr [edi]
                    711:         xor     ah,al
                    712:         and     ah,dl
                    713:         xor     al,ah
                    714:         stosb
                    715: @@:
                    716: 
                    717:         mov     eax,ulScanWidth
                    718:         add     pjSrc,eax
                    719:         mov     eax,lDelta
                    720:         add     pjDst,eax
                    721:         dec     cyScans
                    722:         jnz     process_next_scan
                    723: 
                    724:         PLAIN_RET       ;we're done with this bank
                    725: 
                    726: xxxvConvertVGA2DIB endp
                    727: 
                    728:         end
                    729: 

unix.superglobalmegacorp.com

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