|
|
1.1 ! root 1: page ,132 ! 2: title Dib Conversions ! 3: ;---------------------------Module-Header------------------------------; ! 4: ; Module Name: dibs.asm ! 5: ; ! 6: ; Copyright (c) 1992 Microsoft Corporation ! 7: ;-----------------------------------------------------------------------; ! 8: ! 9: .386 ! 10: ! 11: ifndef DOS_PLATFORM ! 12: .model small,c ! 13: else ! 14: ifdef STD_CALL ! 15: .model small,c ! 16: else ! 17: .model small,pascal ! 18: endif; STD_CALL ! 19: endif; DOS_PLATFORM ! 20: ! 21: ! 22: .xlist ! 23: include stdcall.inc ;calling convention cmacros ! 24: ! 25: include i386\cmacFLAT.inc ; FLATland cmacros ! 26: include i386\display.inc ; Display specific structures ! 27: include i386\ppc.inc ; Pack pel conversion structure ! 28: include i386\bitblt.inc ; General definitions ! 29: include i386\egavga.inc ! 30: .list ! 31: ! 32: assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT ! 33: assume fs:nothing,gs:nothing ! 34: ! 35: EXTRNP comp_byte_interval ! 36: ! 37: ! 38: ; General equates ! 39: ! 40: ; BUGBUG this should be dynamically calculated ! 41: ! 42: CJ_PLANE equ (cj_max_scan+1) ;Extra byte makes algorithm easier ! 43: ! 44: .data ! 45: ! 46: ; Define the buffer for packed-pel to planer conversion. !!! when we do ! 47: ; conversion to planer bitmaps, this will have to come from the extra scan ! 48: ; we'll allocate in our planer color bitmaps !!! ! 49: ! 50: ; BUGBUG this should be allocated memory accessed via the DEVSURF, not static ! 51: ! 52: public ajConvertBuffer ! 53: ajConvertBuffer db (CJ_PLANE * 4) dup (0) ! 54: ! 55: .code ! 56: ! 57: _TEXT$03 SEGMENT DWORD USE32 PUBLIC 'CODE' ! 58: ASSUME CS:FLAT, DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING ! 59: ! 60: ; Define the default pixel mapping table. This table will be used when ! 61: ; converting from 4bpp to planer with no color translation. ! 62: ! 63: align 4 ! 64: ! 65: public aulDefBitMapping ! 66: aulDefBitMapping equ this dword ! 67: ! 68: dd 00000000000000000000000000000000b ;0000 ! 69: dd 00000000000000000000000000000001b ;0001 ! 70: dd 00000000000000000000000100000000b ;0010 ! 71: dd 00000000000000000000000100000001b ;0011 ! 72: dd 00000000000000010000000000000000b ;0100 ! 73: dd 00000000000000010000000000000001b ;0101 ! 74: dd 00000000000000010000000100000000b ;0110 ! 75: dd 00000000000000010000000100000001b ;0111 ! 76: dd 00000001000000000000000000000000b ;1000 ! 77: dd 00000001000000000000000000000001b ;1001 ! 78: dd 00000001000000000000000100000000b ;1010 ! 79: dd 00000001000000000000000100000001b ;1011 ! 80: dd 00000001000000010000000000000000b ;1100 ! 81: dd 00000001000000010000000000000001b ;1101 ! 82: dd 00000001000000010000000100000000b ;1110 ! 83: dd 00000001000000010000000100000001b ;1111 ! 84: ! 85: ! 86: ;-----------------------------------------------------------------------; ! 87: ; vDIB4n8ToPlaner ! 88: ; ! 89: ; Converts a scan of a 4bpp or 8bpp DIB into planer format for bitblt ! 90: ; ! 91: ; Entry: ! 92: ; EBP --> ppc structure ! 93: ; Exit: ! 94: ; ESI --> plane 0 of scan data ! 95: ; Registers Destroyed: ! 96: ; EAX,EBX,EDX,EBP ! 97: ; Registers Preserved: ! 98: ; ECX,EDI ! 99: ;-----------------------------------------------------------------------; ! 100: ! 101: ppc equ [ebp] ! 102: ! 103: vDIB4n8ToPlaner proc ! 104: ! 105: push ecx ! 106: push edi ! 107: ! 108: ; Load up the parameters for the blt ! 109: ! 110: mov esi,ppc.pSrc ;Source pointer ! 111: mov eax,ppc.iNextScan ;Index to next scan ! 112: add eax,esi ! 113: mov ppc.pSrc,eax ;Save next source pointer ! 114: xor eax,eax ;Creating a four bit index in eax ! 115: ! 116: ; pulXlate must be zero for 4bpp conversion since we will be using ! 117: ; ebx for creating an index. No problem since we don't need the ! 118: ; translation by the time we're in this code. ! 119: ! 120: mov ebx,ppc.pulXlate ;Color translation or zero ! 121: lea edi,ajConvertBuffer ;Where to store results ! 122: ! 123: ; Handle a partial first byte and all full bytes ! 124: ! 125: mov ecx,ppc.cLeftMiddle ;Get loop count for middle and left ! 126: jecxz vDIB4n8DoneFirst ;No first/inner ! 127: push ebp ! 128: push offset FLAT:VDIB4n8FinishFirst ;Set return address ! 129: push ppc.pfnLeftMiddle ;Set proc for left partial byte ! 130: mov ebp,ppc.pulConvert ;Base address of conversion table ! 131: xor edx,edx ;Init accumulated bits ! 132: ret ;To ppc.pfnLeftMiddle ! 133: VDIB4n8FinishFirst: ;It returns here ! 134: pop ebp ! 135: ! 136: vDIB4n8DoneFirst: ! 137: mov ecx,ppc.pfnRight ! 138: jecxz short vDIB4n8DoneRightSide ;No left side ! 139: and edx,01010101h ;Carryover from a partial 4bpp byte ! 140: push ebp ! 141: push offset FLAT:VDIB4n8FinishLast ;Set return address ! 142: push ecx ;Set function address ! 143: mov ecx,1 ;No looping ! 144: mov ebp,ppc.pulConvert ;Base address of conversion table ! 145: ret ;To ppc.pfnRight ! 146: VDIB4n8FinishLast: ;It returns here ! 147: pop ebp ! 148: ! 149: mov cl,ppc.cLeftShift ;Must align right side pels ! 150: shl edx,cl ! 151: mov [edi][CJ_PLANE*0][-1],dl ! 152: mov [edi][CJ_PLANE*1][-1],dh ! 153: shr edx,16 ! 154: mov [edi][CJ_PLANE*2][-1],dl ! 155: mov [edi][CJ_PLANE*3][-1],dh ! 156: ! 157: ; Load up the source pointer and exit ! 158: ! 159: vDIB4n8DoneRightSide: ! 160: pop edi ! 161: pop ecx ! 162: mov esi,ppc.pjConverted ! 163: ret ! 164: ! 165: vDIB4n8ToPlaner endp ! 166: ! 167: ppc equ <> ! 168: ! 169: ! 170: ;-----------------------------------------------------------------------; ! 171: ; vDIB4Convert* ! 172: ; ! 173: ; Converts the specified number of source 4 bpp bits into the ! 174: ; buffer. These are support routines for vDIB4Planer, where a ! 175: ; source byte converts into two aligned bits ! 176: ; ! 177: ; Entry: ! 178: ; EAX 31:8 = 0 ! 179: ; EBP --> Bit conversion table ! 180: ; ESI --> Source bitmap ! 181: ; EDI --> Planer destination ! 182: ; ECX = Loop count ! 183: ; Exit: ! 184: ; EBP --> Bit conversion table ! 185: ; ESI --> Next source byte ! 186: ; EDI --> Next planer destination ! 187: ; EDX = Last planer byte accumulated ! 188: ; Registers Destroyed: ! 189: ; EAX,ECX,EDX ! 190: ; Registers Preserved: ! 191: ;-----------------------------------------------------------------------; ! 192: ! 193: vDIB4Convert8:: ! 194: lodsb ! 195: mov ebx,eax ! 196: shr eax,4 ! 197: and ebx,00001111b ! 198: mov edx,[ebp][eax*4] ! 199: shl edx,1 ! 200: or edx,[ebp][ebx*4] ! 201: vDIB4Convert6:: ! 202: lodsb ! 203: shl edx,1 ! 204: mov ebx,eax ! 205: shr eax,4 ! 206: and ebx,00001111b ! 207: or edx,[ebp][eax*4] ! 208: shl edx,1 ! 209: or edx,[ebp][ebx*4] ! 210: vDIB4Convert4:: ! 211: lodsb ! 212: shl edx,1 ! 213: mov ebx,eax ! 214: shr eax,4 ! 215: and ebx,00001111b ! 216: or edx,[ebp][eax*4] ! 217: shl edx,1 ! 218: or edx,[ebp][ebx*4] ! 219: vDIB4Convert2:: ! 220: lodsb ! 221: shl edx,1 ! 222: mov ebx,eax ! 223: shr eax,4 ! 224: and ebx,00001111b ! 225: or edx,[ebp][eax*4] ! 226: shl edx,1 ! 227: or edx,[ebp][ebx*4] ! 228: mov [edi][CJ_PLANE*0],dl ! 229: mov [edi][CJ_PLANE*1],dh ! 230: ror edx,16 ! 231: mov [edi][CJ_PLANE*2],dl ! 232: mov [edi][CJ_PLANE*3],dh ! 233: inc edi ! 234: dec ecx ! 235: jnz vDIB4Convert8 ! 236: rol edx,16 ;Incase alignment of last byte ! 237: ret ! 238: ! 239: ! 240: ;-----------------------------------------------------------------------; ! 241: ; vDIB4NAConvert* ! 242: ; ! 243: ; Converts the specified number of source 4 bpp bits into the ! 244: ; buffer. These are support routines for vDIB4Planer, where a ! 245: ; source byte converts into two non-aligned bytes (we have to carry ! 246: ; a bit over into the next destination byte). ! 247: ; ! 248: ; Entry: ! 249: ; EAX 31:8 = 0 ! 250: ; EBP --> Bit conversion table ! 251: ; ESI --> Source bitmap ! 252: ; EDI --> Planer destination ! 253: ; ECX = Loop count ! 254: ; Exit: ! 255: ; EBP --> Bit conversion table ! 256: ; ESI --> Next source byte ! 257: ; EDI --> Next planer destination ! 258: ; EDX = first pel of next destination ! 259: ; Registers Destroyed: ! 260: ; EAX,ECX,EDX ! 261: ; Registers Preserved: ! 262: ;-----------------------------------------------------------------------; ! 263: ! 264: vDIB4NAConvert7:: ! 265: lodsb ! 266: shl edx,1 ;Carry over bit from last fetch ! 267: mov ebx,eax ! 268: shr eax,4 ! 269: and ebx,00001111b ! 270: or edx,[ebp][eax*4] ! 271: shl edx,1 ! 272: or edx,[ebp][ebx*4] ! 273: vDIB4NAConvert5:: ! 274: lodsb ! 275: shl edx,1 ! 276: mov ebx,eax ! 277: shr eax,4 ! 278: and ebx,00001111b ! 279: or edx,[ebp][eax*4] ! 280: shl edx,1 ! 281: or edx,[ebp][ebx*4] ! 282: vDIB4NAConvert3:: ! 283: lodsb ! 284: shl edx,1 ! 285: mov ebx,eax ! 286: shr eax,4 ! 287: and ebx,00001111b ! 288: or edx,[ebp][eax*4] ! 289: shl edx,1 ! 290: or edx,[ebp][ebx*4] ! 291: vDIB4NAConvert1:: ! 292: lodsb ! 293: shl edx,1 ! 294: mov ebx,eax ! 295: shr eax,4 ! 296: and ebx,00001111b ! 297: or edx,[ebp][eax*4] ! 298: mov [edi][CJ_PLANE*0],dl ! 299: mov [edi][CJ_PLANE*1],dh ! 300: shr edx,16 ! 301: mov [edi][CJ_PLANE*2],dl ! 302: mov [edi][CJ_PLANE*3],dh ! 303: inc edi ! 304: mov edx,[ebp][ebx*4] ;Start of next destination byte ! 305: dec ecx ! 306: jnz vDIB4NAConvert7 ! 307: ret ! 308: ! 309: ;-----------------------------------------------------------------------; ! 310: ; vDIB4NAConvert0 ! 311: ; ! 312: ; Last byte code for the 4bpp non-aligned case where the data already ! 313: ; exists in EDX, but we have to increment the destination pointer since ! 314: ; vDIB4n8ToPlaner assumes we stored the data and incremented the pointer ! 315: ; ! 316: ; Entry: ! 317: ; EDI --> destination ! 318: ; Exit: ! 319: ; EDI = EDI + 1 ! 320: ; Registers Destroyed: ! 321: ; None ! 322: ; Registers Preserved: ! 323: ; All but EDI ! 324: ;-----------------------------------------------------------------------; ! 325: ! 326: vDIB4NAConvert0 proc ! 327: ! 328: inc edi ! 329: vNOP:: ! 330: ret ! 331: ! 332: vDIB4NAConvert0 endp ! 333: ! 334: ! 335: ! 336: ;-----------------------------------------------------------------------; ! 337: ; The following table is indexed into to get the address of where to ! 338: ; enter the 4bpp conversion loops ! 339: ;-----------------------------------------------------------------------; ! 340: ! 341: apfn4bppConvert equ this dword ! 342: ! 343: dd offset FLAT:vDIB4Convert8 ! 344: dd offset FLAT:vDIB4NAConvert7 ! 345: dd offset FLAT:vDIB4Convert6 ! 346: dd offset FLAT:vDIB4NAConvert5 ! 347: dd offset FLAT:vDIB4Convert4 ! 348: dd offset FLAT:vDIB4NAConvert3 ! 349: dd offset FLAT:vDIB4Convert2 ! 350: dd offset FLAT:vDIB4NAConvert1 ! 351: ! 352: ;-----------------------------------------------------------------------; ! 353: ; The following table is indexed into to get the address of where to ! 354: ; enter the 4bpp conversion loops for a partial right hand side byte ! 355: ;-----------------------------------------------------------------------; ! 356: ! 357: apfn4bppConvertRHS equ this dword ! 358: ! 359: dd offset FLAT:vNOP ;Should never be called ! 360: dd offset FLAT:vDIB4Convert6 ;Convert three more source bytes ! 361: dd offset FLAT:vDIB4Convert6 ;Convert three source bytes ! 362: dd offset FLAT:vDIB4Convert4 ;Convert two more source bytes ! 363: dd offset FLAT:vDIB4Convert4 ;Convert two source bytes ! 364: dd offset FLAT:vDIB4Convert2 ;Convert one more source byte ! 365: dd offset FLAT:vDIB4Convert2 ;Convert one source byte ! 366: dd offset FLAT:vDIB4NAConvert0 ;Non-aligned, data in EDX already ! 367: ! 368: ;-----------------------------------------------------------------------; ! 369: ; vDIB8Convert* ! 370: ; ! 371: ; Converts the specified number of source 8 bpp bits into the ! 372: ; buffer. These are support routines for vDIB8Planer. ! 373: ; ! 374: ; Entry: ! 375: ; EAX 31:8 = 0 ! 376: ; EBP --> Bit conversion table ! 377: ; EBX --> Color translation table ! 378: ; ESI --> Source bitmap ! 379: ; EDI --> Planer destination ! 380: ; ECX = Loop count ! 381: ; Exit: ! 382: ; EBP --> Bit conversion table ! 383: ; EBX --> Color translation table ! 384: ; ESI --> Next source byte ! 385: ; EDI --> Next planer destination ! 386: ; Registers Destroyed: ! 387: ; EAX,ECX,EDX ! 388: ; Registers Preserved: ! 389: ; None ! 390: ;-----------------------------------------------------------------------; ! 391: ! 392: vDIB8Convert8:: ! 393: lodsb ;Get pel 1 ! 394: mov al,[ebx][eax*4] ;Color translation into 4 bits ! 395: mov edx,[ebp][eax*4] ! 396: vDIB8Convert7:: ! 397: lodsb ;Get pel 2 ! 398: shl edx,1 ! 399: mov al,[ebx][eax*4] ! 400: or edx,[ebp][eax*4] ! 401: vDIB8Convert6:: ! 402: lodsb ;Get pel 2 ! 403: shl edx,1 ! 404: mov al,[ebx][eax*4] ! 405: or edx,[ebp][eax*4] ! 406: vDIB8Convert5:: ! 407: lodsb ;Get pel 2 ! 408: shl edx,1 ! 409: mov al,[ebx][eax*4] ! 410: or edx,[ebp][eax*4] ! 411: vDIB8Convert4:: ! 412: lodsb ;Get pel 2 ! 413: shl edx,1 ! 414: mov al,[ebx][eax*4] ! 415: or edx,[ebp][eax*4] ! 416: vDIB8Convert3:: ! 417: lodsb ;Get pel 2 ! 418: shl edx,1 ! 419: mov al,[ebx][eax*4] ! 420: or edx,[ebp][eax*4] ! 421: vDIB8Convert2:: ! 422: lodsb ;Get pel 2 ! 423: shl edx,1 ! 424: mov al,[ebx][eax*4] ! 425: or edx,[ebp][eax*4] ! 426: vDIB8Convert1:: ! 427: lodsb ;Get pel 7 ! 428: shl edx,1 ! 429: mov al,[ebx][eax*4] ! 430: or edx,[ebp][eax*4] ! 431: mov [edi][CJ_PLANE*0],dl ! 432: mov [edi][CJ_PLANE*1],dh ! 433: ror edx,16 ! 434: mov [edi][CJ_PLANE*2],dl ! 435: mov [edi][CJ_PLANE*3],dh ! 436: inc edi ! 437: dec ecx ! 438: jnz vDIB8Convert8 ! 439: rol edx,16 ;Incase alignment of last byte ! 440: ret ! 441: ! 442: ;-----------------------------------------------------------------------; ! 443: ; The following table is indexed into to get the address of where to ! 444: ; enter the 8bpp conversion loop ! 445: ;-----------------------------------------------------------------------; ! 446: ! 447: apfn8bppConvert equ this dword ! 448: dd offset FLAT:vDIB8Convert8 ! 449: dd offset FLAT:vDIB8Convert7 ! 450: dd offset FLAT:vDIB8Convert6 ! 451: dd offset FLAT:vDIB8Convert5 ! 452: dd offset FLAT:vDIB8Convert4 ! 453: dd offset FLAT:vDIB8Convert3 ! 454: dd offset FLAT:vDIB8Convert2 ! 455: dd offset FLAT:vDIB8Convert1 ! 456: ! 457: ! 458: ;-----------------------------------------------------------------------; ! 459: ; vDIB8Preprocess() ! 460: ; ! 461: ; Performs whatever processing is necessary to prepare for a blt from ! 462: ; a 8bpp DIB to a planer format bitmap. ! 463: ; ! 464: ; Entry: ! 465: ; EBP --> Bitblt frame structure ! 466: ; Exit: ! 467: ; None ! 468: ; Registers Destroyed: ! 469: ; EAX,EBX,ECX,EDX,ESI,EDI ! 470: ; Registers Preserved: ! 471: ; EBP,EBX ! 472: ;-----------------------------------------------------------------------; ! 473: ! 474: fr equ [ebp] ! 475: ! 476: cProc vDIB8Preprocess ! 477: ! 478: push ebx ! 479: mov fr.ppcBlt.pulConvert,offset FLAT:aulDefBitMapping ! 480: ! 481: ; Align the blt so that the blt's phase will become 0. Both origins are ! 482: ; guaranteed to be positive and < 16 bits !!! ! 483: ! 484: movzx eax,fr.DestxOrg ;Align source and dest X origins ! 485: mov edx,eax ! 486: xchg ax,fr.SrcxOrg ;D31:16 is zero for both ! 487: add eax,fr.src.lp_bits ! 488: mov fr.ppcBlt.pSrc,eax ;Save address of first source pel ! 489: and edx,7 ;Always start in first byte of buffer ! 490: push edx ;Save for computing loop entry ! 491: movzx ebx,fr.xExt ;Compute exclusive right hand side (rhs) ! 492: add ebx,edx ! 493: push ebx ;Save rhs for shift count computation ! 494: ! 495: ; comp_byte_interval returns: ! 496: ; ! 497: ; EDI = offset to first byte to be altered in the scan ! 498: ; ESI = inner loop count (possibly 0) ! 499: ; AL = first byte mask (possibly 0) ! 500: ; AH = last byte mask (possibly 0) ! 501: ! 502: cCall comp_byte_interval ! 503: pop ebx ;Exclusive rhs ! 504: pop edx ;Inclusive lhs ! 505: ! 506: ; If only a partial destination byte will be altered, the mask will have ! 507: ; been returned in AL with AH and ESI 0. ! 508: ! 509: or ah,ah ;See if only a first byte ! 510: jnz short @f ;More than one byte to alter ! 511: or esi,esi ! 512: jnz @F ;More than a partial byte ! 513: ! 514: ; There will only be a partial byte. The normal flow-o-control falls apart ! 515: ; so we have to special case it. ! 516: ! 517: mov fr.ppcBlt.cLeftMiddle,esi ;No first/inner loop ! 518: mov eax,8 ! 519: sub eax,ebx ! 520: mov fr.ppcBlt.cLeftShift,al ;Set shift count to align last byte ! 521: mov eax,8 ! 522: sub ebx,edx ;EBX = # pels needed (<8) ! 523: sub eax,ebx ! 524: mov eax,apfn8bppConvert[eax*4] ! 525: jmp short v8bpp_have_last ! 526: ! 527: @@: ! 528: ! 529: ; More than a single byte will be written for the destination. Compute entry ! 530: ; into the convert loop based on the destination X origin. If the X dest ! 531: ; origin was zero, the first byte will have been combined into the inner loop ! 532: ; count ! 533: ! 534: cmp al,1 ;If partial first byte we need to bump ! 535: cmc ; the loop count by 1 ! 536: adc esi,0 ! 537: mov edx,apfn8bppConvert[edx*4] ! 538: mov al,ah ;Set last byte mask ! 539: mov fr.ppcBlt.pfnLeftMiddle,edx ! 540: v8bpp_have_first_inner: ! 541: mov fr.ppcBlt.cLeftMiddle,esi ;Save innerloop count (possibly 0) ! 542: ! 543: ; Compute the function and shift count for the last byte (if one exists) ! 544: ! 545: movzx eax,al ! 546: or eax,eax ! 547: jz short v8bpp_have_last ;No last byte, set pfn = 0 ! 548: mov al,8 ;D31:8 set to 0 with above movzx ! 549: sub eax,ebx ! 550: and eax,00000111b ! 551: mov fr.ppcBlt.cLeftShift,al ;Set shift count to align last byte ! 552: mov eax,apfn8bppConvert[eax*4] ! 553: v8bpp_have_last: ! 554: mov fr.ppcBlt.pfnRight,eax ! 555: ! 556: ; Set the address of routine which will be called from the compiled blt ! 557: ! 558: mov fr.ppcBlt.pfnConvert,offset FLAT:vDIB4n8ToPlaner ! 559: mov fr.ppcBlt.pjConverted,offset FLAT:ajConvertBuffer ! 560: pop ebx ! 561: cRet vDIB8Preprocess ! 562: ! 563: endProc vDIB8Preprocess ! 564: ! 565: ! 566: ! 567: ;-----------------------------------------------------------------------; ! 568: ; vDIB4Preprocess() ! 569: ; ! 570: ; Performs whatever processing is necessary to prepare for a blt from ! 571: ; a 4bpp DIB to a planer format bitmap. ! 572: ; ! 573: ; Entry: ! 574: ; EBP --> Bitblt frame structure ! 575: ; Exit: ! 576: ; None ! 577: ; Registers Destroyed: ! 578: ; EAX,EBX,ECX,EDX,ESI,EDI ! 579: ; Registers Preserved: ! 580: ; EBP,EBX ! 581: ;-----------------------------------------------------------------------; ! 582: ! 583: fr equ [ebp] ! 584: ! 585: cProc vDIB4Preprocess ! 586: ! 587: push ebx ! 588: ! 589: ; If a color translation vector was given, generate the new bit ! 590: ; conversion array ! 591: ! 592: mov eax,offset FLAT:aulDefBitMapping ! 593: cld ! 594: mov esi,fr.ppcBlt.pulXlate ! 595: or esi,esi ! 596: jz vDIB4_have_mapping_array ! 597: lea edi,fr.aulMap ! 598: mov ecx,16 ! 599: create_next_bit_mapping: ! 600: lodsd ! 601: mov eax,aulDefBitMapping[eax*4] ! 602: stosd ! 603: dec ecx ! 604: jnz create_next_bit_mapping ! 605: lea eax,[edi][-16*4] ! 606: vDIB4_have_mapping_array: ! 607: mov fr.ppcBlt.pulConvert,eax ! 608: ! 609: ! 610: ; Align the blt so that the blt's phase will become 0. Both origins are ! 611: ; guaranteed to be positive and < 16 bits !!! ! 612: ! 613: movzx eax,fr.DestxOrg ;Align source and dest X origins ! 614: mov edx,eax ;Save for later calculations ! 615: xchg ax,fr.SrcxOrg ;D31:16 is zero for both ! 616: ! 617: ; We never want to process a partial source byte. We will move the source ! 618: ; left if necessary, and adjust the extent if necessary. Note that if any ! 619: ; adjustments are made, we won't fetch past the end of the source nor ! 620: ; will we write beyond the end of our buffer (since we made it big enough ! 621: ; in the first place). ! 622: ! 623: ; We don't worry about adjusting the source origin before we save it ! 624: ; since we will be shifting it right later to round it to a byte address ! 625: ! 626: mov ecx,eax ! 627: shr ecx,1 ! 628: add ecx,fr.src.lp_bits ! 629: mov fr.ppcBlt.pSrc,ecx ;Save address of first pel ! 630: and eax,1 ;EAX = 1 if source is odd pel ! 631: movzx ebx,fr.xExt ! 632: sub edx,eax ;Move dest left if necessary ! 633: add ebx,eax ;Also bump extent if moved ! 634: and edx,7 ;Start dest in first byte of buffer ! 635: inc ebx ;Round extent to a multiple of 2 ! 636: and bl,11111110b ! 637: add ebx,edx ;Exclusive right hand side ! 638: ! 639: ; A problem: When moving the source left a pel, we can encounter a situation ! 640: ; wherein the first pel written is in bit position 0. However, it should be ! 641: ; noted that this pel is not part of the blt, so we have to skip over the ! 642: ; byte containing it to get to the correct first pel (which will be bit 7 ! 643: ; of the next byte). ! 644: ! 645: cmp dl,7 ! 646: je @F ! 647: xor ax,ax ! 648: @@: ! 649: add eax,offset FLAT:ajConvertBuffer ! 650: mov fr.ppcBlt.pjConverted,eax ! 651: ! 652: ; comp_byte_interval returns: ! 653: ; ! 654: ; EDI = offset to first byte to be altered in the scan ! 655: ; ESI = inner loop count (possibly 0) ! 656: ; AL = first byte mask (possibly 0) ! 657: ; AH = last byte mask (possibly 0) ! 658: ! 659: push edx ;Save for computing loop entry ! 660: push ebx ;Save rhs for shift count computation ! 661: cCall comp_byte_interval ! 662: pop ebx ;Exclusive rhs ! 663: pop edx ;Inclusive lhs ! 664: ! 665: ; If only a partial destination byte will be altered, the mask will have ! 666: ; been returned in AL with AH and ESI 0. ! 667: ! 668: or ah,ah ;See if only a first byte ! 669: jnz short @f ;More than one byte to alter ! 670: or esi,esi ! 671: jnz short @f ;More than one byte ! 672: ! 673: ; There will only be a partial byte. The normal flow-o-control falls apart ! 674: ; so we have to special case it. ! 675: ! 676: mov fr.ppcBlt.cLeftMiddle,esi ;No first/inner loop ! 677: mov eax,8 ! 678: sub eax,ebx ! 679: mov fr.ppcBlt.cLeftShift,al ;Set shift count to align last byte ! 680: mov eax,8 ! 681: sub ebx,edx ;EBX = # pels needed (<8) ! 682: sub eax,ebx ! 683: mov eax,apfn4bppConvertRHS[eax*4] ! 684: jmp short v4bpp_have_last ! 685: ! 686: @@: ! 687: ! 688: ; More than a single byte will be written for the destination. Compute entry ! 689: ; into the convert loop based on the destination X origin. If the X dest ! 690: ; origin was zero, the first byte will have been combined into the inner loop ! 691: ; count ! 692: ! 693: cmp al,1 ;If partial first byte we need to bump ! 694: cmc ; the loop count by 1 ! 695: adc esi,0 ! 696: mov ecx,apfn4bppConvert[edx*4] ! 697: mov al,ah ;Set last byte mask ! 698: mov fr.ppcBlt.pfnLeftMiddle,ecx ! 699: v4bpp_have_first_inner: ! 700: mov fr.ppcBlt.cLeftMiddle,esi ;Save innerloop count (possibly 0) ! 701: ! 702: ; Compute the function and shift count for the last byte (if one exists) ! 703: ! 704: movzx eax,al ! 705: or eax,eax ! 706: jz short v4bpp_have_last ;No last byte, set pfn = 0 ! 707: mov al,8 ;D31:8 set to 0 with above movzx ! 708: sub eax,ebx ! 709: and eax,00000111b ! 710: mov fr.ppcBlt.cLeftShift,al ;Set shift count to align last byte ! 711: mov eax,apfn4bppConvertRHS[eax*4] ! 712: v4bpp_have_last: ! 713: mov fr.ppcBlt.pfnRight,eax ! 714: ! 715: ; Set the address of the routine which will be called from the compiled blt ! 716: ! 717: mov fr.ppcBlt.pfnConvert,offset FLAT:vDIB4n8ToPlaner ! 718: pop ebx ! 719: cRet vDIB4Preprocess ! 720: ! 721: endProc vDIB4Preprocess ! 722: ! 723: ! 724: ;----------------------------Private-Routine----------------------------; ! 725: ; packed_pel_comp_y ! 726: ; ! 727: ; Compute y-related parameters. ! 728: ; ! 729: ; The parameters related to the Y coordinate and BLT direction ! 730: ; are computed. The parameters include: ! 731: ; ! 732: ; a) Index to next scan line ! 733: ; b) Starting Y address calculation ! 734: ; d) Index to next plane ! 735: ; ! 736: ; Entry: ! 737: ; EBP --> Blt frame ! 738: ; AX = Y coordinate ! 739: ; ECX = BLT direction ! 740: ; 0000 = Y+ ! 741: ; FFFF = Y- ! 742: ; BX = inclusive Y extent ! 743: ; Returns: ! 744: ; None ! 745: ; Registers Preserved: ! 746: ; EBP,ECX,EBX,EDX ! 747: ; Registers Destroyed: ! 748: ; EAX,ESI,EDI,flags ! 749: ; Calls: ! 750: ; None ! 751: ; History: ! 752: ;-----------------------------------------------------------------------; ! 753: ! 754: fr equ [ebp] ! 755: ! 756: cProc packed_pel_comp_y ! 757: ! 758: push edx ! 759: mov fr.src.next_plane,CJ_PLANE ;Index to next plane of data ! 760: movsx esi,fr.src.width_b ;Need bmWidthBytes couple-o-times ! 761: movzx eax,ax ! 762: mul esi ;Compute Y address ! 763: add fr.ppcBlt.pSrc,eax ;Add to base address ! 764: ! 765: xor esi,ecx ;1's complement if Y- ! 766: sub esi,ecx ;2's complement if Y- ! 767: mov fr.ppcBlt.iNextScan,esi ;Set index to next scan line ! 768: pop edx ! 769: cRet packed_pel_comp_y ! 770: ! 771: endProc packed_pel_comp_y ! 772: ! 773: _TEXT$03 ends ! 774: ! 775: end ! 776: ! 777:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.