Annotation of ntddk/src/video/displays/vga256/i386/stretch8.asm, revision 1.1.1.1

1.1       root        1: ;---------------------------Module-Header------------------------------;
                      2: ; Module Name: stretch.asm
                      3: ;
                      4: ; Copyright (c) 1992 Microsoft Corporation
                      5: ;-----------------------------------------------------------------------;
                      6: ;-----------------------------------------------------------------------;
                      7: ; INT vStretchBlt8bpp(PPDEV ppdev, PBYTE pSrc, LONG lSrcNext,
                      8: ;                     PRECTL prclSrc, PRECTL prclDest, PRECTL prclDestClip,
                      9: ;                     PULONG pulXlatVector)
                     10: ; Input:
                     11: ;
                     12: ; Performs accelerated stretch blts from 8-bit DIBs to 256-color VGA
                     13: ; display memory.
                     14: ;-----------------------------------------------------------------------;
                     15: ; Note: Does not handle source clipping.
                     16: ;
                     17: ; Note: Does not yet handle expansion, only shrinking.
                     18: ;-----------------------------------------------------------------------;
                     19: 
                     20:         comment $
                     21: 
                     22: ***
                     23: 
                     24: Note: in the noxlat loop, EBX isn't altered, so it could be used for
                     25: something else, like the scan line count. This isn't done currently
                     26: because the scan-line loop is shared by the xlat and noxlat cases, and
                     27: the xlat cases do alter EBX; separate loops would be needed in order
                     28: to perform this optimization.
                     29: 
                     30:         commend $
                     31: 
                     32: ;-----------------------------------------------------------------------;
                     33: 
                     34:                 .386
                     35: 
                     36: ifndef  DOS_PLATFORM
                     37:         .model  small,c
                     38: else
                     39: ifdef   STD_CALL
                     40:         .model  small,c
                     41: else
                     42:         .model  small,pascal
                     43: endif;  STD_CALL
                     44: endif;  DOS_PLATFORM
                     45: 
                     46:         assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
                     47:         assume fs:nothing,gs:nothing
                     48: 
                     49:         .xlist
                     50:         include stdcall.inc             ;calling convention cmacros
                     51:         include i386\strucs.inc
                     52:         include i386\driver.inc
                     53: 
                     54:         .list
                     55: 
                     56: ;-----------------------------------------------------------------------;
                     57: 
                     58:         .data
                     59: 
                     60: ;-----------------------------------------------------------------------;
                     61: 
                     62:         .code
                     63: 
                     64: ;-----------------------------------------------------------------------;
                     65: 
                     66: cProc vStretchBlt8bpp,28,< \
                     67:  uses esi edi ebx,         \
                     68:  ppdev:ptr,                \
                     69:  pSrc:ptr,                 \
                     70:  lSrcNext:dword,           \
                     71:  prclSrc:ptr,              \
                     72:  prclDest:ptr,             \
                     73:  prclDestClip:ptr,         \
                     74:  pulXlatVector:dword       >
                     75: 
                     76:         local   pulDDAArray:dword       ;pointer to array of n and n+1
                     77:                                         ; values generated by DDA, used to
                     78:                                         ; advance across source
                     79:         local   ulXStretchCount:dword   ;# of pixels or pixel pair to copy to
                     80:                                         ; (pixel pairs except in narrow
                     81:                                         ; cases; doesn't include leading or
                     82:                                         ; trailing single pixels in pixel
                     83:                                         ; pair cases)
                     84:         local   ulDestNext:dword         ;offset from last dest pixel on one
                     85:                                         ; scan to first on next
                     86:         local   ulSrcMinNext:dword      ;offset from start of one source scan
                     87:                                         ; to start of next scan that's skipped
                     88:                                         ; to by minimum DDA advance (basically,
                     89:                                         ; skips over n scans when DDA advances
                     90:                                         ; either n or n+1 scans)
                     91:         local   lYErrorTerm:dword       ;current error term for the DDA in Y
                     92:         local   ulYAdjUp:dword          ;error term adjust up for advancing
                     93:                                         ; DDA in Y
                     94:         local   ulYAdjDown:dword        ;error term adjust down for advancing
                     95:                                         ; DDA in Y
                     96:         local   ulDstTopScan:dword         ;top scan of dest text rect in
                     97:                                         ; current bank
                     98:         local   ulDstBottomScan :dword     ;bottom scan line of dest rectangle
                     99:         local   ulScanCount:dword       ;# of scans to stretch in current
                    100:                                         ; bank
                    101:         local   pfnRowVector:dword      ;pointer to routine to be used to
                    102:                                         ; stretch each row
                    103:         local   pfnStretchFn:dword      ;pointer to routine to do a bank's
                    104:                                         ; worth of stretching
                    105:         local   ulSrcTopScan:dword      ;top scan line of source from which
                    106:                                         ; to copy (after clipping, if needed)
                    107:         local   ulYMinStep:dword        ;minimum # of scans to skip in source
                    108:                                         ; when advancing dest one scan
                    109:         local   lXDstRight:dword        ;right edge of dest area to which to
                    110:                                         ; stretch, accounting for clipping
                    111:         local   lXDstLeft:dword         ;left edge of dest area to which to
                    112:                                         ; stretch, accounting for clipping
                    113:         local   ulXAdjUp:dword          ;X error term adjust up
                    114:         local   ulXMinStep:dword        ;X minimum step per dest 1-pixel step
                    115:         local   ulXAdjDown:dword        ;X error term adjust down
                    116:         local   lXSrcRight:dword        ;right edge of source area from which
                    117:                                         ; to stretch, accounting for clipping
                    118:         local   lXSrcLeft:dword         ;left edge of source area from which to
                    119:                                         ; stretch, accounting for clipping
                    120: 
                    121: ;-----------------------------------------------------------------------;
                    122: 
                    123:         mov     esi,prclSrc
                    124:         mov     edi,prclDest
                    125: 
                    126:         mov     eax,[esi].xRight
                    127:         mov     edx,[esi].xLeft
                    128:         mov     lXSrcLeft,edx
                    129:         sub     eax,edx         ;EAX = source width
                    130:         mov     ecx,[edi].xRight
                    131:         mov     lXDstRight,ecx
                    132:         mov     edx,[edi].xLeft
                    133:         mov     lXDstLeft,edx
                    134:         sub     ecx,edx         ;ECX = dest width
                    135: 
                    136:         cmp     eax,ecx         ;shrink or stretch in X?
                    137:         jge     short x_shrink  ;shrink
                    138:                                 ;stretch
                    139: ;@@@
                    140: DoneFailed:
                    141:         sub     eax,eax         ;@@@shouldn't have to return a value
                    142:         jmp     done
                    143: 
                    144: ;The destination is narrower than the source
                    145: x_shrink:
                    146:         mov     pfnStretchFn,offset shrink_8bpp_loop
                    147: 
                    148: ;-----------------------------------------------------------------------;
                    149: ; Precalculate the DDA steps for X and store them in the temp buffer. We know
                    150: ; these will fit in the temp buffer, because there are only, say, 2K steps
                    151: ; max across the screen, and the temp buffer is guaranteed to be more than
                    152: ; 2K*4 = 8K bytes long.
                    153: ;
                    154: ; At this point, EAX = source width, ECX = destination width
                    155: ;-----------------------------------------------------------------------;
                    156: 
                    157:         sub     edx,edx         ;prepare for division
                    158:         div     ecx             ;SourceDeltaX / DestDeltaX
                    159:         mov     ulXMinStep,eax  ;EAX = minimum step in source for 1 dest step
                    160: 
                    161:         mov     esi,edx         ;set aside SourceDeltaX % DestDeltaX
                    162:         add     edx,edx         ;scale up ulXAdjUp by 2 so we can handle a
                    163:                                 ; half-pixel advance
                    164:         mov     ulXAdjUp,edx    ;ulXAdjUp = (SourceDeltaX % DestDeltaX)*2
                    165: 
                    166:                                 ;prestep source X coord and error term by 1/2
                    167:                                 ; a destination pixel, so we pick the source
                    168:                                 ; pixel that most closely matches the center
                    169:                                 ; of each destination pixel
                    170: 
                    171:                                 ;step by 1/2 the whole source pixel advance
                    172:                                 ; per destination step
                    173:         shr     eax,1           ;minimum step/2
                    174:         jnc     short @F        ;odd
                    175:                                 ;even
                    176:         add     esi,ecx         ;advance error term for 1/2 of the source
                    177:                                 ; pixel we just split (by DestDeltaX)
                    178: @@:
                    179:         add     lXSrcLeft,eax   ;advance 1/2 minimum step in source
                    180:         add     ecx,ecx         ;scale up DestDeltaX by 2 so we can handle a
                    181:                                 ; half-pixel advance
                    182:         mov     ulXAdjDown,ecx  ;ulXAdjDown = DestDeltaX*2
                    183: 
                    184:         sub     esi,ecx         ;initial error term = -(DestDeltaX*2) + 1/2
                    185:                                 ; normal error term step (for 1/2 pixel dest
                    186:                                 ; advance effect on error term; note that 1/2
                    187:                                 ; effect on whole source pixels has already
                    188:                                 ; been accounted for)
                    189: 
                    190: ;-----------------------------------------------------------------------;
                    191: ; Clip to the dest in X, if necessary.
                    192: ;-----------------------------------------------------------------------;
                    193: 
                    194:         mov     ebx,prclDestClip
                    195:         and     ebx,ebx                 ;any clipping?
                    196:         jz      short x_clip_done       ;no, all set
                    197:         mov     eax,[ebx].xRight        ;right clip edge
                    198:         cmp     eax,lXDstRight          ;is the right edge clipped?
                    199:         jge     short check_x_left_clip ;no
                    200:                                         ;right edge is clipped
                    201:         mov     lXDstRight,eax          ;set the clipped right edge
                    202: check_x_left_clip:
                    203:         mov     eax,[ebx].xLeft         ;left clip edge
                    204:         cmp     eax,lXDstLeft           ;is the left edge clipped?
                    205:         jle     short check_x_not_fully_clipped ;no
                    206:                                         ;left edge is clipped
                    207:         mov     edx,lXDstLeft           ;get the unclipped dest left edge
                    208:         mov     lXDstLeft,eax           ;set the clipped dest left edge
                    209:                                         ;now figure out how many source pixels
                    210:                                         ; were clipped, and advance the error
                    211:                                         ; term appropriately
                    212:         sub     eax,edx                 ;# of dest pixels clipped
                    213:         mov     ecx,eax                 ;set aside # of dest pixels to skip
                    214:         mul     ulXAdjUp                ;# of adjust ups in the course of the
                    215:                                         ; skipped pixels
                    216:         add     esi,eax                 ;EDX:ESI = error term after skipping
                    217:         adc     edx,-1                  ;(the initial error term is negative;
                    218:                                         ; this stretches it to 64 bits)
                    219:         jnc     short check_x_not_fully_clipped ;didn't turn over even once
                    220:         mov     eax,esi                 ;EDX:EAX = error term after skipping
                    221:         div     ulXAdjDown              ;EAX = # of times to adjust down
                    222:                                         ; while skipping pixels, minus 1
                    223:         sub     edx,ulXAdjDown          ;do the last adjust down, to cross
                    224:                                         ; back into negative territory where
                    225:                                         ; the error term belongs
                    226:         mov     esi,edx                 ;error term at new, clipped dest left
                    227:                                         ; edge
                    228:         inc     eax                     ;count the last adjust down (# of times
                    229:                                         ; source error turned over while
                    230:                                         ; advancing to the clipped left edge)
                    231:         imul    ecx,ulXMinStep          ;# of whole pixels skipped in source
                    232:                                         ; while advancing to dest clip left
                    233:                                         ; edge
                    234:         add     eax,ecx                 ;total # of pixels skipped in source
                    235:                                         ; while advancing to dest clip left
                    236:                                         ; edge
                    237:         add     lXSrcLeft,eax           ;advance the source left edge to match
                    238:                                         ; advancing the destination left edge
                    239:                                         ; to the left edge of the clip
                    240:                                         ; rectangle
                    241: check_x_not_fully_clipped:
                    242:         mov     eax,lXDstLeft
                    243:         cmp     lXDstRight,eax          ;is the destination fully x-clipped?
                    244:         jle     done                    ;yes, nothing to draw
                    245: x_clip_done:
                    246: 
                    247: ;-----------------------------------------------------------------------;
                    248: ; Now actually generate the (possibly clipped) X DDA skip array
                    249: ;
                    250: ; At this point, ESI = X error term for left edge (accounting for any
                    251: ; X clipping that has occurred)
                    252: ;-----------------------------------------------------------------------;
                    253: 
                    254:         mov     edx,ppdev
                    255:         mov     eax,ulXMinStep
                    256:         mov     edi,[edx].pdev_pvTmp ;we'll store the DDA steps in the temp
                    257:         mov     pulDDAArray,edi      ; buffer
                    258: 
                    259:         mov     edx,ulXAdjUp
                    260:         mov     ebx,ulXAdjDown
                    261:         mov     ecx,lXDstRight
                    262:         sub     ecx,lXDstLeft   ;ECX = # of pixels per dest scan
                    263:         push    ecx             ;remember # of dest pixels across
                    264:         push    ebp             ;preserve stack frame pointer
                    265:         lea     ebp,[eax+1]     ;maximum step
                    266:                                 ;***stack frame unavailable***
                    267: x_shrink_set_dda_loop:
                    268:         add     esi,edx         ;adjust the error term up
                    269:         jnc     short x_shrink_set_dda_min ;didn't turn over, so advance
                    270:                                            ; minimum step
                    271: x_shrink_set_dda_max:
                    272:         sub     esi,ebx         ;turned over; adjust error term back down
                    273:         mov     [edi],ebp       ;advance by maximum step
                    274:         add     edi,4           ;point to next DDA array storage location
                    275:         dec     ecx             ;count down steps
                    276:         jz      short x_shrink_set_dda_done ;no more steps
                    277:         add     esi,edx         ;adjust the error term up
                    278:         jc      x_shrink_set_dda_max ;did turn over, so advance maximum step
                    279: x_shrink_set_dda_min:
                    280:         mov     [edi],eax       ;advance by minimum step
                    281:         add     edi,4           ;point to next DDA array storage location
                    282:         dec     ecx             ;count down steps
                    283:         jnz     x_shrink_set_dda_loop
                    284: x_shrink_set_dda_done:
                    285:         mov     dword ptr [edi],0 ;mark the end of the DDA
                    286:         pop     ebp             ;restore stack frame pointer
                    287:                                 ;***stack frame available***
                    288:         pop     ecx             ;retrieve # of dest pixels across
                    289: 
                    290:         mov     edi,prclDest
                    291:         cmp     pulXlatVector,0         ;translation?
                    292:         jz      short x_shrink_noxlat   ;no
                    293:                                         ;yes
                    294:         cmp     ecx,3           ;narrow case?
                    295:         ja      short @F        ;no
                    296:         mov     pfnRowVector,offset shrink_xlat_8bpp_narrow     ;narrow case
                    297:         mov     ulXStretchCount,ecx     ;do all dest pixels one at a time
                    298:         jmp     check_y_shrink
                    299: @@:                             ;not narrow case; figure out which wide case,
                    300:                                 ; based on the need to perform as many word-
                    301:                                 ; aligned writes to display memory as possible
                    302:         mov     edx,ecx
                    303:         test    [edi].xLeft,1   ;starting at an odd destination address?
                    304:         jnz     short x_shrink_xlat_leading ;yes, need leading pixel
                    305:         mov     pfnRowVector,offset shrink_xlat_8bpp_nl_nt
                    306:                                         ;assume no leading or trailing pixels
                    307:         shr     edx,1                   ;destination width in pixel pairs
                    308:         mov     ulXStretchCount,edx     ;count of pixel pairs to draw
                    309:         jnc     short check_y_shrink  ;no leading or trailing pixels
                    310:         mov     pfnRowVector,offset shrink_xlat_8bpp_nl_t
                    311:                                         ;no leading pixel, is a trailing pixel
                    312:         jmp     short check_y_shrink
                    313: x_shrink_xlat_leading:                  ;there is a leading pixel
                    314:         mov     pfnRowVector,offset shrink_xlat_8bpp_l_nt
                    315:                                         ;assume no trailing pixel
                    316:         shr     edx,1                   ;destination width in pixel pairs
                    317:         mov     ulXStretchCount,edx     ;count of pixel pairs to draw
                    318:         jc      short check_y_shrink  ;no trailing pixel
                    319:         mov     pfnRowVector,offset shrink_xlat_8bpp_l_t
                    320:                                         ;both leading and trailing pixels
                    321:         dec     edx                     ;we'll do one pixel pair in the form
                    322:                                         ; of the leading/trailing pixel pair
                    323:         mov     ulXStretchCount,edx     ;count of pixel pairs to draw
                    324:         jmp     short check_y_shrink
                    325: 
                    326: x_shrink_noxlat:                        ;no translation
                    327:         cmp     ecx,3           ;narrow case?
                    328:         ja      short @F        ;no
                    329:         mov     pfnRowVector,offset shrink_noxlat_8bpp_narrow   ;narrow case
                    330:         mov     ulXStretchCount,ecx     ;do all dest pixels one at a time
                    331:         jmp     short check_y_shrink
                    332: @@:                             ;not narrow case; figure out which wide case,
                    333:                                 ; based on the need to perform as many word-
                    334:                                 ; aligned writes to display memory as possible
                    335:         mov     edx,ecx
                    336:         test    [edi].xLeft,1   ;starting at an odd destination address?
                    337:         jnz     short x_shrink_noxlat_leading ;yes, need leading pixel
                    338:         mov     pfnRowVector,offset shrink_noxlat_8bpp_nl_nt
                    339:                                         ;assume no leading or trailing pixels
                    340:         shr     edx,1                   ;destination width in pixel pairs
                    341:         mov     ulXStretchCount,edx     ;count of pixel pairs to draw
                    342:         jnc     short check_y_shrink  ;no leading or trailing pixels
                    343:         mov     pfnRowVector,offset shrink_noxlat_8bpp_nl_t
                    344:                                         ;no leading pixel, is a trailing pixel
                    345:         jmp     short check_y_shrink
                    346: x_shrink_noxlat_leading:                ;there is a leading pixel
                    347:         mov     pfnRowVector,offset shrink_noxlat_8bpp_l_nt
                    348:                                         ;assume no trailing pixel
                    349:         shr     edx,1                   ;destination width in pixel pairs
                    350:         mov     ulXStretchCount,edx     ;count of pixel pairs to draw
                    351:         jc      short check_y_shrink  ;no trailing pixel
                    352:         mov     pfnRowVector,offset shrink_noxlat_8bpp_l_t
                    353:                                         ;both leading and trailing pixels
                    354:         dec     edx                     ;we'll do one pixel pair in the form
                    355:                                         ; of the leading/trailing pixel pair
                    356:         mov     ulXStretchCount,edx     ;count of pixel pairs to draw
                    357: 
                    358: check_y_shrink:
                    359: 
                    360:         mov     esi,edi                 ;ESI->prclDest
                    361:         mov     edi,prclSrc             ;EDI->prclSrc
                    362:         mov     eax,[edi].yBottom
                    363:         mov     ecx,[edi].yTop
                    364:         mov     ulSrcTopScan,ecx
                    365:         sub     eax,ecx                 ;EAX = source height
                    366:         mov     ecx,[esi].yBottom
                    367:         mov     ulDstBottomScan,ecx
                    368:         mov     edx,[esi].yTop
                    369:         mov     ulDstTopScan,edx
                    370:         sub     ecx,edx         ;ECX = dest height
                    371: 
                    372:         cmp     eax,ecx         ;shrink or stretch in Y?
                    373:         jge     short y_shrink  ;shrink
                    374:                                 ;stretch
                    375: ;@@@
                    376:         sub     eax,eax         ;@@@shouldn't have to return a value
                    377:         jmp     done
                    378: 
                    379: ;The destination is shorter than the source; calculate the error term values
                    380: ; for advancing through the source on a per-dest-scan-line basis.
                    381: y_shrink:
                    382:         sub     edx,edx         ;prepare for division
                    383:         div     ecx             ;SourceDeltaY/DestDeltaY
                    384:         mov     ulYMinStep,eax  ;EAX = minimum step in source for 1 dest step
                    385: 
                    386:         mov     ebx,edx         ;set aside SourceDeltaY % DestDeltaY
                    387:         add     edx,edx         ;scale up ulYAdjUp by 2 so we can handle a
                    388:                                 ; half-pixel advance
                    389:         mov     ulYAdjUp,edx    ;ulYAdjUp = (SourceDeltaY % DestDeltaY)*2
                    390: 
                    391:         imul    lSrcNext        ;(minimum step * source scan width in bytes)
                    392:         mov     ulSrcMinNext,eax ; = minimum offset by which to advance from
                    393:                                  ; one scan to the next
                    394: 
                    395:                                 ;prestep source X coord and error term by 1/2
                    396:                                 ; a destination pixel, so we pick the source
                    397:                                 ; pixel that most closely matches the center
                    398:                                 ; of each destination pixel
                    399: 
                    400:                                 ;step by 1/2 the whole source pixel advance
                    401:                                 ; per destination step
                    402:         mov     eax,ulYMinStep  ;retrieve minimum step
                    403:         shr     eax,1           ;minimum step/2
                    404:         jnc     short @F        ;odd
                    405:                                 ;even
                    406:         add     ebx,ecx         ;advance error term for 1/2 of the source
                    407:                                 ; pixel we just split
                    408: @@:
                    409:         add     ulSrcTopScan,eax ;advance 1/2 minimum step in source
                    410: 
                    411:         add     ecx,ecx         ;scale up DestDeltaY by 2 so we can handle a
                    412:                                 ; half-pixel advance
                    413:         mov     ulYAdjDown,ecx  ;ulYAdjDown = DestDeltaY*2
                    414: 
                    415:         sub     ebx,ecx         ;initial error term = -(DestDeltaY*2) + 1/2
                    416:                                 ; normal error term step (for 1/2 pixel dest
                    417:                                 ; advance effect on error term; note that 1/2
                    418:                                 ; effect on whole source pixels has already
                    419:                                 ; been accounted for)
                    420:         mov     lYErrorTerm,ebx
                    421: 
                    422: ;-----------------------------------------------------------------------;
                    423: ; Clip in Y, if necessary.
                    424: ;-----------------------------------------------------------------------;
                    425: 
                    426:         mov     ebx,prclDestClip
                    427:         and     ebx,ebx                 ;any clipping?
                    428:         jz      short y_clip_done       ;no, all set
                    429:         mov     eax,[ebx].yBottom       ;yes, clipping
                    430:                                         ;see if the dest is clipped off the
                    431:                                         ; bottom
                    432:         cmp     ulDstBottomScan,eax     ;is the bottom clipped?
                    433:         jle     short check_y_top_clip  ;no, check the top
                    434:         mov     ulDstBottomScan,eax     ;yes, set the new bottom
                    435: check_y_top_clip:
                    436:                                         ;see if the dest is clipped off the
                    437:                                         ; top
                    438:         mov     eax,[ebx].yTop
                    439:         cmp     ulDstTopScan,eax        ;is the top clipped?
                    440:         jge     short check_y_not_fully_clipped ;no
                    441:                                         ;yes, so advance the top scan and the
                    442:                                         ; error term accordingly
                    443:         mov     ulDstTopScan,eax        ;top of clipped destination rectangle
                    444:         sub     eax,[esi].yTop          ;# of destination scans to skip
                    445:         mov     ecx,eax                 ;set aside # of dest scans to skip
                    446:         mul     ulYAdjUp                ;# of adjust ups in the course of the
                    447:                                         ; skipped scans
                    448:         add     eax,lYErrorTerm         ;EDX:EAX = error term after skipping
                    449:         adc     edx,-1                  ;(the initial error term is negative;
                    450:                                         ; this stretches it to 64 bits)
                    451:         jnc     short check_y_not_fully_clipped ;didn't turn over even once
                    452:         div     ulYAdjDown              ;EAX = # of times to adjust down
                    453:                                         ; while skipping scans, minus 1
                    454:         sub     edx,ulYAdjDown          ;do the last adjust down, to cross
                    455:                                         ; back into negative territory where
                    456:                                         ; the error term belongs
                    457:         mov     lYErrorTerm,edx         ;error term at new, clipped dest top
                    458:         inc     eax                     ;count the last adjust down (# of
                    459:                                         ; times source error has turned over)
                    460:         imul    ecx,ulYMinStep          ;# of whole steps in source while
                    461:                                         ; advancing to dest clip top
                    462:         add     eax,ecx                 ;total # of scans skipped in source
                    463:                                         ; while advancing to dest clip top
                    464:         add     ulSrcTopScan,eax        ;advance the source top edge to match
                    465:                                         ; advancing the destination top edge to
                    466:                                         ; the top of the clip rectangle
                    467: check_y_not_fully_clipped:
                    468:         mov     eax,ulDstTopScan
                    469:         cmp     ulDstBottomScan,eax        ;is the destination fully y-clipped?
                    470:         jle     done                    ;yes, nothing to draw
                    471: y_clip_done:
                    472: 
                    473: ;-----------------------------------------------------------------------;
                    474: ; Calculate the offset of the initial destination pixel.
                    475: ;-----------------------------------------------------------------------;
                    476: 
                    477:         mov     ebx,ppdev
                    478:         mov     eax,ulDstTopScan   ;top scan line of text
                    479:         mov     esi,[ebx].pdev_lDeltaScreen
                    480:         mul     esi
                    481:         mov     edi,lXDstLeft
                    482:         mov     ecx,lXDstRight
                    483:         sub     ecx,edi         ;dest width
                    484:         sub     esi,ecx         ;dest width - width of a dest scan to stretch
                    485:         mov     ulDestNext,esi  ;offset from end of one dest stretched
                    486:                                 ; scan to start of next
                    487:         add     edi,eax
                    488: 
                    489: ;-----------------------------------------------------------------------;
                    490: ; Map in the bank containing the top scan of the text, if it's not
                    491: ; mapped in already.
                    492: ;-----------------------------------------------------------------------;
                    493: 
                    494:         mov     eax,ulDstTopScan   ;top scan line of text
                    495:         cmp     eax,[ebx].pdev_rcl1WindowClip.yTop ;is text top less than
                    496:                                                    ; current bank?
                    497:         jl      short map_init_bank                ;yes, map in proper bank
                    498:         cmp     eax,[ebx].pdev_rcl1WindowClip.yBottom ;text top greater than
                    499:                                                       ; current bank?
                    500:         jl      short init_bank_mapped        ;no, proper bank already mapped
                    501: map_init_bank:
                    502: 
                    503: ; Map in the bank containing the top scan line of the destination.
                    504: ; Preserves EBX, ESI, and EDI.
                    505: 
                    506:         ptrCall <dword ptr [ebx].pdev_pfnBankControl>,<ebx,eax,JustifyTop>
                    507: 
                    508: init_bank_mapped:
                    509: 
                    510:         add     edi,[ebx].pdev_pvBitmapStart    ;initial destination address
                    511: 
                    512: ;-----------------------------------------------------------------------;
                    513: ; Calculate the offset of the initial source pixel.
                    514: ;-----------------------------------------------------------------------;
                    515: 
                    516:         mov     esi,prclSrc
                    517:         mov     eax,lSrcNext
                    518:         imul    ulSrcTopScan
                    519:         mov     esi,lXSrcLeft
                    520:         add     esi,eax
                    521:         add     esi,pSrc
                    522: 
                    523: ;-----------------------------------------------------------------------;
                    524: ; Main loop for processing stretch blt in each bank.
                    525: ;
                    526: ; At start of loop, EBX->ppdev, ESI->current src, EDI->current dst
                    527: ;-----------------------------------------------------------------------;
                    528: 
                    529: bank_loop:
                    530:         mov     edx,ulDstBottomScan        ;bottom of destination rectangle
                    531:         cmp     edx,[ebx].pdev_rcl1WindowClip.yBottom
                    532:                                         ;which comes first, the bottom of the
                    533:                                         ; text rect or the bottom of the
                    534:                                         ; current bank?
                    535:         jl      short @F                ;text bottom comes first, so draw to
                    536:                                         ; that; this is the last bank in text
                    537:         mov     edx,[ebx].pdev_rcl1WindowClip.yBottom
                    538:                                         ;bank bottom comes first; draw to
                    539:                                         ; bottom of bank
                    540: @@:
                    541:         sub     edx,ulDstTopScan           ;# of scans to draw in bank
                    542:         mov     ulScanCount,edx
                    543: 
                    544:         call    pfnStretchFn    ;stretch the bitmap block that's in this bank
                    545: 
                    546: ;-----------------------------------------------------------------------;
                    547: ; See if there are more banks to draw.
                    548: ;-----------------------------------------------------------------------;
                    549: 
                    550:         mov     ebx,ppdev
                    551:         mov     eax,[ebx].pdev_rcl1WindowClip.yBottom ;is the text bottom in
                    552:         cmp     ulDstBottomScan,eax                   ; the current bank?
                    553:         jnle    short do_next_bank      ;no, map in the next bank and draw
                    554:         mov     eax,1                   ;success
                    555:                                         ;@@@shouldn't return a value
                    556: done:
                    557:         cRet    vStretchBlt8bpp         ;yes, so we're done
                    558: 
                    559:         align   4
                    560: do_next_bank:
                    561:         mov     ulDstTopScan,eax
                    562:         sub     edi,[ebx].pdev_pvBitmapStart ;convert from address to offset
                    563:                                              ; within bitmap
                    564:         ptrCall <dword ptr [ebx].pdev_pfnBankControl>,<ebx,eax,JustifyTop>
                    565:                                              ;map in the bank (call preserves
                    566:                                              ; EBX, ESI, and EDI)
                    567:         add     edi,[ebx].pdev_pvBitmapStart ;convert from offset within bitmap
                    568:                                              ; to address (bitmap start just
                    569:                                              ; moved)
                    570:         jmp     bank_loop                    ;we're ready to draw to the new
                    571:                                              ; bank
                    572: 
                    573: ;-----------------------------------------------------------------------;
                    574: ; Shrink in X and Y, xlat or noxlat, 8-bpp source, VGA dest
                    575: ;
                    576: ; On entry: ESI->first source pixel to copy from
                    577: ;           EDI->first dest pixel to copy to
                    578: ;           pulXlatVector = pointer to color translation array (xlat cases
                    579: ;                           only)
                    580: ;           ulSrcMinNext = minimum offset from end of current source scan to
                    581: ;                          start of next source scan to stretch
                    582: ;           lSrcNext = offset from start of one source scan to start of next
                    583: ;           ulDestNext = offset from end of current dest scan to start of
                    584: ;                        next dest scan to stretch to
                    585: ;           pfnRowVector = pointer to routine to call to stretch one scan
                    586: ;           ulScanCount = # of scans to stretch
                    587: ;           lYErrorTerm, ulYAdjUp, ulYAdjDown = Y DDA error term components
                    588: ;
                    589: ; On exit:  ESI->next source pixel to copy from
                    590: ;           EDI->next dest pixel to copy to
                    591: ;           lYErrorTerm advanced for next scan
                    592: ;-----------------------------------------------------------------------;
                    593: 
                    594: shrink_8bpp_loop:
                    595:         sub     ebx,ebx         ;prepare EBX=0 for xlat-case row-drawing
                    596:                                 ; routines
                    597: shrink_block_8bpp_loop:
                    598:         mov     edx,pulDDAArray ;point to array of skip values to use to scan
                    599:                                 ; across the source
                    600:         mov     ecx,ulXStretchCount ;# of pixels or pixel pairs to copy to
                    601:         push    esi             ;preserve source pointer
                    602:         call    pfnRowVector    ;stretch/shrink this row
                    603:         pop     esi             ;restore source pointer
                    604:         add     esi,ulSrcMinNext ;point to start of next source row, assuming
                    605:                                  ; no extra row for error term turnover
                    606:         mov     eax,lYErrorTerm
                    607:         add     eax,ulYAdjUp    ;advance the error term
                    608:         jnc     short @F        ; didn't turn over (minimum step)
                    609:         sub     eax,ulYAdjDown  ;turned over, adjust down and...
                    610:         add     esi,lSrcNext    ; advance an extra scan (maximum step)
                    611: @@:
                    612:         mov     lYErrorTerm,eax ;remember the new error term
                    613:         add     edi,ulDestNext  ;point to start of next destination row
                    614:         dec     ulScanCount     ;count down scans
                    615:         jnz     shrink_block_8bpp_loop
                    616:         retn
                    617: 
                    618: ;-----------------------------------------------------------------------;
                    619: ; Single-row optimizations, called out of main stretch loops.
                    620: ;-----------------------------------------------------------------------;
                    621: 
                    622: ;-----------------------------------------------------------------------;
                    623: ; Shrink in X
                    624: ; No xlat
                    625: ; 8-bit source
                    626: ; Writes a word at a time
                    627: ;
                    628: ; Input: ECX = number of pixel pairs to do, not counting leading and trailing
                    629: ;              single pixels (except in narrow case, where ECX = number of
                    630: ;              pixels, not pixel pairs)
                    631: ;        EDX = pointer to pre-computed skip array
                    632: ;        ESI = pointer to initial source pixel
                    633: ;        EDI = pointer to initial destination pixel
                    634: ;
                    635: ; Output: ESI = pointer after last source pixel processed
                    636: ;         EDI = pointer after last source pixel processed
                    637: ;
                    638: ; EBX and EBP are preserved
                    639: ; The contents of EAX, ECX, and EDX may be destroyed
                    640: ;-----------------------------------------------------------------------;
                    641: 
                    642: ; No leading byte, no trailing byte.
                    643: 
                    644: shrink_noxlat_8bpp_nl_nt:
                    645: shrink_noxlat_8bpp_nl_nt_pixel_loop:
                    646:         mov     al,[esi]        ;get first source pixel
                    647:         add     esi,[edx]       ;point to next source pixel
                    648:         mov     ah,[esi]        ;get second source pixel
                    649:         add     esi,[edx+4]     ;point to next source pixel
                    650:         add     edx,8           ;point to next skip entry
                    651:         mov     [edi],ax        ;write both pixels to the destination
                    652:         add     edi,2           ;point to next destination pixel
                    653:         dec     ecx             ;count down pixel pairs
                    654:         jnz     shrink_noxlat_8bpp_nl_nt_pixel_loop
                    655:         retn
                    656: 
                    657: ; Leading byte, no trailing byte.
                    658: 
                    659: shrink_noxlat_8bpp_l_nt:
                    660:                                 ;do the leading pixel
                    661:         mov     al,[esi]        ;get the current source pixel
                    662:         add     esi,[edx]       ;point to next source pixel
                    663:         add     edx,4           ;point to next skip entry
                    664:         mov     [edi],al        ;write the pixel to the destination
                    665:         inc     edi             ;point to next destination pixel
                    666:                                 ;now do pixel pairs across the middle
                    667: shrink_noxlat_8bpp_l_nt_pixel_loop:
                    668:         mov     al,[esi]        ;get first source pixel
                    669:         add     esi,[edx]       ;point to next source pixel
                    670:         mov     ah,[esi]        ;get second source pixel
                    671:         add     esi,[edx+4]     ;point to next source pixel
                    672:         add     edx,8           ;point to next skip entry
                    673:         mov     [edi],ax        ;write both pixels to the destination
                    674:         add     edi,2           ;point to next destination pixel
                    675:         dec     ecx             ;count down pixel pairs
                    676:         jnz     shrink_noxlat_8bpp_l_nt_pixel_loop
                    677:         retn
                    678: 
                    679: ; Leading byte, trailing byte.
                    680: 
                    681: shrink_noxlat_8bpp_l_t:
                    682:                                 ;do the leading pixel
                    683:         mov     al,[esi]        ;get current source pixel
                    684:         add     esi,[edx]       ;point to next source pixel
                    685:         add     edx,4           ;point to next skip entry
                    686:         mov     [edi],al        ;write the pixel to the destination
                    687:         inc     edi             ;point to next destination pixel
                    688:                                 ;now do pixel pairs across the middle
                    689: shrink_noxlat_8bpp_l_t_pixel_loop:
                    690:         mov     al,[esi]        ;get first source pixel
                    691:         add     esi,[edx]       ;point to next source pixel
                    692:         mov     ah,[esi]        ;get second source pixel
                    693:         add     esi,[edx+4]     ;point to next source pixel
                    694:         add     edx,8           ;point to next skip entry
                    695:         mov     [edi],ax        ;write both pixels to the destination
                    696:         add     edi,2           ;point to next destination pixel
                    697:         dec     ecx             ;count down pixel pairs
                    698:         jnz     shrink_noxlat_8bpp_l_t_pixel_loop
                    699:                                 ;do the trailing pixel
                    700:         mov     al,[esi]        ;get current source pixel
                    701:         add     esi,[edx]       ;point to next source pixel
                    702:         add     edx,4           ;point to next skip entry
                    703:         mov     [edi],al        ;write the pixel to the destination
                    704:         inc     edi             ;point to next destination pixel
                    705:         retn
                    706: 
                    707: ; No leading byte, trailing byte.
                    708: 
                    709: shrink_noxlat_8bpp_nl_t:
                    710: shrink_noxlat_8bpp_nl_t_pixel_loop:
                    711:         mov     al,[esi]        ;get first source pixel
                    712:         add     esi,[edx]       ;point to next source pixel
                    713:         mov     ah,[esi]        ;get second source pixel
                    714:         add     esi,[edx+4]     ;point to next source pixel
                    715:         add     edx,8           ;point to next skip entry
                    716:         mov     [edi],ax        ;write both pixels to the destination
                    717:         add     edi,2           ;point to next destination pixel
                    718:         dec     ecx             ;count down pixel pairs
                    719:         jnz     shrink_noxlat_8bpp_nl_t_pixel_loop
                    720:                                 ;do the trailing pixel
                    721:         mov     al,[esi]        ;get current source pixel
                    722:         add     esi,[edx]       ;point to next source pixel
                    723:         add     edx,4           ;point to next skip entry
                    724:         mov     [edi],al        ;write the pixel to the destination
                    725:         inc     edi             ;point to next destination pixel
                    726:         retn
                    727: 
                    728: ; Narrow case, a byte at a time.
                    729: 
                    730: shrink_noxlat_8bpp_narrow:
                    731: shrink_noxlat_8bpp_narrow_pixel_loop:
                    732:         mov     al,[esi]        ;get current source pixel
                    733:         add     esi,[edx]       ;point to next source pixel
                    734:         add     edx,4           ;point to next skip entry
                    735:         mov     [edi],al        ;write the pixel to the destination
                    736:         inc     edi             ;point to next destination pixel
                    737:         dec     ecx             ;count down pixels
                    738:         jnz     shrink_noxlat_8bpp_narrow_pixel_loop
                    739:         retn
                    740: 
                    741: ;-----------------------------------------------------------------------;
                    742: ; Shrink in X
                    743: ; Xlat
                    744: ; 8-bit source
                    745: ; Writes a word at a time
                    746: ;
                    747: ; Input: EBX upper three bytes = zero (0)
                    748: ;        ECX = number of pixel pairs to do, not counting leading and trailing
                    749: ;              single pixels (except in narrow case, where ECX = number of
                    750: ;              pixels, not pixel pairs)
                    751: ;        EDX = pointer to pre-computed skip array
                    752: ;        ESI = pointer to initial source pixel
                    753: ;        EDI = pointer to initial destination pixel
                    754: ;        pulXlatVector = pointer to color translation array
                    755: ;
                    756: ; Output: ESI = pointer after last source pixel processed
                    757: ;         EDI = pointer after last source pixel processed
                    758: ;
                    759: ; EBP is preserved
                    760: ; The upper three bytes of EBX are preserved
                    761: ; The contents of EAX, BL, ECX, and EDX may be destroyed
                    762: ;-----------------------------------------------------------------------;
                    763: 
                    764: ; No leading byte, no trailing byte.
                    765: 
                    766: shrink_xlat_8bpp_nl_nt:
                    767:         push    ebp             ;***stack frame not available***
                    768:         mov     ebp,pulXlatVector ;point EBP to the translation table
                    769: shrink_xlat_8bpp_nl_nt_pixel_loop:
                    770:         mov     bl,[esi]        ;get first source pixel
                    771:         add     esi,[edx]       ;point to next source pixel
                    772:         mov     eax,[ebp+ebx*4] ;translate the pixel color
                    773:         mov     bl,[esi]        ;get second source pixel
                    774:         add     esi,[edx+4]     ;point to next source pixel
                    775:         mov     ah,[ebp+ebx*4]  ;translate the pixel color
                    776:         add     edx,8           ;point to next skip entry
                    777:         mov     [edi],ax        ;write both pixels to the destination
                    778:         add     edi,2           ;point to next destination pixel
                    779:         dec     ecx             ;count down pixel pairs
                    780:         jnz     shrink_xlat_8bpp_nl_nt_pixel_loop
                    781:         pop     ebp             ;***stack frame available***
                    782:         retn
                    783: 
                    784: ; Leading byte, no trailing byte.
                    785: 
                    786: shrink_xlat_8bpp_l_nt:
                    787:         push    ebp             ;***stack frame not available***
                    788:         mov     ebp,pulXlatVector ;point EBP to the translation table
                    789:                                 ;do the leading pixel
                    790:         mov     bl,[esi]        ;get first source pixel
                    791:         add     esi,[edx]       ;point to next source pixel
                    792:         mov     eax,[ebp+ebx*4] ;translate the pixel color
                    793:         add     edx,4           ;point to next skip entry
                    794:         mov     [edi],al        ;write the pixel to the destination
                    795:         inc     edi             ;point to next destination pixel
                    796:                                 ;now do pixel pairs across the middle
                    797: shrink_xlat_8bpp_l_nt_pixel_loop:
                    798:         mov     bl,[esi]        ;get first source pixel
                    799:         add     esi,[edx]       ;point to next source pixel
                    800:         mov     eax,[ebp+ebx*4] ;translate the pixel color
                    801:         mov     bl,[esi]        ;get second source pixel
                    802:         add     esi,[edx+4]     ;point to next source pixel
                    803:         mov     ah,[ebp+ebx*4]  ;translate the pixel color
                    804:         add     edx,8           ;point to next skip entry
                    805:         mov     [edi],ax        ;write both pixels to the destination
                    806:         add     edi,2           ;point to next destination pixel
                    807:         dec     ecx             ;count down pixel pairs
                    808:         jnz     shrink_xlat_8bpp_l_nt_pixel_loop
                    809:         pop     ebp             ;***stack frame available***
                    810:         retn
                    811: 
                    812: ; Leading byte, trailing byte.
                    813: 
                    814: shrink_xlat_8bpp_l_t:
                    815:         push    ebp             ;***stack frame not available***
                    816:         mov     ebp,pulXlatVector ;point EBP to the translation table
                    817:                                 ;do the leading pixel
                    818:         mov     bl,[esi]        ;get first source pixel
                    819:         add     esi,[edx]       ;point to next source pixel
                    820:         mov     eax,[ebp+ebx*4] ;translate the pixel color
                    821:         add     edx,4           ;point to next skip entry
                    822:         mov     [edi],al        ;write the pixel to the destination
                    823:         inc     edi             ;point to next destination pixel
                    824:                                 ;now do pixel pairs across the middle
                    825: shrink_xlat_8bpp_l_t_pixel_loop:
                    826:         mov     bl,[esi]        ;get first source pixel
                    827:         add     esi,[edx]       ;point to next source pixel
                    828:         mov     eax,[ebp+ebx*4] ;translate the pixel color
                    829:         mov     bl,[esi]        ;get second source pixel
                    830:         add     esi,[edx+4]     ;point to next source pixel
                    831:         mov     ah,[ebp+ebx*4]  ;translate the pixel color
                    832:         add     edx,8           ;point to next skip entry
                    833:         mov     [edi],ax        ;write both pixels to the destination
                    834:         add     edi,2           ;point to next destination pixel
                    835:         dec     ecx             ;count down pixel pairs
                    836:         jnz     shrink_xlat_8bpp_l_t_pixel_loop
                    837:                                 ;do the trailing pixel
                    838:         mov     bl,[esi]        ;get first source pixel
                    839:         add     esi,[edx]       ;point to next source pixel
                    840:         mov     eax,[ebp+ebx*4] ;translate the pixel color
                    841:         add     edx,4           ;point to next skip entry
                    842:         mov     [edi],al        ;write the pixel to the destination
                    843:         inc     edi             ;point to next destination pixel
                    844:         pop     ebp             ;***stack frame available***
                    845:         retn
                    846: 
                    847: ; No leading byte, trailing byte.
                    848: 
                    849: shrink_xlat_8bpp_nl_t:
                    850:         push    ebp             ;***stack frame not available***
                    851:         mov     ebp,pulXlatVector ;point EBP to the translation table
                    852: shrink_xlat_8bpp_nl_t_pixel_loop:
                    853:         mov     bl,[esi]        ;get first source pixel
                    854:         add     esi,[edx]       ;point to next source pixel
                    855:         mov     eax,[ebp+ebx*4] ;translate the pixel color
                    856:         mov     bl,[esi]        ;get second source pixel
                    857:         add     esi,[edx+4]     ;point to next source pixel
                    858:         mov     ah,[ebp+ebx*4]  ;translate the pixel color
                    859:         add     edx,8           ;point to next skip entry
                    860:         mov     [edi],ax        ;write both pixels to the destination
                    861:         add     edi,2           ;point to next destination pixel
                    862:         dec     ecx             ;count down pixel pairs
                    863:         jnz     shrink_xlat_8bpp_nl_t_pixel_loop
                    864:                                 ;do the trailing pixel
                    865:         mov     bl,[esi]        ;get first source pixel
                    866:         add     esi,[edx]       ;point to next source pixel
                    867:         mov     eax,[ebp+ebx*4] ;translate the pixel color
                    868:         add     edx,4           ;point to next skip entry
                    869:         mov     [edi],al        ;write the pixel to the destination
                    870:         inc     edi             ;point to next destination pixel
                    871:         pop     ebp             ;***stack frame available***
                    872:         retn
                    873: ; Narrow case, a byte at a time.
                    874: 
                    875: shrink_xlat_8bpp_narrow:
                    876:         push    ebp             ;***stack frame not available***
                    877:         mov     ebp,pulXlatVector ;point EBP to the translation table
                    878: shrink_xlat_8bpp_narrow_loop:
                    879:         mov     bl,[esi]        ;get first source pixel
                    880:         add     esi,[edx]       ;point to next source pixel
                    881:         mov     eax,[ebp+ebx*4] ;translate the pixel color
                    882:         add     edx,4           ;point to next skip entry
                    883:         mov     [edi],al        ;write the pixel to the destination
                    884:         inc     edi             ;point to next destination pixel
                    885:         dec     ecx             ;count down pixels
                    886:         jnz     shrink_xlat_8bpp_narrow_loop
                    887:         pop     ebp             ;***stack frame available***
                    888:         retn
                    889: 
                    890: endProc vStretchBlt8bpp
                    891: 
                    892: public DoneFailed
                    893: public x_shrink
                    894: public check_y_shrink
                    895: public x_shrink_set_dda_loop
                    896: public x_shrink_set_dda_max
                    897: public x_shrink_set_dda_min
                    898: public x_shrink_set_dda_done
                    899: public y_shrink
                    900: public map_init_bank
                    901: public init_bank_mapped
                    902: public bank_loop
                    903: public done
                    904: public do_next_bank
                    905: public shrink_8bpp_loop
                    906: public shrink_block_8bpp_loop
                    907: public shrink_noxlat_8bpp_nl_nt
                    908: public shrink_noxlat_8bpp_nl_nt_pixel_loop
                    909: public shrink_noxlat_8bpp_l_nt
                    910: public shrink_noxlat_8bpp_l_nt_pixel_loop
                    911: public shrink_noxlat_8bpp_l_t
                    912: public shrink_noxlat_8bpp_l_t_pixel_loop
                    913: public shrink_noxlat_8bpp_nl_t
                    914: public shrink_noxlat_8bpp_nl_t_pixel_loop
                    915: public shrink_noxlat_8bpp_narrow
                    916: public shrink_noxlat_8bpp_narrow_pixel_loop
                    917: public shrink_xlat_8bpp_nl_nt
                    918: public shrink_xlat_8bpp_nl_nt_pixel_loop
                    919: public shrink_xlat_8bpp_l_nt
                    920: public shrink_xlat_8bpp_l_nt_pixel_loop
                    921: public shrink_xlat_8bpp_l_t
                    922: public shrink_xlat_8bpp_l_t_pixel_loop
                    923: public shrink_xlat_8bpp_nl_t
                    924: public shrink_xlat_8bpp_nl_t_pixel_loop
                    925: public shrink_xlat_8bpp_narrow
                    926: public shrink_xlat_8bpp_narrow_loop
                    927: 
                    928:         end
                    929: 

unix.superglobalmegacorp.com

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