|
|
1.1 ! root 1: ;---------------------------Module-Header------------------------------; ! 2: ; Module Name: dib2vga.asm ! 3: ; ! 4: ; Copyright (c) 1992 Microsoft Corporation ! 5: ;-----------------------------------------------------------------------; ! 6: ;-----------------------------------------------------------------------; ! 7: ; ! 8: ; VOID vDIB2VGA(DEVSURF * pdsurfDst, DEVSURF * pdsurfSrc, ! 9: ; RECTL * prclDst, POINTL * pptlSrc, UCHAR *pConv); ! 10: ; ! 11: ; Performs accelerated copies of DIB pixels to the VGA screen. ! 12: ; ! 13: ; pdsurfDst = pointer to dest surface, which must be the VGA ! 14: ; ! 15: ; pdsurfSrc = pointer to source surface, which must be a 4 bpp DIB. Only the ! 16: ; lNextScan and pvBitmapStart fields need to be set ! 17: ; ! 18: ; prclDst = pointer to rectangle describing area of VGA to be copied to ! 19: ; ! 20: ; pptlSrc = pointer to point structure describing the upper left corner ! 21: ; of the copy in the source DIB ! 22: ; ! 23: ; pConv = pointer to set of four 256-byte tables used for conversion ! 24: ; from DIB4 to VGA, created by vSetDIB4ToVGATables ! 25: ; ! 26: ;-----------------------------------------------------------------------; ! 27: ;-----------------------------------------------------------------------; ! 28: ; ! 29: ; VOID vSetDIB4ToVGATables(UCHAR * pucConvTable); ! 30: ; ! 31: ; Creates the four 256-byte tables used for conversion from DIB4 to VGA. ! 32: ; ! 33: ; pucConvTable = pointer to 1K of storage into which the conversion ! 34: ; tables are placed ! 35: ; ! 36: ;-----------------------------------------------------------------------; ! 37: ;-----------------------------------------------------------------------; ! 38: ; ! 39: ; Note: The general-purpose buffer attached to the PDEV that we used for ! 40: ; temp storage (pvBankBufferPlane0) must be at least 1K+4 bytes wide to ! 41: ; support ! 42: ; ! 43: ; Note: Assumes the destination rectangle has a positive height and width. ! 44: ; Will not work properly if this is not the case. ! 45: ; ! 46: ; Note: The source must be a standard DIB4 bitmap, and the destination ! 47: ; must be VGA display memory. ! 48: ; ! 49: ; Note: Performance would benefit if we did more scans at a time in each ! 50: ; plane on processor/VGA combinations that supported higher conversion ! 51: ; and display memory writing speeds. ! 52: ; ! 53: ;-----------------------------------------------------------------------; ! 54: ! 55: .386 ! 56: ! 57: ifndef DOS_PLATFORM ! 58: .model small,c ! 59: else ! 60: ifdef STD_CALL ! 61: .model small,c ! 62: else ! 63: .model small,pascal ! 64: endif; STD_CALL ! 65: endif; DOS_PLATFORM ! 66: ! 67: assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT ! 68: assume fs:nothing,gs:nothing ! 69: ! 70: .xlist ! 71: include stdcall.inc ;calling convention cmacros ! 72: include i386\egavga.inc ! 73: include i386\strucs.inc ! 74: ! 75: .list ! 76: ! 77: ;-----------------------------------------------------------------------; ! 78: ! 79: .data ! 80: ! 81: ;-----------------------------------------------------------------------; ! 82: ; Masks to be applied to the source data for the 8 possible clip ! 83: ; alignments. ! 84: ;-----------------------------------------------------------------------; ! 85: ! 86: jLeftMasks db 0ffh, 07fh, 03fh, 01fh, 00fh, 007h, 003h, 001h ! 87: jRightMasks db 0ffh, 080h, 0c0h, 0e0h, 0f0h, 0f8h, 0fch, 0feh ! 88: ! 89: ;-----------------------------------------------------------------------; ! 90: ; The following tables *must* start on 256-byte boundaries, so that a ! 91: ; table look-up may be accomplished by loading BL. ! 92: ;-----------------------------------------------------------------------; ! 93: ! 94: ;-----------------------------------------------------------------------; ! 95: ; Table used to multiplex bits from form accumulated from DIB4 to VGA ! 96: ; planar byte format for plane 0. Translation is from 64207531 source ! 97: ; DIB format (where 0 is leftmost, 7 is rightmost) to 76543210 VGA ! 98: ; format (where 7 is leftmost, 0 is rightmost). ! 99: if 0 ! 100: align 256 ! 101: ;@@@ ! 102: db 256-20h dup (?) ! 103: ;@@@ ! 104: ;DIB4_to_VGA_plane0_table label byte ! 105: x=0 ! 106: rept 256 ! 107: db ((x and 10h) shl 3)+((x and 01h) shl 6)+\ ! 108: (x and 20h) +((x and 02h) shl 3)+\ ! 109: ((x and 40h) shr 3)+ (x and 04h) +\ ! 110: ((x and 80h) shr 6)+((x and 08h) shr 3) ! 111: x=x+1 ! 112: endm ! 113: ;-----------------------------------------------------------------------; ! 114: ; Table used to multiplex bits from form accumulated from DIB4 to VGA ! 115: ; planar byte format for plane 0. Translation is from 46025713 source ! 116: ; DIB format (where 0 is leftmost, 7 is rightmost) to 76543210 VGA ! 117: ; format (where 7 is leftmost, 0 is rightmost). ! 118: ! 119: ;DIB4_to_VGA_plane1_table label byte ! 120: x=0 ! 121: rept 256 ! 122: db ((x and 20h) shl 2)+((x and 02h) shl 5)+\ ! 123: ((x and 10h) shl 1)+((x and 01h) shl 4)+\ ! 124: ((x and 80h) shr 4)+((x and 08h) shr 1)+\ ! 125: ((x and 40h) shr 5)+((x and 04h) shr 2) ! 126: x=x+1 ! 127: endm ! 128: ;-----------------------------------------------------------------------; ! 129: ; Table used to multiplex bits from form accumulated from DIB4 to VGA ! 130: ; planar byte format for plane 0. Translation is from 20643175 source ! 131: ; DIB format (where 0 is leftmost, 7 is rightmost) to 76543210 VGA ! 132: ; format (where 7 is leftmost, 0 is rightmost). ! 133: ! 134: ;DIB4_to_VGA_plane2_table label byte ! 135: x=0 ! 136: rept 256 ! 137: db ((x and 40h) shl 1)+((x and 04h) shl 4)+\ ! 138: ((x and 80h) shr 2)+((x and 08h) shl 1)+\ ! 139: ((x and 10h) shr 1)+((x and 01h) shl 2)+\ ! 140: ((x and 20h) shr 4)+((x and 02h) shr 1) ! 141: x=x+1 ! 142: endm ! 143: ;-----------------------------------------------------------------------; ! 144: ; Table used to multiplex bits from form accumulated from DIB4 to VGA ! 145: ; planar byte format for plane 0. Translation is from 02461357 source ! 146: ; DIB format (where 0 is leftmost, 7 is rightmost) to 76543210 VGA ! 147: ; format (where 7 is leftmost, 0 is rightmost). ! 148: ! 149: ;DIB4_to_VGA_plane3_table label byte ! 150: x=0 ! 151: rept 256 ! 152: db (x and 80h) +((x and 08h) shl 3)+\ ! 153: ((x and 40h) shr 1)+((x and 04h) shl 2)+\ ! 154: ((x and 20h) shr 2)+((x and 02h) shl 1)+\ ! 155: ((x and 10h) shr 3)+ (x and 01h) ! 156: x=x+1 ! 157: endm ! 158: endif ! 159: ;-----------------------------------------------------------------------; ! 160: ! 161: .code ! 162: ! 163: _TEXT$01 SEGMENT DWORD USE32 PUBLIC 'CODE' ! 164: ASSUME CS:FLAT, DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING ! 165: ! 166: ;-----------------------------------------------------------------------; ! 167: ! 168: cProc vSetDIB4ToVGATables,4,< \ ! 169: uses esi edi ebx, \ ! 170: pucConvTable : dword > ! 171: ! 172: mov ebx,pucConvTable ! 173: ! 174: ; Generate the table used to multiplex bits from form accumulated from DIB4 ! 175: ; to VGA planar byte format for plane 0. Translation is from 64207531 source ! 176: ; DIB format (where 0 is leftmost, 7 is rightmost) to 76543210 VGA ! 177: ; format (where 7 is leftmost, 0 is rightmost). ! 178: ! 179: mov ecx,256 ! 180: sub al,al ! 181: plane0_conv_table_loop: ! 182: sub dl,dl ! 183: mov ah,al ! 184: and ah,10h ! 185: shl ah,3 ! 186: or dl,ah ! 187: mov ah,al ! 188: and ah,01h ! 189: shl ah,6 ! 190: or dl,ah ! 191: mov ah,al ! 192: and ah,20h ! 193: or dl,ah ! 194: mov ah,al ! 195: and ah,02h ! 196: shl ah,3 ! 197: or dl,ah ! 198: mov ah,al ! 199: and ah,40h ! 200: shr ah,3 ! 201: or dl,ah ! 202: mov ah,al ! 203: and ah,04h ! 204: or dl,ah ! 205: mov ah,al ! 206: and ah,80h ! 207: shr ah,6 ! 208: or dl,ah ! 209: mov ah,al ! 210: and ah,08h ! 211: shr ah,3 ! 212: or dl,ah ! 213: mov [ebx],dl ! 214: inc al ! 215: inc ebx ! 216: dec ecx ! 217: jnz plane0_conv_table_loop ! 218: ! 219: ; Generate the table used to multiplex bits from form accumulated from DIB4 ! 220: ; to VGA planar byte format for plane 1. Translation is from 46025713 source ! 221: ; DIB format (where 0 is leftmost, 7 is rightmost) to 76543210 VGA ! 222: ; format (where 7 is leftmost, 0 is rightmost). ! 223: ! 224: mov ecx,256 ! 225: sub al,al ! 226: plane1_conv_table_loop: ! 227: sub dl,dl ! 228: mov ah,al ! 229: and ah,20h ! 230: shl ah,2 ! 231: or dl,ah ! 232: mov ah,al ! 233: and ah,02h ! 234: shl ah,5 ! 235: or dl,ah ! 236: mov ah,al ! 237: and ah,10h ! 238: shl ah,1 ! 239: or dl,ah ! 240: mov ah,al ! 241: and ah,01h ! 242: shl ah,4 ! 243: or dl,ah ! 244: mov ah,al ! 245: and ah,80h ! 246: shr ah,4 ! 247: or dl,ah ! 248: mov ah,al ! 249: and ah,08h ! 250: shr ah,1 ! 251: or dl,ah ! 252: mov ah,al ! 253: and ah,40h ! 254: shr ah,5 ! 255: or dl,ah ! 256: mov ah,al ! 257: and ah,04h ! 258: shr ah,2 ! 259: or dl,ah ! 260: mov [ebx],dl ! 261: inc al ! 262: inc ebx ! 263: dec ecx ! 264: jnz plane1_conv_table_loop ! 265: ! 266: ; Generate the table used to multiplex bits from form accumulated from DIB4 ! 267: ; to VGA planar byte format for plane 2. Translation is from 20643175 source ! 268: ; DIB format (where 0 is leftmost, 7 is rightmost) to 76543210 VGA ! 269: ; format (where 7 is leftmost, 0 is rightmost). ! 270: ! 271: mov ecx,256 ! 272: sub al,al ! 273: plane2_conv_table_loop: ! 274: sub dl,dl ! 275: mov ah,al ! 276: and ah,40h ! 277: shl ah,1 ! 278: or dl,ah ! 279: mov ah,al ! 280: and ah,04h ! 281: shl ah,4 ! 282: or dl,ah ! 283: mov ah,al ! 284: and ah,80h ! 285: shr ah,2 ! 286: or dl,ah ! 287: mov ah,al ! 288: and ah,08h ! 289: shl ah,1 ! 290: or dl,ah ! 291: mov ah,al ! 292: and ah,10h ! 293: shr ah,1 ! 294: or dl,ah ! 295: mov ah,al ! 296: and ah,01h ! 297: shl ah,2 ! 298: or dl,ah ! 299: mov ah,al ! 300: and ah,20h ! 301: shr ah,4 ! 302: or dl,ah ! 303: mov ah,al ! 304: and ah,02h ! 305: shr ah,1 ! 306: or dl,ah ! 307: mov [ebx],dl ! 308: inc al ! 309: inc ebx ! 310: dec ecx ! 311: jnz plane2_conv_table_loop ! 312: ! 313: ; Generate the table used to multiplex bits from form accumulated from DIB4 ! 314: ; to VGA planar byte format for plane 1. Translation is from 02461357 source ! 315: ; DIB format (where 0 is leftmost, 7 is rightmost) to 76543210 VGA ! 316: ; format (where 7 is leftmost, 0 is rightmost). ! 317: ! 318: mov ecx,256 ! 319: sub al,al ! 320: plane3_conv_table_loop: ! 321: sub dl,dl ! 322: mov ah,al ! 323: and ah,80h ! 324: or dl,ah ! 325: mov ah,al ! 326: and ah,08h ! 327: shl ah,3 ! 328: or dl,ah ! 329: mov ah,al ! 330: and ah,40h ! 331: shr ah,1 ! 332: or dl,ah ! 333: mov ah,al ! 334: and ah,04h ! 335: shl ah,2 ! 336: or dl,ah ! 337: mov ah,al ! 338: and ah,20h ! 339: shr ah,2 ! 340: or dl,ah ! 341: mov ah,al ! 342: and ah,02h ! 343: shl ah,1 ! 344: or dl,ah ! 345: mov ah,al ! 346: and ah,10h ! 347: shr ah,3 ! 348: or dl,ah ! 349: mov ah,al ! 350: and ah,01h ! 351: or dl,ah ! 352: mov [ebx],dl ! 353: inc al ! 354: inc ebx ! 355: dec ecx ! 356: jnz plane3_conv_table_loop ! 357: ! 358: cRet vSetDIB4ToVGATables ;done ! 359: ! 360: endProc vSetDIB4ToVGATables ! 361: ! 362: ;-----------------------------------------------------------------------; ! 363: ! 364: cProc vDIB2VGA,20,< \ ! 365: uses esi edi ebx, \ ! 366: pdsurfDst: ptr DEVSURF, \ ! 367: pdsurfSrc: ptr DEVSURF, \ ! 368: prclDst: ptr RECTL, \ ! 369: pptlSrc : ptr POINTL, \ ! 370: pConv : dword > ! 371: ! 372: local ulWholeDwordCount:dword ;# of whole VGA dwords to copy to ! 373: local ulSourceDwordWidth:dword ;# of DIB dwords from which to copy ! 374: ; (rounded up to the nearest dword) ! 375: local ulLeftMask:dword ;low byte = mask for new pixels at ! 376: ; left edge; ! 377: ;high byte = mask for dest at left ! 378: ; edge; ! 379: ;high word = 0ffffh ! 380: local ulRightMask:dword ;low byte = mask for new pixels at ! 381: ; partial left edge; ! 382: ;high byte = mask for destination at ! 383: ; partial right edge; ! 384: ;high word = 0ffffh ! 385: local ulPlane0Scans:dword ;# of scans to copy in plane 0 in burst ! 386: local ulPlane1Scans:dword ;# of scans to copy in plane 1 in burst ! 387: local ulPlane2Scans:dword ;# of scans to copy in plane 2 in burst ! 388: local ulPlane3Scans:dword ;# of scans to copy in plane 3 in burst ! 389: local ulSrcDelta:dword ;offset from end of one source scan to ! 390: ; copy to start of next in working ! 391: ; source (either DIB or temp buffer) ! 392: local ulTrueSrcDelta:dword ;offset from end of one source scan to ! 393: ; copy to start of next in DIB if temp ! 394: ; buffer is being used ! 395: local ulDstDelta:dword ;offset from end of one destination ! 396: ; scan to copy to start of next ! 397: local pSrc:dword ;pointer to working drawing src start ! 398: ; address (either DIB or temp buffer) ! 399: local pTrueSrc:dword ;pointer to drawing src start address ! 400: ; in DIB if temp buffer is being used ! 401: local pDst:dword ;pointer to drawing dst start address ! 402: local pTempBuffer:dword ;pointer to buffer used for alignment ! 403: local ulCurrentTopScan:dword ;top scan to copy to in current bank ! 404: local ulBottomScan:dword ;bottom scan line of copy rectangle ! 405: local ulAlignShift:dword ;# of bits to shift left (+) or right ! 406: ; (-) to dword align source to dest ! 407: local ulBurstMax:dword ;max # of scans to be done in a single ! 408: ; plane before switching to the next ! 409: ; plane (to avoid flicker) ! 410: local pAlignmentRoutine:dword ;pointer to routine to be used to ! 411: ; copy & align the source with the dest ! 412: local DIB4_to_VGA_plane0_table:dword ;pointers to conversion tables ! 413: local DIB4_to_VGA_plane1_table:dword ; for the four planes ! 414: local DIB4_to_VGA_plane2_table:dword ! 415: local DIB4_to_VGA_plane3_table:dword ! 416: local ulCopyControlFlags:dword ;upper bits indicate which portions of ! 417: ; copy are to be performed, as follows: ! 418: ODD_WHOLE_WORD equ 80000000h ;there are an odd # of VGA words to ! 419: ; copy to ! 420: .errnz ODD_WHOLE_WORD-80000000h ; (note that this *must* be bit 31, ! 421: ; because the sign status is used to ! 422: ; detect this case) ! 423: WHOLE_WORDS equ 40000000h ;whole words to be copied ! 424: LEADING_BYTE equ 20000000h ;leading byte should be copied ! 425: TRAILING_BYTE equ 10000000h ;trailing byte should be copied ! 426: LEADING_PARTIAL equ 08000000h ;partial leading byte should be copied ! 427: TRAILING_PARTIAL equ 04000000h ;partial trailing byte should be copied ! 428: ! 429: ;-----------------------------------------------------------------------; ! 430: ! 431: cld ! 432: ! 433: ;-----------------------------------------------------------------------; ! 434: ; Point to the source start address (nearest dword equal or less). ! 435: ;-----------------------------------------------------------------------; ! 436: ! 437: mov ebx,pptlSrc ;point to coords of source upper left ! 438: mov esi,pdsurfSrc ;point to surface to copy from (DIB4) ! 439: mov edi,pdsurfDst ;point to surface to copy to (VGA) ! 440: mov eax,[ebx].ptl_y ! 441: mul [esi].dsurf_lNextScan ;offset in bitmap of top src rect scan ! 442: mov edx,[ebx].ptl_x ! 443: shr edx,1 ;source byte X address ! 444: and edx,not 11b ;round down to nearest dword ! 445: add eax,edx ;offset in bitmap of first source dword ! 446: add eax,[esi].dsurf_pvBitmapStart ;pointer to first source dword ! 447: mov pSrc,eax ! 448: ! 449: ;-----------------------------------------------------------------------; ! 450: ; Set the pointers to the DIB->VGA conversion tables for the four ! 451: ; planes; those tables are created at start-up, and found via the PDEV. ! 452: ;-----------------------------------------------------------------------; ! 453: ! 454: mov eax,pConv ;first conversion table ! 455: mov DIB4_to_VGA_plane0_table,eax ! 456: inc ah ;add 256 to point to next table ! 457: mov DIB4_to_VGA_plane1_table,eax ! 458: inc ah ;add 256 to point to next table ! 459: mov DIB4_to_VGA_plane2_table,eax ! 460: inc ah ;add 256 to point to next table ! 461: mov DIB4_to_VGA_plane3_table,eax ! 462: ! 463: ;-----------------------------------------------------------------------; ! 464: ; Set up various variables for the copy. ! 465: ; ! 466: ; At this point, EBX = pptlSrc, EDI = pdsurfDst. ! 467: ;-----------------------------------------------------------------------; ! 468: ! 469: mov esi,prclDst ;point to rectangle to which to copy ! 470: sub ecx,ecx ;accumulate copy control flags, which ! 471: ; describe the various portions of the ! 472: ; copy we want to perform ! 473: ! 474: ;first, check for partial-byte edges ! 475: mov eax,[esi].xLeft ! 476: and eax,111b ;left edge pixel alignment ! 477: jz short @F ;whole byte, don't need leading mask ! 478: or ecx,LEADING_PARTIAL ;do need leading mask ! 479: @@: ! 480: mov edx,-1 ;set high word, so copy control bits ! 481: ; aren't wiped out by AND ! 482: mov dl,jLeftMasks[eax] ;mask to apply to source to clip ! 483: mov dh,dl ! 484: not dh ;mask to apply to dest to preserve ! 485: mov ulLeftMask,edx ;remember mask ! 486: ! 487: mov eax,[esi].xRight ! 488: and eax,111b ;right edge pixel alignment ! 489: jz short @F ;whole byte, don't need trailing mask ! 490: or ecx,TRAILING_PARTIAL ;do need trailing mask ! 491: @@: ! 492: mov edx,-1 ;set high word, so copy control bits ! 493: ; aren't wiped out by AND ! 494: mov dl,jRightMasks[eax] ;mask to apply to source to clip ! 495: mov dh,dl ! 496: not dh ;mask to apply to dest to preserve ! 497: mov ulRightMask,edx ;remember mask ! 498: ! 499: ;now, see if there are only partial ! 500: ; bytes, or maybe even only one byte ! 501: mov eax,[esi].xLeft ! 502: add eax,111b ! 503: and eax,not 111b ;round left up to nearest byte ! 504: mov edx,[esi].xRight ! 505: and edx,not 111b ;round right down to nearest byte ! 506: sub edx,eax ;# of pixels, rounded to nearest byte ! 507: ; boundaries (not counting partials) ! 508: ja short check_whole_bytes ;there's at least one whole byte ! 509: ;there are no whole bytes; there may be ! 510: ; only one partial byte, or there may ! 511: ; be two ! 512: jb short one_partial_only ;there is only one, partial byte ! 513: ;if the dest is left- or right- ! 514: ; justified, then there's only one, ! 515: ; partial byte, otherwise there are two ! 516: ; partial bytes ! 517: cmp byte ptr ulLeftMask,0ffh ;left-justified in byte? ! 518: jz short one_partial_only ;yes, so only one, partial byte ! 519: cmp byte ptr ulRightMask,0ffh ;right-justified in byte? ! 520: jnz short set_copy_control_flags ;no, so there are two partial ! 521: ; bytes, which is exactly what ! 522: ; we're already set up to do ! 523: one_partial_only: ;only one, partial byte, so construct a ! 524: ; single mask and set up to do just ! 525: ; one, partial byte ! 526: mov eax,ulLeftMask ! 527: and eax,ulRightMask ;intersect the masks ! 528: mov ah,al ! 529: not ah ;construct the destination mask ! 530: mov ulLeftMask,eax ! 531: mov ecx,LEADING_PARTIAL ;only one partial byte, which we'll ! 532: ; treat as leading ! 533: jmp short set_copy_control_flags ;the copy control flags are set ! 534: ! 535: align 4 ! 536: check_whole_bytes: ! 537: ;check for leading and trailing odd ! 538: ; (non-word-aligned) whole bytes ! 539: mov eax,[esi].xLeft ;check for leading whole byte ! 540: and eax,1111b ;intra-word address ! 541: jz short @F ;whole leading word, so no whole byte ! 542: cmp eax,8 ;is start at or before second byte ! 543: ; start? ! 544: ja short @F ;no, so no whole byte ! 545: or ecx,LEADING_BYTE ;yes, there's a leading byte ! 546: @@: ! 547: ! 548: mov eax,[esi].xRight ;check for trailing whole byte ! 549: and eax,1111b ;intra-word address ! 550: jz short @F ;whole trailing word, so no whole byte ! 551: cmp eax,8 ;is start before second byte start? ! 552: jb short @F ;no, so no whole byte ! 553: or ecx,TRAILING_BYTE ;yes, there's a trailing byte ! 554: @@: ! 555: ! 556: ;finally, calculate the number of whole ! 557: ; aligned words and pairs thereof we'll ! 558: ; process ! 559: mov eax,[esi].xLeft ! 560: add eax,1111b ! 561: shr eax,4 ;round left up to nearest word ! 562: mov edx,[esi].xRight ! 563: shr edx,4 ;round down to nearest word ! 564: sub edx,eax ;# of whole aligned words ! 565: jz short set_copy_control_flags ;no whole aligned words ! 566: or ecx,WHOLE_WORDS ;mark that we have whole aligned words ! 567: inc edx ! 568: shr edx,1 ;# of whole dwords, or fractions ! 569: mov ulWholeDwordCount,edx ; thereof ! 570: jc short set_copy_control_flags ;no odd word ! 571: or ecx,ODD_WHOLE_WORD ;mark that we have an odd word to copy ! 572: ! 573: set_copy_control_flags: ! 574: mov ulCopyControlFlags,ecx ! 575: ! 576: ;-----------------------------------------------------------------------; ! 577: ; If we're going to have to read from display memory, set up the Graphics ! 578: ; Controller to point to the Read Map, so we can save some OUTs later. ! 579: ; ! 580: ; At this point, EBX = pptlSrc, ECX = ulCopyControlFlags, ESI = prclDst, ! 581: ; EDI = pdsurfDst. ! 582: ;-----------------------------------------------------------------------; ! 583: ! 584: test ecx,LEADING_PARTIAL or TRAILING_PARTIAL ! 585: jz short @F ! 586: mov edx,VGA_BASE + GRAF_ADDR ! 587: mov al,GRAF_READ_MAP ! 588: out dx,al ;leave GRAF_ADDR pointing to Read Map ! 589: @@: ! 590: ! 591: ;-----------------------------------------------------------------------; ! 592: ; Set up the offsets to the next source and destination scans. ! 593: ; ! 594: ; At this point, EBX = pptlSrc, ESI = prclDst, EDI = pdsurfDst. ! 595: ;-----------------------------------------------------------------------; ! 596: ! 597: mov eax,[esi].xLeft ! 598: shr eax,3 ;left edge byte ! 599: mov edx,[esi].xRight ! 600: add edx,111b ;byte after right edge ! 601: shr edx,3 ! 602: sub edx,eax ;# of bytes across dest ! 603: mov eax,[edi].dsurf_lNextScan ! 604: sub eax,edx ;offset from last byte dest copied to on one ! 605: mov ulDstDelta,eax ; scan to first dest byte copied to on next ! 606: ! 607: mov ecx,pdsurfSrc ! 608: mov eax,[esi].xLeft ! 609: mov edx,[esi].xRight ! 610: sub edx,eax ;width in pixels ! 611: push edx ;remember width in pixels ! 612: mov eax,[ebx].ptl_x ;source left edge ! 613: add edx,eax ;source right edge ! 614: shr eax,1 ;source left start byte ! 615: and eax,not 11b ;source left start rounded to nearest dword ! 616: inc edx ! 617: shr edx,1 ;source right byte after last byte copied ! 618: add edx,11b ! 619: and edx,not 11b ;round up to source right dword after last byte ! 620: ; copied ! 621: sub edx,eax ;source width in bytes, rounded to dwords ! 622: ; (because we always work with source dwords) ! 623: mov eax,[ecx].dsurf_lNextScan ! 624: sub eax,edx ;offset from last source byte copied from on ! 625: mov ulSrcDelta,eax ; one scan to first source byte copied to on ! 626: ; next ! 627: ! 628: ;-----------------------------------------------------------------------; ! 629: ; Set up the maximum burst size (# of scans to do before switching ! 630: ; planes). ! 631: ; ! 632: ; At this point, EBX = pptlSrc, ESI = prclDst, EDI = pdsurfDst. ! 633: ;-----------------------------------------------------------------------; ! 634: ! 635: pop edx ;retrieve width in pixels ! 636: mov eax,2 ;assume we'll only do two scans per burst ! 637: ; (the minimum number) ! 638: test edx,not 0feh ;>511 pixels? ! 639: jnz short @F ;yes, so do two scans at a time, to avoid ! 640: ; flicker as separate planes are done ! 641: ;***note: this is a tentative value, and ! 642: ; experience may indicate that it should be ! 643: ; increased or reduced to 1*** ! 644: ;<512 pixels, so we can do more scans per ! 645: ; plane, thereby saving lots of OUTs. The exact ! 646: ; # of scans depends on how wide the copy is; ! 647: ; the wider it is, the fewer scans ! 648: mov al,4 ;assume we'll do four scans per plane ! 649: test dh,1 ;256 or more wide? ! 650: jnz short @F ;512>width>=256, four scans will do the job ! 651: mov al,8 ;assume we'll do eight scans per plane ! 652: add dl,dl ;128 or more wide? ! 653: jc short @F ;256>width>=128, eight scans is fine ! 654: mov al,16 ;assume we'll do sixteen scans per plane ! 655: js short @F ;128>width>=64, sixteen will do fine ! 656: mov al,32 ;<64 wide, so we'll do 32 scans per plane ! 657: @@: ! 658: mov ulBurstMax,eax ;this is the longest burst we'll do in a single ! 659: ; plane ! 660: ! 661: ;-----------------------------------------------------------------------; ! 662: ; Determine whether any shift is needed to align the source with the ! 663: ; destination. ! 664: ; ! 665: ; At this point, EBX = pptlSrc, ESI = prclDst, EDI = pdsurfDst. ! 666: ;-----------------------------------------------------------------------; ! 667: ! 668: mov eax,[ebx].ptl_x ! 669: and eax,111b ;source X modulo 8 ! 670: mov edx,[esi].xLeft ! 671: and edx,111b ;dest X modulo 8 ! 672: sub eax,edx ;(source X modulo 8) - (dest X modulo 8) ! 673: mov ulAlignShift,eax ;remember the shift ! 674: jz short set_initial_banking ;if it's 0, we have no alignment to ! 675: ; do, and are ready to roll ! 676: ! 677: ;-----------------------------------------------------------------------; ! 678: ; Alignment is needed, so set up the alignment variables. ! 679: ; ! 680: ; At this point, EBX = pptlSrc, ESI = prclDst, EDI = pdsurfDst, ! 681: ; EAX = shift, in range -7 to 7. ! 682: ;-----------------------------------------------------------------------; ! 683: ! 684: mov edx,ulSrcDelta ;remember the real source width; we'll fake ! 685: mov ulTrueSrcDelta,edx ; ulSrcDelta for the drawing routines ! 686: ! 687: ;set ulSrcDelta to either 0 or 4, ! 688: ; depending on whether the last dword ! 689: ; we rotate is needed (because we ! 690: ; always generate as many dest dwords as ! 691: ; there are source dwords on left shifts, ! 692: ; and we always generate dest dwords = # source ! 693: ; dwords + 1 on right shifts, whether we need ! 694: ; the last dword or not; we only need it when ! 695: ; the right edge shifts left) ! 696: mov ecx,[esi].xRight ! 697: sub ecx,[esi].xLeft ! 698: add ecx,[ebx].ptl_x ;CL = lsb of source right edge ! 699: dec ecx ;adjust to actual right X, rather than X+1 ! 700: mov ch,byte ptr [esi].xRight ;CH = lsb of dest right edge ! 701: dec ch ;adjust to actual right X, rather than X+1 ! 702: and ecx,0707h ;right source and dest intrabyte addresses ! 703: sub edx,edx ;assume we need the last byte, in which case ! 704: ; the source in the temp buffer (from which we ! 705: ; always copy after rotation) is contiguous ! 706: cmp ch,cl ;right or left shift at right edge? ! 707: jb short @F ;left shift at right edge, so every byte in the ! 708: ; temp buffer will be used ! 709: add edx,4 ;right shift at right edge, so the last byte in ! 710: ; the temp buffer won't be used, thus skip it ! 711: @@: ! 712: mov ulSrcDelta,edx ;delta to next scan in temp buffer ! 713: ! 714: mov ecx,[edi].dsurf_ppdev ;point to pdev for 386 flag ! 715: and eax,eax ;shift left or right? ! 716: js short @F ;shift right ! 717: ;shift left ! 718: ! 719: mov edx,offset align_burst_lshift_486 ;shifting left, assume 486 ! 720: cmp [ecx].PDEV_is386,0 ;486? ! 721: jz short set_shift_vec ;yes ! 722: mov edx,offset align_burst_lshift_386 ;386 ! 723: jmp short set_shift_vec ! 724: ! 725: align 4 ! 726: @@: ;shifting right ! 727: ! 728: and eax,7 ;for left shift, shift value is already ! 729: ; correct; for right shift, this is equivalent ! 730: ; to 8 - right shift, since we always shift ! 731: ; left (remember, EAX is currently negative for ! 732: ; right shifts) ! 733: mov edx,offset align_burst_rshift_386 ;shifting right, assume 386 ! 734: cmp [ecx].PDEV_is386,0 ;386? ! 735: jnz short set_shift_vec ;yes ! 736: mov edx,offset align_burst_rshift_486 ;486 ! 737: set_shift_vec: ! 738: mov pAlignmentRoutine,edx ;routine to be used to shift into ! 739: ; alignment with destination ! 740: shl eax,2 ;multiply by 4 because we're dealing with ! 741: ; 4-bit pixels ! 742: mov ulAlignShift,eax ;remember the shift amount ! 743: mov eax,[esi].xRight ! 744: sub eax,[esi].xLeft ;pixel width of rectangle to copy ! 745: mov edx,[ebx].ptl_x ;left pixel of source ! 746: and edx,111b ;distance in pixels from left pixel to pixel at ! 747: ; start of left dword ! 748: add eax,edx ;pixel width from start of left dword to right ! 749: ; edge of copy in source ! 750: add eax,7 ;round up to nearest dword (8 pixel set) ! 751: shr eax,3 ;# of dwords spanned by source ! 752: mov ulSourceDwordWidth,eax ;always pick up this number of dwords ! 753: ; when aligning ! 754: ! 755: mov eax,[edi].dsurf_pvBankBufferPlane0 ;this is the general-purpose ! 756: mov pTempBuffer,eax ; temporary-use buffer ! 757: ! 758: mov eax,pSrc ;remember the real source pointer; we'll fake ! 759: mov pTrueSrc,eax ; pSrc for the drawing routines ! 760: ! 761: ;-----------------------------------------------------------------------; ! 762: ; Copy all banks in the destination rectangle, one at a time. ! 763: ; ! 764: ; At this point, ESI = prclDst, EDI = pdsurfDst ! 765: ;-----------------------------------------------------------------------; ! 766: ! 767: set_initial_banking: ! 768: ! 769: ;-----------------------------------------------------------------------; ! 770: ; Map in the bank containing the top scan to copy to, if it's not mapped ! 771: ; in already. ! 772: ;-----------------------------------------------------------------------; ! 773: ! 774: mov eax,[esi].yBottom ! 775: mov ulBottomScan,eax ;bottom scan to which to copy ! 776: mov eax,[esi].yTop ;top scan line of copy ! 777: mov ulCurrentTopScan,eax ;this will be the copy top in 1st bank ! 778: ! 779: cmp eax,[edi].dsurf_rcl1WindowClip.yTop ;is copy top less than ! 780: ; current bank? ! 781: jl short map_init_bank ;yes, map in proper bank ! 782: cmp eax,[edi].dsurf_rcl1WindowClip.yBottom ;copy top greater than ! 783: ; current bank? ! 784: jl short init_bank_mapped ;no, proper bank already mapped ! 785: map_init_bank: ! 786: ! 787: ; Map in the bank containing the top scan line of the copy dest. ! 788: ! 789: ptrCall <dword ptr [edi].dsurf_pfnBankControl>,<edi,eax,JustifyTop> ! 790: ! 791: init_bank_mapped: ! 792: ! 793: ;-----------------------------------------------------------------------; ! 794: ; Compute the starting address for the initial dest bank. ! 795: ;-----------------------------------------------------------------------; ! 796: ! 797: mov eax,ulCurrentTopScan ;top scan line to which to copy in ! 798: ; current bank ! 799: imul [edi].dsurf_lNextScan ;offset of starting scan line ! 800: mov edx,[esi].xLeft ;left dest X coordinate ! 801: shr edx,3 ;left dest byte offset in row ! 802: add eax,edx ;initial offset in dest bitmap ! 803: ! 804: ; Note that the start of the bitmap will change each time through the ! 805: ; bank loop, because the start of the bitmap is varied to map the ! 806: ; desired scan line to the banking window. ! 807: ! 808: add eax,[edi].dsurf_pvBitmapStart ;initial dest bitmap address ! 809: mov pDst,eax ;remember where to start drawing ! 810: ! 811: ;-----------------------------------------------------------------------; ! 812: ; Main loop for processing copying to each bank. ! 813: ; ! 814: ; At this point, EDI->pdsurfDst ! 815: ;-----------------------------------------------------------------------; ! 816: ! 817: bank_loop: ! 818: ! 819: ; Calculate the # of scans to do in this bank. ! 820: ! 821: mov ebx,ulBottomScan ;bottom of destination rectangle ! 822: cmp ebx,[edi].dsurf_rcl1WindowClip.yBottom ! 823: ;which comes first, the bottom of the ! 824: ; dest rect or the bottom of the ! 825: ; current bank? ! 826: jl short @F ;copy bottom comes first, so draw to ! 827: ; that; this is the last bank in copy ! 828: mov ebx,[edi].dsurf_rcl1WindowClip.yBottom ! 829: ;bank bottom comes first; draw to ! 830: ; bottom of bank ! 831: @@: ! 832: sub ebx,ulCurrentTopScan ;# of scans to copy in bank ! 833: ! 834: ;-----------------------------------------------------------------------; ! 835: ; Copy to the screen in bursts of either ulBurstMax size or remaining ! 836: ; number of scans in bank, whichever is less. ! 837: ; ! 838: ; At this point, EBX = # of scans remaining in bank. ! 839: ;-----------------------------------------------------------------------; ! 840: ! 841: copy_burst_loop: ! 842: mov eax,ulBurstMax ;most scans we can copy per plane ! 843: sub ebx,eax ;# of scans left in bank after copying that many ! 844: jnle short @F ;there are enough scans left to copy max # ! 845: add eax,ebx ;not enough scans left; copy all remaining scans ! 846: sub ebx,ebx ;after this, no scans remain in bank ! 847: @@: ! 848: push ebx ;# of scan lines remaining in bank after burst ! 849: ;EAX = # of scans in burst ! 850: mov ulPlane0Scans,eax ;set the scan count for each of the plane ! 851: mov ulPlane1Scans,eax ; loops ! 852: mov ulPlane2Scans,eax ! 853: mov ulPlane3Scans,eax ! 854: ! 855: ;-----------------------------------------------------------------------; ! 856: ; If necessary, align the dwords in this burst so that the left edge is ! 857: ; on a dword boundary. ! 858: ; ! 859: ; At this point, AL = # of scans in burst. ! 860: ;-----------------------------------------------------------------------; ! 861: ! 862: mov ecx,ulAlignShift ! 863: and ecx,ecx ;is alignment needed? ! 864: jz proceed_with_copy ;no, so we're ready to copy ! 865: ! 866: mov ch,al ;# of scans to copy ! 867: mov esi,pTrueSrc ;copy from current source location ! 868: mov edi,pTempBuffer ;copy to the temp buffer ! 869: ! 870: jmp pAlignmentRoutine ;perform the copy ! 871: ! 872: ;-----------------------------------------------------------------------; ! 873: ; Loops to align this burst's scans for 386/486, left or right shift. ! 874: ; ! 875: ; Input: CH = # of scans to copy in this burst (max burst = 256) ! 876: ; CL = # of bits to shift left to dword align ! 877: ; ESI = first dword of first DIB scan to convert ! 878: ; EDI = first dword of buffer into which to shift ! 879: ; ulSourceDwordWidth = # of dwords across source ! 880: ; ulTrueSrcDelta = distance from end of one source scan (rounded up to ! 881: ; nearest dword) to start of next ! 882: ; ! 883: ; All loops alway flush (write) the last dword, so one more dword ! 884: ; is written to the dest than is read from the source. This requires the ! 885: ; dest buffer to have room for an extra dword. ! 886: ;-----------------------------------------------------------------------; ! 887: ! 888: ;-----------------------------------------------------------------------; ! 889: ; Macro to copy and align the current burst for left shift. ! 890: ;-----------------------------------------------------------------------; ! 891: ! 892: ALIGN_BURST_LSHIFT macro Is486 ! 893: local align_burst_lshift_loop,align_last_lshift,align_odd_lshift ! 894: local align_lshift_loop ! 895: align_burst_lshift_loop: ! 896: mov ebx,ulSourceDwordWidth ;# of dwords across source ! 897: mov edx,[esi] ;load the initial source dword ! 898: add esi,4 ;point to next source dword ! 899: if Is486 ! 900: M_BSWAP edx ;make it big endian ! 901: else ! 902: M_BSWAP_386 edx ! 903: endif ! 904: dec ebx ;any more dwords to shift? ! 905: jz short align_last_lshift ;no, do just this one ! 906: inc ebx ! 907: shr ebx,1 ;double dword count ! 908: jnc short align_odd_lshift ;do odd dword ! 909: align 4 ! 910: align_lshift_loop: ! 911: mov eax,[esi] ;get next dword to align ! 912: add esi,4 ;point to next source dword ! 913: if Is486 ! 914: M_BSWAP eax ;make it big endian ! 915: else ! 916: M_BSWAP_386 eax ! 917: endif ! 918: shld edx,eax,cl ;shift to generate a 32-bit shifted value ! 919: if Is486 ! 920: M_BSWAP edx ;make it big endian ! 921: else ! 922: M_BSWAP_386 edx ! 923: endif ! 924: mov [edi],edx ;store it ! 925: add edi,4 ;point to next dest dword ! 926: mov edx,eax ;set up for the next shift ! 927: align_odd_lshift: ! 928: mov eax,[esi] ;get next dword to align ! 929: add esi,4 ;point to next source dword ! 930: if Is486 ! 931: M_BSWAP eax ;make it big endian ! 932: else ! 933: M_BSWAP_386 eax ! 934: endif ! 935: shld edx,eax,cl ;shift to generate a 32-bit shifted value ! 936: if Is486 ! 937: M_BSWAP edx ;make it big endian ! 938: else ! 939: M_BSWAP_386 edx ! 940: endif ! 941: mov [edi],edx ;store it ! 942: add edi,4 ;point to next dest dword ! 943: mov edx,eax ;set up for the next shift ! 944: dec ebx ;count down dwords to shift ! 945: jnz align_lshift_loop ;do next dword, if any ! 946: align_last_lshift: ;do the last dword, which doesn't require a ! 947: ; new source byte ! 948: shl edx,cl ;shift it into position ! 949: if Is486 ! 950: M_BSWAP edx ;make it big endian ! 951: else ! 952: M_BSWAP_386 edx ! 953: endif ! 954: mov [edi],edx ;store it ! 955: add edi,4 ;point to next dest dword ! 956: ! 957: add esi,ulTrueSrcDelta ;point to next source scan ! 958: dec ch ;count down scans in burst ! 959: jnz align_burst_lshift_loop ! 960: ENDM ;ALIGN_BURST_LSHIFT ! 961: ! 962: ;-----------------------------------------------------------------------; ! 963: ; Macro to copy and align the current burst for right shift. ! 964: ;-----------------------------------------------------------------------; ! 965: ! 966: ALIGN_BURST_RSHIFT macro Is486 ! 967: local align_burst_rshift_loop,align_odd_rshift,align_rshift_loop ! 968: align_burst_rshift_loop: ! 969: mov ebx,ulSourceDwordWidth ;# of dwords across source ! 970: inc ebx ! 971: shr ebx,1 ;double dword count ! 972: jnc short align_odd_rshift ;do odd dword ! 973: align 4 ! 974: align_rshift_loop: ! 975: mov eax,[esi] ;get next dword to align ! 976: add esi,4 ;point to next source dword ! 977: if Is486 ! 978: M_BSWAP eax ;make it big endian ! 979: else ! 980: M_BSWAP_386 eax ! 981: endif ! 982: shld edx,eax,cl ;shift to generate a 32-bit shifted value ! 983: if Is486 ! 984: M_BSWAP edx ;make it little endian ! 985: else ! 986: M_BSWAP_386 edx ! 987: endif ! 988: mov [edi],edx ;store it ! 989: add edi,4 ;point to next dest dword ! 990: mov edx,eax ;set up for the next shift ! 991: align_odd_rshift: ! 992: mov eax,[esi] ;get next dword to align ! 993: add esi,4 ;point to next source dword ! 994: if Is486 ! 995: M_BSWAP eax ;make it big endian ! 996: else ! 997: M_BSWAP_386 eax ! 998: endif ! 999: shld edx,eax,cl ;shift to generate a 32-bit shifted value ! 1000: if Is486 ! 1001: M_BSWAP edx ;make it little endian ! 1002: else ! 1003: M_BSWAP_386 edx ! 1004: endif ! 1005: mov [edi],edx ;store it ! 1006: add edi,4 ;point to next dest dword ! 1007: mov edx,eax ;set up for the next shift ! 1008: dec ebx ;count down dwords to shift ! 1009: jnz align_rshift_loop ;do next dword, if any ! 1010: ! 1011: ;do the trailing destination dword ! 1012: shl edx,cl ;shift into position ! 1013: if Is486 ! 1014: M_BSWAP edx ;make it little endian ! 1015: else ! 1016: M_BSWAP_386 edx ! 1017: endif ! 1018: mov [edi],edx ;store it ! 1019: add edi,4 ;point to next dest dword ! 1020: ! 1021: add esi,ulTrueSrcDelta ;point to next source scan ! 1022: dec ch ;count down scans in burst ! 1023: jnz align_burst_rshift_loop ! 1024: ENDM ;ALIGN_BURST_RSHIFT ! 1025: ;-----------------------------------------------------------------------; ! 1026: ! 1027: align 4 ! 1028: align_burst_rshift_386: ! 1029: ALIGN_BURST_RSHIFT 0 ! 1030: jmp set_alignment_source ! 1031: ! 1032: align 4 ! 1033: align_burst_lshift_386: ! 1034: ALIGN_BURST_LSHIFT 0 ! 1035: jmp set_alignment_source ! 1036: ! 1037: align 4 ! 1038: align_burst_rshift_486: ! 1039: ALIGN_BURST_RSHIFT 1 ! 1040: jmp short set_alignment_source ! 1041: ! 1042: align 4 ! 1043: align_burst_lshift_486: ! 1044: ALIGN_BURST_LSHIFT 1 ! 1045: ! 1046: ;-----------------------------------------------------------------------; ! 1047: ; Set up the pointers for a copy from the temp buffer, and advance the ! 1048: ; real pointer. ! 1049: ;-----------------------------------------------------------------------; ! 1050: set_alignment_source: ! 1051: mov pTrueSrc,esi ;remember where to start next time in source ! 1052: mov esi,pTempBuffer ;copy from the temp buffer ! 1053: mov pSrc,esi ;remember where the copy source is (DIB or ! 1054: ; temp buffer) ! 1055: ! 1056: proceed_with_copy: ! 1057: ! 1058: ; Load ECX with the copy control flags; this stays set throughout the ! 1059: ; copying of this burst. ! 1060: ! 1061: mov ecx,ulCopyControlFlags ! 1062: ! 1063: ; Copy the DIB scan to VGA plane 0. ! 1064: ! 1065: mov esi,pSrc ! 1066: mov edi,pDst ! 1067: ! 1068: ; Map in plane 0 for writes. ! 1069: ! 1070: mov edx,VGA_BASE + SEQ_DATA ! 1071: mov al,MM_C0 ! 1072: out dx,al ;map in plane 0 for writes (SEQ_ADDR points to the Map ! 1073: ; Mask by default) ! 1074: ! 1075: ; Map in plane 0 for reads if and only if we need to handle partial edge ! 1076: ; bytes, which require read/modify/write cycles. ! 1077: ! 1078: test ecx,LEADING_PARTIAL or TRAILING_PARTIAL ! 1079: jz short @F ! 1080: mov edx,VGA_BASE + GRAF_DATA ! 1081: mov al,RM_C0 ! 1082: out dx,al ;map in plane 0 for reads (GRAF_ADDR already points to ! 1083: ; Read Map) ! 1084: @@: ! 1085: jmp DIB4_to_VGA_plane0_copy ! 1086: ! 1087: align 4 ! 1088: copy_burst_plane0_done: ! 1089: ! 1090: ; Copy the DIB scan to VGA plane 1. ! 1091: ! 1092: mov esi,pSrc ! 1093: mov edi,pDst ! 1094: ! 1095: ; Map in plane 1 for writes. ! 1096: ! 1097: mov edx,VGA_BASE + SEQ_DATA ! 1098: mov al,MM_C1 ! 1099: out dx,al ;map in plane 1 for writes (SEQ_ADDR points to the Map ! 1100: ; Mask by default) ! 1101: ! 1102: ; Map in plane 1 for reads if and only if we need to handle partial edge ! 1103: ; bytes, which require read/modify/write cycles. ! 1104: ! 1105: test ecx,LEADING_PARTIAL or TRAILING_PARTIAL ! 1106: jz short @F ! 1107: mov edx,VGA_BASE + GRAF_DATA ! 1108: mov al,RM_C1 ! 1109: out dx,al ;map in plane 1 for reads (GRAF_ADDR already points to ! 1110: ; Read Map) ! 1111: @@: ! 1112: jmp DIB4_to_VGA_plane1_copy ! 1113: ! 1114: align 4 ! 1115: copy_burst_plane1_done: ! 1116: ! 1117: ; Copy the DIB scan to VGA plane 2. ! 1118: ! 1119: mov esi,pSrc ! 1120: mov edi,pDst ! 1121: ! 1122: ; Map in plane 2 for writes. ! 1123: ! 1124: mov edx,VGA_BASE + SEQ_DATA ! 1125: mov al,MM_C2 ! 1126: out dx,al ;map in plane 2 for writes (SEQ_ADDR points to the Map ! 1127: ; Mask by default) ! 1128: ! 1129: ; Map in plane 2 for reads if and only if we need to handle partial edge ! 1130: ; bytes, which require read/modify/write cycles. ! 1131: ! 1132: test ecx,LEADING_PARTIAL or TRAILING_PARTIAL ! 1133: jz short @F ! 1134: mov edx,VGA_BASE + GRAF_DATA ! 1135: mov al,RM_C2 ! 1136: out dx,al ;map in plane 2 for reads (GRAF_ADDR already points to ! 1137: ; Read Map) ! 1138: @@: ! 1139: jmp DIB4_to_VGA_plane2_copy ! 1140: ! 1141: align 4 ! 1142: copy_burst_plane2_done: ! 1143: ! 1144: ; Copy the DIB scan to VGA plane 3. ! 1145: ! 1146: mov esi,pSrc ! 1147: mov edi,pDst ! 1148: ! 1149: ; Map in plane 3 for writes. ! 1150: ! 1151: mov edx,VGA_BASE + SEQ_DATA ! 1152: mov al,MM_C3 ! 1153: out dx,al ;map in plane 3 for writes (SEQ_ADDR points to the Map ! 1154: ; Mask by default) ! 1155: ! 1156: ; Map in plane 3 for reads if and only if we need to handle partial edge ! 1157: ; bytes, which require read/modify/write cycles. ! 1158: ! 1159: test ecx,LEADING_PARTIAL or TRAILING_PARTIAL ! 1160: jz short @F ! 1161: mov edx,VGA_BASE + GRAF_DATA ! 1162: mov al,RM_C3 ! 1163: out dx,al ;map in plane 3 for reads (GRAF_ADDR already points to ! 1164: ; Read Map) ! 1165: @@: ! 1166: jmp DIB4_to_VGA_plane3_copy ! 1167: ! 1168: align 4 ! 1169: copy_burst_plane3_done: ! 1170: mov pSrc,esi ;remember where we are, for next burst ! 1171: mov pDst,edi ! 1172: ! 1173: pop ebx ;get back remaining length in bank ! 1174: and ebx,ebx ;anything left in this bank? ! 1175: jnz copy_burst_loop ;continue if so ! 1176: ! 1177: ; Done with bank; are there more banks to do? ! 1178: ! 1179: mov edi,pdsurfDst ! 1180: mov eax,[edi].dsurf_rcl1WindowClip.yBottom ;is the copy bottom in ! 1181: cmp ulBottomScan,eax ; the current bank? ! 1182: jnle short next_bank ;no, map in the next bank and copy to ! 1183: ; it ! 1184: ;yes, we're done ! 1185: ;-----------------------------------------------------------------------; ! 1186: ; Restore default Map Mask and done. ! 1187: ;-----------------------------------------------------------------------; ! 1188: mov edx,VGA_BASE + SEQ_DATA ! 1189: mov al,MM_ALL ! 1190: out dx,al ;map in all planes ! 1191: ! 1192: cRet vDIB2VGA ;done! ! 1193: ! 1194: ;-----------------------------------------------------------------------; ! 1195: ; Advance to the next bank and copy to it. ! 1196: ;-----------------------------------------------------------------------; ! 1197: align 4 ! 1198: next_bank: ! 1199: mov ulCurrentTopScan,eax ;remember where the top of the bank ! 1200: ; we're about to map in is (same as ! 1201: ; bottom of bank we just did) ! 1202: mov ecx,[edi].dsurf_pvBitmapStart ! 1203: sub pDst,ecx ;offset of current position in screen ! 1204: ! 1205: ptrCall <dword ptr [edi].dsurf_pfnBankControl>,<edi,eax,JustifyTop> ! 1206: ;map in the bank ! 1207: ! 1208: mov ecx,[edi].dsurf_pvBitmapStart ! 1209: add pDst,ecx ;pointer to current position in screen ! 1210: ! 1211: jmp bank_loop ;copy the next bank ! 1212: ! 1213: ;-----------------------------------------------------------------------; ! 1214: ; Loops for converting 1 or more scans in each of planes 0, 1, 2, and 3. ! 1215: ;-----------------------------------------------------------------------; ! 1216: ! 1217: ;-----------------------------------------------------------------------; ! 1218: ; Plane 0 DIB->VGA conversion code for a single scan line. ! 1219: ;-----------------------------------------------------------------------; ! 1220: align 4 ! 1221: DIB4_to_VGA_plane0_copy: ! 1222: ! 1223: ;-----------------------------------------------------------------------; ! 1224: ; Set EBX to point to multiplexed DIB byte->planar byte conversion table ! 1225: ; for plane 0. ! 1226: ; ! 1227: ; Input: ECX with bits sets as described for ulCopyControlFlags, above ! 1228: ; ESI = DIB pointer to first two pixels ! 1229: ; EDI = VGA pointer to planar byte ! 1230: ; ulPlane0Scans = # of scan lines to copy to ! 1231: ; ulSrcDelta = offset from end of one source scan copied to start of next ! 1232: ; ulDstDelta = offset from end of one dest scan copied to start of next ! 1233: ; ulWholeDwordCount = # of whole, aligned dwords to copy ! 1234: ; ulLeftMask = mask for partial left edge, if any ! 1235: ; ulRightMask = mask for partial right edge, if any ! 1236: ; Plane 0 must be mapped in for writes ! 1237: ;-----------------------------------------------------------------------; ! 1238: ! 1239: mov ebx,DIB4_to_VGA_plane0_table ;stays set for all bytes/words ! 1240: ! 1241: DIB4_to_VGA_plane0_copy_loop: ! 1242: ! 1243: ;-----------------------------------------------------------------------; ! 1244: ; Code to convert 1-7 DIB4 pixels to a partial VGA plane 0 byte (8 ! 1245: ; pixels in plane 0). Assumes that a full dword of DIB4 pixels (8 ! 1246: ; pixels) is available, starting at ESI, although some of the pixels ! 1247: ; will be masked off. Assumes the DIB4 pixels (including masked-off ! 1248: ; pixels) start in the upper nibble of [ESI], and that the first ! 1249: ; (possibly masked-off) DIB4 pixel maps to bit 7 of the VGA at [EDI]. ! 1250: ; ! 1251: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 1252: ; (must start on a 256-byte boundary) ! 1253: ; ECX with bits sets as described for ulCopyControlFlags, above ! 1254: ; ESI = DIB pointer to first two pixels (possibly masked off) ! 1255: ; EDI = VGA pointer to planar byte ! 1256: ; Plane 0 must be mapped in for writes ! 1257: ;-----------------------------------------------------------------------; ! 1258: ! 1259: test ecx,LEADING_PARTIAL ;handle a leading partial byte? ! 1260: jz short DIB4_to_VGA_plane0_copy_lbyte ;no, go straight to whole ! 1261: ; byte ! 1262: ;yes, handle leading partial byte ! 1263: mov edx,[esi] ;get 8 pixels to convert of DIB ! 1264: and edx,11111111h ;keep only the plane 0 bits of DIB dword ! 1265: ; EDX = xxx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1 ! 1266: shld eax,edx,16+2 ;put bits 7-4 of DIB dword in AX, ! 1267: ; shifted left 2 (x = zero bit) ! 1268: ; DX = xxx2xxx3xxx0xxx1 ! 1269: ; AX = x6xxx7xxx4xxx5xx ! 1270: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 1271: ; x6x2x7x3x4x0x5x1 ! 1272: mov bl,al ;BL = x4x0x5x1 of DIB dword 0 ! 1273: add ah,ah ;make AH 6x2x7x3x of DIB dword 0 (shl 1) ! 1274: or bl,ah ;BL = 64207531 of DIB dword 0 ! 1275: add esi,4 ;point to next DIB dword ! 1276: inc edi ;point to next VGA byte (placed here ! 1277: ; for 486 pipelining reasons) ! 1278: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 1279: mov ch,[edi-1] ;get the VGA destination byte ! 1280: and ecx,ulLeftMask ;mask off source and dest ! 1281: or cl,ch ;combine masked source and dest ! 1282: mov [edi-1],cl ;write the new pixels to the VGA ! 1283: ! 1284: ;-----------------------------------------------------------------------; ! 1285: ; Code to convert 8 DIB4 pixels to a single VGA plane 0 byte (8 pixels ! 1286: ; in plane 0). Assumes the DIB4 pixels start in the upper nibble of ! 1287: ; [ESI], and that the first DIB4 pixel maps to bit 7 of the VGA at ! 1288: ; [EDI]. ! 1289: ; ! 1290: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 1291: ; (must start on a 256-byte boundary) ! 1292: ; ECX with bits sets as described for ulCopyControlFlags, above ! 1293: ; ESI = DIB pointer to first two pixels ! 1294: ; EDI = VGA pointer to planar byte ! 1295: ; Plane 0 must be mapped in for writes ! 1296: ;-----------------------------------------------------------------------; ! 1297: ! 1298: DIB4_to_VGA_plane0_copy_lbyte: ! 1299: test ecx,LEADING_BYTE ;should we handle a leading byte? ! 1300: jz short DIB4_to_VGA_plane0_copy_words ;no, go straight to words ! 1301: ;yes, handle leading byte ! 1302: mov edx,[esi] ;get 8 pixels to convert of DIB ! 1303: and edx,11111111h ;keep only the plane 0 bits of DIB dword ! 1304: ; EDX = xxx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1 ! 1305: shld eax,edx,16+2 ;put bits 7-4 of DIB dword in AX, ! 1306: ; shifted left 2 (x = zero bit) ! 1307: ; DX = xxx2xxx3xxx0xxx1 ! 1308: ; AX = x6xxx7xxx4xxx5xx ! 1309: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 1310: ; x6x2x7x3x4x0x5x1 ! 1311: mov bl,al ;BL = x4x0x5x1 of DIB dword 0 ! 1312: add ah,ah ;make AH 6x2x7x3x of DIB dword 0 (shl 1) ! 1313: or bl,ah ;BL = 64207531 of DIB dword 0 ! 1314: add esi,4 ;point to next DIB dword ! 1315: inc edi ;point to next VGA byte (placed here ! 1316: ; for 486 pipelining reasons) ! 1317: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 1318: mov [edi-1],cl ;write 8 bits from DIB dword to VGA ! 1319: ! 1320: ;-----------------------------------------------------------------------; ! 1321: ; Code to convert sets of 32 DIB4 pixels to 4 VGA plane 0 bytes (32 ! 1322: ; pixels in plane 0). Assumes the VGA destination is word aligned. ! 1323: ; Assumes the DIB4 pixels start in the upper nibble of [ESI], and that ! 1324: ; the first DIB4 pixel maps to bit 7 of the VGA at [EDI]. ! 1325: ; ! 1326: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 1327: ; (must start on a 256-byte boundary) ! 1328: ; ECX with bits sets as described for ulCopyControlFlags, above ! 1329: ; ESI = DIB pointer to first two pixels ! 1330: ; EDI = VGA pointer to two planar bytes (must be word aligned) ! 1331: ; ulWholeDwordCount = # of VGA dwords to convert ! 1332: ; Plane 0 must be mapped in for writes ! 1333: ; ! 1334: ; Note: on entry at DIB4_to_VGA_plane0_word_odd, ESI must point to the ! 1335: ; desired source start minus 8, and EAX must be loaded as if the following ! 1336: ; instructions had been performed: ! 1337: ; mov edx,[esi+8] ! 1338: ; and edx,11111111h ! 1339: ; shld eax,edx,16+2 ! 1340: ; or eax,edx ! 1341: ; ! 1342: ; Note: the code is so odd because of 486 pipeline optimization. ! 1343: ; DO NOT CHANGE THIS CODE UNLESS YOU KNOW EXACTLY WHAT YOU'RE DOING!!! ! 1344: ; ! 1345: ; Note: all 486 pipeline penalties are eliminated except for SHLD, which ! 1346: ; is losing 4 cycles total, and writing CX to memory (2 cycles), so far ! 1347: ; as I know. ! 1348: ;-----------------------------------------------------------------------; ! 1349: ! 1350: DIB4_to_VGA_plane0_copy_words: ! 1351: test ecx,ODD_WHOLE_WORD or WHOLE_WORDS ;any whole words to copy? ! 1352: jz DIB4_to_VGA_plane0_copy_tbyte ;no, check for trailing whole ! 1353: ; bytes ! 1354: ;yes, copy the whole words ! 1355: push ebp ;preserve stack frame pointer ! 1356: mov ebp,ulWholeDwordCount ;# of VGA dwords to copy to ! 1357: ;even # of DIB dwords to copy? (flags still ! 1358: ; set from TEST) ! 1359: .errnz ODD_WHOLE_WORD - 80000000h ! 1360: jns short DIB4_to_VGA_plane0_word_loop ;yes, start copying ! 1361: ;no, there's an odd word; prepare to enter loop ! 1362: ; in middle ! 1363: mov edx,[esi] ;get 8 pixels to convert of first DIB dword ! 1364: and edx,11111111h ;keep only the plane 0 bits of DIB dword ! 1365: ; EDX = xxx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1 ! 1366: shld eax,edx,16+2 ;put bits 7-4 of DIB dword in AX, ! 1367: ; shifted left 2 ! 1368: ; DX = xxx2xxx3xxx0xxx1 ! 1369: ; AX = x6xxx7xxx4xxx5xx ! 1370: or eax,edx ;put bits 7-0 of DIB dword in AX: ! 1371: sub esi,8 ;compensate source back for entering in middle ! 1372: sub edi,2 ;compensate dest back for entering in middle ! 1373: ! 1374: jmp short DIB4_to_VGA_plane0_word_odd ! 1375: ! 1376: ;-----------------------------------------------------------------------; ! 1377: ; Loop to copy a word at a time to VGA plane 0 (actually, unrolled once ! 1378: ; so copies dwords). ! 1379: ;-----------------------------------------------------------------------; ! 1380: ! 1381: align 16 ! 1382: DIB4_to_VGA_plane0_word_loop: ! 1383: mov edx,[esi] ;get 8 pixels to convert of DIB dword 0 ! 1384: and edx,11111111h ;keep only the plane 0 bits of DIB ! 1385: ; dword 0 ! 1386: ; EDX = xxx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1 ! 1387: shld eax,edx,16+2 ;put bits 7-4 of DIB dword 0 in AX, ! 1388: ; shifted left 2 (x = zero bit) ! 1389: ; DX = xxx2xxx3xxx0xxx1 ! 1390: ; AX = x6xxx7xxx4xxx5xx ! 1391: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 1392: ; x6x2x7x3x4x0x5x1 ! 1393: mov edx,[esi+4] ;get 8 pixels to convert of DIB dword 1 ! 1394: mov bl,al ;BL = x4x0x5x1 of DIB dword 0 ! 1395: add ah,ah ;make AH 6x2x7x3x of DIB dword 0 (shl 1) ! 1396: or bl,ah ;BL = 64207531 of DIB dword 0 ! 1397: and edx,11111111h ;keep only the plane 0 bits of DIB ! 1398: ; dword 1 ! 1399: ; EDX = xxx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1 ! 1400: shld eax,edx,16+2 ;put bits 7-4 of DIB dword 1 in AX, ! 1401: ; shifted left 2 ! 1402: ; DX = xxx2xxx3xxx0xxx1 ! 1403: ; AX = x6xxx7xxx4xxx5xx ! 1404: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 1405: or eax,edx ;put bits 7-0 of DIB dword 1 in AX: ! 1406: ; x6x2x7x3x4x0x5x1 ! 1407: mov bl,al ;BL = x4x0x5x1 of DIB dword 1 ! 1408: mov edx,[esi+8] ;get 8 pixels to convert of DIB dword 2 ! 1409: add ah,ah ;make AH 6x2x7x3x of DIB dword 1 (shl 1) ! 1410: or bl,ah ;BL = 64207531 of DIB dword 1 ! 1411: and edx,11111111h ;keep only the plane 0 bits of DIB ! 1412: ; dword 2 ! 1413: ; EDX = xxx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1 ! 1414: shld eax,edx,16+2 ;put bits 7-4 of DIB dword 2 in AX, ! 1415: ; shifted left 2 ! 1416: ; DX = xxx2xxx3xxx0xxx1 ! 1417: ; AX = x6xxx7xxx4xxx5xx ! 1418: mov ch,[ebx] ;CH = 76543210 of DIB dword 1 ! 1419: or eax,edx ;put bits 7-0 of DIB dword 2 in AX: ! 1420: ; x6x2x7x3x4x0x5x1 ! 1421: mov [edi],cx ;write 16 bits from DIB dwords 0 and 1 ! 1422: ; to VGA ! 1423: DIB4_to_VGA_plane0_word_odd: ! 1424: mov edx,[esi+12] ;get 8 pixels to convert of DIB dword 3 ! 1425: mov bl,al ;BL = x4x0x5x1 of DIB dword 2 ! 1426: add ah,ah ;make AH 6x2x7x3x of DIB dword 2 (shl 1) ! 1427: or bl,ah ;BL = 64207531 of DIB dword 2 ! 1428: and edx,11111111h ;keep only the plane 0 bits of DIB ! 1429: ; dword 3 ! 1430: ; EDX = xxx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1 ! 1431: shld eax,edx,16+2 ;put bits 7-4 of DIB dword 3 in AX, ! 1432: ; shifted left 2 ! 1433: ; DX = xxx2xxx3xxx0xxx1 ! 1434: ; AX = x6xxx7xxx4xxx5xx ! 1435: mov cl,[ebx] ;CL = 76543210 of DIB dword 2 ! 1436: or eax,edx ;put bits 7-0 of DIB dword 3 in AX: ! 1437: ; x6x2x7x3x4x0x5x1 ! 1438: mov bl,al ;BL = x4x0x5x1 of DIB dword 3 ! 1439: add ah,ah ;make AH 6x2x7x3x of DIB dword 3 (shl 1) ! 1440: or bl,ah ;BL = 64207531 of DIB dword 3 ! 1441: add esi,16 ;point to next set of 4 DIB dwords ! 1442: add edi,4 ;point to next VGA dword ! 1443: mov ch,[ebx] ;CH = 76543210 of dword 0 ! 1444: dec ebp ;count down VGA dwords ! 1445: mov [edi-2],cx ;write 16 bits from DIB dwords 2 and 3 ! 1446: ; to VGA ! 1447: jnz DIB4_to_VGA_plane0_word_loop ;do next VGA dword, if any ! 1448: ! 1449: pop ebp ;restore stack frame pointer ! 1450: ! 1451: ! 1452: ;-----------------------------------------------------------------------; ! 1453: ; Code to convert 8 DIB4 pixels to a single VGA plane 0 byte (8 pixels ! 1454: ; in plane 0). Assumes the DIB4 pixels start in the upper nibble of ! 1455: ; [ESI], and that the first DIB4 pixel maps to bit 7 of the VGA at ! 1456: ; [EDI]. ! 1457: ; ! 1458: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 1459: ; (must start on a 256-byte boundary) ! 1460: ; ECX with bits sets as described for ulCopyControlFlags, above ! 1461: ; ESI = DIB pointer to first two pixels ! 1462: ; EDI = VGA pointer to planar byte ! 1463: ; Plane 0 must be mapped in for writes ! 1464: ; ! 1465: ;-----------------------------------------------------------------------; ! 1466: ! 1467: DIB4_to_VGA_plane0_copy_tbyte: ! 1468: test ecx,TRAILING_BYTE ;should we handle a trailing byte? ! 1469: jz short DIB4_to_VGA_plane0_copy_tpart ;no, check for trailing ! 1470: ; partial ! 1471: ;yes, handle trailing byte ! 1472: mov edx,[esi] ;get 8 pixels to convert of DIB ! 1473: and edx,11111111h ;keep only the plane 0 bits of DIB dword ! 1474: ; EDX = xxx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1 ! 1475: shld eax,edx,16+2 ;put bits 7-4 of DIB dword in AX, ! 1476: ; shifted left 2 (x = zero bit) ! 1477: ; DX = xxx2xxx3xxx0xxx1 ! 1478: ; AX = x6xxx7xxx4xxx5xx ! 1479: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 1480: ; x6x2x7x3x4x0x5x1 ! 1481: mov bl,al ;BL = x4x0x5x1 of DIB dword 0 ! 1482: add ah,ah ;make AH 6x2x7x3x of DIB dword 0 (shl 1) ! 1483: or bl,ah ;BL = 64207531 of DIB dword 0 ! 1484: add esi,4 ;point to next DIB dword ! 1485: inc edi ;point to next VGA byte (placed here ! 1486: ; for 486 pipelining reasons) ! 1487: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 1488: mov [edi-1],cl ;write 8 bits from DIB dword to VGA ! 1489: ! 1490: ;-----------------------------------------------------------------------; ! 1491: ; Code to convert 1-7 DIB4 pixels to a partial VGA plane 0 byte (8 ! 1492: ; pixels in plane 0). Assumes that a full dword of DIB4 pixels (8 ! 1493: ; pixels) is available, starting at ESI, although some of the pixels ! 1494: ; will be masked off. Assumes the DIB4 pixels (including masked-off ! 1495: ; pixels) start in the upper nibble of [ESI], and that the first ! 1496: ; (possibly masked-off) DIB4 pixel maps to bit 7 of the VGA at [EDI]. ! 1497: ; ! 1498: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 1499: ; (must start on a 256-byte boundary) ! 1500: ; ECX with bits sets as described for ulCopyControlFlags, above ! 1501: ; ESI = DIB pointer to first two pixels (possibly masked off) ! 1502: ; EDI = VGA pointer to planar byte ! 1503: ; Plane 0 must be mapped in for writes ! 1504: ;-----------------------------------------------------------------------; ! 1505: ! 1506: DIB4_to_VGA_plane0_copy_tpart: ! 1507: test ecx,TRAILING_PARTIAL ;handle a trailing partial byte? ! 1508: jz short DIB4_to_VGA_plane0_copy_done ;no, done ! 1509: ;yes, handle trailing partial byte ! 1510: mov edx,[esi] ;get 8 pixels to convert of DIB ! 1511: and edx,11111111h ;keep only the plane 0 bits of DIB dword ! 1512: ; EDX = xxx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1 ! 1513: shld eax,edx,16+2 ;put bits 7-4 of DIB dword in AX, ! 1514: ; shifted left 2 (x = zero bit) ! 1515: ; DX = xxx2xxx3xxx0xxx1 ! 1516: ; AX = x6xxx7xxx4xxx5xx ! 1517: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 1518: ; x6x2x7x3x4x0x5x1 ! 1519: mov bl,al ;BL = x4x0x5x1 of DIB dword 0 ! 1520: add ah,ah ;make AH 6x2x7x3x of DIB dword 0 (shl 1) ! 1521: or bl,ah ;BL = 64207531 of DIB dword 0 ! 1522: add esi,4 ;point to next DIB dword ! 1523: inc edi ;point to next VGA byte (placed here ! 1524: ; for 486 pipelining reasons) ! 1525: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 1526: mov ch,[edi-1] ;get the VGA destination byte ! 1527: and ecx,ulRightMask ;mask off source and dest ! 1528: or cl,ch ;combine masked source and dest ! 1529: mov [edi-1],cl ;write the new pixels to the VGA ! 1530: ! 1531: DIB4_to_VGA_plane0_copy_done: ! 1532: add esi,ulSrcDelta ;point to start of next DIB scan ! 1533: add edi,ulDstDelta ;point to start of next VGA scan ! 1534: dec ulPlane0Scans ;count down scans in this plane ! 1535: jnz DIB4_to_VGA_plane0_copy_loop ;do next scan in this plane, if any ! 1536: ! 1537: jmp copy_burst_plane0_done ;return to the top of the plane-copy ! 1538: ; loop ! 1539: ! 1540: ;-----------------------------------------------------------------------; ! 1541: ; Plane 1 DIB->VGA conversion code for a single scan line. ! 1542: ; ! 1543: ; Input: ECX with bits sets as described for ulCopyControlFlags, above ! 1544: ; bit 30 = 1 if there are whole words to be copied, = 0 if not ! 1545: ; bit 29 = 1 if leading byte should be copied, = 0 if not ! 1546: ; bit 28 = 1 if trailing byte should be copied, = 0 if not ! 1547: ; bit 27 = 1 if partial leading byte should be copied, = 0 if not ! 1548: ; bit 26 = 1 if partial trailing byte should be copied, = 0 if not ! 1549: ; ESI = DIB pointer to first two pixels ! 1550: ; EDI = VGA pointer to planar byte ! 1551: ; ulPlane1Scans = # of scan lines to copy to ! 1552: ; ulSrcDelta = offset from end of one source scan copied to start of next ! 1553: ; ulDstDelta = offset from end of one dest scan copied to start of next ! 1554: ; ulWholeDwordCount = # of whole, aligned dwords to copy ! 1555: ; ulLeftMask = mask for partial left edge, if any ! 1556: ; ulRightMask = mask for partial right edge, if any ! 1557: ; Plane 1 must be mapped in for writes ! 1558: ;-----------------------------------------------------------------------; ! 1559: align 4 ! 1560: DIB4_to_VGA_plane1_copy: ! 1561: ! 1562: ;-----------------------------------------------------------------------; ! 1563: ; Set EBX to point to multiplexed DIB byte->planar byte conversion table ! 1564: ; for plane 1. ! 1565: ;-----------------------------------------------------------------------; ! 1566: ! 1567: mov ebx,DIB4_to_VGA_plane1_table ;stays set for all bytes/words ! 1568: ! 1569: DIB4_to_VGA_plane1_copy_loop: ! 1570: ! 1571: ;-----------------------------------------------------------------------; ! 1572: ; Code to convert 1-7 DIB4 pixels to a partial VGA plane 1 byte (8 ! 1573: ; pixels in plane 1). Assumes that a full dword of DIB4 pixels (8 ! 1574: ; pixels) is available, starting at ESI, although some of the pixels ! 1575: ; will be masked off. Assumes the DIB4 pixels (including masked-off ! 1576: ; pixels) start in the upper nibble of [ESI], and that the first ! 1577: ; (possibly masked-off) DIB4 pixel maps to bit 7 of the VGA at [EDI]. ! 1578: ; ! 1579: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 1580: ; (must start on a 256-byte boundary) ! 1581: ; ECX with bits sets as described for ulCopyControlFlags, above ! 1582: ; ESI = DIB pointer to first two pixels (possibly masked off) ! 1583: ; EDI = VGA pointer to planar byte ! 1584: ; plane 1 must be mapped in for writes ! 1585: ;-----------------------------------------------------------------------; ! 1586: ! 1587: test ecx,LEADING_PARTIAL ;handle a leading partial byte? ! 1588: jz short DIB4_to_VGA_plane1_copy_lbyte ;no, go straight to whole ! 1589: ; byte ! 1590: ;yes, handle leading partial byte ! 1591: mov edx,[esi] ;get 8 pixels to convert of DIB ! 1592: and edx,22222222h ;keep only the plane 1 bits of DIB ! 1593: ; dword 0 ! 1594: ; EDX = xx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1x ! 1595: shld eax,edx,16+2 ;put bits 7-4 of DIB dword 0 in AX, ! 1596: ; shifted left 2 (x = zero bit) ! 1597: ; DX = xx2xxx3xxx0xxx1x ! 1598: ; AX = 6xxx7xxx4xxx5xxx ! 1599: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 1600: ; 6x2x7x3x4x0x5x1x ! 1601: mov bl,al ;BL = 4x0x5x1x of DIB dword 0 ! 1602: rol ah,7 ;make AH x6x2x7x3 of DIB dword 0 (shr 1) ! 1603: or bl,ah ;BL = 46025713 of DIB dword 0 ! 1604: add esi,4 ;point to next DIB dword ! 1605: inc edi ;point to next VGA byte (placed here ! 1606: ; for 486 pipelining reasons) ! 1607: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 1608: mov ch,[edi-1] ;get the VGA destination byte ! 1609: and ecx,ulLeftMask ;mask off source and dest ! 1610: or cl,ch ;combine masked source and dest ! 1611: mov [edi-1],cl ;write the new pixels to the VGA ! 1612: ! 1613: ;-----------------------------------------------------------------------; ! 1614: ; Code to convert 8 DIB4 pixels to a single VGA plane 1 byte (8 pixels ! 1615: ; in plane 1). Assumes the DIB4 pixels start in the upper nibble of ! 1616: ; [ESI], and that the first DIB4 pixel maps to bit 7 of the VGA at ! 1617: ; [EDI]. ! 1618: ; ! 1619: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 1620: ; (must start on a 256-byte boundary) ! 1621: ; ECX with bits sets as described for ulCopyControlFlags, above ! 1622: ; ESI = DIB pointer to first two pixels ! 1623: ; EDI = VGA pointer to planar byte ! 1624: ; plane 1 must be mapped in for writes ! 1625: ;-----------------------------------------------------------------------; ! 1626: ! 1627: DIB4_to_VGA_plane1_copy_lbyte: ! 1628: test ecx,LEADING_BYTE ;should we handle a leading byte? ! 1629: jz short DIB4_to_VGA_plane1_copy_words ;no, go straight to words ! 1630: ;yes, handle leading byte ! 1631: mov edx,[esi] ;get 8 pixels to convert of DIB ! 1632: and edx,22222222h ;keep only the plane 1 bits of DIB ! 1633: ; dword 0 ! 1634: ; EDX = xx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1x ! 1635: shld eax,edx,16+2 ;put bits 7-4 of DIB dword 0 in AX, ! 1636: ; shifted left 2 (x = zero bit) ! 1637: ; DX = xx2xxx3xxx0xxx1x ! 1638: ; AX = 6xxx7xxx4xxx5xxx ! 1639: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 1640: ; 6x2x7x3x4x0x5x1x ! 1641: mov bl,al ;BL = 4x0x5x1x of DIB dword 0 ! 1642: rol ah,7 ;make AH x6x2x7x3 of DIB dword 0 (shr 1) ! 1643: or bl,ah ;BL = 46025713 of DIB dword 0 ! 1644: add esi,4 ;point to next DIB dword ! 1645: inc edi ;point to next VGA byte (placed here ! 1646: ; for 486 pipelining reasons) ! 1647: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 1648: mov [edi-1],cl ;write 8 bits from DIB dword to VGA ! 1649: ! 1650: ;-----------------------------------------------------------------------; ! 1651: ; Code for converting sets of 32 DIB4 pixels to 4 VGA plane 1 bytes (32 ! 1652: ; pixels in plane 1). Assumes the VGA destination is word aligned. ! 1653: ; Assumes the DIB4 pixels start in the upper nibble of [ESI], and that ! 1654: ; the first DIB4 pixel maps to bit 7 of the VGA at [EDI]. ! 1655: ; ! 1656: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 1657: ; (must start on a 256-byte boundary) ! 1658: ; ECX with bits sets as described for ulCopyControlFlags, above ! 1659: ; ESI = DIB pointer to first two pixels ! 1660: ; EDI = VGA pointer to two planar bytes (must be word aligned) ! 1661: ; EBP = # of VGA dwords to convert ! 1662: ; ulWholeDwordCount = # of VGA dwords to convert ! 1663: ; Plane 1 must be mapped in for writes ! 1664: ; ! 1665: ; Note: on entry at DIB4_to_VGA_plane1_word_odd, ESI must point to the ! 1666: ; desired source start minus 8, and EAX must be loaded as if the following ! 1667: ; instructions had been performed: ! 1668: ; mov edx,[esi+8] ! 1669: ; and edx,22222222h ! 1670: ; shld eax,edx,16+2 ! 1671: ; or eax,edx ! 1672: ; ! 1673: ; Note: ROL AH,7 is used instead of SHR AH,1 because the shift-by-1 ! 1674: ; form is 1 cycle slower on a 486, and in this case the two forms are ! 1675: ; functionally identical. ! 1676: ; ! 1677: ; Note: the code is so odd because of 486 pipeline optimization. ! 1678: ; DO NOT CHANGE THIS CODE UNLESS YOU KNOW EXACTLY WHAT YOU'RE DOING!!! ! 1679: ; ! 1680: ; Note: all 486 pipeline penalties are eliminated except for SHLD, which ! 1681: ; is losing 4 cycles total, and writing CX to memory (2 cycles), so far ! 1682: ; as I know. ! 1683: ;-----------------------------------------------------------------------; ! 1684: ! 1685: DIB4_to_VGA_plane1_copy_words: ! 1686: test ecx,ODD_WHOLE_WORD or WHOLE_WORDS ;any whole words to copy? ! 1687: jz DIB4_to_VGA_plane1_copy_tbyte ;no, check for trailing whole ! 1688: ; bytes ! 1689: ;yes, copy the whole words ! 1690: push ebp ;preserve stack frame pointer ! 1691: mov ebp,ulWholeDwordCount ;# of VGA dwords to copy to ! 1692: ;even # of DIB dwords to copy? (flags still ! 1693: ; set from TEST) ! 1694: .errnz ODD_WHOLE_WORD - 80000000h ! 1695: jns short DIB4_to_VGA_plane1_word_loop ;yes, start copying ! 1696: ;no, there's an odd word; prepare to enter loop ! 1697: ; in middle ! 1698: mov edx,[esi] ;get 8 pixels to convert of first DIB dword ! 1699: and edx,22222222h ;keep only the plane 1 bits of DIB dword ! 1700: ; EDX = xx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1x ! 1701: shld eax,edx,16+2 ;put bits 7-4 of DIB dword in AX, ! 1702: ; shifted left 2 ! 1703: ; DX = xx2xxx3xxx0xxx1x ! 1704: ; AX = 6xxx7xxx4xxx5xxx ! 1705: or eax,edx ;put bits 7-0 of DIB dword in AX: ! 1706: ; 6x2x7x3x4x0x5x1x ! 1707: sub esi,8 ;compensate source back for entering in middle ! 1708: sub edi,2 ;compensate dest back for entering in middle ! 1709: ! 1710: jmp short DIB4_to_VGA_plane1_word_odd ! 1711: ! 1712: ;-----------------------------------------------------------------------; ! 1713: ; Loop to copy a word at a time to VGA plane 1 (actually, unrolled once ! 1714: ; so copies dwords). ! 1715: ;-----------------------------------------------------------------------; ! 1716: ! 1717: align 16 ! 1718: DIB4_to_VGA_plane1_word_loop: ! 1719: mov edx,[esi] ;get 8 pixels to convert of DIB dword 0 ! 1720: and edx,22222222h ;keep only the plane 1 bits of DIB ! 1721: ; dword 0 ! 1722: ; EDX = xx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1x ! 1723: shld eax,edx,16+2 ;put bits 7-4 of DIB dword 0 in AX, ! 1724: ; shifted left 2 (x = zero bit) ! 1725: ; DX = xx2xxx3xxx0xxx1x ! 1726: ; AX = 6xxx7xxx4xxx5xxx ! 1727: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 1728: ; 6x2x7x3x4x0x5x1x ! 1729: mov edx,[esi+4] ;get 8 pixels to convert of DIB dword 1 ! 1730: mov bl,al ;BL = 4x0x5x1x of DIB dword 0 ! 1731: rol ah,7 ;make AH x6x2x7x3 of DIB dword 0 (shr 1) ! 1732: or bl,ah ;BL = 46025713 of DIB dword 0 ! 1733: and edx,22222222h ;keep only the plane 1 bits of DIB ! 1734: ; dword 1 ! 1735: ; EDX = xx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1x ! 1736: shld eax,edx,16+2 ;put bits 7-4 of DIB dword 1 in AX, ! 1737: ; shifted left 2 ! 1738: ; DX = xx2xxx3xxx0xxx1x ! 1739: ; AX = 6xxx7xxx4xxx5xxx ! 1740: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 1741: or eax,edx ;put bits 7-0 of DIB dword 1 in AX: ! 1742: ; 6x2x7x3x4x0x5x1x ! 1743: mov bl,al ;BL = 4x0x5x1x of DIB dword 1 ! 1744: mov edx,[esi+8] ;get 8 pixels to convert of DIB dword 2 ! 1745: rol ah,7 ;make AH x6x2x7x3 of DIB dword 1 (shr 1) ! 1746: or bl,ah ;BL = 46025713 of DIB dword 1 ! 1747: and edx,22222222h ;keep only the plane 1 bits of DIB ! 1748: ; dword 2 ! 1749: ; EDX = xx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1x ! 1750: shld eax,edx,16+2 ;put bits 7-4 of DIB dword 2 in AX, ! 1751: ; shifted left 2 ! 1752: ; DX = xx2xxx3xxx0xxx1x ! 1753: ; AX = 6xxx7xxx4xxx5xxx ! 1754: mov ch,[ebx] ;CH = 76543210 of DIB dword 1 ! 1755: or eax,edx ;put bits 7-0 of DIB dword 2 in AX: ! 1756: ; 6x2x7x3x4x0x5x1x ! 1757: mov [edi],cx ;write 16 bits from DIB dwords 0 and 1 ! 1758: ; to VGA ! 1759: DIB4_to_VGA_plane1_word_odd: ! 1760: mov edx,[esi+12] ;get 8 pixels to convert of DIB dword 3 ! 1761: mov bl,al ;BL = 4x0x5x1x of DIB dword 2 ! 1762: rol ah,7 ;make AH x6x2x7x3 of DIB dword 2 (shr 1) ! 1763: or bl,ah ;BL = 46025713 of DIB dword 2 ! 1764: and edx,22222222h ;keep only the plane 1 bits of DIB ! 1765: ; dword 3 ! 1766: ; EDX = xx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1x ! 1767: shld eax,edx,16+2 ;put bits 7-4 of DIB dword 3 in AX, ! 1768: ; shifted left 2 ! 1769: ; DX = xx2xxx3xxx0xxx1x ! 1770: ; AX = 6xxx7xxx4xxx5xxx ! 1771: mov cl,[ebx] ;CL = 76543210 of DIB dword 2 ! 1772: or eax,edx ;put bits 7-0 of DIB dword 3 in AX: ! 1773: ; 6x2x7x3x4x0x5x1x ! 1774: mov bl,al ;BL = 4x0x5x1x of DIB dword 3 ! 1775: rol ah,7 ;make AH x6x2x7x3 of DIB dword 3 (shr 1) ! 1776: or bl,ah ;BL = 46025713 of DIB dword 3 ! 1777: add esi,16 ;point to next set of 4 DIB dwords ! 1778: add edi,4 ;point to next VGA dword ! 1779: mov ch,[ebx] ;CH = 76543210 of dword 0 ! 1780: dec ebp ;count down VGA dwords ! 1781: mov [edi-2],cx ;write 16 bits from DIB dwords 2 and 3 ! 1782: ; to VGA ! 1783: jnz DIB4_to_VGA_plane1_word_loop ;do next VGA dword, if any ! 1784: ! 1785: pop ebp ;restore stack frame pointer ! 1786: ! 1787: ;-----------------------------------------------------------------------; ! 1788: ; Code to convert 8 DIB4 pixels to a single VGA plane 1 byte (8 pixels ! 1789: ; in plane 1). Assumes the DIB4 pixels start in the upper nibble of ! 1790: ; [ESI], and that the first DIB4 pixel maps to bit 7 of the VGA at ! 1791: ; [EDI]. ! 1792: ; ! 1793: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 1794: ; (must start on a 256-byte boundary) ! 1795: ; ECX with bits sets as described for ulCopyControlFlags, above ! 1796: ; ESI = DIB pointer to first two pixels ! 1797: ; EDI = VGA pointer to planar byte ! 1798: ; Plane 1 must be mapped in for writes ! 1799: ; ! 1800: ;-----------------------------------------------------------------------; ! 1801: ! 1802: DIB4_to_VGA_plane1_copy_tbyte: ! 1803: test ecx,TRAILING_BYTE ;should we handle a trailing byte? ! 1804: jz short DIB4_to_VGA_plane1_copy_tpart ;no, check for trailing ! 1805: ; partial ! 1806: ;yes, handle trailing byte ! 1807: mov edx,[esi] ;get 8 pixels to convert of DIB ! 1808: and edx,22222222h ;keep only the plane 1 bits of DIB ! 1809: ; dword 0 ! 1810: ; EDX = xx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1x ! 1811: shld eax,edx,16+2 ;put bits 7-4 of DIB dword 0 in AX, ! 1812: ; shifted left 2 (x = zero bit) ! 1813: ; DX = xx2xxx3xxx0xxx1x ! 1814: ; AX = 6xxx7xxx4xxx5xxx ! 1815: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 1816: ; 6x2x7x3x4x0x5x1x ! 1817: mov bl,al ;BL = 4x0x5x1x of DIB dword 0 ! 1818: rol ah,7 ;make AH x6x2x7x3 of DIB dword 0 (shr 1) ! 1819: or bl,ah ;BL = 46025713 of DIB dword 0 ! 1820: add esi,4 ;point to next DIB dword ! 1821: inc edi ;point to next VGA byte (placed here ! 1822: ; for 486 pipelining reasons) ! 1823: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 1824: mov [edi-1],cl ;write 8 bits from DIB dword to VGA ! 1825: ! 1826: ;-----------------------------------------------------------------------; ! 1827: ; Code to convert 1-7 DIB4 pixels to a partial VGA plane 1 byte (8 ! 1828: ; pixels in plane 1). Assumes that a full dword of DIB4 pixels (8 ! 1829: ; pixels) is available, starting at ESI, although some of the pixels ! 1830: ; will be masked off. Assumes the DIB4 pixels (including masked-off ! 1831: ; pixels) start in the upper nibble of [ESI], and that the first ! 1832: ; (possibly masked-off) DIB4 pixel maps to bit 7 of the VGA at [EDI]. ! 1833: ; ! 1834: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 1835: ; (must start on a 256-byte boundary) ! 1836: ; ECX with bits sets as described for ulCopyControlFlags, above ! 1837: ; ESI = DIB pointer to first two pixels (possibly masked off) ! 1838: ; EDI = VGA pointer to planar byte ! 1839: ; plane 1 must be mapped in for writes ! 1840: ;-----------------------------------------------------------------------; ! 1841: ! 1842: DIB4_to_VGA_plane1_copy_tpart: ! 1843: test ecx,TRAILING_PARTIAL ;handle a trailing partial byte? ! 1844: jz short DIB4_to_VGA_plane1_copy_done ;no, done ! 1845: ;yes, handle trailing partial byte ! 1846: mov edx,[esi] ;get 8 pixels to convert of DIB ! 1847: and edx,22222222h ;keep only the plane 1 bits of DIB ! 1848: ; dword 0 ! 1849: ; EDX = xx6xxx7xxx4xxx5xxx2xxx3xxx0xxx1x ! 1850: shld eax,edx,16+2 ;put bits 7-4 of DIB dword 0 in AX, ! 1851: ; shifted left 2 (x = zero bit) ! 1852: ; DX = xx2xxx3xxx0xxx1x ! 1853: ; AX = 6xxx7xxx4xxx5xxx ! 1854: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 1855: ; 6x2x7x3x4x0x5x1x ! 1856: mov bl,al ;BL = 4x0x5x1x of DIB dword 0 ! 1857: rol ah,7 ;make AH x6x2x7x3 of DIB dword 0 (shr 1) ! 1858: or bl,ah ;BL = 46025713 of DIB dword 0 ! 1859: add esi,4 ;point to next DIB dword ! 1860: inc edi ;point to next VGA byte (placed here ! 1861: ; for 486 pipelining reasons) ! 1862: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 1863: mov ch,[edi-1] ;get the VGA destination byte ! 1864: and ecx,ulRightMask ;mask off source and dest ! 1865: or cl,ch ;combine masked source and dest ! 1866: mov [edi-1],cl ;write the new pixels to the VGA ! 1867: ! 1868: DIB4_to_VGA_plane1_copy_done: ! 1869: add esi,ulSrcDelta ;point to start of next DIB scan ! 1870: add edi,ulDstDelta ;point to start of next VGA scan ! 1871: dec ulPlane1Scans ;count down scans in this plane ! 1872: jnz DIB4_to_VGA_plane1_copy_loop ;do next scan in this plane, if any ! 1873: ! 1874: jmp copy_burst_plane1_done ;return to the top of the plane-copy ! 1875: ; loop ! 1876: ! 1877: ;-----------------------------------------------------------------------; ! 1878: ; Plane 2 DIB->VGA conversion code for a single scan line. ! 1879: ; ! 1880: ; Input: ECX with bits sets as described for ulCopyControlFlags, above ! 1881: ; bit 30 = 1 if there are whole words to be copied, = 0 if not ! 1882: ; bit 29 = 1 if leading byte should be copied, = 0 if not ! 1883: ; bit 28 = 1 if trailing byte should be copied, = 0 if not ! 1884: ; bit 27 = 1 if partial leading byte should be copied, = 0 if not ! 1885: ; bit 26 = 1 if partial trailing byte should be copied, = 0 if not ! 1886: ; ESI = DIB pointer to first two pixels ! 1887: ; EDI = VGA pointer to planar byte ! 1888: ; ulPlane2Scans = # of scan lines to copy to ! 1889: ; ulSrcDelta = offset from end of one source scan copied to start of next ! 1890: ; ulDstDelta = offset from end of one dest scan copied to start of next ! 1891: ; ulWholeDwordCount = # of whole, aligned dwords to copy ! 1892: ; ulLeftMask = mask for partial left edge, if any ! 1893: ; ulRightMask = mask for partial right edge, if any ! 1894: ; Plane 2 must be mapped in for writes ! 1895: ;-----------------------------------------------------------------------; ! 1896: align 4 ! 1897: DIB4_to_VGA_plane2_copy: ! 1898: ! 1899: ;-----------------------------------------------------------------------; ! 1900: ; Set EBX to point to multiplexed DIB byte->planar byte conversion table ! 1901: ; for plane 2. ! 1902: ;-----------------------------------------------------------------------; ! 1903: ! 1904: mov ebx,DIB4_to_VGA_plane2_table ;stays set for all bytes/words ! 1905: ! 1906: DIB4_to_VGA_plane2_copy_loop: ! 1907: ! 1908: ;-----------------------------------------------------------------------; ! 1909: ; Code to convert 1-7 DIB4 pixels to a partial VGA plane 2 byte (8 ! 1910: ; pixels in plane 2). Assumes that a full dword of DIB4 pixels (8 ! 1911: ; pixels) is available, starting at ESI, although some of the pixels ! 1912: ; will be masked off. Assumes the DIB4 pixels (including masked-off ! 1913: ; pixels) start in the upper nibble of [ESI], and that the first ! 1914: ; (possibly masked-off) DIB4 pixel maps to bit 7 of the VGA at [EDI]. ! 1915: ; ! 1916: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 1917: ; (must start on a 256-byte boundary) ! 1918: ; ECX with bits sets as described for ulCopyControlFlags, above ! 1919: ; ESI = DIB pointer to first two pixels (possibly masked off) ! 1920: ; EDI = VGA pointer to planar byte ! 1921: ; plane 2 must be mapped in for writes ! 1922: ;-----------------------------------------------------------------------; ! 1923: ! 1924: test ecx,LEADING_PARTIAL ;handle a leading partial byte? ! 1925: jz short DIB4_to_VGA_plane2_copy_lbyte ;no, go straight to whole ! 1926: ; byte ! 1927: ;yes, handle leading partial byte ! 1928: mov edx,[esi] ;get 8 pixels to convert of DIB ! 1929: and edx,44444444h ;keep only the plane 2 bits of DIB ! 1930: ; dword 0 ! 1931: ; EDX = x6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xx ! 1932: mov eax,edx ;put bits 7-4 of DIB dword 0 in AX, ! 1933: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 1934: ; DX = x2xxx3xxx0xxx1xx ! 1935: ; AX = xxx6xxx7xxx4xxx5 ! 1936: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 1937: ; x2x6x3x7x0x4x1x5 ! 1938: mov bl,al ;BL = x0x4x1x5 of DIB dword 0 ! 1939: add ah,ah ;make AH 2x6x3x7x of DIB dword 0 (shl 1) ! 1940: or bl,ah ;BL = 20643175 of DIB dword 0 ! 1941: add esi,4 ;point to next DIB dword ! 1942: inc edi ;point to next VGA byte (placed here ! 1943: ; for 486 pipelining reasons) ! 1944: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 1945: mov ch,[edi-1] ;get the VGA destination byte ! 1946: and ecx,ulLeftMask ;mask off source and dest ! 1947: or cl,ch ;combine masked source and dest ! 1948: mov [edi-1],cl ;write the new pixels to the VGA ! 1949: ! 1950: ;-----------------------------------------------------------------------; ! 1951: ; Code to convert 8 DIB4 pixels to a single VGA plane 2 byte (8 pixels ! 1952: ; in plane 2). Assumes the DIB4 pixels start in the upper nibble of ! 1953: ; [ESI], and that the first DIB4 pixel maps to bit 7 of the VGA at ! 1954: ; [EDI]. ! 1955: ; ! 1956: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 1957: ; (must start on a 256-byte boundary) ! 1958: ; ECX with bits sets as described for ulCopyControlFlags, above ! 1959: ; ESI = DIB pointer to first two pixels ! 1960: ; EDI = VGA pointer to planar byte ! 1961: ; plane 2 must be mapped in for writes ! 1962: ;-----------------------------------------------------------------------; ! 1963: ! 1964: DIB4_to_VGA_plane2_copy_lbyte: ! 1965: test ecx,LEADING_BYTE ;should we handle a leading byte? ! 1966: jz short DIB4_to_VGA_plane2_copy_words ;no, go straight to words ! 1967: ;yes, handle leading byte ! 1968: mov edx,[esi] ;get 8 pixels to convert of DIB ! 1969: and edx,44444444h ;keep only the plane 2 bits of DIB ! 1970: ; dword 0 ! 1971: ; EDX = x6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xx ! 1972: mov eax,edx ;put bits 7-4 of DIB dword 0 in AX, ! 1973: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 1974: ; DX = x2xxx3xxx0xxx1xx ! 1975: ; AX = xxx6xxx7xxx4xxx5 ! 1976: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 1977: ; x2x6x3x7x0x4x1x5 ! 1978: mov bl,al ;BL = x0x4x1x5 of DIB dword 0 ! 1979: add ah,ah ;make AH 2x6x3x7x of DIB dword 0 (shl 1) ! 1980: or bl,ah ;BL = 20643175 of DIB dword 0 ! 1981: add esi,4 ;point to next DIB dword ! 1982: inc edi ;point to next VGA byte (placed here ! 1983: ; for 486 pipelining reasons) ! 1984: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 1985: mov [edi-1],cl ;write 8 bits from DIB dword to VGA ! 1986: ! 1987: ;-----------------------------------------------------------------------; ! 1988: ; Code for converting sets of 32 DIB4 pixels to 4 VGA plane 2 bytes (32 ! 1989: ; pixels in plane 2). Assumes the VGA destination is word aligned. ! 1990: ; Assumes the DIB4 pixels start in the upper nibble of [ESI], and that ! 1991: ; the first DIB4 pixel maps to bit 7 of the VGA at [EDI]. ! 1992: ; ! 1993: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 1994: ; (must start on a 256-byte boundary) ! 1995: ; ECX with bits sets as described for ulCopyControlFlags, above ! 1996: ; ESI = DIB pointer to first two pixels ! 1997: ; EDI = VGA pointer to two planar bytes (must be word aligned) ! 1998: ; EBP = # of VGA dwords to convert ! 1999: ; ulWholeDwordCount = # of VGA dwords to convert ! 2000: ; Plane 2 must be mapped in for writes ! 2001: ; ! 2002: ; Note: on entry at DIB4_to_VGA_plane2_word_odd, ESI must point to the ! 2003: ; desired source start minus 8, and EAX must be loaded as if the following ! 2004: ; instructions had been performed: ! 2005: ; mov edx,[esi+8] ! 2006: ; and edx,44444444h ! 2007: ; mov eax,edx ! 2008: ; shr eax,16+2 ! 2009: ; or eax,edx ! 2010: ; ! 2011: ; Note: the code is so odd because of 486 pipeline optimization. ! 2012: ; DO NOT CHANGE THIS CODE UNLESS YOU KNOW EXACTLY WHAT YOU'RE DOING!!! ! 2013: ; ! 2014: ; Note: all 486 pipeline penalties are eliminated except for writing CX ! 2015: ; to memory (2 cycles), so far as I know. ! 2016: ;-----------------------------------------------------------------------; ! 2017: ! 2018: DIB4_to_VGA_plane2_copy_words: ! 2019: test ecx,ODD_WHOLE_WORD or WHOLE_WORDS ;any whole words to copy? ! 2020: jz DIB4_to_VGA_plane2_copy_tbyte ;no, check for trailing whole ! 2021: ; bytes ! 2022: ;yes, copy the whole words ! 2023: push ebp ;preserve stack frame pointer ! 2024: mov ebp,ulWholeDwordCount ;# of VGA dwords to copy to ! 2025: ;even # of DIB dwords to copy? (flags still ! 2026: ; set from TEST) ! 2027: .errnz ODD_WHOLE_WORD - 80000000h ! 2028: jns short DIB4_to_VGA_plane2_word_loop ;yes, start copying ! 2029: ;no, there's an odd word; prepare to enter loop ! 2030: ; in middle ! 2031: mov edx,[esi] ;get 8 pixels to convert of first DIB dword ! 2032: and edx,44444444h ;keep only the plane 2 bits of DIB dword ! 2033: ; EDX = x6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xx ! 2034: mov eax,edx ;put bits 7-4 of DIB dword in AX, ! 2035: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 2036: ; DX = x2xxx3xxx0xxx1xx ! 2037: ; AX = xxx6xxx7xxx4xxx5 ! 2038: or eax,edx ;put bits 7-0 of DIB dword in AX: ! 2039: ; 62xx73xx40xx51xx ! 2040: sub esi,8 ;compensate source back for entering in middle ! 2041: sub edi,2 ;compensate dest back for entering in middle ! 2042: ! 2043: jmp short DIB4_to_VGA_plane2_word_odd ! 2044: ! 2045: ;-----------------------------------------------------------------------; ! 2046: ; Loop to copy a word at a time to VGA plane 2 (actually, unrolled once ! 2047: ; so copies dwords). ! 2048: ;-----------------------------------------------------------------------; ! 2049: ! 2050: align 16 ! 2051: DIB4_to_VGA_plane2_word_loop: ! 2052: mov edx,[esi] ;get 8 pixels to convert of DIB dword 0 ! 2053: and edx,44444444h ;keep only the plane 2 bits of DIB ! 2054: ; dword 0 ! 2055: ; EDX = x6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xx ! 2056: mov eax,edx ;put bits 7-4 of DIB dword 0 in AX, ! 2057: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 2058: ; DX = x2xxx3xxx0xxx1xx ! 2059: ; AX = xxx6xxx7xxx4xxx5 ! 2060: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 2061: ; x2x6x3x7x0x4x1x5 ! 2062: mov edx,[esi+4] ;get 8 pixels to convert of DIB dword 1 ! 2063: mov bl,al ;BL = x0x4x1x5 of DIB dword 0 ! 2064: add ah,ah ;make AH 2x6x3x7x of DIB dword 0 (shl 1) ! 2065: or bl,ah ;BL = 20643175 of DIB dword 0 ! 2066: and edx,44444444h ;keep only the plane 2 bits of DIB ! 2067: ; dword 1 ! 2068: ; EDX = x6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xx ! 2069: mov eax,edx ;put bits 7-4 of DIB dword 1 in AX, ! 2070: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 2071: ; DX = x2xxx3xxx0xxx1xx ! 2072: ; AX = xxx6xxx7xxx4xxx5 ! 2073: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 2074: or eax,edx ;put bits 7-0 of DIB dword 1 in AX: ! 2075: ; 62xx73xx40xx51xx ! 2076: mov bl,al ;BL = x0x4x1x5 of DIB dword 1 ! 2077: mov edx,[esi+8] ;get 8 pixels to convert of DIB dword 2 ! 2078: add ah,ah ;make AH 2x6x3x7x of DIB dword 1 (shl 1) ! 2079: or bl,ah ;BL = 20643175 of DIB dword 1 ! 2080: and edx,44444444h ;keep only the plane 2 bits of DIB ! 2081: ; dword 2 ! 2082: ; EDX = x6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xx ! 2083: mov eax,edx ;put bits 7-4 of DIB dword 2 in AX, ! 2084: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 2085: ; DX = x2xxx3xxx0xxx1xx ! 2086: ; AX = xxx6xxx7xxx4xxx5 ! 2087: mov ch,[ebx] ;CH = 76543210 of DIB dword 1 ! 2088: or eax,edx ;put bits 7-0 of DIB dword 2 in AX: ! 2089: ; 62xx73xx40xx51xx ! 2090: mov [edi],cx ;write 16 bits from DIB dwords 0 and 1 ! 2091: ; to VGA ! 2092: DIB4_to_VGA_plane2_word_odd: ! 2093: mov edx,[esi+12] ;get 8 pixels to convert of DIB dword 3 ! 2094: mov bl,al ;BL = x0x4x1x5 of DIB dword 2 ! 2095: add ah,ah ;make AH 2x6x3x7x of DIB dword 2 (shl 1) ! 2096: or bl,ah ;BL = 20643175 of DIB dword 2 ! 2097: and edx,44444444h ;keep only the plane 2 bits of DIB ! 2098: ; dword 3 ! 2099: ; EDX = x6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xx ! 2100: mov eax,edx ;put bits 7-4 of DIB dword 3 in AX, ! 2101: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 2102: ; DX = x2xxx3xxx0xxx1xx ! 2103: ; AX = xxx6xxx7xxx4xxx5 ! 2104: mov cl,[ebx] ;CL = 76543210 of DIB dword 2 ! 2105: or eax,edx ;put bits 7-0 of DIB dword 3 in AX: ! 2106: ; 62xx73xx40xx51xx ! 2107: mov bl,al ;BL = x0x4x1x5 of DIB dword 3 ! 2108: add ah,ah ;make AH 2x6x3x7x of DIB dword 3 (shl 1) ! 2109: or bl,ah ;BL = 20643175 of DIB dword 3 ! 2110: add esi,16 ;point to next set of 4 DIB dwords ! 2111: add edi,4 ;point to next VGA dword ! 2112: mov ch,[ebx] ;CH = 76543210 of dword 0 ! 2113: dec ebp ;count down VGA dwords ! 2114: mov [edi-2],cx ;write 16 bits from DIB dwords 2 and 3 ! 2115: ; to VGA ! 2116: jnz DIB4_to_VGA_plane2_word_loop ;do next VGA dword, if any ! 2117: ! 2118: pop ebp ;restore stack frame pointer ! 2119: ! 2120: ;-----------------------------------------------------------------------; ! 2121: ; Code to convert 8 DIB4 pixels to a single VGA plane 2 byte (8 pixels ! 2122: ; in plane 2). Assumes the DIB4 pixels start in the upper nibble of ! 2123: ; [ESI], and that the first DIB4 pixel maps to bit 7 of the VGA at ! 2124: ; [EDI]. ! 2125: ; ! 2126: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 2127: ; (must start on a 256-byte boundary) ! 2128: ; ECX with bits sets as described for ulCopyControlFlags, above ! 2129: ; ESI = DIB pointer to first two pixels ! 2130: ; EDI = VGA pointer to planar byte ! 2131: ; plane 2 must be mapped in for writes ! 2132: ; ! 2133: ;-----------------------------------------------------------------------; ! 2134: ! 2135: DIB4_to_VGA_plane2_copy_tbyte: ! 2136: test ecx,TRAILING_BYTE ;should we handle a trailing byte? ! 2137: jz short DIB4_to_VGA_plane2_copy_tpart ;no, check for trailing ! 2138: ; partial ! 2139: ;yes, handle trailing byte ! 2140: mov edx,[esi] ;get 8 pixels to convert of DIB ! 2141: and edx,44444444h ;keep only the plane 2 bits of DIB ! 2142: ; dword 0 ! 2143: ; EDX = x6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xx ! 2144: mov eax,edx ;put bits 7-4 of DIB dword 0 in AX, ! 2145: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 2146: ; DX = x2xxx3xxx0xxx1xx ! 2147: ; AX = xxx6xxx7xxx4xxx5 ! 2148: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 2149: ; x2x6x3x7x0x4x1x5 ! 2150: mov bl,al ;BL = x0x4x1x5 of DIB dword 0 ! 2151: add ah,ah ;make AH 2x6x3x7x of DIB dword 0 (shl 1) ! 2152: or bl,ah ;BL = 20643175 of DIB dword 0 ! 2153: add esi,4 ;point to next DIB dword ! 2154: inc edi ;point to next VGA byte (placed here ! 2155: ; for 486 pipelining reasons) ! 2156: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 2157: mov [edi-1],cl ;write 8 bits from DIB dword to VGA ! 2158: ! 2159: ;-----------------------------------------------------------------------; ! 2160: ; Code to convert 1-7 DIB4 pixels to a partial VGA plane 2 byte (8 ! 2161: ; pixels in plane 2). Assumes that a full dword of DIB4 pixels (8 ! 2162: ; pixels) is available, starting at ESI, although some of the pixels ! 2163: ; will be masked off. Assumes the DIB4 pixels (including masked-off ! 2164: ; pixels) start in the upper nibble of [ESI], and that the first ! 2165: ; (possibly masked-off) DIB4 pixel maps to bit 7 of the VGA at [EDI]. ! 2166: ; ! 2167: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 2168: ; (must start on a 256-byte boundary) ! 2169: ; ECX with bits sets as described for ulCopyControlFlags, above ! 2170: ; ESI = DIB pointer to first two pixels (possibly masked off) ! 2171: ; EDI = VGA pointer to planar byte ! 2172: ; plane 2 must be mapped in for writes ! 2173: ;-----------------------------------------------------------------------; ! 2174: ! 2175: DIB4_to_VGA_plane2_copy_tpart: ! 2176: test ecx,TRAILING_PARTIAL ;handle a trailing partial byte? ! 2177: jz short DIB4_to_VGA_plane2_copy_done ;no, done ! 2178: ;yes, handle trailing partial byte ! 2179: mov edx,[esi] ;get 8 pixels to convert of DIB ! 2180: and edx,44444444h ;keep only the plane 2 bits of DIB ! 2181: ; dword 0 ! 2182: ; EDX = x6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xx ! 2183: mov eax,edx ;put bits 7-4 of DIB dword 0 in AX, ! 2184: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 2185: ; DX = x2xxx3xxx0xxx1xx ! 2186: ; AX = xxx6xxx7xxx4xxx5 ! 2187: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 2188: ; x2x6x3x7x0x4x1x5 ! 2189: mov bl,al ;BL = x0x4x1x5 of DIB dword 0 ! 2190: add ah,ah ;make AH 2x6x3x7x of DIB dword 0 (shl 1) ! 2191: or bl,ah ;BL = 20643175 of DIB dword 0 ! 2192: add esi,4 ;point to next DIB dword ! 2193: inc edi ;point to next VGA byte (placed here ! 2194: ; for 486 pipelining reasons) ! 2195: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 2196: mov ch,[edi-1] ;get the VGA destination byte ! 2197: and ecx,ulRightMask ;mask off source and dest ! 2198: or cl,ch ;combine masked source and dest ! 2199: mov [edi-1],cl ;write the new pixels to the VGA ! 2200: ! 2201: DIB4_to_VGA_plane2_copy_done: ! 2202: add esi,ulSrcDelta ;point to start of next DIB scan ! 2203: add edi,ulDstDelta ;point to start of next VGA scan ! 2204: dec ulPlane2Scans ;count down scans in this plane ! 2205: jnz DIB4_to_VGA_plane2_copy_loop ;do next scan in this plane, if any ! 2206: ! 2207: jmp copy_burst_plane2_done ;return to the top of the plane-copy ! 2208: ; loop ! 2209: ! 2210: ;-----------------------------------------------------------------------; ! 2211: ; Plane 3 DIB->VGA conversion code for a single scan line. ! 2212: ; ! 2213: ; Input: ECX with bits sets as described for ulCopyControlFlags, above ! 2214: ; ESI = DIB pointer to first two pixels ! 2215: ; EDI = VGA pointer to planar byte ! 2216: ; ulPlane3Scans = # of scan lines to copy to ! 2217: ; ulSrcDelta = offset from end of one source scan copied to start of next ! 2218: ; ulDstDelta = offset from end of one dest scan copied to start of next ! 2219: ; ulWholeDwordCount = # of whole, aligned dwords to copy ! 2220: ; ulLeftMask = mask for partial left edge, if any ! 2221: ; ulRightMask = mask for partial right edge, if any ! 2222: ; Plane 3 must be mapped in for writes ! 2223: ;-----------------------------------------------------------------------; ! 2224: align 4 ! 2225: DIB4_to_VGA_plane3_copy: ! 2226: ! 2227: ;-----------------------------------------------------------------------; ! 2228: ; Set EBX to point to multiplexed DIB byte->planar byte conversion table ! 2229: ; for plane 3. ! 2230: ;-----------------------------------------------------------------------; ! 2231: ! 2232: mov ebx,DIB4_to_VGA_plane3_table ;stays set for all bytes/words ! 2233: ! 2234: DIB4_to_VGA_plane3_copy_loop: ! 2235: ! 2236: ;-----------------------------------------------------------------------; ! 2237: ; Code to convert 1-7 DIB4 pixels to a partial VGA plane 3 byte (8 ! 2238: ; pixels in plane 3). Assumes that a full dword of DIB4 pixels (8 ! 2239: ; pixels) is available, starting at ESI, although some of the pixels ! 2240: ; will be masked off. Assumes the DIB4 pixels (including masked-off ! 2241: ; pixels) start in the upper nibble of [ESI], and that the first ! 2242: ; (possibly masked-off) DIB4 pixel maps to bit 7 of the VGA at [EDI]. ! 2243: ; ! 2244: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 2245: ; (must start on a 256-byte boundary) ! 2246: ; ECX with bits sets as described for ulCopyControlFlags, above ! 2247: ; ESI = DIB pointer to first two pixels (possibly masked off) ! 2248: ; EDI = VGA pointer to planar byte ! 2249: ; plane 3 must be mapped in for writes ! 2250: ;-----------------------------------------------------------------------; ! 2251: ! 2252: test ecx,LEADING_PARTIAL ;handle a leading partial byte? ! 2253: jz short DIB4_to_VGA_plane3_copy_lbyte ;no, go straight to whole ! 2254: ; byte ! 2255: ;yes, handle leading partial byte ! 2256: mov edx,[esi] ;get 8 pixels to convert of DIB dword 0 ! 2257: and edx,88888888h ;keep only the plane 3 bits of DIB ! 2258: ; dword 0 ! 2259: ; EDX = 6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xxx ! 2260: mov eax,edx ;put bits 7-4 of DIB dword 0 in AX, ! 2261: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 2262: ; DX = 2xxx3xxx0xxx1xxx ! 2263: ; AX = xx6xxx7xxx4xxx5x ! 2264: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 2265: ; 2x6x3x7x0x4x1x5x ! 2266: mov bl,al ;BL = 0x4x1x5x of DIB dword 0 ! 2267: rol ah,7 ;make AH x2x6x3x7 of DIB dword 0 (shr 1) ! 2268: or bl,ah ;BL = 02461357 of DIB dword 0 ! 2269: add esi,4 ;point to next DIB dword ! 2270: inc edi ;point to next VGA byte (placed here ! 2271: ; for 486 pipelining reasons) ! 2272: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 2273: mov ch,[edi-1] ;get the VGA destination byte ! 2274: and ecx,ulLeftMask ;mask off source and dest ! 2275: or cl,ch ;combine masked source and dest ! 2276: mov [edi-1],cl ;write the new pixels to the VGA ! 2277: ! 2278: ;-----------------------------------------------------------------------; ! 2279: ; Code to convert 8 DIB4 pixels to a single VGA plane 3 byte (8 pixels ! 2280: ; in plane 3). Assumes the DIB4 pixels start in the upper nibble of ! 2281: ; [ESI], and that the first DIB4 pixel maps to bit 7 of the VGA at ! 2282: ; [EDI]. ! 2283: ; ! 2284: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 2285: ; (must start on a 256-byte boundary) ! 2286: ; ECX with bits sets as described for ulCopyControlFlags, above ! 2287: ; ESI = DIB pointer to first two pixels ! 2288: ; EDI = VGA pointer to planar byte ! 2289: ; plane 3 must be mapped in for writes ! 2290: ;-----------------------------------------------------------------------; ! 2291: ! 2292: DIB4_to_VGA_plane3_copy_lbyte: ! 2293: test ecx,LEADING_BYTE ;should we handle a leading byte? ! 2294: jz short DIB4_to_VGA_plane3_copy_words ;no, go straight to words ! 2295: ;yes, handle leading byte ! 2296: mov edx,[esi] ;get 8 pixels to convert of DIB dword 0 ! 2297: and edx,88888888h ;keep only the plane 3 bits of DIB ! 2298: ; dword 0 ! 2299: ; EDX = 6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xxx ! 2300: mov eax,edx ;put bits 7-4 of DIB dword 0 in AX, ! 2301: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 2302: ; DX = 2xxx3xxx0xxx1xxx ! 2303: ; AX = xx6xxx7xxx4xxx5x ! 2304: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 2305: ; 2x6x3x7x0x4x1x5x ! 2306: mov bl,al ;BL = 0x4x1x5x of DIB dword 0 ! 2307: rol ah,7 ;make AH x2x6x3x7 of DIB dword 0 (shr 1) ! 2308: or bl,ah ;BL = 02461357 of DIB dword 0 ! 2309: add esi,4 ;point to next DIB dword ! 2310: inc edi ;point to next VGA byte (placed here ! 2311: ; for 486 pipelining reasons) ! 2312: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 2313: mov [edi-1],cl ;write 8 bits from DIB dword to VGA ! 2314: ! 2315: ;-----------------------------------------------------------------------; ! 2316: ; Code for converting sets of 32 DIB4 pixels to 4 VGA plane 3 bytes (32 ! 2317: ; pixels in plane 3). Assumes the VGA destination is word aligned. ! 2318: ; Assumes the DIB4 pixels start in the upper nibble of [ESI], and that ! 2319: ; the first DIB4 pixel maps to bit 7 of the VGA at [EDI]. ! 2320: ; ! 2321: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 2322: ; (must start on a 256-byte boundary) ! 2323: ; ECX with bits sets as described for ulCopyControlFlags, above ! 2324: ; ESI = DIB pointer to first two pixels ! 2325: ; EDI = VGA pointer to two planar bytes (must be word aligned) ! 2326: ; EBP = # of VGA dwords to convert ! 2327: ; ulWholeDwordCount = # of VGA dwords to convert ! 2328: ; plane 3 must be mapped in for writes ! 2329: ; ! 2330: ; Note: on entry at DIB4_to_VGA_plane3_word_odd, ESI must point to the ! 2331: ; desired source start minus 8, and EAX must be loaded as if the following ! 2332: ; instructions had been performed: ! 2333: ; mov edx,[esi+8] ! 2334: ; and edx,88888888h ! 2335: ; mov eax,edx ! 2336: ; shr eax,16+2 ! 2337: ; or eax,edx ! 2338: ; ! 2339: ; Note: ROL AH,7 is used instead of SHR AH,1 because the shift-by-1 ! 2340: ; form is 1 cycle slower on a 486, and in this case the two forms are ! 2341: ; functionally identical. ! 2342: ; ! 2343: ; Note: the code is so odd because of 486 pipeline optimization. ! 2344: ; DO NOT CHANGE THIS CODE UNLESS YOU KNOW EXACTLY WHAT YOU'RE DOING!!! ! 2345: ; ! 2346: ; Note: all 486 pipeline penalties are eliminated except for writing CX ! 2347: ; to memory (2 cycles), so far as I know. ! 2348: ;-----------------------------------------------------------------------; ! 2349: ! 2350: DIB4_to_VGA_plane3_copy_words: ! 2351: test ecx,ODD_WHOLE_WORD or WHOLE_WORDS ;any whole words to copy? ! 2352: jz DIB4_to_VGA_plane3_copy_tbyte ;no, check for trailing whole ! 2353: ; bytes ! 2354: ;yes, copy the whole words ! 2355: push ebp ;preserve stack frame pointer ! 2356: mov ebp,ulWholeDwordCount ;# of VGA dwords to copy to ! 2357: ;even # of DIB dwords to copy? (flags still ! 2358: ; set from TEST) ! 2359: .errnz ODD_WHOLE_WORD - 80000000h ! 2360: jns short DIB4_to_VGA_plane3_word_loop ;yes, start copying ! 2361: ;no, there's an odd word; prepare to enter loop ! 2362: ; in middle ! 2363: mov edx,[esi] ;get 8 pixels to convert of first DIB dword ! 2364: and edx,88888888h ;keep only the plane 3 bits of DIB dword ! 2365: ; EDX = 6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xxx ! 2366: mov eax,edx ;put bits 7-4 of DIB dword in AX, ! 2367: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 2368: ; DX = 2xxx3xxx0xxx1xxx ! 2369: ; AX = xx6xxx7xxx4xxx5x ! 2370: or eax,edx ;put bits 7-0 of DIB dword in AX: ! 2371: ; 2x6x3x7x0x4x1x5x ! 2372: sub esi,8 ;compensate source back for entering in middle ! 2373: sub edi,2 ;compensate dest back for entering in middle ! 2374: ! 2375: jmp short DIB4_to_VGA_plane3_word_odd ! 2376: ! 2377: ;-----------------------------------------------------------------------; ! 2378: ; Loop to copy a word at a time to VGA plane 3 (actually, unrolled once ! 2379: ; so copies dwords). ! 2380: ;-----------------------------------------------------------------------; ! 2381: ! 2382: align 16 ! 2383: DIB4_to_VGA_plane3_word_loop: ! 2384: mov edx,[esi] ;get 8 pixels to convert of DIB dword 0 ! 2385: and edx,88888888h ;keep only the plane 3 bits of DIB ! 2386: ; dword 0 ! 2387: ; EDX = 6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xxx ! 2388: mov eax,edx ;put bits 7-4 of DIB dword 0 in AX, ! 2389: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 2390: ; DX = 2xxx3xxx0xxx1xxx ! 2391: ; AX = xx6xxx7xxx4xxx5x ! 2392: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 2393: ; 2x6x3x7x0x4x1x5x ! 2394: mov edx,[esi+4] ;get 8 pixels to convert of DIB dword 1 ! 2395: mov bl,al ;BL = 0x4x1x5x of DIB dword 0 ! 2396: rol ah,7 ;make AH x2x6x3x7 of DIB dword 0 (shr 1) ! 2397: or bl,ah ;BL = 02461357 of DIB dword 0 ! 2398: and edx,88888888h ;keep only the plane 3 bits of DIB ! 2399: ; dword 1 ! 2400: ; EDX = 6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xxx ! 2401: mov eax,edx ;put bits 7-4 of DIB dword 1 in AX, ! 2402: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 2403: ; DX = 2xxx3xxx0xxx1xxx ! 2404: ; AX = xx6xxx7xxx4xxx5x ! 2405: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 2406: or eax,edx ;put bits 7-0 of DIB dword 1 in AX: ! 2407: ; 2x6x3x7x0x4x1x5x ! 2408: mov bl,al ;BL = 0x4x1x5x of DIB dword 1 ! 2409: mov edx,[esi+8] ;get 8 pixels to convert of DIB dword 2 ! 2410: rol ah,7 ;make AH x2x6x3x7 of DIB dword 1 (shr 1) ! 2411: or bl,ah ;BL = 02461357 of DIB dword 1 ! 2412: and edx,88888888h ;keep only the plane 3 bits of DIB ! 2413: ; dword 2 ! 2414: ; EDX = 6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xxx ! 2415: mov eax,edx ;put bits 7-4 of DIB dword 2 in AX, ! 2416: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 2417: ; DX = 2xxx3xxx0xxx1xxx ! 2418: ; AX = xx6xxx7xxx4xxx5x ! 2419: mov ch,[ebx] ;CH = 76543210 of DIB dword 1 ! 2420: or eax,edx ;put bits 7-0 of DIB dword 2 in AX: ! 2421: ; 2x6x3x7x0x4x1x5x ! 2422: mov [edi],cx ;write 16 bits from DIB dwords 0 and 1 ! 2423: ; to VGA ! 2424: DIB4_to_VGA_plane3_word_odd: ! 2425: mov edx,[esi+12] ;get 8 pixels to convert of DIB dword 3 ! 2426: mov bl,al ;BL = 0x4x1x5x of DIB dword 2 ! 2427: rol ah,7 ;make AH x2x6x3x7 of DIB dword 2 (shr 1) ! 2428: or bl,ah ;BL = 02461357 of DIB dword 2 ! 2429: and edx,88888888h ;keep only the plane 3 bits of DIB ! 2430: ; dword 3 ! 2431: ; EDX = 6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xxx ! 2432: mov eax,edx ;put bits 7-4 of DIB dword 3 in AX, ! 2433: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 2434: ; DX = 2xxx3xxx0xxx1xxx ! 2435: ; AX = xx6xxx7xxx4xxx5x ! 2436: mov cl,[ebx] ;CL = 76543210 of DIB dword 2 ! 2437: or eax,edx ;put bits 7-0 of DIB dword 3 in AX: ! 2438: ; 2x6x3x7x0x4x1x5x ! 2439: mov bl,al ;BL = 0x4x1x5x of DIB dword 3 ! 2440: rol ah,7 ;make AH x2x6x3x7 of DIB dword 3 (shr 1) ! 2441: or bl,ah ;BL = 02461357 of DIB dword 3 ! 2442: add esi,16 ;point to next set of 4 DIB dwords ! 2443: add edi,4 ;point to next VGA dword ! 2444: mov ch,[ebx] ;CH = 76543210 of dword 0 ! 2445: dec ebp ;count down VGA dwords ! 2446: mov [edi-2],cx ;write 16 bits from DIB dwords 2 and 3 ! 2447: ; to VGA ! 2448: jnz DIB4_to_VGA_plane3_word_loop ;do next VGA dword, if any ! 2449: ! 2450: pop ebp ;restore stack frame pointer ! 2451: ! 2452: ;-----------------------------------------------------------------------; ! 2453: ; Code to convert 8 DIB4 pixels to a single VGA plane 3 byte (8 pixels ! 2454: ; in plane 3). Assumes the DIB4 pixels start in the upper nibble of ! 2455: ; [ESI], and that the first DIB4 pixel maps to bit 7 of the VGA at ! 2456: ; [EDI]. ! 2457: ; ! 2458: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 2459: ; (must start on a 256-byte boundary) ! 2460: ; ECX with bits sets as described for ulCopyControlFlags, above ! 2461: ; ESI = DIB pointer to first two pixels ! 2462: ; EDI = VGA pointer to planar byte ! 2463: ; plane 3 must be mapped in for writes ! 2464: ; ! 2465: ;-----------------------------------------------------------------------; ! 2466: ! 2467: DIB4_to_VGA_plane3_copy_tbyte: ! 2468: test ecx,TRAILING_BYTE ;should we handle a trailing byte? ! 2469: jz short DIB4_to_VGA_plane3_copy_tpart ;no, check for trailing ! 2470: ; partial ! 2471: ;yes, handle trailing byte ! 2472: mov edx,[esi] ;get 8 pixels to convert of DIB dword 0 ! 2473: and edx,88888888h ;keep only the plane 3 bits of DIB ! 2474: ; dword 0 ! 2475: ; EDX = 6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xxx ! 2476: mov eax,edx ;put bits 7-4 of DIB dword 0 in AX, ! 2477: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 2478: ; DX = 2xxx3xxx0xxx1xxx ! 2479: ; AX = xx6xxx7xxx4xxx5x ! 2480: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 2481: ; 2x6x3x7x0x4x1x5x ! 2482: mov bl,al ;BL = 0x4x1x5x of DIB dword 0 ! 2483: rol ah,7 ;make AH x2x6x3x7 of DIB dword 0 (shr 1) ! 2484: or bl,ah ;BL = 02461357 of DIB dword 0 ! 2485: add esi,4 ;point to next DIB dword ! 2486: inc edi ;point to next VGA byte (placed here ! 2487: ; for 486 pipelining reasons) ! 2488: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 2489: mov [edi-1],cl ;write 8 bits from DIB dword to VGA ! 2490: ! 2491: ;-----------------------------------------------------------------------; ! 2492: ; Code to convert 1-7 DIB4 pixels to a partial VGA plane 3 byte (8 ! 2493: ; pixels in plane 3). Assumes that a full dword of DIB4 pixels (8 ! 2494: ; pixels) is available, starting at ESI, although some of the pixels ! 2495: ; will be masked off. Assumes the DIB4 pixels (including masked-off ! 2496: ; pixels) start in the upper nibble of [ESI], and that the first ! 2497: ; (possibly masked-off) DIB4 pixel maps to bit 7 of the VGA at [EDI]. ! 2498: ; ! 2499: ; Input: EBX = pointer to multiplexed DIB byte->planar byte conversion table ! 2500: ; (must start on a 256-byte boundary) ! 2501: ; ECX with bits sets as described for ulCopyControlFlags, above ! 2502: ; ESI = DIB pointer to first two pixels (possibly masked off) ! 2503: ; EDI = VGA pointer to planar byte ! 2504: ; plane 3 must be mapped in for writes ! 2505: ;-----------------------------------------------------------------------; ! 2506: ! 2507: DIB4_to_VGA_plane3_copy_tpart: ! 2508: test ecx,TRAILING_PARTIAL ;handle a trailing partial byte? ! 2509: jz short DIB4_to_VGA_plane3_copy_done ;no, done ! 2510: ;yes, handle trailing partial byte ! 2511: mov edx,[esi] ;get 8 pixels to convert of DIB dword 0 ! 2512: and edx,88888888h ;keep only the plane 3 bits of DIB ! 2513: ; dword 0 ! 2514: ; EDX = 6xxx7xxx4xxx5xxx2xxx3xxx0xxx1xxx ! 2515: mov eax,edx ;put bits 7-4 of DIB dword 0 in AX, ! 2516: shr eax,16+2 ; shifted right 2 (x = zero bit) ! 2517: ; DX = 2xxx3xxx0xxx1xxx ! 2518: ; AX = xx6xxx7xxx4xxx5x ! 2519: or eax,edx ;put bits 7-0 of DIB dword 0 in AX: ! 2520: ; 2x6x3x7x0x4x1x5x ! 2521: mov bl,al ;BL = 0x4x1x5x of DIB dword 0 ! 2522: rol ah,7 ;make AH x2x6x3x7 of DIB dword 0 (shr 1) ! 2523: or bl,ah ;BL = 02461357 of DIB dword 0 ! 2524: add esi,4 ;point to next DIB dword ! 2525: inc edi ;point to next VGA byte (placed here ! 2526: ; for 486 pipelining reasons) ! 2527: mov cl,[ebx] ;CL = 76543210 of DIB dword 0 ! 2528: mov ch,[edi-1] ;get the VGA destination byte ! 2529: and ecx,ulRightMask ;mask off source and dest ! 2530: or cl,ch ;combine masked source and dest ! 2531: mov [edi-1],cl ;write the new pixels to the VGA ! 2532: ! 2533: DIB4_to_VGA_plane3_copy_done: ! 2534: add esi,ulSrcDelta ;point to start of next DIB scan ! 2535: add edi,ulDstDelta ;point to start of next VGA scan ! 2536: dec ulPlane3Scans ;count down scans in this plane ! 2537: jnz DIB4_to_VGA_plane3_copy_loop ;do next scan in this plane, if any ! 2538: ! 2539: jmp copy_burst_plane3_done ;return to the top of the plane-copy ! 2540: ; loop ! 2541: ! 2542: endProc vDIB2VGA ! 2543: ! 2544: public jLeftMasks ! 2545: public jRightMasks ! 2546: public one_partial_only ! 2547: public check_whole_bytes ! 2548: public set_copy_control_flags ! 2549: public set_shift_vec ! 2550: public set_initial_banking ! 2551: public map_init_bank ! 2552: public init_bank_mapped ! 2553: public bank_loop ! 2554: public copy_burst_loop ! 2555: public align_burst_rshift_386 ! 2556: public align_burst_lshift_386 ! 2557: public align_burst_rshift_486 ! 2558: public align_burst_lshift_486 ! 2559: public set_alignment_source ! 2560: public proceed_with_copy ! 2561: public copy_burst_plane0_done ! 2562: public copy_burst_plane1_done ! 2563: public copy_burst_plane2_done ! 2564: public copy_burst_plane3_done ! 2565: public next_bank ! 2566: public DIB4_to_VGA_plane0_copy ! 2567: public DIB4_to_VGA_plane0_copy_loop ! 2568: public DIB4_to_VGA_plane0_copy_lbyte ! 2569: public DIB4_to_VGA_plane0_copy_words ! 2570: public DIB4_to_VGA_plane0_word_loop ! 2571: public DIB4_to_VGA_plane0_word_odd ! 2572: public DIB4_to_VGA_plane0_copy_tbyte ! 2573: public DIB4_to_VGA_plane0_copy_tpart ! 2574: public DIB4_to_VGA_plane0_copy_done ! 2575: public DIB4_to_VGA_plane1_copy ! 2576: public DIB4_to_VGA_plane1_copy_loop ! 2577: public DIB4_to_VGA_plane1_copy_lbyte ! 2578: public DIB4_to_VGA_plane1_copy_words ! 2579: public DIB4_to_VGA_plane1_word_loop ! 2580: public DIB4_to_VGA_plane1_word_odd ! 2581: public DIB4_to_VGA_plane1_copy_tbyte ! 2582: public DIB4_to_VGA_plane1_copy_tpart ! 2583: public DIB4_to_VGA_plane1_copy_done ! 2584: public DIB4_to_VGA_plane2_copy ! 2585: public DIB4_to_VGA_plane2_copy_loop ! 2586: public DIB4_to_VGA_plane2_copy_lbyte ! 2587: public DIB4_to_VGA_plane2_copy_words ! 2588: public DIB4_to_VGA_plane2_word_loop ! 2589: public DIB4_to_VGA_plane2_word_odd ! 2590: public DIB4_to_VGA_plane2_copy_tbyte ! 2591: public DIB4_to_VGA_plane2_copy_tpart ! 2592: public DIB4_to_VGA_plane2_copy_done ! 2593: public DIB4_to_VGA_plane3_copy ! 2594: public DIB4_to_VGA_plane3_copy_loop ! 2595: public DIB4_to_VGA_plane3_copy_lbyte ! 2596: public DIB4_to_VGA_plane3_copy_words ! 2597: public DIB4_to_VGA_plane3_word_loop ! 2598: public DIB4_to_VGA_plane3_word_odd ! 2599: public DIB4_to_VGA_plane3_copy_tbyte ! 2600: public DIB4_to_VGA_plane3_copy_tpart ! 2601: public DIB4_to_VGA_plane3_copy_done ! 2602: ! 2603: _TEXT$01 ends ! 2604: ! 2605: end ! 2606:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.