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

1.1       root        1: ;---------------------------Module-Header------------------------------;
                      2: ; Module Name: restscrn.asm
                      3: ;
                      4: ; Copyright (c) 1992 Microsoft Corporation
                      5: ;-----------------------------------------------------------------------;
                      6: ;-----------------------------------------------------------------------;
                      7: ; VOID vRestoreScreenBitsFromMemory(PDEVSURF pdsurf, PRECTL prcl,
                      8: ;                              PVOID pjSrcBuffer, ULONG ulRestoreWidthInBytes,
                      9: ;                              ULONG ulSrcDelta);
                     10: ; Input:
                     11: ;  pdsurf - surface to which to copy
                     12: ;  prcl - pointer to rectangle to which to copy
                     13: ;  pjSrcBuffer - pointer to source memory buffer. Should have the same
                     14: ;                 dword alignment as the dest rect left edge does in screen
                     15: ;                 memory
                     16: ;  ulRestoreWidthInBytes - # of bytes to restore per scan (including any
                     17: ;                 partial edges)
                     18: ;  ulSrcDelta - distance from end of one source scan to start of next.
                     19: ;                 together with ulRestoreWidthInBytes, should maintain
                     20: ;                 dword alignment between source and dest
                     21: ;
                     22: ; Copies a rectangle from a memory buffer to VGA memory.
                     23: ;
                     24: ;-----------------------------------------------------------------------;
                     25: ;
                     26: ; Note: Assumes all rectangles have positive heights and widths. Will not
                     27: ; work properly if this is not the case.
                     28: ;
                     29: ;-----------------------------------------------------------------------;
                     30: ;
                     31: ; Note: The rectangle is restored from interleaved-scan format; all four planes
                     32: ; of one scan are saved together, then all four planes of the next scan,
                     33: ; and so on. This is done for maximum restoration efficiency. Planes are
                     34: ; saved in order 3, 2, 1, 0:
                     35: ;
                     36: ;  Scan n, plane 3
                     37: ;  Scan n, plane 2
                     38: ;  Scan n, plane 1
                     39: ;  Scan n, plane 0
                     40: ;  Scan n+1, plane 3
                     41: ;  Scan n+1, plane 2
                     42: ;  Scan n+1, plane 1
                     43: ;  Scan n+1, plane 0
                     44: ;          :
                     45: ;
                     46: ; There may be padding on either edge of the saved bits in the destination
                     47: ; buffer, so that the destination can be dword aligned with the source.
                     48: ;
                     49: ;-----------------------------------------------------------------------;
                     50: ;Additional optimizations:
                     51: ;
                     52: ; Could break out separate scan copy code with and without edge handling.
                     53: ; (Possibly by threading the desired operations, or by having many separate
                     54: ; optimizations.)
                     55: ;
                     56: ; Could handle odd bytes to dword align more efficiently, by having separate
                     57: ; optimizations for various alignment widths, thereby avoiding starting REP
                     58: ; and getting word accesses for 2 and 3 wide cases. Most VGAs are 8 or 16
                     59: ; bit devices, and for them, using MOVSB/REP MOVSW/MOVSB might actually be
                     60: ; faster, especially because it's easier to break out optimizations.
                     61: ;
                     62: ; Could end all scan handlers with loop bottom code.
                     63: ;
                     64: ; Could do more scans in one plane before doing next plane, to avoid
                     65: ; slow OUTs. This could cause color effects, but that might be avoidable
                     66: ; by scaling the # of scans done per plane to the width of the rectangle.
                     67: ;
                     68: ;-----------------------------------------------------------------------;
                     69: 
                     70: 
                     71:                 .386
                     72: 
                     73: ifndef  DOS_PLATFORM
                     74:         .model  small,c
                     75: else
                     76: ifdef   STD_CALL
                     77:         .model  small,c
                     78: else
                     79:         .model  small,pascal
                     80: endif;  STD_CALL
                     81: endif;  DOS_PLATFORM
                     82: 
                     83:         assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
                     84:         assume fs:nothing,gs:nothing
                     85: 
                     86:         .xlist
                     87:         include stdcall.inc             ;calling convention cmacros
                     88:         include i386\egavga.inc
                     89:         include i386\strucs.inc
                     90: 
                     91:         .list
                     92: 
                     93:         .data
                     94: 
                     95: ;-----------------------------------------------------------------------;
                     96: ; Masks used to do left and right edge clipping for various alignments.
                     97: ; Low byte = destination mask, high byte = source mask.
                     98: ;-----------------------------------------------------------------------;
                     99:         align   2
                    100: usLeftMasks     label   word
                    101:         dw      0ff00h, 07f80h, 03fc0h, 01fe0h, 00ff0h, 007f8h, 003fch, 001feh
                    102: 
                    103: usRightMasks    label   word
                    104:         dw      0ff00h, 0807fh, 0c03fh, 0e01fh, 0f00fh, 0f807h, 0fc03h, 0fe01h
                    105: 
                    106: ;-----------------------------------------------------------------------;
                    107: ; Same as above, but dest masks only, and whole byte case is represented
                    108: ; as 0ffh rather than 0. Used for 1-byte-wide cases.
                    109: ;-----------------------------------------------------------------------;
                    110: jLeftMasks      label   byte
                    111:         db      0ffh, 080h, 0c0h, 0e0h, 0f0h, 0f8h, 0fch, 0feh
                    112: 
                    113: jRightMasks     label   byte
                    114:         db      0ffh, 07fh, 03fh, 01fh, 00fh, 007h, 003h, 001h
                    115: 
                    116:         .code
                    117: 
                    118: _TEXT$03   SEGMENT DWORD USE32 PUBLIC 'CODE'
                    119:            ASSUME  CS:FLAT, DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
                    120: 
                    121: ;-----------------------------------------------------------------------;
                    122: 
                    123: cProc   vRestoreScreenBitsFromMemory,20,< \
                    124:         uses    esi edi ebx,         \
                    125:         pdsurf:ptr,                  \
                    126:         prcl:ptr,                    \
                    127:         pjSrcBuffer:ptr,             \
                    128:         ulRestoreWidthInBytes:dword, \
                    129:         ulSrcDelta:dword             >
                    130: 
                    131:         local   ulCurrentTopScan :dword ;top scan line to copy to in current
                    132:                                         ; bank
                    133:         local   ulBottomScan :dword     ;bottom scan line of rectangle to which
                    134:                                         ; to copy
                    135:         local   pjDstStart :dword       ;destination address
                    136:         local   ulDstDelta :dword       ;distance from end of dest scan to
                    137:                                         ; start of next
                    138:         local   ulBlockHeight :dword    ;# of scans to copy in block
                    139:         local   ulLeadingBytes :dword   ;# of leading bytes to copy per scan
                    140:         local   ulMiddleDwords :dword   ;# of dwords to copy per scan
                    141:         local   ulTrailingBytes :dword  ;# of trailing bytes to copy per scan
                    142:         local   pfnCopyVector :dword    ;pointer to inner loop routine to copy
                    143:                                         ; from buffer to screen
                    144:         local   ulLeftMask :dword       ;2 byte masks for left edge clipping
                    145:                                         ; (low byte = dest mask,
                    146:                                         ;  high byte = src mask)
                    147:         local   ulRightMask :dword      ;2 byte masks for right edge clipping
                    148: 
                    149: ;-----------------------------------------------------------------------;
                    150: ; Leave the GC Index pointing to the Read Map for the rest of this routine.
                    151: ;-----------------------------------------------------------------------;
                    152: 
                    153:         mov     edx,VGA_BASE + GRAF_ADDR
                    154:         mov     al,GRAF_READ_MAP
                    155:         out     dx,al
                    156: 
                    157: ;-----------------------------------------------------------------------;
                    158: ; Set up local variables.
                    159: ;-----------------------------------------------------------------------;
                    160: 
                    161:         mov     edi,prcl                ;point to rectangle from which to copy
                    162:         mov     esi,pdsurf              ;point to surface from which to copy
                    163: 
                    164:         mov     eax,[edi].yBottom
                    165:         mov     ulBottomScan,eax        ;bottom scan line of source rect
                    166: 
                    167:         mov     eax,[esi].dsurf_lNextScan
                    168:         sub     eax,ulRestoreWidthInBytes
                    169:         mov     ulDstDelta,eax  ;distance from end of one scan's bits to save
                    170:                                 ; to start of next scan's in display memory
                    171: 
                    172: ;-----------------------------------------------------------------------;
                    173: ; Figure out the left and right clip masks. If either or both edges are
                    174: ; solid, add them into the whole bytes.
                    175: ;-----------------------------------------------------------------------;
                    176: 
                    177:         mov     ebx,[edi].xLeft
                    178:         mov     ecx,[edi].xRight
                    179:         mov     edx,ebx
                    180:         lea     eax,[ecx-1]
                    181:         and     ebx,0111b
                    182:         and     ecx,0111b
                    183: 
                    184:         and     edx,not 0111b
                    185:         sub     eax,edx
                    186:         shr     eax,3           ;width in bytes - 1
                    187:                                 ;only 1 byte wide?
                    188:         jnz     short @F        ;no
                    189:                                 ;1 byte wide; special case
                    190:         mov     al,jLeftMasks[ebx]      ;look up left dest mask
                    191:         and     al,jRightMasks[ecx]     ;factor in right dest mask
                    192:         mov     ah,0ffh
                    193:         mov     ebx,offset copy_from_buffer_l_whole_only ;assume whole byte
                    194:         xor     ah,al                   ;calculate matching dest mask
                    195:                                 ;is this single byte a whole byte?
                    196:         jz      set_copy_vector ;yes, select whole byte optimization
                    197:                                 ;no, select partial byte optimization
                    198:         mov     ebx,offset copy_from_buffer_l_partial_only
                    199:         mov     ulLeftMask,eax
                    200:         jmp     set_copy_vector
                    201: 
                    202:         align   4
                    203: @@:                                     ;more than 1 byte wide
                    204: 
                    205:         mov     edx,ulRestoreWidthInBytes
                    206: 
                    207:         mov     ax,usLeftMasks[ebx*2]   ;look up left masks
                    208:         mov     ulLeftMask,eax
                    209:         and     al,al                   ;any left clipping?
                    210:         jz      short @F                ;no, do as part of whole bytes
                    211:         dec     edx                     ;yes, don't count as whole byte
                    212: @@:
                    213: 
                    214: 
                    215:         mov     ax,usRightMasks[ecx*2]  ;look up right masks
                    216:         mov     ulRightMask,eax
                    217:         and     al,al                   ;any right clipping?
                    218:         jz      short @F                ;no, do as part of whole bytes
                    219:         dec     edx                     ;yes, don't count as whole byte
                    220: @@:
                    221: 
                    222: ;-----------------------------------------------------------------------;
                    223: ; Set up for copying as much as possible via aligned dwords, and
                    224: ; select the most efficient loop for doing the copy, based on the copy
                    225: ; width, and on the necessity for leading and/or trailing bytes to
                    226: ; dword align.
                    227: ;-----------------------------------------------------------------------;
                    228: 
                    229:         cmp     edx,8                   ;if it's less than 8 bytes, just do a
                    230:                                         ; straight byte copy. This means we
                    231:                                         ; we only have to start 1 REP per line,
                    232:                                         ; and performing this check guarantees
                    233:                                         ; that we have at least 1 aligned dword
                    234:                                         ; to copy in the dword loops
                    235:         jb      short copy_all_as_bytes ;do straight byte copy
                    236:         mov     eax,pjSrcBuffer
                    237:         neg     eax
                    238:         and     eax,3           ;# of bytes that have to be done as leading
                    239:                                 ; bytes to dword align with source (note that
                    240:                                 ; for performance, the source should be dword
                    241:                                 ; aligned with the destination)
                    242:         jz      short copy_no_leading_bytes     ;no leading bytes
                    243:                                 ;leading bytes
                    244:         mov     ulLeadingBytes,eax
                    245:         mov     ebx,offset copy_from_buffer_l ;assume no trailing bytes
                    246:         sub     edx,eax         ;# of bytes after leading bytes
                    247:         mov     eax,edx
                    248:         shr     eax,2           ;# of dwords that can be handled as aligned
                    249:                                 ; dwords
                    250:         mov     ulMiddleDwords,eax
                    251:         and     edx,3           ;# of trailing bytes left after aligned dwords
                    252:                                 ; copied
                    253:         jz      short set_copy_vector ;no trailing bytes
                    254:         mov     ulTrailingBytes,edx
                    255:         mov     ebx,offset copy_from_buffer_lt  ;there are both leading and
                    256:                                                 ; trailing bytes
                    257:         jmp     short set_copy_vector
                    258: 
                    259:         align   4
                    260: copy_no_leading_bytes:
                    261:         mov     ebx,offset copy_from_buffer ;assume no trailing bytes
                    262:         mov     eax,edx
                    263:         shr     eax,2           ;# of dwords that can be handled as aligned
                    264:                                 ; dwords
                    265:         mov     ulMiddleDwords,eax
                    266:         and     edx,3           ;# of trailing bytes left after aligned dwords
                    267:                                 ; copied
                    268:         jz      short set_copy_vector ;no trailing bytes
                    269:         mov     ulTrailingBytes,edx
                    270:         mov     ebx,offset copy_from_buffer_t     ;there are trailing bytes
                    271:         jmp     short set_copy_vector
                    272: 
                    273: ; It's so narrow that we'll forget about aligned dwords, and just do a straight
                    274: ; byte copy, which we'll handle by treating the entire copy as leading bytes.
                    275:         align   4
                    276: copy_all_as_bytes:
                    277:         mov     ulLeadingBytes,edx
                    278:         mov     ebx,offset copy_from_buffer_lonly
                    279: 
                    280: set_copy_vector:
                    281:         mov     pfnCopyVector,ebx
                    282: 
                    283: ;-----------------------------------------------------------------------;
                    284: ; Map in the bank containing the top scan to copy, if it's not mapped in
                    285: ; already.
                    286: ;-----------------------------------------------------------------------;
                    287: 
                    288:         mov     eax,[edi].yTop          ;top scan line of copy
                    289:         mov     ulCurrentTopScan,eax    ;this will be the copy top in 1st bank
                    290: 
                    291:         cmp     eax,[esi].dsurf_rcl1WindowClip.yTop ;is copy top less than
                    292:                                                     ; current bank?
                    293:         jl      short map_init_bank             ;yes, map in proper bank
                    294:         cmp     eax,[esi].dsurf_rcl1WindowClip.yBottom ;copy top greater than
                    295:                                                        ; current bank?
                    296:         jl      short init_bank_mapped          ;no, proper bank already mapped
                    297: map_init_bank:
                    298: 
                    299: ; Map in the bank containing the top scan line of the copy.
                    300: 
                    301:         ptrCall   <dword ptr [esi].dsurf_pfnBankControl>,<esi,eax,JustifyTop>
                    302: 
                    303: init_bank_mapped:
                    304: 
                    305: ;-----------------------------------------------------------------------;
                    306: ; Calculate the initial start address to which to copy.
                    307: ;-----------------------------------------------------------------------;
                    308: 
                    309:         mov     eax,ulCurrentTopScan    ;top scan line to copy to in current
                    310:                                         ; bank
                    311:         imul    [esi].dsurf_lNextScan   ;offset of starting scan line in bitmap
                    312:         add     eax,[esi].dsurf_pvBitmapStart ;start address of scan
                    313:         mov     ebx,[edi].xLeft
                    314:         shr     ebx,3                   ;convert from pixel to byte address
                    315:         add     eax,ebx                 ;start dest address
                    316:         mov     pjDstStart,eax
                    317: 
                    318: ;-----------------------------------------------------------------------;
                    319: ; Loop through and copy all bank blocks spanned by the destination
                    320: ; rectangle.
                    321: ;
                    322: ; Input:
                    323: ;  ESI = pdsurf
                    324: ;-----------------------------------------------------------------------;
                    325: 
                    326: copy_from_buffer_bank_loop:
                    327: 
                    328: ; Copy this bank block to the buffer.
                    329: 
                    330: ; Calculate # of scans in this bank.
                    331: 
                    332:         mov     ebx,ulBottomScan        ;bottom of dest rectangle
                    333:         cmp     ebx,[esi].dsurf_rcl1WindowClip.yBottom
                    334:                                         ;which comes first, the bottom of the
                    335:                                         ; dest rect or the bottom of the
                    336:                                         ; current bank?
                    337:         jl      short @F                ;dest bottom comes first, so copy to
                    338:                                         ; that; this is the last bank in copy
                    339:         mov     ebx,[esi].dsurf_rcl1WindowClip.yBottom
                    340:                                         ;bank bottom comes first; copy to
                    341:                                         ; bottom of bank
                    342: @@:
                    343:         sub     ebx,ulCurrentTopScan    ;# of scans to copy in this bank
                    344:         mov     ulBlockHeight,ebx
                    345: 
                    346:         mov     esi,pjSrcBuffer ;point to start of source rect
                    347: 
                    348:         mov     dh,VGA_BASE SHR 8       ;leave DH pointing to VGA_BASE
                    349: 
                    350: ;-----------------------------------------------------------------------;
                    351: ; Loop through all scans in this block, copying all four planes of each
                    352: ; scan in turn, then doing the next scan.
                    353: ;-----------------------------------------------------------------------;
                    354: copy_to_buffer_scan_loop:
                    355: 
                    356:         mov     bl,MM_C3        ;start by copying to plane 3
                    357: 
                    358: ;-----------------------------------------------------------------------;
                    359: ; Loop through all four planes, copying all scans in this block for each
                    360: ; plane in turn.
                    361: ;-----------------------------------------------------------------------;
                    362: 
                    363: copy_to_buffer_plane_loop:
                    364: 
                    365:         mov     dl,SEQ_DATA
                    366:         mov     al,bl
                    367:         out     dx,al           ;set Map Mask to plane to which we're copying
                    368: 
                    369:         mov     dl,GRAF_DATA
                    370:         shr     al,1
                    371:         cmp     al,3
                    372:         adc     al,-1
                    373:         out     dx,al
                    374: 
                    375:         mov     edi,pjDstStart  ;point to start of dest buffer (scan starts
                    376:                                 ; at same address in all planes)
                    377:         jmp     pfnCopyVector   ;jump to the appropriate loop to copy plane
                    378: 
                    379: ;-----------------------------------------------------------------------;
                    380: ; Copy loops, broken out by leading and trailing bytes needed for dword
                    381: ; alignment, plus one loop to perform a straight byte copy.
                    382: ;
                    383: ; Input:
                    384: ;  ESI = initial source copy address
                    385: ;  EDI = initial dest copy address
                    386: ;-----------------------------------------------------------------------;
                    387: 
                    388: ; All bytes can be copied as aligned dwords (no leading or trailing whole
                    389: ; bytes).
                    390:         align   4
                    391: copy_from_buffer:
                    392: 
                    393: ; Do the left edge byte, if there's a partial left edge byte.
                    394: 
                    395:         mov     eax,ulLeftMask  ;AL = dest mask, AH = source mask
                    396:         and     al,al           ;any left mask?
                    397:         jz      short @F        ;left edge is whole
                    398:         and     al,[edi]        ;mask the dest
                    399:         and     ah,[esi]        ;mask the source
                    400:         inc     esi             ;point to next source byte
                    401:         or      al,ah           ;combine the source and dest
                    402:         stosb                   ;store the new byte
                    403: @@:
                    404: 
                    405: ; Do the middle (whole) bytes.
                    406: 
                    407:         mov     ecx,ulMiddleDwords
                    408:         rep     movsd
                    409: 
                    410: ; Do the right edge byte, if there's a partial right edge byte.
                    411: 
                    412:         mov     eax,ulRightMask ;AL = dest mask, AH = source mask
                    413:         and     al,al           ;any left mask?
                    414:         jz      short @F        ;right edge is whole
                    415:         and     al,[edi]        ;mask the dest
                    416:         and     ah,[esi]        ;mask the source
                    417:         inc     esi             ;point to next source byte
                    418:         or      al,ah           ;combine the source and dest
                    419:         stosb                   ;store the new byte
                    420: @@:
                    421: 
                    422:         jmp     copy_from_buffer_scan_done
                    423: 
                    424: ; Leading odd whole bytes, but no trailing whole bytes.
                    425:         align   4
                    426: copy_from_buffer_l:
                    427: 
                    428: ; Do the left edge byte, if there's a partial left edge byte.
                    429: 
                    430:         mov     eax,ulLeftMask  ;AL = dest mask, AH = source mask
                    431:         and     al,al           ;any left mask?
                    432:         jz      short @F        ;left edge is whole
                    433:         and     al,[edi]        ;mask the dest
                    434:         and     ah,[esi]        ;mask the source
                    435:         inc     esi             ;point to next source byte
                    436:         or      al,ah           ;combine the source and dest
                    437:         stosb                   ;store the new byte
                    438: @@:
                    439: 
                    440: ; Do the middle (whole) bytes.
                    441: 
                    442:         mov     ecx,ulLeadingBytes
                    443:         rep     movsb
                    444:         mov     ecx,ulMiddleDwords
                    445:         rep     movsd
                    446: 
                    447: ; Do the right edge byte, if there's a partial right edge byte.
                    448: 
                    449:         mov     eax,ulRightMask ;AL = dest mask, AH = source mask
                    450:         and     al,al           ;any left mask?
                    451:         jz      short @F        ;right edge is whole
                    452:         and     al,[edi]        ;mask the dest
                    453:         and     ah,[esi]        ;mask the source
                    454:         inc     esi             ;point to next source byte
                    455:         or      al,ah           ;combine the source and dest
                    456:         stosb                   ;store the new byte
                    457: @@:
                    458: 
                    459:         jmp     copy_from_buffer_scan_done
                    460: 
                    461: ; Trailing odd whole bytes, but no leading whole bytes.
                    462:         align   4
                    463: copy_from_buffer_t:
                    464: 
                    465: ; Do the left edge byte, if there's a partial left edge byte.
                    466: 
                    467:         mov     eax,ulLeftMask  ;AL = dest mask, AH = source mask
                    468:         and     al,al           ;any left mask?
                    469:         jz      short @F        ;left edge is whole
                    470:         and     al,[edi]        ;mask the dest
                    471:         and     ah,[esi]        ;mask the source
                    472:         inc     esi             ;point to next source byte
                    473:         or      al,ah           ;combine the source and dest
                    474:         stosb                   ;store the new byte
                    475: @@:
                    476: 
                    477: ; Do the middle (whole) bytes.
                    478: 
                    479:         mov     ecx,ulMiddleDwords
                    480:         rep     movsd
                    481:         mov     ecx,ulTrailingBytes
                    482:         rep     movsb
                    483: 
                    484: ; Do the right edge byte, if there's a partial right edge byte.
                    485: 
                    486:         mov     eax,ulRightMask ;AL = dest mask, AH = source mask
                    487:         and     al,al           ;any left mask?
                    488:         jz      short @F        ;right edge is whole
                    489:         and     al,[edi]        ;mask the dest
                    490:         and     ah,[esi]        ;mask the source
                    491:         inc     esi             ;point to next source byte
                    492:         or      al,ah           ;combine the source and dest
                    493:         stosb                   ;store the new byte
                    494: @@:
                    495: 
                    496:         jmp     copy_from_buffer_scan_done
                    497: 
                    498: ; Only leading whole bytes (straight whole byte copy; no aligned dwords).
                    499:         align   4
                    500: copy_from_buffer_lonly:
                    501: 
                    502: ; Do the left edge byte, if there's a partial left edge byte.
                    503: 
                    504:         mov     eax,ulLeftMask  ;AL = dest mask, AH = source mask
                    505:         and     al,al           ;any left mask?
                    506:         jz      short @F        ;left edge is whole
                    507:         and     al,[edi]        ;mask the dest
                    508:         and     ah,[esi]        ;mask the source
                    509:         inc     esi             ;point to next source byte
                    510:         or      al,ah           ;combine the source and dest
                    511:         stosb                   ;store the new byte
                    512: @@:
                    513: 
                    514: ; Do the middle (whole) bytes.
                    515: 
                    516:         mov     ecx,ulLeadingBytes
                    517:         rep     movsb
                    518: 
                    519: ; Do the right edge byte, if there's a partial right edge byte.
                    520: 
                    521:         mov     eax,ulRightMask ;AL = dest mask, AH = source mask
                    522:         and     al,al           ;any left mask?
                    523:         jz      short @F        ;right edge is whole
                    524:         and     al,[edi]        ;mask the dest
                    525:         and     ah,[esi]        ;mask the source
                    526:         inc     esi             ;point to next source byte
                    527:         or      al,ah           ;combine the source and dest
                    528:         stosb                   ;store the new byte
                    529: @@:
                    530: 
                    531:         jmp     short copy_from_buffer_scan_done
                    532: 
                    533: ; Only one masked byte; no whole bytes and no right byte.
                    534:         align   4
                    535: copy_from_buffer_l_partial_only:
                    536: 
                    537:         mov     eax,ulLeftMask  ;AL = dest mask, AH = source mask
                    538:         and     al,[edi]        ;mask the dest
                    539:         and     ah,[esi]        ;mask the source
                    540:         inc     esi             ;point to next source byte
                    541:         or      al,ah           ;combine the source and dest
                    542:         stosb                   ;store the new byte
                    543:         jmp     short copy_from_buffer_scan_done
                    544: 
                    545: ; Only one whole byte; no left byte and no right byte.
                    546:         align   4
                    547: copy_from_buffer_l_whole_only:
                    548: 
                    549:         movsb                   ;copy the one byte
                    550:         jmp     short copy_from_buffer_scan_done
                    551: 
                    552: ; Leading and trailing odd whole bytes.
                    553:         align   4
                    554: copy_from_buffer_lt:
                    555: 
                    556: ; Do the left edge byte, if there's a partial left edge byte.
                    557: 
                    558:         mov     eax,ulLeftMask  ;AL = dest mask, AH = source mask
                    559:         and     al,al           ;any left mask?
                    560:         jz      short @F        ;left edge is whole
                    561:         and     al,[edi]        ;mask the dest
                    562:         and     ah,[esi]        ;mask the source
                    563:         inc     esi             ;point to next source byte
                    564:         or      al,ah           ;combine the source and dest
                    565:         stosb                   ;store the new byte
                    566: @@:
                    567: 
                    568: ; Do the middle (whole) bytes.
                    569: 
                    570:         mov     ecx,ulLeadingBytes
                    571:         rep     movsb
                    572:         mov     ecx,ulMiddleDwords
                    573:         rep     movsd
                    574:         mov     ecx,ulTrailingBytes
                    575:         rep     movsb
                    576: 
                    577: ; Do the right edge byte, if there's a partial right edge byte.
                    578: 
                    579:         mov     eax,ulRightMask ;AL = dest mask, AH = source mask
                    580:         and     al,al           ;any left mask?
                    581:         jz      short @F        ;right edge is whole
                    582:         and     al,[edi]        ;mask the dest
                    583:         and     ah,[esi]        ;mask the source
                    584:         inc     esi             ;point to next source byte
                    585:         or      al,ah           ;combine the source and dest
                    586:         stosb                   ;store the new byte
                    587: @@:
                    588: 
                    589: copy_from_buffer_scan_done:
                    590: 
                    591:         add     esi,ulSrcDelta  ;point to next source scan
                    592:         shr     bl,1            ;count down planes
                    593:         jnz     copy_to_buffer_plane_loop
                    594: 
                    595:         add     edi,ulDstDelta  ;point to next dest scan
                    596:         mov     pjDstStart,edi
                    597:         dec     ulBlockHeight   ;count down scans
                    598:         jnz     copy_to_buffer_scan_loop
                    599: 
                    600: ; Remember where we left off, for the next block.
                    601: 
                    602:         mov     pjSrcBuffer,esi
                    603: 
                    604: ;-----------------------------------------------------------------------;
                    605: ; See if there are more banks to do
                    606: ;-----------------------------------------------------------------------;
                    607: 
                    608:         mov     esi,pdsurf
                    609:         mov     eax,[esi].dsurf_rcl1WindowClip.yBottom ;is the copy bottom in
                    610:         cmp     ulBottomScan,eax                       ; the current bank?
                    611:         jle     short copy_from_buffer_banks_done        ;yes, so we're done
                    612:                                         ;no, map in the next bank and copy it
                    613:         mov     ulCurrentTopScan,eax    ;remember where the top of the bank
                    614:                                         ; we're about to map in is (same as
                    615:                                         ; bottom of bank we just did)
                    616:         mov     edx,[esi].dsurf_pvBitmapStart
                    617:         sub     pjDstStart,edx  ;convert from address to offset within bitmap
                    618: 
                    619:         ptrCall   <dword ptr [esi].dsurf_pfnBankControl>,<esi,eax,JustifyTop>
                    620:                                         ;map in the bank
                    621: 
                    622: ; Compute the starting address in this bank.
                    623: ; Note that the start of the bitmap will change each time through the
                    624: ; bank loop, because the start of the bitmap is varied to map the
                    625: ; desired scan line to the banking window.
                    626: 
                    627:         mov     eax,[esi].dsurf_pvBitmapStart
                    628:         add     pjDstStart,eax  ;address of next scan to draw
                    629: 
                    630: ; Copy the new bank.
                    631: 
                    632:         jmp     copy_from_buffer_bank_loop
                    633: 
                    634: 
                    635: ;-----------------------------------------------------------------------;
                    636: ; Done with all banks.
                    637: ;
                    638: ; At this point:
                    639: ;  DX = VGA_BASE + GRAF_DATA
                    640: ;-----------------------------------------------------------------------;
                    641:         align 4
                    642: copy_from_buffer_banks_done:
                    643: 
                    644:         mov     ax,(MM_ALL shl 8)+SEQ_MAP_MASK  ;restore writability for all planes
                    645:         mov     dx,VGA_BASE+SEQ_ADDR
                    646:         out     dx,ax
                    647: 
                    648:         cRet    vRestoreScreenBitsFromMemory ;done
                    649: 
                    650: ;-----------------------------------------------------------------------;
                    651: 
                    652: endProc vRestoreScreenBitsFromMemory
                    653: 
                    654: _TEXT$03   ends
                    655: 
                    656:         end
                    657: 
                    658: 

unix.superglobalmegacorp.com

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