|
|
1.1 ! root 1: ;!!! This is all temp crap to be replaced when the blinker is written ! 2: ! 3: ;---------------------------Module-Header------------------------------; ! 4: ; Module Name: cpybits.asm ! 5: ; ! 6: ; Copyright (c) 1992 Microsoft Corporation ! 7: ;-----------------------------------------------------------------------; ! 8: page ,132 ! 9: title DrvCopyBits Support ! 10: .386 ! 11: ! 12: ifndef DOS_PLATFORM ! 13: .model small,c ! 14: else ! 15: ifdef STD_CALL ! 16: .model small,c ! 17: else ! 18: .model small,pascal ! 19: endif; STD_CALL ! 20: endif; DOS_PLATFORM ! 21: ! 22: assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT ! 23: assume fs:nothing,gs:nothing ! 24: ! 25: .xlist ! 26: include stdcall.inc ;calling convention cmacros ! 27: include i386\egavga.inc ;VGA register definitions ! 28: include i386\strucs.inc ! 29: .list ! 30: ! 31: ! 32: .data ! 33: ! 34: ; Reuse the work area from the dib conversion code. ! 35: ! 36: ; BUGBUG this should be allocated memory accessed via the DEVSURF, not static ! 37: ! 38: extrn ajConvertBuffer:byte ;Buffer for converting to/from display ! 39: ! 40: ; BUGBUG this should be dynamically calculated ! 41: ! 42: CJ_WORK_PLANE equ cj_max_scan+1 ;Width of each plane in ajConvertBuffer ! 43: ! 44: .code ! 45: ! 46: ; ausLo16 is used to convert the low nibble of a byte into 4bpp packed pel ! 47: ! 48: ausLo16 equ this word ! 49: ! 50: dw 0000h ;0000 ! 51: dw 0100h ;0001 ! 52: dw 1000h ;0010 ! 53: dw 1100h ;0011 ! 54: dw 0001h ;0100 ! 55: dw 0101h ;0101 ! 56: dw 1001h ;0110 ! 57: dw 1101h ;0111 ! 58: dw 0010h ;1000 ! 59: dw 0110h ;1001 ! 60: dw 1010h ;1010 ! 61: dw 1110h ;1011 ! 62: dw 0011h ;1100 ! 63: dw 0111h ;1101 ! 64: dw 1011h ;1110 ! 65: dw 1111h ;1111 ! 66: ! 67: ; aulHi16 is used to convert the hi nibble of a byte into 4bpp packed pel ! 68: ! 69: aulHi16 equ this dword ! 70: ! 71: dd 00000000h ;0000 ! 72: dd 01000000h ;0001 ! 73: dd 10000000h ;0010 ! 74: dd 11000000h ;0011 ! 75: dd 00010000h ;0100 ! 76: dd 01010000h ;0101 ! 77: dd 10010000h ;0110 ! 78: dd 11010000h ;0111 ! 79: dd 00100000h ;1000 ! 80: dd 01100000h ;1001 ! 81: dd 10100000h ;1010 ! 82: dd 11100000h ;1011 ! 83: dd 00110000h ;1100 ! 84: dd 01110000h ;1101 ! 85: dd 10110000h ;1110 ! 86: dd 11110000h ;1111 ! 87: ! 88: ; ajRightMasks turns an exclusive bit position (0-7) into a mask of bits ! 89: ; to alter for the right hand side of the blt ! 90: ! 91: ajRightMasks equ this byte ! 92: ! 93: db 11111111b ;0 should never be used ! 94: db 01111111b ;1 ! 95: db 00111111b ;2 ! 96: db 00011111b ;3 ! 97: db 00001111b ;4 ! 98: db 00000111b ;5 ! 99: db 00000011b ;6 ! 100: db 00000001b ;7 ! 101: ! 102: ; ajLeftMasks turns a bit position (0-7) into a mask of bits to alter for ! 103: ; the left hand side of the blt ! 104: ! 105: ajLeftMasks equ this byte ! 106: ! 107: db 11111111b ;0 should never be used ! 108: db 10000000b ;1 ! 109: db 11000000b ;2 ! 110: db 11100000b ;3 ! 111: db 11110000b ;4 ! 112: db 11111000b ;5 ! 113: db 11111100b ;6 ! 114: db 11111110b ;7 ! 115: ! 116: ! 117: CB_4BPP_SCAN equ (CX_SCREEN_MAX / 2) ;# bytes for a 4bpp screen scan ! 118: ! 119: ;-----------------------------Public-Routine----------------------------; ! 120: ; vConvertVGAScan ! 121: ; ! 122: ; Converts a VGA scan into a 4bpp format with a given phase alignment, ! 123: ; and returns a pointer to the converted buffer. ! 124: ; ! 125: ; pdsurfsrc - pointer to source surface (must be VGA display memory) ! 126: ; xSrc - X origin of the source ! 127: ; ySrc - Y origin of the source ! 128: ; pjDstBase - Base address of the destination ! 129: ; xDst - X origin of the destination ! 130: ; yDst - Y origin of the destination ! 131: ; cxPels - Number of pels in X ! 132: ; cyTotalScans - Number of scans in overall operation ! 133: ; lDelta - Width in bytes of a destination scan ! 134: ; iFormat - Format of destination ! 135: ; pulXlate - Color translation vector ! 136: ;-----------------------------------------------------------------------; ! 137: ! 138: ProcName xxxvConvertVGA2DIB,vConvertVGA2DIB,44 ! 139: ! 140: xxxvConvertVGA2DIB proc uses esi edi ebx,\ ! 141: pdsurfsrc :ptr DEVSURF, \ ! 142: xSrc :dword, \ ! 143: ySrc :dword, \ ! 144: pjDstBase :dword, \ ! 145: xDst :dword, \ ! 146: yDst :dword, \ ! 147: cxPels :dword, \ ! 148: cyTotalScans :dword, \ ! 149: lDelta :dword, \ ! 150: iFormat :dword, \ ! 151: pulXlate :dword ! 152: ! 153: ;-----------------------------------------------------------------------; ! 154: ; Local variables and their meaning ! 155: ; ! 156: ; cjScreenCopy This is the number of bytes to copy from each scan ! 157: ; into ajConvertBuffer. ! 158: ; jLeftMask This is the left-hand side (lhs) mask used when copying ! 159: ; the converted data to the destination ! 160: ; jRightMask This is the right-hand side (lhs) mask used when copying ! 161: ; the converted data to the destination ! 162: ; cRightShift This is the number of bits that the converted data needs ! 163: ; to be shifted right to align with the destination. ! 164: ; cjRightShift This is the number of bytes which must be shifted right ! 165: ; by cRightShift ! 166: ; cCopy This is the number of full (e.g. not masked) bytes which ! 167: ; must be copied to the destination ! 168: ; pjWork Pointer to the work area where ! 169: ; a) color converted data is written into ! 170: ; b) bits are phase-aligned if needed ! 171: ; c) data is read from for the final copy to the DIB ! 172: ; pjSrc Address of scan 0 in memory ! 173: ; pjDst Address of scan 0 in memory ! 174: ; cyScans Number of scans to do in current bank ! 175: ; ulScanWidth Offset from start of one scan to start of next ! 176: ; ulBottomSrcScan Bottom scan line of source rectangle (non-inclusive) ! 177: ;-----------------------------------------------------------------------; ! 178: ! 179: local cjScreenCopy :dword ! 180: local jLeftMask :byte ! 181: local jRightMask :byte ! 182: local cRightShift :byte ! 183: local cjRightShift :dword ! 184: local cCopy :dword ! 185: local pfnXlate :ptr ! 186: local pjWork :ptr ! 187: local cjSkip :dword ! 188: local pjSrc :dword ! 189: local pjDst :dword ! 190: local cyScans :dword ! 191: local ulScanWidth :dword ! 192: local ulBottomSrcScan :dword ! 193: ! 194: local ajColorConv[16]:byte ! 195: local ajWork[CB_4BPP_SCAN+4]:byte ! 196: local aj8bpp[CX_SCREEN_MAX+8]:byte ! 197: ! 198: ! 199: ;----------------------------------------------------------------------; ! 200: ; Loop through source banks, copying & converting one bank at a time. ! 201: ! 202: ; Calculate the bottom scan line of the source rectangle (non-inclusive). ! 203: ! 204: mov eax,ySrc ! 205: add eax,cyTotalScans ! 206: mov ulBottomSrcScan,eax ! 207: ! 208: mov ecx,pdsurfsrc ;point to source surface ! 209: mov eax,[ecx].dsurf_lNextScan ! 210: mov ulScanWidth,eax ;local copy of scan line width ! 211: ! 212: ; Map in the bank containing the top scan to fill, if it's not mapped in ! 213: ; already. ! 214: ! 215: mov eax,ySrc ;top scan line of source ! 216: ! 217: cmp eax,[ecx].dsurf_rcl1WindowClip.yTop ;is fill top less than ! 218: ; current bank? ! 219: jl short map_init_bank ;yes, map in proper bank ! 220: cmp eax,[ecx].dsurf_rcl1WindowClip.yBottom ;fill top greater than ! 221: ; current bank? ! 222: jl short init_bank_mapped ;no, proper bank already mapped ! 223: map_init_bank: ! 224: ! 225: ; Map in the bank containing the top scan line of the fill. ! 226: ! 227: ptrCall <dword ptr [ecx].dsurf_pfnBankControl>,<ecx,eax,JustifyTop> ! 228: ! 229: init_bank_mapped: ! 230: ! 231: bank_loop: ! 232: ! 233: ; Set the start address of the source bitmap. ! 234: ; Note that the start of the bitmap will change each time through the ! 235: ; bank loop, because the start of the bitmap is varied to map the ! 236: ; desired scan line to the banking window. ! 237: ! 238: mov eax,pdsurfsrc ;point to source surface ! 239: mov ebx,[eax].dsurf_pvBitmapStart ;start of scan 0 in bitmap ! 240: mov pjSrc,ebx ! 241: ! 242: ; Set the start address of the destination bitmap. ! 243: ! 244: mov ebx,pjDstBase ! 245: mov pjDst,ebx ! 246: ! 247: ; Figure out how many scan lines we'll fill in the current bank. ! 248: ! 249: mov ebx,ulBottomSrcScan ;bottom of destination rectangle ! 250: cmp ebx,[eax].dsurf_rcl1WindowClip.yBottom ! 251: ;which comes first, the bottom of the ! 252: ; dest rect or the bottom of the ! 253: ; current bank? ! 254: jl short BottomScanSet ;fill bottom comes first, so draw to ! 255: ; that; this is the last bank in fill ! 256: mov ebx,[eax].dsurf_rcl1WindowClip.yBottom ! 257: ;bank bottom comes first; draw to ! 258: ; bottom of bank ! 259: BottomScanSet: ! 260: sub ebx,ySrc ;# of scans to fill in bank ! 261: mov cyScans,ebx ! 262: push ebx ;remember # of scans in bank ! 263: ! 264: call DoOneBank ;copy and convert within the current bank ! 265: ! 266: pop ebx ;restore # of scans in bank ! 267: ! 268: sub cyTotalScans,ebx ;count off this bank's scans from total ! 269: jz short banks_done ;no more scans; done ! 270: add yDst,ebx ;advance to the next destination scan ! 271: ; to copy to ! 272: mov edi,pdsurfsrc ! 273: mov eax,[edi].dsurf_rcl1WindowClip.yBottom ! 274: mov ySrc,eax ;remember where the top of the bank ! 275: ; we're about to map in is (same as ! 276: ; bottom of bank we just did) ! 277: ! 278: ptrCall <dword ptr [edi].dsurf_pfnBankControl>,<edi,eax,JustifyTop> ! 279: ;map in the bank ! 280: ! 281: jmp bank_loop ;fill the next bank ! 282: ! 283: ! 284: ; Done. ! 285: ! 286: align 4 ! 287: banks_done: ! 288: ! 289: cRet vConvertVGA2DIB ! 290: ! 291: ;----------------------------------------------------------------------; ! 292: ; Copies and converts bits within a single bank. ! 293: ! 294: align 4 ! 295: DoOneBank: ! 296: ! 297: cld ! 298: ! 299: ; Compute the number of bytes to copy from the screen, and the starting ! 300: ; address of the source ! 301: ! 302: mov eax,ySrc ;Compute addr of first source scan ! 303: mov ebx,xSrc ! 304: imul eax,ulScanWidth ! 305: mov ecx,ebx ! 306: shr ebx,3 ! 307: add eax,ebx ! 308: add pjSrc,eax ! 309: ! 310: ; Compute the number of bytes to actually transfer from the screen ! 311: ! 312: mov eax,cxPels ;Compute rhs ! 313: add eax,ecx ! 314: dec eax ;Make rhs inclusive ! 315: shr ecx,3 ;Compute byte of lhs ! 316: shr eax,3 ;Compute byte of rhs ! 317: sub eax,ecx ;Compute number of bytes for copy ! 318: inc eax ;(because rhs inclusive, always inc) ! 319: mov cjScreenCopy,eax ! 320: ! 321: ; Compute the address of the starting destination scan. ! 322: ! 323: mov eax,yDst ! 324: imul lDelta ! 325: add pjDst,eax ! 326: ! 327: ; Set up for the preprocess loops and invoke the correct one. First make ! 328: ; some assumptions about defaults ! 329: ! 330: xor eax,eax ! 331: mov cRightShift,al ;No shifting needed ! 332: mov jLeftMask,al ;No left masking needed ! 333: mov jRightMask,al ;No right masking needed ! 334: lea eax,ajWork ;Intermediate work area ! 335: mov pjWork,eax ! 336: ! 337: mov esi,cxPels ! 338: mov ebx,xSrc ! 339: mov edx,xDst ! 340: ! 341: mov eax,iFormat ! 342: dec eax ! 343: jz preproc_1bpp ! 344: dec eax ! 345: jz preproc_4bpp ! 346: .errnz BMF_1BPP-1 ! 347: .errnz BMF_4BPP-2 ! 348: .errnz BMF_8BPP-3 ! 349: ! 350: ; Destination is 8bpp. Copy will be phased aligned from the conversion buffer ! 351: ; to the destination. ! 352: ! 353: preproc_8bpp: ! 354: add pjDst,edx ;Offset to first pel in DIB ! 355: and ebx,7 ;Offset to first pel for final copy ! 356: mov cjSkip,ebx ! 357: mov cCopy,esi ;Number of bytes for final copy ! 358: lea eax,aj8bpp ;Intermediate work area ! 359: mov pjWork,eax ! 360: mov pfnXlate,offset FLAT:cvt_to_8bpp ! 361: jmp preproc_done ! 362: ! 363: ! 364: ; Destination is 4bpp. Copy will either be phase aligned or be off by 4 in ! 365: ; which case we will phase align the entire buffer before copying. ! 366: ! 367: preproc_4bpp: ! 368: lea eax,[esi][edx] ;Compute rhs for later ! 369: test dl,1 ;Odd if left mask needed ! 370: jz @F ! 371: mov jLeftMask,11110000b ! 372: dec esi ;One less pel in inner loop ! 373: @@: ! 374: test al,1 ;Odd if right mask needed ! 375: jz @F ! 376: mov jRightMask,00001111b ! 377: dec esi ;One less pel in inner loop ! 378: @@: ! 379: ! 380: and ebx,7 ;Offset for final copy is xSrc mod 8 ! 381: ! 382: ; If the source and destination have different alignments, we'll have to ! 383: ; compute phase alignment stuff. ! 384: ! 385: mov eax,ebx ! 386: xor eax,edx ! 387: shr eax,1 ! 388: jnc @F ! 389: mov eax,cjScreenCopy ;* 4 for size of data in buffer ! 390: shl eax,2 ! 391: inc eax ;+ 1 to shift into last byte! ! 392: mov cjRightShift,eax ! 393: mov cRightShift,4 ;Shift entire buffer right 4 pels ! 394: inc ebx ;First pel just moved right ! 395: @@: ! 396: ! 397: ; Finish calculating the other parameters ! 398: ! 399: shr edx,1 ;Offset to first pel in DIB ! 400: add pjDst,edx ! 401: shr ebx,1 ! 402: mov cjSkip,ebx ! 403: shr esi,1 ! 404: mov cCopy,esi ;# of inner bytes for final copy ! 405: ! 406: mov eax,offset FLAT:copy_to_dest;Assume no color translation needed ! 407: cmp pulXlate,0 ! 408: je @F ! 409: mov eax,offset FLAT:cvt_to_4bpp ;Addreess of color xlate routine ! 410: @@: ! 411: mov pfnXlate,eax ! 412: jmp preproc_done ! 413: ! 414: ! 415: ; Destination is 1bpp. Copy most likely will require masking and phase ! 416: ; alignment. ! 417: ! 418: preproc_1bpp: ! 419: mov edi,00000007h ;A handy mask used a lot ! 420: xor ecx,ecx ;CL = lhs mask, CH = rhs mask ! 421: lea eax,[esi][edx] ;Compute rhs for later ! 422: test edx,edi ;See if partial byte ! 423: jz preproc_1bpp_done_lhs ;No partial lhs byte ! 424: mov ecx,edx ! 425: neg ecx ! 426: and ecx,edi ;CL = # bits in lhs, CH = 0 ! 427: sub esi,ecx ;Compute # remaining bytes ! 428: mov cl,ajLeftMasks[ecx] ;Get lhs mask ! 429: jnc preproc_1bpp_done_lhs ;Didn't combine into one byte ! 430: and eax,edi ;Combine rhs mask with lhs mask ! 431: and cl,ajRightMasks[eax] ! 432: xor esi,esi ;No more bytes ! 433: xor eax,eax ;To show no rhs ! 434: jmp short preproc_1bpp_have_masks ! 435: ! 436: preproc_1bpp_done_lhs: ! 437: and eax,edi ;See if partial rhs byte ! 438: jz preproc_1bpp_have_masks ;No partial rhs byte ! 439: mov ch,ajRightMasks[eax] ! 440: sub esi,eax ;Compute # remaining bytes ! 441: ! 442: preproc_1bpp_have_masks: ! 443: mov jLeftMask,cl ;Set left and right masks ! 444: mov jRightMask,ch ! 445: shr esi,3 ;# of inner bytes for final copy ! 446: mov cCopy,esi ! 447: ! 448: ; Compute offset to first byte in destination DIB ! 449: ! 450: mov eax,edx ! 451: shr eax,3 ! 452: add pjDst,eax ! 453: ! 454: ; Compute phase alignment parameters ! 455: ! 456: xor ecx,ecx ;Assume cjSkip is 0 ! 457: and edx,edi ! 458: and ebx,edi ! 459: sub edx,ebx ;Determine phase alignment ! 460: jz preproc_finish_1bpp ;No phase alignment needed ! 461: ! 462: ; We're really shifting left, so we'll set it up to shift right a lot, and ! 463: ; get the first byte of the final move from byte 1 of the work area. ! 464: ! 465: adc ecx,ecx ;Set cjSkip = 0 or 1 ! 466: and edx,edi ;3 LSBs is shift count ! 467: mov cRightShift,dl ;Phase for the shift ! 468: mov eax,cjScreenCopy ;Size of data in buffer ! 469: inc eax ;+ 1 to shift into last byte! ! 470: mov cjRightShift,eax ! 471: preproc_finish_1bpp: ! 472: mov cjSkip,ecx ;No skipping needed ! 473: mov esi,pulXlate ;Copy color translation table to the ! 474: lea edi,ajColorConv ; frame because we are out of regs. ! 475: mov ecx,16 ! 476: @@: ! 477: lodsd ! 478: stosb ! 479: dec ecx ! 480: jnz @B ! 481: ! 482: mov pfnXlate,offset FLAT:cvt_to_1bpp ! 483: ! 484: preproc_done: ! 485: ! 486: process_next_scan: ! 487: ! 488: mov edi,offset FLAT:ajConvertBuffer ! 489: mov edx,EGA_BASE + GRAF_ADDR ! 490: mov eax,GRAF_READ_MAP ! 491: copy_next_plane: ! 492: mov esi,pjSrc ;ESI --> first Source byte ! 493: out dx,ax ;Set read plane ! 494: mov ecx,cjScreenCopy ;Set number of bytes to read ! 495: mov ebx,edi ! 496: rep movsb ! 497: lea edi,[ebx][CJ_WORK_PLANE];EDI --> next scan in convert buf ! 498: inc ah ;Set next read plane ! 499: cmp ah,4 ! 500: jb copy_next_plane ! 501: ! 502: ; The scan has been read in from the VGA. Convert it into 4bpp format which ! 503: ; will be needed for doing the color conversion. ! 504: ! 505: lea edi,ajWork ;Convert dwords into here ! 506: mov esi,offset FLAT:ajConvertBuffer ! 507: mov ecx,cjScreenCopy ;# of source bytes to convert ! 508: ! 509: cvt_next_src_byte: ! 510: xor eax,eax ! 511: mov al,[esi][CJ_WORK_PLANE*3] ;Get data for plane C3 ! 512: mov ebx,eax ! 513: and ebx,00001111b ! 514: shr eax,4 ! 515: mov edx,aulHi16[ebx*4] ! 516: or dx,ausLo16[eax*2] ! 517: shl edx,1 ! 518: mov al,[esi][CJ_WORK_PLANE*2] ;Get data for plane C2 ! 519: mov ebx,eax ! 520: and ebx,00001111b ! 521: shr eax,4 ! 522: or edx,aulHi16[ebx*4] ! 523: or dx,ausLo16[eax*2] ! 524: shl edx,1 ! 525: mov al,[esi][CJ_WORK_PLANE*1] ;Get data for plane C1 ! 526: mov ebx,eax ! 527: and ebx,00001111b ! 528: shr eax,4 ! 529: or edx,aulHi16[ebx*4] ! 530: or dx,ausLo16[eax*2] ! 531: shl edx,1 ! 532: lodsb ;Get data for plane C0 ! 533: mov ebx,eax ! 534: and ebx,00001111b ! 535: shr eax,4 ! 536: or edx,aulHi16[ebx*4] ! 537: or dx,ausLo16[eax*2] ! 538: mov eax,edx ! 539: stosd ;8 pels down! ! 540: dec ecx ! 541: jnz cvt_next_src_byte ! 542: ! 543: ! 544: ; Perform the format conversion ! 545: mov ecx,cjScreenCopy ;Set lopp count ! 546: lea esi,ajWork ;Set source pointer ! 547: mov edi,pjWork ;Set destination pointer ! 548: mov ebx,pulXlate ;Set color translate vector ! 549: xor eax,eax ;Init D31:D8 to 0 ! 550: jmp pfnXlate ;Invoke correct conversion routine ! 551: ! 552: ; Convert from 4bpp to 8bpp with color translation ! 553: ! 554: cvt_to_8bpp: ! 555: lodsb ;Get two nibbles worth ! 556: mov edx,eax ! 557: shr eax,4 ! 558: and edx,00001111b ! 559: mov al,[ebx][eax*4] ! 560: stosb ! 561: mov al,[ebx][edx*4] ! 562: stosb ! 563: lodsb ;Get two nibbles worth ! 564: mov edx,eax ! 565: shr eax,4 ! 566: and edx,00001111b ! 567: mov al,[ebx][eax*4] ! 568: stosb ! 569: mov al,[ebx][edx*4] ! 570: stosb ! 571: lodsb ;Get two nibbles worth ! 572: mov edx,eax ! 573: shr eax,4 ! 574: and edx,00001111b ! 575: mov al,[ebx][eax*4] ! 576: stosb ! 577: mov al,[ebx][edx*4] ! 578: stosb ! 579: lodsb ;Get two nibbles worth ! 580: mov edx,eax ! 581: shr eax,4 ! 582: and edx,00001111b ! 583: mov al,[ebx][eax*4] ! 584: stosb ! 585: mov al,[ebx][edx*4] ! 586: stosb ! 587: dec ecx ! 588: jnz cvt_to_8bpp ! 589: jmp copy_to_dest ! 590: ! 591: ; Convert from 4bpp to 4bpp with color translation. ! 592: ! 593: cvt_to_4bpp: ! 594: lodsb ;Get two nibbles worth ! 595: mov edx,eax ! 596: shr eax,4 ! 597: and edx,00001111b ! 598: mov al,[ebx][eax*4] ! 599: shl al,4 ! 600: or al,[ebx][edx*4] ! 601: stosb ! 602: lodsb ;Get two nibbles worth ! 603: mov edx,eax ! 604: shr eax,4 ! 605: and edx,00001111b ! 606: mov al,[ebx][eax*4] ! 607: shl al,4 ! 608: or al,[ebx][edx*4] ! 609: stosb ! 610: lodsb ;Get two nibbles worth ! 611: mov edx,eax ! 612: shr eax,4 ! 613: and edx,00001111b ! 614: mov al,[ebx][eax*4] ! 615: shl al,4 ! 616: or al,[ebx][edx*4] ! 617: stosb ! 618: lodsb ;Get two nibbles worth ! 619: mov edx,eax ! 620: shr eax,4 ! 621: and edx,00001111b ! 622: mov al,[ebx][eax*4] ! 623: shl al,4 ! 624: or al,[ebx][edx*4] ! 625: stosb ! 626: dec ecx ! 627: jnz cvt_to_4bpp ! 628: jmp copy_to_dest ! 629: ! 630: ! 631: ; Convert from 4bpp to 1bpp with color translation. ! 632: ! 633: ! 634: cvt_to_1bpp: ! 635: lodsb ;Get two nibbles worth ! 636: mov edx,eax ! 637: shr eax,4 ! 638: and edx,00001111b ! 639: mov bl,ajColorConv[eax] ! 640: shl bl,1 ! 641: or bl,ajColorConv[edx] ! 642: lodsb ! 643: mov edx,eax ! 644: shr eax,4 ! 645: and edx,00001111b ! 646: shl bl,1 ! 647: or bl,ajColorConv[eax] ! 648: shl bl,1 ! 649: or bl,ajColorConv[edx] ! 650: lodsb ;Get two nibbles worth ! 651: mov edx,eax ! 652: shr eax,4 ! 653: and edx,00001111b ! 654: shl bl,1 ! 655: or bl,ajColorConv[eax] ! 656: shl bl,1 ! 657: or bl,ajColorConv[edx] ! 658: lodsb ;Get two nibbles worth ! 659: mov edx,eax ! 660: shr eax,4 ! 661: and edx,00001111b ! 662: shl bl,1 ! 663: or bl,ajColorConv[eax] ! 664: shl bl,1 ! 665: or bl,ajColorConv[edx] ! 666: mov al,bl ! 667: stosb ! 668: dec ecx ! 669: jnz cvt_to_1bpp ! 670: ! 671: ! 672: ; Copy to the destination. This unfortunately may involve phase alignment ! 673: ! 674: copy_to_dest: ! 675: movzx ecx,cRightShift ! 676: jecxz copy_aligned_to_dest ! 677: mov edi,pjWork ! 678: mov ebx,cjRightShift ! 679: phase_align_it: ! 680: mov ah,dl ;Get previous unused bits ! 681: mov al,byte ptr [edi] ! 682: mov dl,al ! 683: shr eax,cl ! 684: stosb ! 685: dec ebx ! 686: jnz phase_align_it ! 687: ! 688: copy_aligned_to_dest: ! 689: mov esi,pjWork ! 690: add esi,cjSkip ! 691: mov edi,pjDst ! 692: ! 693: mov dl,jLeftMask ! 694: or dl,dl ! 695: jz @F ! 696: lodsb ! 697: mov ah,byte ptr [edi] ! 698: xor ah,al ! 699: and ah,dl ! 700: xor al,ah ! 701: stosb ! 702: @@: ! 703: mov ecx,cCopy ! 704: rep movsb ! 705: ! 706: mov dl,jRightMask ! 707: or dl,dl ! 708: jz @F ! 709: lodsb ! 710: mov ah,byte ptr [edi] ! 711: xor ah,al ! 712: and ah,dl ! 713: xor al,ah ! 714: stosb ! 715: @@: ! 716: ! 717: mov eax,ulScanWidth ! 718: add pjSrc,eax ! 719: mov eax,lDelta ! 720: add pjDst,eax ! 721: dec cyScans ! 722: jnz process_next_scan ! 723: ! 724: PLAIN_RET ;we're done with this bank ! 725: ! 726: xxxvConvertVGA2DIB endp ! 727: ! 728: end ! 729:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.