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

1.1       root        1: ;---------------------------Module-Header------------------------------;
                      2: ; Module Name: rleblts.asm
                      3: ;
                      4: ; Copyright (c) 1992 Microsoft Corporation
                      5: ;-----------------------------------------------------------------------;
                      6:         .386
                      7: 
                      8: ifndef  DOS_PLATFORM
                      9:         .model  small,c
                     10: else
                     11: ifdef   STD_CALL
                     12:         .model  small,c
                     13: else
                     14:         .model  small,pascal
                     15: endif;  STD_CALL
                     16: endif;  DOS_PLATFORM
                     17: 
                     18:         assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
                     19:         assume fs:nothing,gs:nothing
                     20: 
                     21:         .xlist
                     22:         include stdcall.inc             ;calling convention cmacros
                     23:         include i386\egavga.inc
                     24:         include i386\strucs.inc
                     25:         .list
                     26: 
                     27:         .code
                     28: 
                     29: ;-------------------------------Macro-----------------------------------;
                     30: ; RleSetUp
                     31: ;
                     32: ;   Set the EGA\VGA to write mode 2 (M_COLOR_WRITE).  Initialize local vars
                     33: ;
                     34: ; Entry:
                     35: ;       None
                     36: ; Returns:
                     37: ;       ESI = pointer to the source bitmap
                     38: ;
                     39: ;-----------------------------------------------------------------------;
                     40: 
                     41: RleSetUp    macro
                     42: 
                     43:         cld
                     44: 
                     45:         mov     dx,VGA_BASE + GRAF_ADDR
                     46:         mov     ax,(M_COLOR_WRITE shl 8) + GRAF_MODE
                     47:         out     dx,ax
                     48: 
                     49:         mov     esi,pRleInfo
                     50:         mov     edi,[esi].RLE_prctlTrg
                     51:         mov     eax,[edi].xLeft
                     52:         mov     xStart,eax
                     53:         mov     eax,[esi].RLE_xBegin
                     54:         mov     xCurr,eax
                     55:         mov     eax,[edi].yBottom
                     56:         dec     eax
                     57:         mov     yCurr,eax
                     58: 
                     59:         mov     eax,[esi].RLE_pulTranslate
                     60:         mov     pulXlate,eax
                     61:         mov     eax,[esi].RLE_prctlClip
                     62:         mov     prclClip,eax
                     63:         mov     eax,[esi].RLE_pjSrcBitsMax
                     64:         mov     pjSrcEnd,eax
                     65:         mov     ebx,[esi].RLE_pjTrg
                     66: 
                     67:         mov     pjDst,ebx
                     68:         mov     esi,[esi].RLE_pjSrcBits
                     69: endm
                     70: 
                     71: ;-------------------------------Macro-----------------------------------;
                     72: ; RleDelta
                     73: ;
                     74: ;   Handle the Delta case.
                     75: ;
                     76: ; Entry:
                     77: ;       ESI = pointer to the horz/vert offset of the source bitmap
                     78: ; Returns:
                     79: ;       None
                     80: ;
                     81: ;-----------------------------------------------------------------------;
                     82: 
                     83: RleDelta    macro   dest
                     84: 
                     85:         lodsw
                     86:         movzx   ecx,al
                     87:         add     xCurr,ecx               ;x adjustment
                     88: 
                     89:         movzx   eax,ah
                     90:         sub     yCurr,eax               ;y adjustment
                     91: 
                     92:         mul     lNextScan
                     93:         sub     pjDst,eax
                     94:         jmp     dest
                     95: endm
                     96: 
                     97: ;-------------------------------Macro-----------------------------------;
                     98: ; RleExit
                     99: ;
                    100: ;   Prepare the Rle routine to exit.  Set the EGA/VGA to default write
                    101: ;   mode.  Save the current status in the RleInfo so we can continue
                    102: ;   from where we left off if a complex clipping is encountered.
                    103: ;
                    104: ; Entry:
                    105: ;       ESI = pointer pass the first run above the clipping rect
                    106: ;       EBX = yCurr(y value of the first run above the clipping rect)
                    107: ;       ECX = xCurr(x value of the first run above the clipping rect)
                    108: ; Returns:
                    109: ;       None
                    110: ;
                    111: ;-----------------------------------------------------------------------;
                    112: 
                    113: RleExit macro
                    114: 
                    115:         mov     dx,VGA_BASE + GRAF_ADDR
                    116:         mov     ax,(M_PROC_WRITE shl 8) + GRAF_MODE
                    117:         out     dx,ax
                    118: 
                    119:         mov     ax,0FF00h + GRAF_BIT_MASK
                    120:         out     dx,ax                   ;no mask
                    121: 
                    122:         mov     edi,pRleInfo            ;update for next call
                    123:         dec     esi
                    124:         dec     esi
                    125:         mov     [edi].RLE_pjSrcBits,esi
                    126:         mov     esi,[edi].RLE_prctlTrg
                    127:         inc     ebx                     ;make it exclusive
                    128:         mov     [esi].yBottom,ebx
                    129:         mov     eax,pjDst
                    130:         mov     [edi].RLE_pjTrg,eax
                    131:         mov     [edi].RLE_xBegin,ecx
                    132: endm
                    133: 
                    134: ;-------------------------------Macro-----------------------------------;
                    135: ; Clip_Encoded
                    136: ;
                    137: ;   Clip the current run in encoded mode against the clipping rect.
                    138: ;
                    139: ; Entry:
                    140: ;       AH = pel color of this run
                    141: ;       AL = number of pels of this run
                    142: ; Returns:
                    143: ;       EAX = left coordinate if no clipping
                    144: ;       ECX = left coordinate of the clipped run
                    145: ;       EBX = right coordinate of the clipped run
                    146: ;
                    147: ;-----------------------------------------------------------------------;
                    148: 
                    149: Clip_Encoded    macro   done, loop_start
                    150: 
                    151:         movzx   edx,ah                  ;EDX = pel color
                    152:         movzx   eax,al                  ;EAX = number of pels
                    153:         mov     ecx,xCurr               ;ECX = left coordinate
                    154:         add     xCurr,eax               ;compute new x position
                    155:         mov     ebx,yCurr
                    156: 
                    157: ; Check if y is inside the clipping range.
                    158: 
                    159:         mov     edi,prclClip
                    160:         cmp     ebx,[edi].yTop
                    161:         jb      done
                    162:         cmp     ebx,[edi].yBottom
                    163:         jae short loop_start
                    164: 
                    165: ; Clip to the passed in clip rectangle.
                    166: 
                    167:         mov     eax,ecx
                    168:         cmp     ecx,[edi].xLeft
                    169:         jae short @F
                    170:         mov     ecx,[edi].xLeft
                    171: 
                    172: @@:
                    173:         mov     ebx,xCurr
                    174:         cmp     ebx,[edi].xRight
                    175:         jbe short @F
                    176:         mov     ebx,[edi].xRight
                    177: 
                    178: @@:
                    179:         cmp     ebx,ecx                 ;clipped out if left and right crossed
                    180:         jbe short loop_start
                    181: endm
                    182: 
                    183: ;-------------------------------Macro-----------------------------------;
                    184: ; Draw_Encoded
                    185: ;
                    186: ;   Write the current encoded run to the EGA/VGA.
                    187: ;
                    188: ; Entry:
                    189: ;       EBX = right coordinate (exclusive)
                    190: ;       ECX = left coordinate  (inclusive)
                    191: ;       EDX = pel color
                    192: ; Returns:
                    193: ;       None
                    194: ;
                    195: ;-----------------------------------------------------------------------;
                    196: 
                    197: Draw_Encoded    macro   loop_start
                    198: 
                    199:         call    comp_masks              ;compute bit masks
                    200: 
                    201:         shl     eax,8                   ;save right mask in high word
                    202:         add     edi,pjDst
                    203: 
                    204:         mov     ebx,pulXlate
                    205:         mov     ebx,[ebx][edx*4]
                    206: 
                    207:         mov     dx,VGA_BASE + GRAF_ADDR
                    208: 
                    209:         or      ah,ah                   ;AH = left mask
                    210:         jz short @F
                    211: 
                    212:         mov     al,GRAF_BIT_MASK        ;Set bitmask for altered bits
                    213:         out     dx,ax
                    214: 
                    215:         mov     al,bl                   ;write color
                    216:         xchg    [edi],al
                    217:         inc     edi                     ;update destination pointer
                    218: 
                    219: @@:
                    220:         or      ecx,ecx                 ;ECX = inner loop count
                    221:         jz short @F
                    222: 
                    223:         mov     ax,0FF00h + GRAF_BIT_MASK
                    224:         out     dx,ax                   ;no mask
                    225: 
                    226:         mov     al,bl
                    227:         rep     stosb                   ;write color
                    228: 
                    229: @@:
                    230:         shr     eax,8                   ;AH = right mask
                    231:         or      ah,ah
                    232:         jz      loop_start
                    233: 
                    234:         mov     al,GRAF_BIT_MASK        ;Set bitmask for altered bits
                    235:         out     dx,ax
                    236:         xchg    [edi],bl                ;write color
                    237: 
                    238:         jmp     loop_start
                    239: endm
                    240: 
                    241: ;-------------------------------Macro-----------------------------------;
                    242: ; Clip_Absolute
                    243: ;
                    244: ;   Clip the current run in absolute mode against the clipping rect.
                    245: ;   Compute initial bit mask and other vars for subsequent loop.
                    246: ;
                    247: ; Entry:
                    248: ;       AH = number of pels of this run
                    249: ; Returns:
                    250: ;       AL = GRAF_BIT_MASK
                    251: ;       AH = bitmap for the first pel
                    252: ;       EBX = pulXlate (pointer to the xlate table)
                    253: ;       CH = 01000001b
                    254: ;       EDI = pointer to destination byte to be altered
                    255: ;       loop_count = loop count (number of pels to be altered)
                    256: ;
                    257: ;-----------------------------------------------------------------------;
                    258: 
                    259: Clip_Absolute   macro   done,loop_end,loop_count
                    260: 
                    261:         movzx   eax,ah                  ;EAX = number of pels
                    262:         mov     ecx,xCurr               ;ECX = left coordinate
                    263:         add     xCurr,eax
                    264: 
                    265:         mov     ebx,yCurr
                    266: 
                    267: ; Check if y is inside the clipping range.
                    268: 
                    269:         mov     edi,prclClip
                    270:         cmp     ebx,[edi].yTop
                    271:         jb      done
                    272:         cmp     ebx,[edi].yBottom
                    273:         jae     loop_end
                    274: 
                    275: ; Check if x is inside the clipping range.
                    276: 
                    277:         cmp     ecx,[edi].xRight        ;check if x is in range
                    278:         jae     loop_end
                    279: 
                    280:         mov     ebx,xCurr               ;EBX = right coordinate
                    281:         cmp     ebx,[edi].xLeft         ;can I not jump???!!!
                    282:         jbe     loop_end
                    283: 
                    284: ; Clip to the passed in clip rectangle.
                    285: 
                    286:         cmp     ecx,[edi].xLeft
                    287:         mov     cPreSrcAdv,0
                    288:         jae short @F
                    289:         mov     eax,[edi].xLeft
                    290:         sub     eax,ecx                 ;diff of left coor and prclClip->xLeft
                    291:         mov     cPreSrcAdv,eax
                    292:         add     ecx,eax                 ;ECX = left coordinate = prclClip->xLeft
                    293: 
                    294: @@:
                    295:         xor     eax,eax                 ;diff of right coor and prclClip->xRight
                    296:         cmp     ebx,[edi].xRight
                    297:         jbe short @F
                    298:         mov     eax,ebx
                    299:         mov     ebx,[edi].xRight        ;EBX = right coor = prclClip->xRight
                    300:         sub     eax,ebx
                    301: 
                    302: @@:
                    303:         mov     cPostSrcAdv,eax
                    304:         sub     ebx,ecx                 ;loop count
                    305: 
                    306:         mov     edi,ecx
                    307:         shr     edi,3
                    308:         add     edi,pjDst               ;point to the first byte to write
                    309: 
                    310:         and     ecx,00000111b           ;Compute bit index for left side
                    311:         mov     ah,080h                 ;Compute bit mask
                    312:         shr     ah,cl                   ;AL = first pel bit mask
                    313:         mov     al,GRAF_BIT_MASK
                    314:         mov     loop_count,bl           ;loop count < 0FFh
                    315:         mov     ch,01000001b            ;for later use
                    316:         mov     ebx,pulXlate
                    317: endm
                    318: 
                    319: ;-------------------------------Macro-----------------------------------;
                    320: ; RleEOL
                    321: ;
                    322: ;   Handle the End of line case.
                    323: ;
                    324: ; Entry:
                    325: ;       None.
                    326: ; Returns:
                    327: ;       None.
                    328: ;
                    329: ;-----------------------------------------------------------------------;
                    330: 
                    331: RleEOL  macro   loop_start
                    332: 
                    333:         mov     eax,lNextScan
                    334:         sub     pjDst,eax               ;adjust pjDst
                    335:         dec     yCurr                   ;adjust yCurr
                    336:         mov     eax,xStart              ;adjust xCurr
                    337:         mov     xCurr,eax
                    338:         jmp     loop_start
                    339: endm
                    340: 
                    341: 
                    342: ;-------------------------------Macro-----------------------------------;
                    343: ; Set up banking-related variables, and make sure the bank for the
                    344: ; initial (bottom) scan line is mapped in.
                    345: ;
                    346: ; Entry:
                    347: ;       None.
                    348: ; Returns:
                    349: ;       EBX = pdsurf
                    350: ;       ESI = pRleInfo
                    351: ;       EDI = RLE_prctlClip
                    352: ;
                    353: ;-------------------------------Macro-----------------------------------;
                    354: 
                    355: RleBankSetUp macro
                    356:         local   map_bank,bank_mapped
                    357: 
                    358:         mov     esi,pRleInfo
                    359:         mov     ebx,[esi].Rle_pdsurfTrg
                    360:         mov     pdsurf,ebx
                    361: 
                    362:         mov     eax,[ebx].dsurf_lNextScan
                    363:         mov     lNextScan,eax
                    364: 
                    365:         mov     edi,[esi].RLE_prctlClip
                    366:         mov     eax,[edi].yTop
                    367:         mov     ulTrueClipTop,eax       ;we blt until we reach this scan line
                    368: 
                    369: ; Map in the bottom scan line of the clip rect.
                    370: 
                    371:         mov     eax,[edi].yBottom       ;bottom clip scan, exclusive
                    372:         dec     eax                     ;make it inclusive
                    373:         cmp     eax,[ebx].dsurf_rcl1WindowClip.yTop
                    374:         jl      short map_bank
                    375:         cmp     eax,[ebx].dsurf_rcl1WindowClip.yBottom
                    376:         jl      short bank_mapped
                    377: map_bank:
                    378:         ptrCall <dword ptr [ebx].dsurf_pfnBankControl>,<ebx,eax,JustifyBottom>
                    379: bank_mapped:
                    380: 
                    381:         endm
                    382: 
                    383: 
                    384: ;-------------------------------Macro-----------------------------------;
                    385: ; Set up the screen pointer and clip the clip rect to the current bank.
                    386: ;
                    387: ; Entry:
                    388: ;       EBX = pdsurf
                    389: ;       ESI = pRleInfo
                    390: ;       EDI = RLE_prctlClip
                    391: ; Returns:
                    392: ;       None.
                    393: ;
                    394: ;-------------------------------Macro-----------------------------------;
                    395: 
                    396: RleBankTop macro
                    397: 
                    398: ; Convert the screen pointer from an offset within the bitmap to a virtual
                    399: ; address.
                    400: 
                    401:         mov     eax,[ebx].dsurf_pvBitmapStart
                    402:         add     [esi].RLE_pjTrg,eax
                    403: 
                    404: ; Set the clip rect top to MAX(top_of_bank,top_of_clip), to confine drawing to
                    405: ; this bank.
                    406: 
                    407:         mov     eax,[ebx].dsurf_rcl1WindowClip.yTop
                    408:         cmp     ulTrueClipTop,eax
                    409:         jl      short @F
                    410:         mov     eax,ulTrueClipTop
                    411: @@:
                    412:         mov     [edi].yTop,eax
                    413: 
                    414:         endm
                    415: 
                    416: 
                    417: ;-------------------------------Macro-----------------------------------;
                    418: ; Check whether we've done the last bank spanned by this clip rect; exit
                    419: ; if so, map in the bank and continue if not.
                    420: ;
                    421: ; Entry:
                    422: ;       None.
                    423: ; Returns:
                    424: ;       EBX = pdsurf
                    425: ;       ESI = pRleInfo
                    426: ;       EDI = RLE_prctlClip
                    427: ;
                    428: ;-------------------------------Macro-----------------------------------;
                    429: 
                    430: RleBankBottom macro     loop_top,done
                    431: 
                    432: ; Convert the screen pointer back to an offset within the bitmap.
                    433: 
                    434:         mov     ebx,pdsurf
                    435:         mov     esi,pRleInfo
                    436:         mov     eax,[ebx].dsurf_pvBitmapStart
                    437:         sub     [esi].RLE_pjTrg,eax
                    438: 
                    439: ; Have we reached the top bank involved in this blt? If so, done; if not, map
                    440: ; it in and blt the next bank.
                    441: 
                    442:         mov     eax,[ebx].dsurf_rcl1WindowClip.yTop
                    443:         cmp     eax,ulTrueClipTop
                    444:         jle     &done
                    445:         dec     eax     ;map in the bank above the current one
                    446:         ptrCall <dword ptr [ebx].dsurf_pfnBankControl>,<ebx,eax,JustifyBottom>
                    447: 
                    448:         mov     edi,[esi].RLE_prctlClip ;for RleBankTop
                    449: 
                    450:         jmp     &loop_top
                    451: 
                    452:         endm
                    453: 
                    454: 
                    455: ;--------------------------Public-Routine-------------------------------;
                    456: ; vRle8ToVga
                    457: ;
                    458: ;   Write an RLE8 bitmap onto the VGA device.
                    459: ;
                    460: ; Entry:
                    461: ;       None.
                    462: ; Returns:
                    463: ;       None
                    464: ;
                    465: ;-----------------------------------------------------------------------;
                    466: 
                    467: cProc   vRle8ToVga,4,<       \
                    468:         uses    esi edi ebx,  \
                    469:         pRleInfo: ptr RLEINFO >
                    470: 
                    471:         local   pjDst       :ptr
                    472:         local   pulXlate    :ptr
                    473:         local   xCurr       :dword
                    474:         local   yCurr       :dword
                    475:         local   xStart      :dword
                    476:         local   cPreSrcAdv  :dword
                    477:         local   cPostSrcAdv :dword
                    478:         local   prclClip    :ptr RECTL
                    479:         local   pjSrcEnd    :ptr
                    480:         local   pdsurf      :ptr DEVSURF
                    481:         local   ulTrueClipTop :dword
                    482:         local   lNextScan   : dword
                    483: 
                    484:         RleBankSetUp    ;wrap a banking loop around everything
                    485: 
                    486: rle8_bank_loop:
                    487: 
                    488:         RleBankTop
                    489: 
                    490:         RleSetUp
                    491: 
                    492: rle8_loop:
                    493:         cmp     esi,pjSrcEnd
                    494:         jae     rle8_done
                    495:         lodsw                           ;fetch a word from src RLE bitmap
                    496: 
                    497:         or      al,al
                    498:         jz      rle8_escape
                    499: 
                    500: rle8_encoded:
                    501:         Clip_Encoded    rle8_done,rle8_loop
                    502:         Draw_Encoded    rle8_loop
                    503: 
                    504: rle8_escape:
                    505:         cmp     ah,2                    ; First byte is 0, check the second byte.
                    506:         ja      short rle8_absolute
                    507:         jb      rle8_end_of_line_or_bitmap
                    508: 
                    509: rle8_delta:
                    510:         RleDelta    rle8_loop
                    511: 
                    512: rle8_absolute:
                    513:         Clip_Absolute   rle8_done,rle8_absolute_advance_src,cl
                    514:         add     esi,cPreSrcAdv          ;advance esi to point to the clipped run
                    515: 
                    516: ; I am doing a per pel loop rather than a per byte loop which writes 1 plane
                    517: ; at a time because it appears to me that most of the time we output 2 or
                    518: ; 3 pels per encounter of absolute mode.  The logic here is simple and we can
                    519: ; stay with M_COLOR_WRITE mode all the time.
                    520: 
                    521: rle8_absolute_loop:
                    522:         mov     dx,VGA_BASE + GRAF_ADDR
                    523:         out     dx,ax                   ;Set bitmask for altered bit
                    524: 
                    525:         movzx   edx,byte ptr [esi]      ;grab color for this pel
                    526:         inc     esi
                    527: 
                    528:         mov     edx,[ebx][edx*4]
                    529:         xchg    [edi],dl                ;write to destination
                    530: 
                    531:         ror     ah,1                    ;rotate bit mask for next pel
                    532:         cmp     ch,ah                   ;cmp bitmask with 01000001b
                    533:         adc     edi,0                   ;advance edi if bitmask is 10000000b
                    534: 
                    535:         dec     cl                      ;per pel loop
                    536:         jnz short rle8_absolute_loop
                    537:         mov     eax,cPostSrcAdv
                    538: 
                    539: rle8_absolute_advance_src:
                    540:         add     esi,eax                 ;advance src ptr for clipped out pels
                    541:         bt      esi,0                   ;add 1 if not word aligned
                    542:         adc     esi,0
                    543:         jmp     rle8_loop
                    544: 
                    545: rle8_end_of_line_or_bitmap:
                    546:         or      ah,ah
                    547:         jnz short rle8_end_of_bitmap
                    548: 
                    549: rle8_end_of_line:
                    550: 
                    551:         RleEOL  rle8_loop
                    552: 
                    553: rle8_done:
                    554:         RleExit
                    555: 
                    556:         RleBankBottom   rle8_bank_loop,rle8_exit ;see if there are more banks
                    557:                                                  ; to do
                    558:         align   4
                    559: rle8_end_of_bitmap:
                    560:         RleExit
                    561: rle8_exit:
                    562:         cRet    vRle8ToVga
                    563: 
                    564: endProc vRle8ToVga
                    565: 
                    566: 
                    567: ;--------------------------Public-Routine-------------------------------;
                    568: ; vRle4ToVga
                    569: ;
                    570: ;   Write an RLE4 bitmap onto the VGA device.
                    571: ;
                    572: ; Entry:
                    573: ;       None
                    574: ; Returns:
                    575: ;       None
                    576: ;
                    577: ;-----------------------------------------------------------------------;
                    578: 
                    579: cProc   vRle4ToVga,4,<       \
                    580:         uses    esi edi ebx,  \
                    581:         pRleInfo: ptr RLEINFO >
                    582: 
                    583:         local   pjDst       :ptr
                    584:         local   pulXlate    :ptr
                    585:         local   xCurr       :dword
                    586:         local   yCurr       :dword
                    587:         local   xStart      :dword
                    588:         local   cPreSrcAdv  :dword
                    589:         local   cPostSrcAdv :dword
                    590:         local   pjDstStart  :ptr
                    591:         local   iPels       :dword
                    592:         local   xMask       :dword
                    593:         local   nPels       :byte
                    594:         local   prclClip    :ptr RECTL
                    595:         local   pjSrcEnd    :ptr
                    596:         local   pdsurf      :ptr DEVSURF
                    597:         local   ulTrueClipTop :dword
                    598:         local   lNextScan   : dword
                    599: 
                    600:         RleBankSetUp    ;wrap a banking loop around everything
                    601: 
                    602: rle4_bank_loop:
                    603: 
                    604:         RleBankTop
                    605: 
                    606:         RleSetUp
                    607: 
                    608: rle4_loop:
                    609:         cmp     esi,pjSrcEnd
                    610:         jae     rle4_done
                    611:         lodsw                           ;fetch a word
                    612: 
                    613:         or      al,al
                    614:         jz      rle4_escape
                    615: 
                    616: rle4_encoded:
                    617:         Clip_Encoded    rle4_done,rle4_loop
                    618: 
                    619:         mov     dh,dl                   ;separate two colors into dl, dh
                    620:         and     dl,0Fh
                    621:         shr     dh,4
                    622:         cmp     dh,dl
                    623:         jnz short encoded_diff_color
                    624:         xor     dh,dh                   ;Draw_Encoded use edx as color index
                    625:         Draw_Encoded    rle4_loop
                    626: 
                    627: encoded_diff_color:
                    628:         sub     eax,ecx                 ;-eax = #pels clipped away
                    629:         bt      eax,0
                    630:         jnc short @F
                    631:         xchg    dl,dh                   ;xchg colors if odd #pels clipped
                    632: @@:
                    633:         mov     iPels,edx               ;save color index
                    634:         sub     ebx,ecx                 ;Compute extent of interval
                    635:         dec     ebx                     ;Make interval inclusive
                    636:         mov     edi,ecx                 ;Don't destroy starting X
                    637:         shr     edi,3                   ;/8 for byte address
                    638:         add     edi,pjDst
                    639: 
                    640:         and     ecx,00000111b           ;Compute bit index for first byte
                    641:         mov     eax,00AAAAAAh           ;Compute altered bits mask
                    642:         shr     eax,cl                  ;AL = left side altered bytes mask
                    643: 
                    644:         add     ebx,ecx                 ;Compute bit index for last byte
                    645:         mov     ecx,ebx                 ;(save for inner loop count)
                    646:         and     ecx,00000111b
                    647:         mov     ch,80h
                    648:         sar     ch,cl
                    649:         and     al,ch                   ;AL = last byte altered bits mask
                    650: 
                    651:         mov     edx,eax
                    652:         shr     edx,1
                    653:         and     dl,ch                   ;EDX = mask for 2nd pel
                    654: 
                    655:         mov     ecx,ebx
                    656:         shr     ecx,3                   ;Compute inner byte count
                    657:         jnz     short comp_byte_dont_combine ;loop count + 1 > 0, check it out
                    658: 
                    659: ; Only one byte will be affected.  Combine first/last masks, set loop count = 0
                    660: 
                    661:         mov     ebx,eax
                    662:         shl     eax,16                  ;Will use first byte mask only
                    663:         and     eax,ebx                 ;AH = first mask. Rest of the bits = 0
                    664: 
                    665:         mov     ebx,edx
                    666:         shl     edx,16                  ;Will use first byte mask only
                    667:         and     edx,ebx                 ;DH = first mask. Rest of the bits = 0
                    668:         inc     ecx                     ;Fall through to set 0
                    669: 
                    670: comp_byte_dont_combine:
                    671:         dec     ecx                     ;Dec inner loop count (might become 0)
                    672: 
                    673:         xchg    al,ah
                    674:         ror     eax,16                  ;EAX = last mask:inter mask:first mask:0
                    675:         xchg    al,ah                   ;for first pel
                    676:         xchg    dl,dh
                    677:         ror     edx,16                  ;EDX = last mask:inter mask:first mask:0
                    678:         xchg    dl,dh                   ;for second pel
                    679: 
                    680:         mov     pjDstStart,edi
                    681:         mov     xMask,edx                ;save mask for the 2nd round
                    682: 
                    683:         mov     ebx,pulXlate
                    684:         mov     edx,iPels
                    685:         shr     edx,8                   ;index for the first pel
                    686:         mov     ebx,[ebx][edx*4]
                    687:         inc     bh                      ;BH = rle4_encoded_diff_color_loop count
                    688:         inc     bh
                    689:         mov     dx,VGA_BASE + GRAF_ADDR
                    690:                                         ;BL = color for first pel
                    691: rle4_encoded_diff_color_loop:
                    692:         or      ah,ah                   ;AH = first mask
                    693:         jz short encoded_inner_diff_color
                    694: 
                    695:         mov     al,GRAF_BIT_MASK        ;Set bitmask for altered bits
                    696:         out     dx,ax
                    697: 
                    698:         mov     al,bl
                    699:         xchg    [edi],al                ;write color
                    700: encoded_inner_diff_color:
                    701:         inc     edi                     ;update destination pointer
                    702:         shr     eax,8                   ;AH = internal mask
                    703:         or      cl,cl                   ;ECX = inner loop count
                    704:         jz short encoded_last_byte_diff_color
                    705: 
                    706:         mov     ch,cl                   ;save loop count in ch
                    707:                                         ;loop count always fit in a byte
                    708:         mov     al,GRAF_BIT_MASK
                    709:         out     dx,ax                   ;no mask
                    710: 
                    711: encoded_loop_diff_color:
                    712:         mov     al,bl
                    713:         xchg    [edi],al                ;write color
                    714:         inc     edi
                    715:         dec     cl
                    716:         jnz     encoded_loop_diff_color
                    717: 
                    718: encoded_last_byte_diff_color:
                    719:         shr     eax,8                   ;AH = last mask
                    720:         or      ah,ah
                    721:         jz      encoded_this_run_maybe_done
                    722: 
                    723:         mov     al,GRAF_BIT_MASK        ;Set bitmask for altered bits
                    724:         out     dx,ax
                    725: 
                    726: encoded_write:
                    727:         xchg    [edi],bl                ;write color
                    728: 
                    729: encoded_this_run_maybe_done:
                    730:         dec     bh
                    731:         jz      rle4_loop
                    732: 
                    733:         mov     edi,pulXlate
                    734:         mov     eax,iPels               ;index of the second pel
                    735:         xor     ah,ah
                    736:         mov     bl,byte ptr [edi][eax*4]
                    737:         mov     edi,pjDstStart
                    738:         mov     eax,xMask               ;load mask
                    739:         mov     cl,ch                   ;loop count
                    740: 
                    741:         jmp     rle4_encoded_diff_color_loop
                    742: 
                    743: rle4_escape:
                    744:         cmp     ah,2                    ; First byte is 0, check the second byte.
                    745:         ja      rle4_absolute
                    746:         jb      rle4_end_of_line_or_bitmap
                    747: 
                    748: rle4_delta:
                    749: 
                    750:         RleDelta    rle4_loop
                    751: 
                    752: rle4_absolute:
                    753:         Clip_Absolute   rle4_done,rle4_absolute_advance_src,nPels
                    754: 
                    755: ;advance esi to point to the clipped run
                    756: 
                    757:         mov     edx,cPreSrcAdv          ;number of pels to advance
                    758:         shr     edx,1                   ;number of bytes
                    759:         jnc     @F
                    760: 
                    761:         add     esi,edx                 ;odd number of pels to advance
                    762:         movzx   edx,byte ptr [esi]      ;grab color for prev and this pels
                    763:         inc     esi
                    764:         mov     iPels,edx
                    765: 
                    766:         inc     nPels                   ;inc loop count since we start from 1
                    767:         mov     cl,1
                    768:         jmp short absolute_loop
                    769: 
                    770: @@:                                     ;even number of pels to advance
                    771:         add     esi,edx
                    772: 
                    773: ; I am doing a per pel loop rather than a per byte loop which writes 1 plane
                    774: ; at a time because it appears to me that most of the time we output 2 or
                    775: ; 3 pels per encounter of absolute mode.  The logic here is simple and we can
                    776: ; stay with M_COLOR_WRITE mode all the time.
                    777: 
                    778:         xor     cl,cl                   ;initialize loop count
                    779: 
                    780: absolute_loop:
                    781:         mov     dx,VGA_BASE + GRAF_ADDR
                    782:         out     dx,ax                   ;Set bitmask for altered bit
                    783: 
                    784:         bt      cl,0
                    785:         jc      @F
                    786: 
                    787:         movzx   edx,byte ptr [esi]      ;grab color for this and next pels
                    788:         inc     esi
                    789: 
                    790:         mov     iPels,edx               ;save for next pel
                    791:         shr     dl,4
                    792:         jmp short   ready_to_draw
                    793: @@:
                    794:         mov     edx,iPels               ;second pel
                    795:         and     dl,0Fh                  ;mask out the second pel
                    796: 
                    797: ready_to_draw:
                    798:         mov     edx,[ebx][edx*4]        ;look up for VGA color
                    799:         xchg    [edi],dl                ;write to destination
                    800: 
                    801:         ror     ah,1                    ;rotate bit mask for next pel
                    802:         cmp     ch,ah                   ;cmp bitmask with 01000001b
                    803:         adc     edi,0                   ;advance edi if bitmask is 10000000b
                    804: 
                    805:         inc     cl
                    806:         cmp     cl,nPels
                    807:         jnz short absolute_loop
                    808: 
                    809:         mov     eax,cPostSrcAdv
                    810: 
                    811: rle4_absolute_advance_src:
                    812:         shr     eax,1                   ;2 pels for one byte
                    813:         add     esi,eax                 ;advance src ptr for clipped out pels
                    814:         bt      esi,0                   ;add 1 if not word aligned
                    815:         adc     esi,0
                    816:         jmp     rle4_loop
                    817: 
                    818: 
                    819: rle4_end_of_line_or_bitmap:
                    820:         or      ah,ah
                    821:         jnz short rle4_end_of_bitmap
                    822: 
                    823: rle4_end_of_line:
                    824:         RleEOL  rle4_loop
                    825: 
                    826: rle4_done:
                    827:         RleExit
                    828: 
                    829:         RleBankBottom   rle4_bank_loop,rle4_exit ;see if there are more banks
                    830:                                                  ; to do
                    831:         align   4
                    832: rle4_end_of_bitmap:
                    833:         RleExit
                    834: rle4_exit:
                    835:         cRet    vRle4ToVga
                    836: 
                    837: endProc vRle4ToVga
                    838: 
                    839: ;--------------------------Private-Routine------------------------------;
                    840: ; comp_byte_interval
                    841: ;
                    842: ;   An interval will be computed for byte boundaries.
                    843: ;
                    844: ;   A first mask and a last mask will be calculated, and possibly
                    845: ;   combined into the inner loop count.  If no first byte exists,
                    846: ;   the start address will be incremented to adjust for it.
                    847: ;
                    848: ; Entry:
                    849: ;       EBX = right coordinate (exclusive)
                    850: ;       ECX = left coordinate  (inclusive)
                    851: ; Returns:
                    852: ;       EDI = offset to first byte to be altered in the scan
                    853: ;       ECX = inner loop count
                    854: ;       AL  = first byte mask (possibly 0)
                    855: ;       AH  = last  byte mask (possibly 0)
                    856: ; Error Returns:
                    857: ;       None
                    858: ; Registers Preserved:
                    859: ;       ES,BP
                    860: ; Registers Destroyed:
                    861: ;       AX,BX,CX,DI,FLAGS
                    862: ; Calls:
                    863: ;       None
                    864: ;
                    865: ;-----------------------------------------------------------------------;
                    866: 
                    867: comp_masks      proc
                    868: 
                    869:         sub     ebx,ecx                 ;Compute extent of interval
                    870:         dec     ebx                     ;Make interval inclusive
                    871:         mov     edi,ecx                 ;Don't destroy starting X
                    872:         shr     edi,3                   ;/8 for byte address
                    873: 
                    874:         and     ecx,00000111b           ;Compute bit index for left side
                    875:         mov     al,0FFh                 ;Compute left side altered bits mask
                    876:         shr     al,cl                   ;AL = left side altered bytes mask
                    877: 
                    878:         add     ebx,ecx                 ;Compute bit index for right side
                    879:         mov     ecx,ebx                 ;(save for inner loop count)
                    880:         and     ecx,00000111b
                    881:         mov     ah,80h
                    882:         sar     ah,cl                   ;AH = right side altered bits mask
                    883: 
                    884:         shr     ebx,3                   ;Compute inner byte count
                    885:         jnz     short comp_byte_dont_combine ;loop count + 1 > 0, check it out
                    886: 
                    887: ; Only one byte will be affected.  Combine first/last masks, set loop count = 0
                    888: 
                    889:         and     al,ah                   ;Will use first byte mask only
                    890:         xor     ah,ah                   ;Want last byte mask to be 0
                    891:         inc     ebx                     ;Fall through to set 0
                    892: 
                    893: comp_byte_dont_combine:
                    894:         dec     ebx                     ;Dec inner loop count (might become 0)
                    895: 
                    896: ; If all pixels in the first byte are altered, combine the first byte into the
                    897: ; inner loop and clear the first byte mask.  Ditto for the last byte mask.
                    898: 
                    899:         mov     ecx,0FFFFFFFFh
                    900:         cmp     al,cl                   ;Set 'C' if not all pixels 1
                    901:         sbb     ebx,ecx                 ;If no 'C', sub -1 (add 1), else sub 0
                    902:         cmp     al,cl                   ;Set 'C' if not all pixels 1
                    903:         sbb     al,cl                   ;If no 'C', sub -1 (add 1), else sub 0
                    904: 
                    905:         cmp     ah,cl                   ;Set 'C' if not all pixels 1
                    906:         sbb     ebx,ecx                 ;If no 'C', sub -1 (add 1), else sub 0
                    907:         cmp     ah,cl                   ;Set 'C' if not all pixels 1
                    908:         sbb     ah,cl                   ;If no 'C', sub -1 (add 1), else sub 0
                    909: 
                    910:         mov     ecx,ebx                 ;Return inner loop count in ECX
                    911: 
                    912:         ret
                    913: 
                    914: comp_masks endp
                    915: 
                    916:         end
                    917: 

unix.superglobalmegacorp.com

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