|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.