Annotation of ntddk/src/video/displays/vga256/i386/stretch8.asm, revision 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.