|
|
1.1 ! root 1: ;---------------------------Module-Header------------------------------; ! 2: ; Module Name: monopat.asm ! 3: ; ! 4: ; Copyright (c) 1992-1993 Microsoft Corporation. All rights reserved. ! 5: ;-----------------------------------------------------------------------; ! 6: ! 7: ;-----------------------------------------------------------------------; ! 8: ; VOID vMonoPat(ppdev, culRcl, prcl, ulMix, prb, pptlBrush) ! 9: ; ! 10: ; Input: ! 11: ; ! 12: ; ppdev - surface on which to draw ! 13: ; culRcl - number of rectangles ! 14: ; prcl - pointer to rectangles ! 15: ; ulMix - mix mode (i.e., ROP) ! 16: ; prb - pointer to realized brush ! 17: ; pptlBrush - brush alignment ! 18: ; ! 19: ; Draws two color patterns using the VGA hardware. If the ROP is a ! 20: ; PATCOPY ROP, we can light 8 pixels on every word write to VGA memory. ! 21: ; ! 22: ; We special case black & white patterns because we can do slightly less ! 23: ; initialization, and we can handle arbitrary ROPs (although if the ROP ! 24: ; has to read video memory, we can only do 4 pixels on every read/write ! 25: ; operation). ! 26: ; ! 27: ;-----------------------------------------------------------------------; ! 28: ; ! 29: ; NOTE: Assumes all rectangles have positive heights and widths. Will ! 30: ; not work properly if this is not the case. ! 31: ; ! 32: ;-----------------------------------------------------------------------; ! 33: ! 34: ;-----------------------------------------------------------------------; ! 35: ; Set LOOP_UNROLL_SHIFT to the log2 of the number of times you want loops in ! 36: ; this module unrolled. For example, LOOP_UNROLL_SHIFT of 3 yields 2**3 = 8 ! 37: ; times unrolling. This is the only thing you need to change to control ! 38: ; unrolling. ! 39: ! 40: LOOP_UNROLL_SHIFT equ 2 ! 41: ! 42: ;-----------------------------------------------------------------------; ! 43: ! 44: .386 ! 45: ! 46: .model small,c ! 47: ! 48: assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT ! 49: assume fs:nothing,gs:nothing ! 50: ! 51: .xlist ! 52: include stdcall.inc ;calling convention cmacros ! 53: include i386\strucs.inc ! 54: include i386\driver.inc ! 55: include i386\unroll.inc ! 56: include i386\egavga.inc ! 57: include i386\ropdefs.inc ! 58: ! 59: .list ! 60: ! 61: ;-----------------------------------------------------------------------; ! 62: ! 63: .data ! 64: ! 65: ; vTrgBlt is used for 2-pass ROPs: ! 66: ! 67: EXTRNP vTrgBlt,24 ! 68: ! 69: ; Tables shared with vgablts.asm: ! 70: ! 71: extrn jALUFuncTable: byte ! 72: extrn jInvertDest: byte ! 73: ! 74: ;-----------------------------------------------------------------------; ! 75: ; Bits for drawing routine look-ups. ! 76: ! 77: BLOCK_LEFT_EDGE equ 010000b ! 78: BLOCK_RIGHT_EDGE equ 001000b ! 79: BLOCK_MIDDLE_STARTS_UNALIGNED equ 000100b ! 80: BLOCK_NO_MIDDLE equ 000010b ! 81: BLOCK_MIDDLE_ENDS_UNALIGNED equ 000001b ! 82: ! 83: ;-----------------------------------------------------------------------; ! 84: ; Table of drawing routines, with the look-up index a 5 bit field as ! 85: ; follows: ! 86: ; ! 87: ; Bit 4 = 1 if a left edge must be drawn ! 88: ; Bit 3 = 1 if a right edge must be drawn ! 89: ; Bit 2 = 1 if middle block starts unaligned word-wise ! 90: ; Bit 1 = 1 if no middle block ! 91: ; Bit 0 = 1 if middle block is an odd number of bytes in length ! 92: ! 93: align 4 ! 94: gapfnSetTable label dword ! 95: dd dual_wide_00_w ;00000 ! 96: dd dual_wide_01_w ;00001 ! 97: dd 0 ;00010 ! 98: dd 0 ;00011 ! 99: dd dual_wide_11_w ;00100 ! 100: dd dual_wide_10_w ;00101 ! 101: dd 0 ;00110 ! 102: dd 0 ;00111 ! 103: dd Block_01000_w ;01000 ! 104: dd Block_01001_w ;01001 ! 105: dd dual_right_0_w ;01010 ! 106: dd dual_right_1_w ;01011 ! 107: dd Block_01100_w ;01100 ! 108: dd Block_01101_w ;01101 ! 109: dd dual_right_1_w ;01110 ! 110: dd dual_right_0_w ;01111 ! 111: dd Block_10000_w ;10000 ! 112: dd Block_10001_w ;10001 ! 113: dd dual_left_0_w ;10010 ! 114: dd dual_left_0_w ;10011 ! 115: dd Block_10100_w ;10100 ! 116: dd Block_10101_w ;10101 ! 117: dd dual_left_1_w ;10110 ! 118: dd dual_left_1_w ;10111 ! 119: dd Block_11000_w ;11000 ! 120: dd Block_11001_w ;11001 ! 121: dd Block_11010_w ;11010 ! 122: dd 0 ;11011 - can never happen ! 123: dd Block_11100_w ;11100 ! 124: dd Block_11101_w ;11101 ! 125: dd Block_11110_w ;11110 ! 126: dd 0 ;11111 - can never happen ! 127: ! 128: gapfnROPTable label dword ! 129: dd dual_wide_00_rw ;00000 ! 130: dd dual_wide_01_rw ;00001 ! 131: dd 0 ;00010 ! 132: dd 0 ;00011 ! 133: dd dual_wide_11_rw ;00100 ! 134: dd dual_wide_10_rw ;00101 ! 135: dd 0 ;00110 ! 136: dd 0 ;00111 ! 137: dd Block_01000_rw ;01000 ! 138: dd Block_01001_rw ;01001 ! 139: dd dual_right_0_rw ;01010 ! 140: dd dual_right_1_rw ;01011 ! 141: dd Block_01100_rw ;01100 ! 142: dd Block_01101_rw ;01101 ! 143: dd dual_right_1_rw ;01110 ! 144: dd dual_right_0_rw ;01111 ! 145: dd Block_10000_rw ;10000 ! 146: dd Block_10001_rw ;10001 ! 147: dd dual_left_0_rw ;10010 ! 148: dd dual_left_0_rw ;10011 ! 149: dd Block_10100_rw ;10100 ! 150: dd Block_10101_rw ;10101 ! 151: dd dual_left_1_rw ;10110 ! 152: dd dual_left_1_rw ;10111 ! 153: dd Block_11000_rw ;11000 ! 154: dd Block_11001_rw ;11001 ! 155: dd Block_11010_rw ;11010 ! 156: dd 0 ;11011 - can never happen ! 157: dd Block_11100_rw ;11100 ! 158: dd Block_11101_rw ;11101 ! 159: dd Block_11110_rw ;11110 ! 160: dd 0 ;11111 - can never happen ! 161: ! 162: gaulForceOffTable label dword ! 163: dd 0 ;ignored - there is no mix 0 ! 164: dd 0 ! 165: dd 0ffffffffh ! 166: dd 0ffffffffh ! 167: dd 0ffffffffh ! 168: dd 0ffffffffh ! 169: dd 0ffffffffh ! 170: dd 0ffffffffh ! 171: dd 0ffffffffh ! 172: dd 0ffffffffh ! 173: dd 0ffffffffh ! 174: dd 0 ! 175: dd 0ffffffffh ! 176: dd 0ffffffffh ! 177: dd 0ffffffffh ! 178: dd 0ffffffffh ! 179: dd 0ffffffffh ! 180: ! 181: gaulForceOnTable label dword ! 182: dd 0 ;ignored - there is no mix 0 ! 183: dd 0 ! 184: dd 0 ! 185: dd 0 ! 186: dd 0 ! 187: dd 0 ! 188: dd 0ffffffffh ! 189: dd 0 ! 190: dd 0 ! 191: dd 0 ! 192: dd 0 ! 193: dd 0 ! 194: dd 0 ! 195: dd 0 ! 196: dd 0 ! 197: dd 0 ! 198: dd 0ffffffffh ! 199: ! 200: gaulForceNotTable label dword ! 201: dd 0 ;ignored - there is no mix 0 ! 202: dd 0 ! 203: dd 0ffffffffh ! 204: dd 0ffffffffh ! 205: dd 0ffffffffh ! 206: dd 0 ! 207: dd 0 ! 208: dd 0 ! 209: dd 0ffffffffh ! 210: dd 0 ! 211: dd 0ffffffffh ! 212: dd 0 ! 213: dd 0ffffffffh ! 214: dd 0 ! 215: dd 0 ! 216: dd 0 ! 217: dd 0 ! 218: ! 219: ;-----------------------------------------------------------------------; ! 220: ! 221: .code ! 222: ;-----------------------------------------------------------------------; ! 223: ; Write thunks (for set ROPs) ! 224: ;-----------------------------------------------------------------------; ! 225: ! 226: align 4 ! 227: Block_01000_w: ! 228: push offset dual_right_0_w ! 229: jmp dual_wide_00_w ! 230: ! 231: align 4 ! 232: Block_01001_w: ! 233: push offset dual_right_1_w ! 234: jmp dual_wide_01_w ! 235: ! 236: align 4 ! 237: Block_01100_w: ! 238: push offset dual_right_1_w ! 239: jmp dual_wide_11_w ! 240: ! 241: align 4 ! 242: Block_01101_w: ! 243: push offset dual_right_0_w ! 244: jmp dual_wide_10_w ! 245: ! 246: align 4 ! 247: Block_11000_w: ! 248: push offset dual_right_0_w ! 249: Block_10000_w: ! 250: push offset dual_left_0_w ! 251: jmp dual_wide_00_w ! 252: ! 253: align 4 ! 254: Block_11001_w: ! 255: push offset dual_right_1_w ! 256: Block_10001_w: ! 257: push offset dual_left_0_w ! 258: jmp dual_wide_01_w ! 259: ! 260: align 4 ! 261: Block_11100_w: ! 262: push offset dual_right_1_w ! 263: Block_10100_w: ! 264: push offset dual_left_1_w ! 265: jmp dual_wide_11_w ! 266: ! 267: align 4 ! 268: Block_11101_w: ! 269: push offset dual_right_0_w ! 270: Block_10101_w: ! 271: push offset dual_left_1_w ! 272: jmp dual_wide_10_w ! 273: ! 274: align 4 ! 275: Block_11010_w: ! 276: push offset dual_right_0_w ! 277: jmp dual_left_0_w ! 278: ! 279: align 4 ! 280: Block_11110_w: ! 281: push offset dual_right_1_w ! 282: jmp dual_left_1_w ! 283: ! 284: ;-----------------------------------------------------------------------; ! 285: ; Read/write thunks (for arbitrary ROPs) ! 286: ;-----------------------------------------------------------------------; ! 287: ! 288: Block_01000_rw: ! 289: push offset dual_right_0_rw ! 290: jmp dual_wide_00_rw ! 291: ! 292: Block_01001_rw: ! 293: push offset dual_right_1_rw ! 294: jmp dual_wide_01_rw ! 295: ! 296: Block_01100_rw: ! 297: push offset dual_right_1_rw ! 298: jmp dual_wide_11_rw ! 299: ! 300: Block_01101_rw: ! 301: push offset dual_right_0_rw ! 302: jmp dual_wide_10_rw ! 303: ! 304: Block_11000_rw: ! 305: push offset dual_right_0_rw ! 306: Block_10000_rw: ! 307: push offset dual_left_0_rw ! 308: jmp dual_wide_00_rw ! 309: ! 310: Block_11001_rw: ! 311: push offset dual_right_1_rw ! 312: Block_10001_rw: ! 313: push offset dual_left_0_rw ! 314: jmp dual_wide_01_rw ! 315: ! 316: Block_11100_rw: ! 317: push offset dual_right_1_rw ! 318: Block_10100_rw: ! 319: push offset dual_left_1_rw ! 320: jmp dual_wide_11_rw ! 321: ! 322: Block_11101_rw: ! 323: push offset dual_right_0_rw ! 324: Block_10101_rw: ! 325: push offset dual_left_1_rw ! 326: jmp dual_wide_10_rw ! 327: ! 328: Block_11010_rw: ! 329: push offset dual_right_0_rw ! 330: jmp dual_left_0_rw ! 331: ! 332: Block_11110_rw: ! 333: push offset dual_right_1_rw ! 334: jmp dual_left_1_rw ! 335: ! 336: ;-----------------------------------------------------------------------; ! 337: ! 338: cProc vMonoPat,24,< \ ! 339: uses esi edi ebx, \ ! 340: ppdev: ptr PDEV, \ ! 341: culRcl: dword, \ ! 342: prcl: ptr RECTL, \ ! 343: ulMix: dword, \ ! 344: prb: ptr RBRUSH,\ ! 345: pptlBrush: ptr POINTL > ! 346: ! 347: ; Variables used in block drawers: ! 348: ! 349: local ppfnDraw: ptr ;pointer to array of draw routines ! 350: local pfnDraw: ptr ;pointer to draw routines ! 351: ! 352: local yBrush: dword ;current y brush alignment ! 353: local yBrushOrg: dword ;original y brush alignment ! 354: local ulMiddleDest: dword ;bitmap offset to middle ! 355: local lMiddleDelta: dword ;delta from end of middle scan to next ! 356: local ulBlockHeight: dword ;# of scans to be drawn in block ! 357: local cwMiddle: dword ;# of words to be written in middle ! 358: ! 359: local ulLeftDest: dword ;bitmap offset to left edge ! 360: local ulLeftMask: dword ;plane mask for left-edge drawing ! 361: local ulRightDest: dword ;bitmap offset to right edge ! 362: local ulRightMask: dword ;plane mask for right-edge drawing ! 363: local lDelta: dword ;delta between scans ! 364: ! 365: local ulCurrentDestScan: dword ;current destination scan ! 366: local ulLastDestScan: dword ;last destination scan ! 367: ! 368: local ulSaveEsp: dword ;for when we really need a register ! 369: local pulPattern: ptr ;pointer to working pattern buffer ! 370: ; (to account for brush inversions) ! 371: local aulPatternBuffer[8]: dword ;pattern buffer ! 372: ! 373: local cUnrolledLoops: dword ;number of unrolled loops to do ! 374: local pfnUnroll: ptr ;points to start point in unroll table ! 375: ! 376: mov esi,pptlBrush ! 377: mov edi,prb ! 378: mov ecx,[esi].ptl_y ! 379: mov yBrushOrg,ecx ;yBrushOrg = pptlBrush->y ! 380: mov ecx,[esi].ptl_x ! 381: mov eax,[edi].rb_xBrush ! 382: and ecx,7 ! 383: cmp eax,ecx ! 384: jne dual_align_brush ;only align if we really have to ! 385: ! 386: dual_done_align_brush: ! 387: test [edi].rb_fl,RBRUSH_2COLOR ! 388: jnz col2_colors ! 389: ! 390: ; Set VGA to read mode 1 and write mode 2: ! 391: ! 392: mov esi,ppdev ! 393: mov edx,VGA_BASE + GRAF_ADDR ! 394: mov ah,byte ptr [esi].pdev_ulrm0_wmX[2] ! 395: or ah,M_COLOR_READ ! 396: mov al,GRAF_MODE ! 397: out dx,ax ;write mode 2 to expand pattern bits to ! 398: ; 0 or 0ffh per plane, read mode 1 so ! 399: ; we can read 0xFF from memory always, ! 400: ; for ANDing (because Color Don't Care ! 401: ; is all zeros) ! 402: ! 403: ;-----------------------------------------------------------------------; ! 404: ; Handle only black/white patterns. ! 405: ;-----------------------------------------------------------------------; ! 406: ! 407: lea eax,[edi].rb_aulPattern ! 408: mov pulPattern,eax ;pulPattern = &pbr.rb_aulPattern[0] ! 409: lea eax,gapfnSetTable ! 410: mov ppfnDraw,eax ;ppfnDraw = gapfnSetTable ! 411: ! 412: mov ecx,ulMix ! 413: and ecx,0fh ! 414: cmp ecx,R2_COPYPEN ! 415: jne bw_init_rop ;do some more work if not copy ROP ! 416: ! 417: bw_done_init_rop: ! 418: ! 419: call dual_draw_rectangles ;draw those puppies ! 420: ! 421: ; All done! Restore read mode 0, write mode 0: ! 422: ! 423: mov esi,ppdev ! 424: mov edx,VGA_BASE + GRAF_ADDR ! 425: mov ah,byte ptr [esi].pdev_ulrm0_wmX[0] ! 426: mov al,GRAF_MODE ! 427: out dx,ax ! 428: ! 429: ; Enable all planes: ! 430: ! 431: mov edx,VGA_BASE + SEQ_DATA ! 432: mov al,MM_ALL ! 433: out dx,al ! 434: ! 435: cmp ulMix,R2_COPYPEN ! 436: jne short bw_enable_set_mode ! 437: cRet vMonoPat ! 438: ! 439: ; Set ALU function to Set mode (we don't have to bother if we had a ! 440: ; COPYPEN ROP): ! 441: ! 442: bw_enable_set_mode: ! 443: mov eax,GRAF_DATA_ROT + (DR_SET shl 8) ! 444: mov edx,VGA_BASE + GRAF_ADDR ! 445: out dx,ax ! 446: cRet vMonoPat ! 447: ! 448: ;-----------------------------------------------------------------------; ! 449: ; Draw both black and white and 2 color rectangles. ! 450: ;-----------------------------------------------------------------------; ! 451: ! 452: align 4 ! 453: public dual_draw_rectangles ! 454: dual_draw_rectangles: ! 455: ! 456: mov edi,prcl ;edi = prcl ! 457: mov edx,ppdev ! 458: mov eax,[edi].yBottom ! 459: mov ebx,[edi].yTop ! 460: mov edx,[edx].pdev_lPlanarNextScan ! 461: ! 462: mov lDelta,edx ;lDelta = ppdev->lPlanarNextScan ! 463: mov ulLastDestScan,eax ;ulLastDestScan = prcl->bottom ! 464: mov ulCurrentDestScan,ebx ;ulCurrentDestScan = prcl->top ! 465: ! 466: mov ecx,edx ! 467: imul ecx,ebx ! 468: ! 469: sub ebx,yBrushOrg ! 470: and ebx,7 ! 471: mov yBrush,ebx ;yBrush = (prcl->top - pptlBrush->y) & 7 ! 472: ; (our current index into the pattern ! 473: ; array) ! 474: ! 475: mov ebx,[edi].xLeft ! 476: shr ebx,2 ! 477: add ebx,ecx ;ebx = prcl->top * lDelta + ! 478: ; (prcl->left >> 2) ! 479: ; (offset into bitmap of left side) ! 480: ! 481: mov eax,[edi].xRight ! 482: shr eax,2 ! 483: add eax,ecx ! 484: mov ulRightDest,eax ;ulRightDest = prcl->top * lDelta + ! 485: ; (prcl->right >> 2) ! 486: ; (offset into bitmap of right side) ! 487: ! 488: xor esi,esi ;zero our flags ! 489: ! 490: mov ecx,[edi].xLeft ! 491: and ecx,3 ! 492: jz short dual_done_left ;skip if we don't need a left edge ! 493: ! 494: mov esi,0fh ;compute the plane mask for the left ! 495: shl esi,cl ; edge. we don't use a look-up table ! 496: mov ulLeftMask,esi ; 'cause it won't be in the cache. ! 497: ! 498: mov esi,(BLOCK_LEFT_EDGE shr 2) ! 499: ;set our flag (we soon shift left by 2) ! 500: ! 501: mov ulLeftDest,ebx ;ulLeftDest = prcl->top * lDelta + ! 502: ; (prcl->left >> 2) ! 503: inc ebx ;ebx = ulMiddleDest = ulLeftDest + 1 ! 504: ; (we have to adjust our offset to ! 505: ; the first whole byte) ! 506: ! 507: dual_done_left: ! 508: sub eax,ebx ;eax = cjMiddle = ! 509: ; ulRightDest - ulMiddleDest ! 510: mov ulMiddleDest,ebx ;ulMiddleDest ! 511: ! 512: .errnz (BLOCK_MIDDLE_STARTS_UNALIGNED shr 2) - 1 ! 513: and ebx,1 ;set bit if middle doesn't start ! 514: or esi,ebx ; word aligned (remembering we'll ! 515: ; soon shift flags left by 2) ! 516: ! 517: mov ecx,[edi].xRight ! 518: and ecx,3 ! 519: jz short dual_done_right ;skip if we don't need a right edge ! 520: ! 521: mov ebx,0f0h ;compute the plane mask for the right ! 522: rol bl,cl ; edge. we don't use a look-up table ! 523: mov ulRightMask,ebx ; 'cause it won't be in the cache. ! 524: ! 525: or esi,(BLOCK_RIGHT_EDGE shr 2) ! 526: ;set our flag (we soon shift left by 2) ! 527: ! 528: ; If the count of whole bytes is negative, that means that the pattern ! 529: ; starts and ends in the same quadpixel, so we do some more work: ! 530: ! 531: cmp eax,0 ! 532: jge short dual_done_right ! 533: ! 534: ; It starts and ends in the same quadpixel: ! 535: ! 536: and esi,not (BLOCK_RIGHT_EDGE shr 2) ! 537: ;turn off right edge ! 538: and ebx,ulLeftMask ! 539: mov ulLeftMask,ebx ! 540: xor eax,eax ;we do zero middle bytes ! 541: ! 542: align 4 ! 543: public dual_done_right ! 544: dual_done_right: ! 545: mov ebx,ppfnDraw ! 546: ! 547: ; We're going to do two 'adc esi,esi' instructions here, effectively ! 548: ; shifting our flags left by 2, and setting the low bits: ! 549: ! 550: .errnz (BLOCK_NO_MIDDLE shr 1) - 1 ! 551: cmp eax,1 ;shift flags left one, and set low ! 552: adc esi,esi ; bit if we don't need to do a middle ! 553: ! 554: .errnz (BLOCK_MIDDLE_ENDS_UNALIGNED) - 1 ! 555: shr eax,1 ! 556: adc esi,esi ;shift flags left one, and set low ! 557: ; bit if the middle isn't an even ! 558: ; number of bytes in length ! 559: mov cwMiddle,eax ;cwMiddle = cjMiddle / 2 ! 560: ! 561: sub edx,eax ! 562: sub edx,eax ! 563: mov lMiddleDelta,edx ;lMiddleDelta = lDelta - 2 * cwMiddle ! 564: ! 565: mov eax,[ebx+esi*4] ! 566: mov pfnDraw,eax ;pointer to function that draws ! 567: ; everything in the bank ! 568: ! 569: mov ebx,ppdev ! 570: mov edi,[edi].yTop ! 571: ! 572: cmp edi,[ebx].pdev_rcl1PlanarClip.yTop ! 573: jl short dual_map_init_bank ! 574: ! 575: cmp edi,[ebx].pdev_rcl1PlanarClip.yBottom ! 576: jl short dual_init_bank_mapped ! 577: ! 578: dual_map_init_bank: ! 579: ptrCall <dword ptr [ebx].pdev_pfnPlanarControl>, \ ! 580: <ebx,edi,JustifyTop> ! 581: ! 582: dual_init_bank_mapped: ! 583: mov eax,ulLastDestScan ! 584: mov ebx,[ebx].pdev_rcl1PlanarClip.yBottom ! 585: ! 586: sub eax,ebx ! 587: sbb ecx,ecx ! 588: and ecx,eax ! 589: add ebx,ecx ;ebx = min(ulLastDestScan, ! 590: ; ppdev->rcl1PlanarClip.yBottom) ! 591: mov ulCurrentDestScan,ebx ! 592: ! 593: sub ebx,edi ! 594: mov ulBlockHeight,ebx ;ulBlockHeight = ebx - ulCurrentDestScan ! 595: ! 596: ; Draw everything in this bank: ! 597: ! 598: call pfnDraw ! 599: ! 600: dual_done_pfnDraw: ! 601: mov edi,ulCurrentDestScan ! 602: cmp edi,ulLastDestScan ! 603: jge short dual_next_rectangle ! 604: ! 605: ; Get the next bank: ! 606: ! 607: mov ebx,ppdev ! 608: mov yBrush,esi ;make sure we record the new brush ! 609: ; alignment ! 610: ! 611: ; Map the next bank into window. ! 612: ; Note: EBX, ESI, and EDI are preserved, according to C calling conventions. ! 613: ! 614: ptrCall <dword ptr [ebx].pdev_pfnPlanarControl>, \ ! 615: <ebx,edi,JustifyTop> ! 616: ! 617: jmp short dual_init_bank_mapped ! 618: ! 619: ;-----------------------------------------------------------------------; ! 620: ; Done rectangle. ! 621: ;-----------------------------------------------------------------------; ! 622: ! 623: align 4 ! 624: public dual_next_rectangle ! 625: dual_next_rectangle: ! 626: add prcl, size RECTL ! 627: dec culRcl ! 628: jg dual_draw_rectangles ;do more rectangles ! 629: ! 630: PLAIN_RET ;return ! 631: ! 632: ;-----------------------------------------------------------------------; ! 633: ; Handle x-brush alignment. ! 634: ;-----------------------------------------------------------------------; ! 635: ! 636: align 4 ! 637: public dual_align_brush ! 638: dual_align_brush: ! 639: ! 640: ; Align the pattern on x. Remember it in the realized brush, because if ! 641: ; the brush is used again, it's likely to have the same alignment... ! 642: ! 643: mov [edi].rb_xBrush,ecx ;remember our new alignment ! 644: sub ecx,eax ;rotate pattern left by ! 645: ; pptlBrush->x - prb->xBrush ! 646: ! 647: ; We keep each row of the pattern in the low word of each dword. If the ! 648: ; bits are to appear on the screen as 01234567, the word of our pattern ! 649: ; has the bits 32107654|76543210 -- we're in write mode 3, and when ! 650: ; written as a word, this results in 3210 being written in the first ! 651: ; byte, and 7654 in the second byte. ! 652: ; ! 653: ; For brush alignment, we would want to rotate 01234567 right by 'cl'. ! 654: ; For our funky plaanr format, we just rotate each byte of the word left by ! 655: ; 'cl' to get the desired result. ! 656: ! 657: rol byte ptr [edi][0].rb_aulPattern,cl ;0 ! 658: rol byte ptr [edi][1].rb_aulPattern,cl ! 659: rol byte ptr [edi][4].rb_aulPattern,cl ;1 ! 660: rol byte ptr [edi][5].rb_aulPattern,cl ! 661: rol byte ptr [edi][8].rb_aulPattern,cl ;2 ! 662: rol byte ptr [edi][9].rb_aulPattern,cl ! 663: rol byte ptr [edi][12].rb_aulPattern,cl ;3 ! 664: rol byte ptr [edi][13].rb_aulPattern,cl ! 665: rol byte ptr [edi][16].rb_aulPattern,cl ;4 ! 666: rol byte ptr [edi][17].rb_aulPattern,cl ! 667: rol byte ptr [edi][20].rb_aulPattern,cl ;5 ! 668: rol byte ptr [edi][21].rb_aulPattern,cl ! 669: rol byte ptr [edi][24].rb_aulPattern,cl ;6 ! 670: rol byte ptr [edi][25].rb_aulPattern,cl ! 671: rol byte ptr [edi][28].rb_aulPattern,cl ;7 ! 672: rol byte ptr [edi][29].rb_aulPattern,cl ! 673: ! 674: jmp dual_done_align_brush ! 675: ! 676: ;-----------------------------------------------------------------------; ! 677: ; Handle arbitrary ROPs for black/white patterns. ! 678: ;-----------------------------------------------------------------------; ! 679: ! 680: ; Expect: ! 681: ; ! 682: ; ecx = ulMix ! 683: ! 684: align 4 ! 685: public bw_init_rop ! 686: bw_init_rop: ! 687: cmp jInvertDest[ecx],0 ! 688: je short bw_set_that_ALU ;skip if don't need 2 passes ! 689: ! 690: ; For some ROPs, we have to invert the destination first, then do another ! 691: ; operation (that is, it's a 2-pass ROP). We handle the inversion here: ! 692: ! 693: cCall vTrgBlt,<ppdev, culRcl, prcl, R2_NOT, 0, 0> ! 694: mov ecx,ulMix ! 695: ! 696: bw_set_that_ALU: ! 697: mov ah,jALUFuncTable[ecx] ! 698: cmp ah,DR_SET ! 699: je short bw_that_ALU_is_set ! 700: ;we're already in Set mode ! 701: ! 702: mov edx,VGA_BASE + GRAF_ADDR ! 703: mov al,GRAF_DATA_ROT ! 704: out dx,ax ;set the ALU logical function ! 705: lea ebx,gapfnROPTable ! 706: mov ppfnDraw,ebx ! 707: ! 708: bw_that_ALU_is_set: ! 709: lea esi,aulPatternBuffer ! 710: mov pulPattern,esi ;we're using the temporary buffer ! 711: ! 712: mov ebx,gaulForceOffTable[ecx*4] ! 713: mov edx,gaulForceOnTable[ecx*4] ! 714: mov esi,gaulForceNotTable[ecx*4] ! 715: ! 716: mov eax,[edi][0].rb_aulPattern ;0 ! 717: and eax,ebx ! 718: or eax,edx ! 719: xor eax,esi ! 720: mov [aulPatternBuffer][0],eax ! 721: mov eax,[edi][4].rb_aulPattern ;1 ! 722: and eax,ebx ! 723: or eax,edx ! 724: xor eax,esi ! 725: mov [aulPatternBuffer][4],eax ! 726: mov eax,[edi][8].rb_aulPattern ;2 ! 727: and eax,ebx ! 728: or eax,edx ! 729: xor eax,esi ! 730: mov [aulPatternBuffer][8],eax ! 731: mov eax,[edi][12].rb_aulPattern ;3 ! 732: and eax,ebx ! 733: or eax,edx ! 734: xor eax,esi ! 735: mov [aulPatternBuffer][12],eax ! 736: mov eax,[edi][16].rb_aulPattern ;4 ! 737: and eax,ebx ! 738: or eax,edx ! 739: xor eax,esi ! 740: mov [aulPatternBuffer][16],eax ! 741: mov eax,[edi][20].rb_aulPattern ;5 ! 742: and eax,ebx ! 743: or eax,edx ! 744: xor eax,esi ! 745: mov [aulPatternBuffer][20],eax ! 746: mov eax,[edi][24].rb_aulPattern ;6 ! 747: and eax,ebx ! 748: or eax,edx ! 749: xor eax,esi ! 750: mov [aulPatternBuffer][24],eax ! 751: mov eax,[edi][28].rb_aulPattern ;7 ! 752: and eax,ebx ! 753: or eax,edx ! 754: xor eax,esi ! 755: mov [aulPatternBuffer][28],eax ! 756: ! 757: jmp bw_done_init_rop ! 758: ! 759: ;-----------------------------------------------------------------------; ! 760: ; Handle 2-color patterns. ! 761: ;-----------------------------------------------------------------------; ! 762: ! 763: align 4 ! 764: public col2_colors ! 765: col2_colors: ! 766: lea eax,[edi].rb_aulPattern ! 767: mov pulPattern,eax ;pulPattern = &pbr.rb_aulPattern[0] ! 768: lea eax,gapfnSetTable ! 769: mov ppfnDraw,eax ;ppfnDraw = gapfnSetTable ! 770: ! 771: call col2_first_rectangle ! 772: ! 773: ; Restore VGA hardware to its default state: ! 774: ! 775: mov edx,VGA_BASE + GRAF_DATA ! 776: mov al,0ffh ! 777: out dx,al ;enable all bits through the Bit Mask ! 778: ! 779: mov esi,ppdev ! 780: dec edx ;point back to the Graphics Index reg ! 781: mov ah,byte ptr [esi].pdev_ulrm0_wmX[0] ! 782: ;write mode 0 setting for Graphics Mode ! 783: mov al,GRAF_MODE ! 784: out dx,ax ;write mode 0, read mode 0 ! 785: ! 786: mov eax,GRAF_DATA_ROT + (DR_SET SHL 8) ! 787: out dx,ax ;replace mode, no rotate ! 788: ! 789: mov edx,VGA_BASE + SEQ_DATA ! 790: mov al,MM_ALL ! 791: out dx,al ;enable all planes ! 792: ! 793: cRet vMonoPat ! 794: ! 795: ;-----------------------------------------------------------------------; ! 796: ; Handle first rectangle for 2-color patterns. ! 797: ;-----------------------------------------------------------------------; ! 798: ! 799: ; We have to special case the first rectangle because we have to load ! 800: ; the latches with the background color after mapping the bank but before ! 801: ; doing any drawing. ! 802: ! 803: align 4 ! 804: public col2_first_rectangle ! 805: col2_first_rectangle: ! 806: mov edi,prcl ;edi = prcl ! 807: mov edx,ppdev ! 808: mov eax,[edi].yBottom ! 809: mov ebx,[edi].yTop ! 810: mov edx,[edx].pdev_lPlanarNextScan ! 811: ! 812: mov lDelta,edx ;lDelta = ppdev->lPlanarNextScan ! 813: mov ulLastDestScan,eax ;ulLastDestScan = prcl->bottom ! 814: mov ulCurrentDestScan,ebx ;ulCurrentDestScan = prcl->top ! 815: ! 816: mov ecx,edx ! 817: imul ecx,ebx ! 818: ! 819: sub ebx,yBrushOrg ! 820: and ebx,7 ! 821: mov yBrush,ebx ;yBrush = (prcl->top - pptlBrush->y) & 7 ! 822: ; (our current index into the pattern ! 823: ; array) ! 824: ! 825: mov ebx,[edi].xLeft ! 826: shr ebx,2 ! 827: add ebx,ecx ;ebx = prcl->top * lDelta + ! 828: ; (prcl->left >> 2) ! 829: ; (offset into bitmap of left side) ! 830: ! 831: mov eax,[edi].xRight ! 832: shr eax,2 ! 833: add eax,ecx ! 834: mov ulRightDest,eax ;ulRightDest = prcl->top * lDelta + ! 835: ; (prcl->right >> 2) ! 836: ; (offset into bitmap of right side) ! 837: ! 838: xor esi,esi ;zero our flags ! 839: ! 840: mov ecx,[edi].xLeft ! 841: and ecx,3 ! 842: jz short col2_done_left ;skip if we don't need a left edge ! 843: ! 844: mov esi,0fh ;compute the plane mask for the left ! 845: shl esi,cl ; edge. we don't use a look-up table ! 846: mov ulLeftMask,esi ; 'cause it won't be in the cache. ! 847: ! 848: mov esi,(BLOCK_LEFT_EDGE shr 2) ! 849: ;set our flag (we soon shift left by 2) ! 850: ! 851: mov ulLeftDest,ebx ;ulLeftDest = prcl->top * lDelta + ! 852: ; (prcl->left >> 2) ! 853: inc ebx ;ebx = ulMiddleDest = ulLeftDest + 1 ! 854: ; (we have to adjust our offset to ! 855: ; the first whole byte) ! 856: ! 857: col2_done_left: ! 858: sub eax,ebx ;eax = cjMiddle = ! 859: ; ulRightDest - ulMiddleDest ! 860: mov ulMiddleDest,ebx ;ulMiddleDest ! 861: ! 862: .errnz (BLOCK_MIDDLE_STARTS_UNALIGNED shr 2) - 1 ! 863: and ebx,1 ;set bit if middle doesn't start ! 864: or esi,ebx ; word aligned (remembering we'll ! 865: ; soon shift flags left by 2) ! 866: ! 867: mov ecx,[edi].xRight ! 868: and ecx,3 ! 869: jz short col2_done_right ;skip if we don't need a right edge ! 870: ! 871: mov ebx,0f0h ;compute the plane mask for the right ! 872: rol bl,cl ; edge. we don't use a look-up table ! 873: mov ulRightMask,ebx ; 'cause it won't be in the cache. ! 874: ! 875: or esi,(BLOCK_RIGHT_EDGE shr 2) ! 876: ;set our flag (we soon shift left by 2) ! 877: ! 878: ; If the count of whole bytes is negative, that means that the pattern ! 879: ; starts and ends in the same quadpixel, so we do some more work: ! 880: ! 881: cmp eax,0 ! 882: jge short col2_done_right ! 883: ! 884: ; It starts and ends in the same quadpixel: ! 885: ! 886: and esi,not (BLOCK_RIGHT_EDGE shr 2) ! 887: ;turn off right edge ! 888: and ebx,ulLeftMask ! 889: mov ulLeftMask,ebx ! 890: xor eax,eax ;we do zero middle bytes ! 891: ! 892: align 4 ! 893: public col2_done_right ! 894: col2_done_right: ! 895: mov ebx,ppfnDraw ! 896: ! 897: ; We're going to do two 'adc esi,esi' instructions here, effectively ! 898: ; shifting our flags left by 2, and setting the low bits: ! 899: ! 900: .errnz (BLOCK_NO_MIDDLE shr 1) - 1 ! 901: cmp eax,1 ;shift flags left one, and set low ! 902: adc esi,esi ; bit if we don't need to do a middle ! 903: ! 904: .errnz (BLOCK_MIDDLE_ENDS_UNALIGNED) - 1 ! 905: shr eax,1 ! 906: mov cwMiddle,eax ;cwMiddle = cjMiddle / 2 ! 907: adc esi,esi ;shift flags left one, and set low ! 908: ; bit if the middle isn't an even ! 909: ; number of bytes in length ! 910: ! 911: sub edx,eax ! 912: sub edx,eax ! 913: mov lMiddleDelta,edx ;lMiddleDelta = lDelta - 2 * cwMiddle ! 914: ! 915: mov eax,[ebx+esi*4] ! 916: mov pfnDraw,eax ;pointer to function that draws ! 917: ; everything in the bank ! 918: ! 919: mov ebx,ppdev ! 920: test esi,BLOCK_NO_MIDDLE ! 921: jz short col2_have_a_middle ! 922: ! 923: ;-----------------------------------------; ! 924: ! 925: ; Handle case where there isn't a whole quadpixel that will be overwritten ! 926: ; by the pattern, and so we don't have a convenient place for loading the ! 927: ; latches. For this case, we'll use off-screen memory. ! 928: ! 929: mov esi,[ebx].pdev_pbceCache ! 930: mov eax,[esi].bce_yCache ! 931: ! 932: cmp eax,[ebx].pdev_rcl1PlanarClip.yTop ! 933: jl short col2_no_middle_map_brush_bank ! 934: ! 935: cmp eax,[ebx].pdev_rcl1PlanarClip.yBottom ! 936: jl short col2_no_middle_brush_bank_mapped ! 937: ! 938: col2_no_middle_map_brush_bank: ! 939: ptrCall <dword ptr [ebx].pdev_pfnPlanarControl>, \ ! 940: <ebx,eax,JustifyBottom> ! 941: ! 942: col2_no_middle_brush_bank_mapped: ! 943: mov ecx,prb ;ecx = prb ! 944: mov esi,[esi].bce_ulCache ! 945: add esi,[ebx].pdev_pvBitmapStart ! 946: ! 947: mov eax,[ecx].rb_ulBkColor ! 948: mov [esi],al ! 949: mov al,[esi] ;latches now laoded with bk color ! 950: ! 951: mov edi,[edi].yTop ! 952: ! 953: cmp edi,[ebx].pdev_rcl1PlanarClip.yTop ! 954: jl short col2_no_middle_map_init_bank ! 955: ! 956: cmp edi,[ebx].pdev_rcl1PlanarClip.yBottom ! 957: jl col2_latches_loaded ! 958: ! 959: col2_no_middle_map_init_bank: ! 960: ptrCall <dword ptr [ebx].pdev_pfnPlanarControl>, \ ! 961: <ebx,edi,JustifyTop> ! 962: ! 963: mov ecx,prb ;reload ecx = prb ! 964: jmp col2_latches_loaded ! 965: ! 966: ;-----------------------------------------; ! 967: ! 968: col2_have_a_middle: ! 969: mov edi,[edi].yTop ! 970: ! 971: cmp edi,[ebx].pdev_rcl1PlanarClip.yTop ! 972: jl short col2_map_init_bank ! 973: ! 974: cmp edi,[ebx].pdev_rcl1PlanarClip.yBottom ! 975: jl short col2_init_bank_mapped ! 976: ! 977: col2_map_init_bank: ! 978: ptrCall <dword ptr [ebx].pdev_pfnPlanarControl>, \ ! 979: <ebx,edi,JustifyTop> ! 980: ! 981: col2_init_bank_mapped: ! 982: mov ecx,prb ;ecx = prb ! 983: mov esi,ulMiddleDest ! 984: add esi,[ebx].pdev_pvBitmapStart ! 985: ;pointer to the first whole quadpixel ! 986: ; that will be overwritten by the ! 987: ; pattern, and so which is a great ! 988: ; place to use to load the latches ! 989: ! 990: mov eax,[ecx].rb_ulBkColor ! 991: mov [esi],al ! 992: mov al,[esi] ;latches now loaded with bk color ! 993: ! 994: ; Set VGA to read mode 0 and write mode 2: ! 995: ! 996: col2_latches_loaded: ! 997: ! 998: ; ebx = ppdev ! 999: ; ecx = prb ! 1000: ; edi = top line of rectangle ! 1001: ! 1002: mov esi,ppdev ! 1003: mov edx,VGA_BASE + GRAF_ADDR ! 1004: mov ah,byte ptr [esi].pdev_ulrm0_wmX[2] ! 1005: mov al,GRAF_MODE ! 1006: out dx,ax ! 1007: ! 1008: mov eax,GRAF_DATA_ROT + (DR_XOR SHL 8) ! 1009: out dx,ax ;XOR to flip latched data to make ~bk ! 1010: ! 1011: mov ah,byte ptr [ecx].rb_ulBkColor ! 1012: xor ah,byte ptr [ecx].rb_ulFgColor ! 1013: mov al,GRAF_BIT_MASK ! 1014: out dx,ax ;pass through common fg & bk bits ! 1015: ; unchanged from bk color in latches; ! 1016: ; non-common bits come from XOR in the ! 1017: ; ALUs, flipped from the bk to the fg ! 1018: ; state if the glyph bit for the pixel ! 1019: ; in that plane is 1, still in bk state ! 1020: ; if the glyph bit for that plane is 0 ! 1021: ! 1022: ; All done hardware initialization. Do rest of this boring stuff: ! 1023: ! 1024: mov eax,ulLastDestScan ! 1025: mov ebx,[ebx].pdev_rcl1PlanarClip.yBottom ! 1026: ! 1027: sub eax,ebx ! 1028: sbb ecx,ecx ! 1029: and ecx,eax ! 1030: add ebx,ecx ;ebx = min(ulLastDestScan, ! 1031: ; ppdev->rcl1PlanarClip.yBottom) ! 1032: mov ulCurrentDestScan,ebx ! 1033: ! 1034: sub ebx,edi ! 1035: mov ulBlockHeight,ebx ;ulBlockHeight = ebx - ulCurrentDestScan ! 1036: ! 1037: ; Draw everything in this bank: ! 1038: ! 1039: CALL_AND_JUMP pfnDraw,dual_done_pfnDraw ! 1040: ! 1041: ;=======================================================================; ! 1042: ;========================= Set Block Drawers ===========================; ! 1043: ;=======================================================================; ! 1044: ! 1045: ;-----------------------------------------------------------------------; ! 1046: ; dual_wide_11_w ! 1047: ; ! 1048: ; Draws middle words with 1 leading byte and 1 trailing byte. ! 1049: ; ! 1050: ; Input: ! 1051: ; ppdev - pointer to physical device structure ! 1052: ; ulBlockHeight - # of scans to draw ! 1053: ; lMiddleDelta - distance from end of current scan to start of next ! 1054: ; ulMiddleDest - offset in bitmap at which to start drawing ! 1055: ; yBrush - current y brush alignment ! 1056: ; cwMiddle - # of words to draw on each scan ! 1057: ; ! 1058: ; Output: ! 1059: ; esi - new y brush alignment ! 1060: ; ulMiddleDest - new bitmap offset ! 1061: ;-----------------------------------------------------------------------; ! 1062: ! 1063: align 4 ! 1064: public dual_wide_11_w ! 1065: dual_wide_11_w: ! 1066: ! 1067: ; We only have to reset which planes are enabled if we do edges too: ! 1068: ! 1069: mov edx,VGA_BASE + SEQ_DATA ! 1070: mov al,MM_ALL ! 1071: out dx,al ! 1072: ! 1073: ; Calculate full start addresses: ! 1074: ! 1075: mov ulSaveEsp,esp ! 1076: mov edi,ppdev ! 1077: mov ebx,ulBlockHeight ! 1078: mov esp,pulPattern ! 1079: mov edx,lMiddleDelta ! 1080: add edx,2 ;account for first and last ! 1081: ; bytes ! 1082: mov esi,yBrush ! 1083: mov edi,[edi].pdev_pvBitmapStart ! 1084: add edi,ulMiddleDest ! 1085: inc edi ;align to word ! 1086: ! 1087: SET_UP_UNROLL_AND_BRANCH ebx,ecx,pfnMonoWide11,LOOP_UNROLL_SHIFT ! 1088: ! 1089: UNROLL_LOOP_ENTRY_TABLE pfnMonoWide11,W11,LOOP_UNROLL_COUNT ! 1090: ! 1091: MONO_WIDE_11_W_M macro ENTRY_LABEL,ENTRY_INDEX ! 1092: &ENTRY_LABEL&ENTRY_INDEX&: ! 1093: ! 1094: ; We aim to overdrive. ! 1095: ! 1096: mov eax,[esp+esi * 4] ;load pattern for this scan ! 1097: mov [edi-1],ah ;write the first byte ! 1098: ! 1099: mov ecx,cwMiddle ! 1100: dec ecx ;account for first and last ! 1101: ; bytes ! 1102: rep stosw ;light 8 pels on every write ! 1103: ! 1104: inc esi ;advance to next scan of pattern ! 1105: and esi,7 ! 1106: mov [edi],al ;write that last byte ! 1107: ! 1108: add edi,edx ;advance to next scan ! 1109: endm ;-----------------------------------; ! 1110: ! 1111: ; EBX = count of unrolled loop iterations ! 1112: ; EDX = offset from end of scan to start of next ! 1113: ; ESI = current offset into pattern ! 1114: ; EDI = target address to which to write ! 1115: ; ESP = pointer to start of pattern ! 1116: ! 1117: align 4 ! 1118: dual_wide_11_w_loop: ! 1119: UNROLL_LOOP MONO_WIDE_11_W_M,W11,LOOP_UNROLL_COUNT ! 1120: dec ebx ! 1121: jnz short dual_wide_11_w_loop ! 1122: ! 1123: ; get ready for next time: ! 1124: ! 1125: mov ecx,ppdev ! 1126: mov esp,ulSaveEsp ! 1127: sub edi,[ecx].pdev_pvBitmapStart ! 1128: dec edi ;undo our word alignment ! 1129: mov ulMiddleDest,edi ! 1130: ! 1131: PLAIN_RET ! 1132: ! 1133: ;-----------------------------------------------------------------------; ! 1134: ; dual_wide_10_w ! 1135: ; ! 1136: ; Draws middle words with 1 leading byte and 0 trailing bytes. ! 1137: ; ! 1138: ; Input: ! 1139: ; ppdev - pointer to physical device structure ! 1140: ; ulBlockHeight - # of scans to draw ! 1141: ; lMiddleDelta - distance from end of current scan to start of next ! 1142: ; ulMiddleDest - offset in bitmap at which to start drawing ! 1143: ; yBrush - current y brush alignment ! 1144: ; cwMiddle - # of words to draw on each scan ! 1145: ; ! 1146: ; Output: ! 1147: ; esi - new y brush alignment ! 1148: ; ulMiddleDest - new bitmap offset ! 1149: ;-----------------------------------------------------------------------; ! 1150: ! 1151: align 4 ! 1152: public dual_wide_10_w ! 1153: dual_wide_10_w: ! 1154: ! 1155: ; We only have to reset which planes are enabled if we do edges too: ! 1156: ! 1157: mov edx,VGA_BASE + SEQ_DATA ! 1158: mov al,MM_ALL ! 1159: out dx,al ! 1160: ! 1161: ; Calculate full start addresses: ! 1162: ! 1163: mov ulSaveEsp,esp ! 1164: mov edi,ppdev ! 1165: mov ebx,ulBlockHeight ! 1166: mov esp,pulPattern ! 1167: mov edx,lMiddleDelta ! 1168: mov esi,yBrush ! 1169: mov edi,[edi].pdev_pvBitmapStart ! 1170: add edi,ulMiddleDest ! 1171: inc edi ;align to word ! 1172: ! 1173: SET_UP_UNROLL_AND_BRANCH ebx,ecx,pfnMonoWide10,LOOP_UNROLL_SHIFT ! 1174: ! 1175: UNROLL_LOOP_ENTRY_TABLE pfnMonoWide10,W10,LOOP_UNROLL_COUNT ! 1176: ! 1177: MONO_WIDE_10_W_M macro ENTRY_LABEL,ENTRY_INDEX ! 1178: &ENTRY_LABEL&ENTRY_INDEX&: ! 1179: ! 1180: mov eax,[esp+esi * 4] ;load pattern for this scan ! 1181: mov [edi-1],ah ;write the first byte ! 1182: ! 1183: mov ecx,cwMiddle ! 1184: rep stosw ;light 8 pels on every write ! 1185: ! 1186: inc esi ;advance to next scan of pattern ! 1187: and esi,7 ! 1188: ! 1189: add edi,edx ;advance to next scan ! 1190: endm ;-----------------------------------; ! 1191: ! 1192: ; EBX = count of unrolled loop iterations ! 1193: ; EDX = offset from end of scan to start of next ! 1194: ; ESI = current offset into pattern ! 1195: ; EDI = target address to which to write ! 1196: ; ESP = pointer to start of pattern ! 1197: ! 1198: align 4 ! 1199: dual_wide_10_w_loop: ! 1200: UNROLL_LOOP MONO_WIDE_10_W_M,W10,LOOP_UNROLL_COUNT ! 1201: dec ebx ! 1202: jnz short dual_wide_10_w_loop ! 1203: ! 1204: ; get ready for next time: ! 1205: ! 1206: mov ecx,ppdev ! 1207: mov esp,ulSaveEsp ! 1208: sub edi,[ecx].pdev_pvBitmapStart ! 1209: dec edi ;undo our word alignment ! 1210: mov ulMiddleDest,edi ! 1211: ! 1212: PLAIN_RET ! 1213: ! 1214: ;-----------------------------------------------------------------------; ! 1215: ; dual_wide_01_w ! 1216: ; ! 1217: ; Draws middle words with 0 leading bytes and 1 trailing byte. ! 1218: ; ! 1219: ; Input: ! 1220: ; ppdev - pointer to physical device structure ! 1221: ; ulBlockHeight - # of scans to draw ! 1222: ; lMiddleDelta - distance from end of current scan to start of next ! 1223: ; ulMiddleDest - offset in bitmap at which to start drawing ! 1224: ; yBrush - current y brush alignment ! 1225: ; cwMiddle - # of words to draw on each scan ! 1226: ; ! 1227: ; Output: ! 1228: ; esi - new y brush alignment ! 1229: ; ulMiddleDest - new bitmap offset ! 1230: ;-----------------------------------------------------------------------; ! 1231: ! 1232: align 4 ! 1233: public dual_wide_01_w ! 1234: dual_wide_01_w: ! 1235: ! 1236: ; We only have to reset which planes are enabled if we do edges too: ! 1237: ! 1238: mov edx,VGA_BASE + SEQ_DATA ! 1239: mov al,MM_ALL ! 1240: out dx,al ! 1241: ! 1242: ; Calculate full start addresses: ! 1243: ! 1244: mov ulSaveEsp,esp ! 1245: mov edi,ppdev ! 1246: mov ebx,ulBlockHeight ! 1247: mov esp,pulPattern ! 1248: mov edx,lMiddleDelta ! 1249: mov esi,yBrush ! 1250: mov edi,[edi].pdev_pvBitmapStart ! 1251: add edi,ulMiddleDest ! 1252: ! 1253: SET_UP_UNROLL_AND_BRANCH ebx,ecx,pfnMonoWide01,LOOP_UNROLL_SHIFT ! 1254: ! 1255: UNROLL_LOOP_ENTRY_TABLE pfnMonoWide01,W01,LOOP_UNROLL_COUNT ! 1256: ! 1257: MONO_WIDE_01_W_M macro ENTRY_LABEL,ENTRY_INDEX ! 1258: &ENTRY_LABEL&ENTRY_INDEX&: ! 1259: ! 1260: mov eax,[esp+esi*4] ;load pattern for this scan ! 1261: ! 1262: mov ecx,cwMiddle ! 1263: rep stosw ;light 8 pels on every write ! 1264: ! 1265: inc esi ;advance to next scan of pattern ! 1266: and esi,7 ! 1267: mov [edi],al ;write that last byte ! 1268: ! 1269: add edi,edx ;advance to next scan ! 1270: endm ;-----------------------------------; ! 1271: ! 1272: ; EBX = count of unrolled loop iterations ! 1273: ; EDX = offset from end of scan to start of next ! 1274: ; ESI = current offset into pattern ! 1275: ; EDI = target address to which to write ! 1276: ; ESP = pointer to start of pattern ! 1277: ! 1278: align 4 ! 1279: dual_wide_01_w_loop: ! 1280: UNROLL_LOOP MONO_WIDE_01_W_M,W01,LOOP_UNROLL_COUNT ! 1281: dec ebx ! 1282: jnz short dual_wide_01_w_loop ! 1283: ! 1284: ; get ready for next time: ! 1285: ! 1286: mov ecx,ppdev ! 1287: mov esp,ulSaveEsp ! 1288: sub edi,[ecx].pdev_pvBitmapStart ! 1289: mov ulMiddleDest,edi ! 1290: ! 1291: PLAIN_RET ! 1292: ! 1293: ;-----------------------------------------------------------------------; ! 1294: ; dual_wide_00_w ! 1295: ; ! 1296: ; Draws middle words with 0 leading bytes and 1 trailing byte. ! 1297: ; ! 1298: ; Input: ! 1299: ; ppdev - pointer to physical device structure ! 1300: ; ulBlockHeight - # of scans to draw ! 1301: ; lMiddleDelta - distance from end of current scan to start of next ! 1302: ; ulMiddleDest - offset in bitmap at which to start drawing ! 1303: ; yBrush - current y brush alignment ! 1304: ; cwMiddle - # of words to draw on each scan ! 1305: ; ! 1306: ; Output: ! 1307: ; esi - new y brush alignment ! 1308: ; ulMiddleDest - new bitmap offset ! 1309: ;-----------------------------------------------------------------------; ! 1310: ! 1311: align 4 ! 1312: public dual_wide_00_w ! 1313: dual_wide_00_w: ! 1314: ! 1315: ; We only have to reset which planes are enabled if we do edges too: ! 1316: ! 1317: mov edx,VGA_BASE + SEQ_DATA ! 1318: mov al,MM_ALL ! 1319: out dx,al ! 1320: ! 1321: ; Calculate full start addresses: ! 1322: ! 1323: mov ulSaveEsp,esp ! 1324: mov edi,ppdev ! 1325: mov ebx,ulBlockHeight ! 1326: mov esp,pulPattern ! 1327: mov edx,lMiddleDelta ! 1328: mov esi,yBrush ! 1329: mov edi,[edi].pdev_pvBitmapStart ! 1330: add edi,ulMiddleDest ! 1331: ! 1332: SET_UP_UNROLL_AND_BRANCH ebx,ecx,pfnMonoWide00,LOOP_UNROLL_SHIFT ! 1333: ! 1334: UNROLL_LOOP_ENTRY_TABLE pfnMonoWide00,W00,LOOP_UNROLL_COUNT ! 1335: ! 1336: MONO_WIDE_00_W_M macro ENTRY_LABEL,ENTRY_INDEX ! 1337: &ENTRY_LABEL&ENTRY_INDEX&: ! 1338: ! 1339: mov eax,[esp+esi*4] ;load pattern for this scan ! 1340: ! 1341: mov ecx,cwMiddle ! 1342: rep stosw ;light 8 pels on every write ! 1343: ! 1344: inc esi ;advance to next scan of pattern ! 1345: and esi,7 ! 1346: ! 1347: add edi,edx ;advance to next scan ! 1348: endm ;-----------------------------------; ! 1349: ! 1350: ; EBX = count of unrolled loop iterations ! 1351: ; EDX = offset from end of scan to start of next ! 1352: ; ESI = current offset into pattern ! 1353: ; EDI = target address to which to write ! 1354: ; ESP = pointer to start of pattern ! 1355: ! 1356: align 4 ! 1357: dual_wide_00_w_loop: ! 1358: UNROLL_LOOP MONO_WIDE_00_W_M,W00,LOOP_UNROLL_COUNT ! 1359: dec ebx ! 1360: jnz short dual_wide_00_w_loop ! 1361: ! 1362: ; get ready for next time: ! 1363: ! 1364: mov ecx,ppdev ! 1365: mov esp,ulSaveEsp ! 1366: sub edi,[ecx].pdev_pvBitmapStart ! 1367: mov ulMiddleDest,edi ! 1368: ! 1369: PLAIN_RET ! 1370: ! 1371: ;-----------------------------------------------------------------------; ! 1372: ; dual_left_1_w ! 1373: ; ! 1374: ; Draws a left edge when the next byte is not word aligned. ! 1375: ; ! 1376: ; Input: ! 1377: ; ppdev - pointer to physical device structure ! 1378: ; ulBlockHeight - # of scans to draw ! 1379: ; lDelta - distance from end of current scan to start of next ! 1380: ; ulLeftDest - offset in bitmap at which to start drawing ! 1381: ; yBrush - current y brush alignment ! 1382: ; ! 1383: ; Output: ! 1384: ; esi - new y brush alignment ! 1385: ; ulLeftDest - new bitmap offset ! 1386: ;-----------------------------------------------------------------------; ! 1387: ! 1388: align 4 ! 1389: public dual_left_1_w ! 1390: dual_left_1_w: ! 1391: ! 1392: ; Set left mask by disabling some planes: ! 1393: ! 1394: mov edx,VGA_BASE + SEQ_DATA ! 1395: mov eax,ulLeftMask ! 1396: out dx,al ! 1397: ! 1398: ; Calculate full start addresses: ! 1399: ! 1400: mov edi,ppdev ! 1401: mov ebx,ulBlockHeight ! 1402: mov ecx,pulPattern ! 1403: mov edx,lDelta ! 1404: mov esi,yBrush ! 1405: mov edi,[edi].pdev_pvBitmapStart ! 1406: add edi,ulLeftDest ! 1407: ! 1408: SET_UP_UNROLL_AND_BRANCH ebx,eax,pfnMonoLeft1,LOOP_UNROLL_SHIFT ! 1409: ! 1410: UNROLL_LOOP_ENTRY_TABLE pfnMonoLeft1,LEFT_W1,LOOP_UNROLL_COUNT ! 1411: ! 1412: MONO_LEFT_1_W_M macro ENTRY_LABEL,ENTRY_INDEX ! 1413: &ENTRY_LABEL&ENTRY_INDEX&: ! 1414: ! 1415: mov eax,[ecx+esi*4] ;load pattern for this scan ! 1416: mov [edi],al ;write the low byte ! 1417: inc esi ;advance to next scan of pattern ! 1418: and esi,7 ! 1419: add edi,edx ;advance to next scan ! 1420: endm ;-----------------------------------; ! 1421: ! 1422: ; EBX = count of unrolled loop iterations ! 1423: ; ECX = pointer to start of pattern ! 1424: ; EDX = offset to next scan ! 1425: ; ESI = current offset into pattern ! 1426: ; EDI = target address to which to write ! 1427: ! 1428: align 4 ! 1429: dual_left_1_w_loop: ! 1430: UNROLL_LOOP MONO_LEFT_1_W_M,LEFT_W1,LOOP_UNROLL_COUNT ! 1431: dec ebx ! 1432: jnz short dual_left_1_w_loop ! 1433: ! 1434: ; get ready for next time: ! 1435: ! 1436: mov ecx,ppdev ! 1437: sub edi,[ecx].pdev_pvBitmapStart ! 1438: mov ulLeftDest,edi ! 1439: ! 1440: PLAIN_RET ! 1441: ! 1442: ;-----------------------------------------------------------------------; ! 1443: ; dual_left_0_w ! 1444: ; ! 1445: ; Draws a left edge when the next byte is word aligned. ! 1446: ; ! 1447: ; Input: ! 1448: ; ppdev - pointer to physical device structure ! 1449: ; ulBlockHeight - # of scans to draw ! 1450: ; lDelta - distance from end of current scan to start of next ! 1451: ; ulLeftDest - offset in bitmap at which to start drawing ! 1452: ; yBrush - current y brush alignment ! 1453: ; ! 1454: ; Output: ! 1455: ; esi - new y brush alignment ! 1456: ; ulLeftDest - new bitmap offset ! 1457: ;-----------------------------------------------------------------------; ! 1458: ! 1459: align 4 ! 1460: public dual_left_0_w ! 1461: dual_left_0_w: ! 1462: ! 1463: ; Set left mask by disabling some planes: ! 1464: ! 1465: mov edx,VGA_BASE + SEQ_DATA ! 1466: mov eax,ulLeftMask ! 1467: out dx,al ! 1468: ! 1469: ; Calculate full start addresses: ! 1470: ! 1471: mov edi,ppdev ! 1472: mov ebx,ulBlockHeight ! 1473: mov ecx,pulPattern ! 1474: mov edx,lDelta ! 1475: mov esi,yBrush ! 1476: mov edi,[edi].pdev_pvBitmapStart ! 1477: add edi,ulLeftDest ! 1478: ! 1479: SET_UP_UNROLL_AND_BRANCH ebx,eax,pfnMonoLeft0,LOOP_UNROLL_SHIFT ! 1480: ! 1481: UNROLL_LOOP_ENTRY_TABLE pfnMonoLeft0,LEFT_W0,LOOP_UNROLL_COUNT ! 1482: ! 1483: MONO_LEFT_0_W_M macro ENTRY_LABEL,ENTRY_INDEX ! 1484: &ENTRY_LABEL&ENTRY_INDEX&: ! 1485: ! 1486: mov eax,[ecx+esi*4] ;load pattern for this scan ! 1487: mov [edi],ah ;write the high byte ! 1488: inc esi ;advance to next scan of pattern ! 1489: and esi,7 ! 1490: add edi,edx ;advance to next scan ! 1491: endm ;-----------------------------------; ! 1492: ! 1493: ; EBX = count of unrolled loop iterations ! 1494: ; ECX = pointer to start of pattern ! 1495: ; EDX = offset to next scan ! 1496: ; ESI = current offset into pattern ! 1497: ; EDI = target address to which to write ! 1498: ! 1499: align 4 ! 1500: dual_left_0_w_loop: ! 1501: UNROLL_LOOP MONO_LEFT_0_W_M,LEFT_W0,LOOP_UNROLL_COUNT ! 1502: dec ebx ! 1503: jnz short dual_left_0_w_loop ! 1504: ! 1505: ; get ready for next time: ! 1506: ! 1507: mov ecx,ppdev ! 1508: sub edi,[ecx].pdev_pvBitmapStart ! 1509: mov ulLeftDest,edi ! 1510: ! 1511: PLAIN_RET ! 1512: ! 1513: ;-----------------------------------------------------------------------; ! 1514: ; dual_right_1_w ! 1515: ; ! 1516: ; Draws a right edge when not word aligned. ! 1517: ; ! 1518: ; Input: ! 1519: ; ppdev - pointer to physical device structure ! 1520: ; ulBlockHeight - # of scans to draw ! 1521: ; lDelta - distance from end of current scan to start of next ! 1522: ; ulRightDest - offset in bitmap at which to start drawing ! 1523: ; yBrush - current y brush alignment ! 1524: ; ! 1525: ; Output: ! 1526: ; esi - new y brush alignment ! 1527: ; ulRightDest - new bitmap offset ! 1528: ;-----------------------------------------------------------------------; ! 1529: ! 1530: align 4 ! 1531: public dual_right_1_w ! 1532: dual_right_1_w: ! 1533: ! 1534: ; Set right mask by disabling some planes: ! 1535: ! 1536: mov edx,VGA_BASE + SEQ_DATA ! 1537: mov eax,ulRightMask ! 1538: out dx,al ! 1539: ! 1540: ; Calculate full start addresses: ! 1541: ! 1542: mov edi,ppdev ! 1543: mov ebx,ulBlockHeight ! 1544: mov ecx,pulPattern ! 1545: mov edx,lDelta ! 1546: mov esi,yBrush ! 1547: mov edi,[edi].pdev_pvBitmapStart ! 1548: add edi,ulRightDest ! 1549: ! 1550: SET_UP_UNROLL_AND_BRANCH ebx,eax,pfnMonoRight1,LOOP_UNROLL_SHIFT ! 1551: ! 1552: UNROLL_LOOP_ENTRY_TABLE pfnMonoRight1,RIGHT_W1,LOOP_UNROLL_COUNT ! 1553: ! 1554: MONO_RIGHT_1_W_M macro ENTRY_LABEL,ENTRY_INDEX ! 1555: &ENTRY_LABEL&ENTRY_INDEX&: ! 1556: ! 1557: mov eax,[ecx+esi*4] ;load pattern for this scan ! 1558: mov [edi],ah ;write the high byte ! 1559: inc esi ;advance to next scan of pattern ! 1560: and esi,7 ! 1561: add edi,edx ;advance to next scan ! 1562: endm ;-----------------------------------; ! 1563: ! 1564: ; EBX = count of unrolled loop iterations ! 1565: ; ECX = pointer to start of pattern ! 1566: ; EDX = offset to next scan ! 1567: ; ESI = current offset into pattern ! 1568: ; EDI = target address to which to write ! 1569: ! 1570: align 4 ! 1571: dual_right_1_w_loop: ! 1572: UNROLL_LOOP MONO_RIGHT_1_W_M,RIGHT_W1,LOOP_UNROLL_COUNT ! 1573: dec ebx ! 1574: jnz short dual_right_1_w_loop ! 1575: ! 1576: ; get ready for next time: ! 1577: ! 1578: mov ecx,ppdev ! 1579: sub edi,[ecx].pdev_pvBitmapStart ! 1580: mov ulRightDest,edi ! 1581: ! 1582: PLAIN_RET ! 1583: ! 1584: ;-----------------------------------------------------------------------; ! 1585: ; dual_right_0_w ! 1586: ; ! 1587: ; Draws a right edge when word aligned. ! 1588: ; ! 1589: ; Input: ! 1590: ; ppdev - pointer to physical device structure ! 1591: ; ulBlockHeight - # of scans to draw ! 1592: ; lDelta - distance from end of current scan to start of next ! 1593: ; ulRightDest - offset in bitmap at which to start drawing ! 1594: ; yBrush - current y brush alignment ! 1595: ; ! 1596: ; Output: ! 1597: ; esi - new y brush alignment ! 1598: ; ulRightDest - new bitmap offset ! 1599: ;-----------------------------------------------------------------------; ! 1600: ! 1601: align 4 ! 1602: public dual_right_0_w ! 1603: dual_right_0_w: ! 1604: ! 1605: ; Set right mask by disabling some planes: ! 1606: ! 1607: mov edx,VGA_BASE + SEQ_DATA ! 1608: mov eax,ulRightMask ! 1609: out dx,al ! 1610: ! 1611: ; Calculate full start addresses: ! 1612: ! 1613: mov edi,ppdev ! 1614: mov ebx,ulBlockHeight ! 1615: mov ecx,pulPattern ! 1616: mov edx,lDelta ! 1617: mov esi,yBrush ! 1618: mov edi,[edi].pdev_pvBitmapStart ! 1619: add edi,ulRightDest ! 1620: ! 1621: SET_UP_UNROLL_AND_BRANCH ebx,eax,pfnMonoRight0,LOOP_UNROLL_SHIFT ! 1622: ! 1623: UNROLL_LOOP_ENTRY_TABLE pfnMonoRight0,RIGHT_W0,LOOP_UNROLL_COUNT ! 1624: ! 1625: MONO_RIGHT_0_W_M macro ENTRY_LABEL,ENTRY_INDEX ! 1626: &ENTRY_LABEL&ENTRY_INDEX&: ! 1627: ! 1628: mov eax,[ecx+esi*4] ;load pattern for this scan ! 1629: mov [edi],al ;write the low byte ! 1630: inc esi ;advance to next scan of pattern ! 1631: and esi,7 ! 1632: add edi,edx ;advance to next scan ! 1633: endm ;-----------------------------------; ! 1634: ! 1635: ; EBX = count of unrolled loop iterations ! 1636: ; ECX = pointer to start of pattern ! 1637: ; EDX = offset to next scan ! 1638: ; ESI = current offset into pattern ! 1639: ; EDI = target address to which to write ! 1640: ! 1641: align 4 ! 1642: dual_right_0_w_loop: ! 1643: UNROLL_LOOP MONO_RIGHT_0_W_M,RIGHT_W0,LOOP_UNROLL_COUNT ! 1644: dec ebx ! 1645: jnz short dual_right_0_w_loop ! 1646: ! 1647: ; get ready for next time: ! 1648: ! 1649: mov ecx,ppdev ! 1650: sub edi,[ecx].pdev_pvBitmapStart ! 1651: mov ulRightDest,edi ! 1652: ! 1653: PLAIN_RET ! 1654: ! 1655: ;=======================================================================; ! 1656: ;========================= ROP Block Drawers ===========================; ! 1657: ;=======================================================================; ! 1658: ! 1659: ;-----------------------------------------------------------------------; ! 1660: ; dual_wide_11_rw ! 1661: ; ! 1662: ; Draws middle words with 1 leading byte and 1 trailing byte. ! 1663: ; ! 1664: ; Input: ! 1665: ; ppdev - pointer to physical device structure ! 1666: ; ulBlockHeight - # of scans to draw ! 1667: ; lMiddleDelta - distance from end of current scan to start of next ! 1668: ; ulMiddleDest - offset in bitmap at which to start drawing ! 1669: ; yBrush - current y brush alignment ! 1670: ; cwMiddle - # of words to draw on each scan ! 1671: ; ! 1672: ; Output: ! 1673: ; esi - new y brush alignment ! 1674: ; ulMiddleDest - new bitmap offset ! 1675: ;-----------------------------------------------------------------------; ! 1676: ! 1677: UNROLL_LOOP_ENTRY_TABLE pfnMonoWide_rw_11,RW11,LOOP_UNROLL_COUNT ! 1678: ! 1679: align 4 ! 1680: public dual_wide_11_rw ! 1681: dual_wide_11_rw: ! 1682: ! 1683: ; We only have to reset which planes are enabled if we do edges too: ! 1684: ! 1685: mov edx,VGA_BASE + SEQ_DATA ! 1686: mov al,MM_ALL ! 1687: out dx,al ! 1688: ! 1689: mov ulSaveEsp,esp ! 1690: mov edi,ppdev ! 1691: ! 1692: mov esp,pulPattern ;load those registers ! 1693: mov edi,[edi].pdev_pvBitmapStart ! 1694: add edi,ulMiddleDest ! 1695: mov esi,yBrush ! 1696: mov edx,ulBlockHeight ! 1697: mov ebx,cwMiddle ! 1698: ! 1699: mov eax,[esp+esi*4] ;load pattern for this scan ! 1700: inc esi ! 1701: and esi,7 ! 1702: ! 1703: SET_UP_UNROLL_VARS ebx,ecx,ebx,pfnMonoWide_rw_11,LOOP_UNROLL_SHIFT ! 1704: ! 1705: mov pfnUnroll,ecx ! 1706: mov cUnrolledLoops,ebx ! 1707: ! 1708: jmp ecx ! 1709: ! 1710: MONO_RWIDE_11_RW_M macro ENTRY_LABEL,ENTRY_INDEX ! 1711: &ENTRY_LABEL&ENTRY_INDEX&: ! 1712: and [edi],ah ! 1713: and [edi+1],al ! 1714: add edi,2 ;the write will overlap this ! 1715: endm ;-----------------------------------; ! 1716: ! 1717: ; EAX = pattern for this scan ! 1718: ; EBX = count of unrolled loop iterations ! 1719: ; EDX = number of scans to do ! 1720: ; ESI = current offset into pattern ! 1721: ; EDI = target address to which to write ! 1722: ; ESP = pointer to start of pattern ! 1723: ! 1724: align 4 ! 1725: dual_wide_11_rw_loop: ! 1726: UNROLL_LOOP MONO_RWIDE_11_RW_M,RW11,LOOP_UNROLL_COUNT ! 1727: dec ebx ! 1728: jnz short dual_wide_11_rw_loop ! 1729: ! 1730: add edi,lMiddleDelta ! 1731: dec edx ! 1732: jz short dual_wide_11_rw_done ! 1733: ! 1734: mov eax,[esp+esi*4] ;load pattern for this scan ! 1735: inc esi ! 1736: and esi,7 ! 1737: ! 1738: mov ebx,cUnrolledLoops ! 1739: jmp pfnUnroll ! 1740: ! 1741: dual_wide_11_rw_done: ! 1742: mov ecx,ppdev ! 1743: mov esp,ulSaveEsp ! 1744: sub edi,[ecx].pdev_pvBitmapStart ! 1745: mov ulMiddleDest,edi ! 1746: ! 1747: PLAIN_RET ! 1748: ! 1749: ;-----------------------------------------------------------------------; ! 1750: ; dual_wide_10_rw ! 1751: ; ! 1752: ; Draws middle words with 1 leading byte and 0 trailing bytes. ! 1753: ; ! 1754: ; Input: ! 1755: ; ppdev - pointer to physical device structure ! 1756: ; ulBlockHeight - # of scans to draw ! 1757: ; lMiddleDelta - distance from end of current scan to start of next ! 1758: ; ulMiddleDest - offset in bitmap at which to start drawing ! 1759: ; yBrush - current y brush alignment ! 1760: ; cwMiddle - # of words to draw on each scan ! 1761: ; ! 1762: ; Output: ! 1763: ; esi - new y brush alignment ! 1764: ; ulMiddleDest - new bitmap offset ! 1765: ;-----------------------------------------------------------------------; ! 1766: ! 1767: UNROLL_LOOP_ENTRY_TABLE pfnMonoWide_rw_10,RW10,LOOP_UNROLL_COUNT ! 1768: ! 1769: align 4 ! 1770: public dual_wide_10_rw ! 1771: dual_wide_10_rw: ! 1772: ! 1773: ; We only have to reset which planes are enabled if we do edges too: ! 1774: ! 1775: mov edx,VGA_BASE + SEQ_DATA ! 1776: mov al,MM_ALL ! 1777: out dx,al ! 1778: ! 1779: mov ulSaveEsp,esp ! 1780: mov edi,ppdev ! 1781: ! 1782: mov esp,pulPattern ;load those registers ! 1783: mov edi,[edi].pdev_pvBitmapStart ! 1784: add edi,ulMiddleDest ! 1785: mov esi,yBrush ! 1786: mov edx,ulBlockHeight ! 1787: mov ebx,cwMiddle ! 1788: ! 1789: mov eax,[esp+esi*4] ;load pattern for this scan ! 1790: inc esi ! 1791: and esi,7 ! 1792: ! 1793: or ebx,ebx ;have to watch for zero words ! 1794: jz short dual_wide_10_rw_only_one_byte ! 1795: ! 1796: SET_UP_UNROLL_VARS ebx,ecx,ebx,pfnMonoWide_rw_10,LOOP_UNROLL_SHIFT ! 1797: ! 1798: mov pfnUnroll,ecx ! 1799: mov cUnrolledLoops,ebx ! 1800: ! 1801: jmp ecx ! 1802: ! 1803: dual_wide_10_rw_only_one_byte: ! 1804: mov pfnUnroll,offset dual_wide_10_rw_odd_byte ! 1805: jmp short dual_wide_10_rw_odd_byte ! 1806: ! 1807: MONO_RWIDE_10_RW_M macro ENTRY_LABEL,ENTRY_INDEX ! 1808: &ENTRY_LABEL&ENTRY_INDEX&: ! 1809: and [edi],ah ! 1810: and [edi+1],al ! 1811: add edi,2 ;the write will overlap this ! 1812: endm ;-----------------------------------; ! 1813: ! 1814: ; EAX = pattern for this scan ! 1815: ; EBX = count of unrolled loop iterations ! 1816: ; EDX = number of scans to do ! 1817: ; ESI = current offset into pattern ! 1818: ; EDI = target address to which to write ! 1819: ; ESP = pointer to start of pattern ! 1820: ! 1821: align 4 ! 1822: dual_wide_10_rw_loop: ! 1823: UNROLL_LOOP MONO_RWIDE_10_RW_M,RW10,LOOP_UNROLL_COUNT ! 1824: dec ebx ! 1825: jnz short dual_wide_10_rw_loop ! 1826: ! 1827: dual_wide_10_rw_odd_byte: ! 1828: and [edi],ah ;write that odd byte ! 1829: ! 1830: add edi,lMiddleDelta ! 1831: dec edx ! 1832: jz short dual_wide_10_rw_done ! 1833: ! 1834: mov eax,[esp+esi*4] ;load pattern for this scan ! 1835: inc esi ! 1836: and esi,7 ! 1837: ! 1838: mov ebx,cUnrolledLoops ! 1839: jmp pfnUnroll ! 1840: ! 1841: dual_wide_10_rw_done: ! 1842: mov ecx,ppdev ! 1843: mov esp,ulSaveEsp ! 1844: sub edi,[ecx].pdev_pvBitmapStart ! 1845: mov ulMiddleDest,edi ! 1846: ! 1847: PLAIN_RET ! 1848: ! 1849: ;-----------------------------------------------------------------------; ! 1850: ; dual_wide_01_rw ! 1851: ; ! 1852: ; Draws middle words with 0 leading bytes and 1 trailing byte. ! 1853: ; ! 1854: ; Input: ! 1855: ; ppdev - pointer to physical device structure ! 1856: ; ulBlockHeight - # of scans to draw ! 1857: ; lMiddleDelta - distance from end of current scan to start of next ! 1858: ; ulMiddleDest - offset in bitmap at which to start drawing ! 1859: ; yBrush - current y brush alignment ! 1860: ; cwMiddle - # of words to draw on each scan ! 1861: ; ! 1862: ; Output: ! 1863: ; esi - new y brush alignment ! 1864: ; ulMiddleDest - new bitmap offset ! 1865: ;-----------------------------------------------------------------------; ! 1866: ! 1867: UNROLL_LOOP_ENTRY_TABLE pfnMonoWide_rw_01,RW01,LOOP_UNROLL_COUNT ! 1868: ! 1869: align 4 ! 1870: public dual_wide_01_rw ! 1871: dual_wide_01_rw: ! 1872: ! 1873: ; We only have to reset which planes are enabled if we do edges too: ! 1874: ! 1875: mov edx,VGA_BASE + SEQ_DATA ! 1876: mov al,MM_ALL ! 1877: out dx,al ! 1878: ! 1879: mov ulSaveEsp,esp ! 1880: mov edi,ppdev ! 1881: ! 1882: mov esp,pulPattern ;load those registers ! 1883: mov edi,[edi].pdev_pvBitmapStart ! 1884: add edi,ulMiddleDest ! 1885: mov esi,yBrush ! 1886: mov edx,ulBlockHeight ! 1887: mov ebx,cwMiddle ! 1888: ! 1889: mov eax,[esp+esi*4] ;load pattern for this scan ! 1890: inc esi ! 1891: and esi,7 ! 1892: ! 1893: or ebx,ebx ! 1894: jz short dual_wide_01_rw_only_one_byte ! 1895: ! 1896: SET_UP_UNROLL_VARS ebx,ecx,ebx,pfnMonoWide_rw_01,LOOP_UNROLL_SHIFT ! 1897: ! 1898: mov pfnUnroll,ecx ! 1899: mov cUnrolledLoops,ebx ! 1900: ! 1901: jmp ecx ! 1902: ! 1903: dual_wide_01_rw_only_one_byte: ! 1904: mov pfnUnroll,offset dual_wide_01_rw_odd_byte ! 1905: jmp short dual_wide_01_rw_odd_byte ! 1906: ! 1907: MONO_RWIDE_01_RW_M macro ENTRY_LABEL,ENTRY_INDEX ! 1908: &ENTRY_LABEL&ENTRY_INDEX&: ! 1909: and [edi],al ! 1910: and [edi+1],ah ! 1911: add edi,2 ;the write will overlap this ! 1912: endm ;-----------------------------------; ! 1913: ! 1914: ; EAX = pattern for this scan ! 1915: ; EBX = count of unrolled loop iterations ! 1916: ; EDX = number of scans to do ! 1917: ; ESI = current offset into pattern ! 1918: ; EDI = target address to which to write ! 1919: ; ESP = pointer to start of pattern ! 1920: ! 1921: align 4 ! 1922: dual_wide_01_rw_loop: ! 1923: UNROLL_LOOP MONO_RWIDE_01_RW_M,RW01,LOOP_UNROLL_COUNT ! 1924: dec ebx ! 1925: jnz short dual_wide_01_rw_loop ! 1926: ! 1927: dual_wide_01_rw_odd_byte: ! 1928: and [edi],al ;write that odd byte ! 1929: ! 1930: add edi,lMiddleDelta ! 1931: dec edx ! 1932: jz short dual_wide_01_rw_done ! 1933: ! 1934: mov eax,[esp+esi*4] ;load pattern for this scan ! 1935: inc esi ! 1936: and esi,7 ! 1937: ! 1938: mov ebx,cUnrolledLoops ! 1939: jmp pfnUnroll ! 1940: ! 1941: dual_wide_01_rw_done: ! 1942: mov ecx,ppdev ! 1943: mov esp,ulSaveEsp ! 1944: sub edi,[ecx].pdev_pvBitmapStart ! 1945: mov ulMiddleDest,edi ! 1946: ! 1947: PLAIN_RET ! 1948: ! 1949: ;-----------------------------------------------------------------------; ! 1950: ; dual_wide_00_rw ! 1951: ; ! 1952: ; Draws middle words with 0 leading bytes and 0 trailing bytes. ! 1953: ; ! 1954: ; Input: ! 1955: ; ppdev - pointer to physical device structure ! 1956: ; ulBlockHeight - # of scans to draw ! 1957: ; lMiddleDelta - distance from end of current scan to start of next ! 1958: ; ulMiddleDest - offset in bitmap at which to start drawing ! 1959: ; yBrush - current y brush alignment ! 1960: ; cwMiddle - # of words to draw on each scan ! 1961: ; ! 1962: ; Output: ! 1963: ; esi - new y brush alignment ! 1964: ; ulMiddleDest - new bitmap offset ! 1965: ;-----------------------------------------------------------------------; ! 1966: ! 1967: UNROLL_LOOP_ENTRY_TABLE pfnMonoWide_rw_00,RW00,LOOP_UNROLL_COUNT ! 1968: ! 1969: align 4 ! 1970: public dual_wide_00_rw ! 1971: dual_wide_00_rw: ! 1972: ! 1973: ; We only have to reset which planes are enabled if we do edges too: ! 1974: ! 1975: mov edx,VGA_BASE + SEQ_DATA ! 1976: mov al,MM_ALL ! 1977: out dx,al ! 1978: ! 1979: mov ulSaveEsp,esp ! 1980: mov edi,ppdev ! 1981: ! 1982: mov esp,pulPattern ;load those registers ! 1983: mov edi,[edi].pdev_pvBitmapStart ! 1984: add edi,ulMiddleDest ! 1985: mov esi,yBrush ! 1986: mov edx,ulBlockHeight ! 1987: mov ebx,cwMiddle ! 1988: ! 1989: mov eax,[esp+esi*4] ;load pattern for this scan ! 1990: inc esi ! 1991: and esi,7 ! 1992: ! 1993: SET_UP_UNROLL_VARS ebx,ecx,ebx,pfnMonoWide_rw_00,LOOP_UNROLL_SHIFT ! 1994: ! 1995: mov pfnUnroll,ecx ! 1996: mov cUnrolledLoops,ebx ! 1997: ! 1998: jmp ecx ! 1999: ! 2000: MONO_RWIDE_00_RW_M macro ENTRY_LABEL,ENTRY_INDEX ! 2001: &ENTRY_LABEL&ENTRY_INDEX&: ! 2002: and [edi],al ! 2003: and [edi+1],ah ! 2004: add edi,2 ;the write will overlap this ! 2005: endm ;-----------------------------------; ! 2006: ! 2007: ; EAX = pattern for this scan ! 2008: ; EBX = count of unrolled loop iterations ! 2009: ; EDX = number of scans to do ! 2010: ; ESI = current offset into pattern ! 2011: ; EDI = target address to which to write ! 2012: ; ESP = pointer to start of pattern ! 2013: ! 2014: align 4 ! 2015: dual_wide_00_rw_loop: ! 2016: UNROLL_LOOP MONO_RWIDE_00_RW_M,RW00,LOOP_UNROLL_COUNT ! 2017: dec ebx ! 2018: jnz short dual_wide_00_rw_loop ! 2019: ! 2020: add edi,lMiddleDelta ! 2021: dec edx ! 2022: jz short dual_wide_00_rw_done ! 2023: ! 2024: mov eax,[esp+esi*4] ;load pattern for this scan ! 2025: inc esi ! 2026: and esi,7 ! 2027: ! 2028: mov ebx,cUnrolledLoops ! 2029: jmp pfnUnroll ! 2030: ! 2031: dual_wide_00_rw_done: ! 2032: mov ecx,ppdev ! 2033: mov esp,ulSaveEsp ! 2034: sub edi,[ecx].pdev_pvBitmapStart ! 2035: mov ulMiddleDest,edi ! 2036: ! 2037: PLAIN_RET ! 2038: ! 2039: ;-----------------------------------------------------------------------; ! 2040: ; dual_left_1_rw ! 2041: ; ! 2042: ; Draws a left edge when the next byte is not word aligned. ! 2043: ; ! 2044: ; Input: ! 2045: ; ppdev - pointer to physical device structure ! 2046: ; ulBlockHeight - # of scans to draw ! 2047: ; lDelta - distance from end of current scan to start of next ! 2048: ; ulLeftDest - offset in bitmap at which to start drawing ! 2049: ; yBrush - current y brush alignment ! 2050: ; ! 2051: ; Output: ! 2052: ; esi - new y brush alignment ! 2053: ; ulLeftDest - new bitmap offset ! 2054: ;-----------------------------------------------------------------------; ! 2055: ! 2056: align 4 ! 2057: public dual_left_1_rw ! 2058: dual_left_1_rw: ! 2059: ! 2060: ; Set left mask by disabling some planes: ! 2061: ! 2062: mov edx,VGA_BASE + SEQ_DATA ! 2063: mov eax,ulLeftMask ! 2064: out dx,al ! 2065: ! 2066: ; Calculate full start addresses: ! 2067: ! 2068: mov edi,ppdev ! 2069: mov ebx,ulBlockHeight ! 2070: mov ecx,pulPattern ! 2071: mov edx,lDelta ! 2072: mov esi,yBrush ! 2073: mov edi,[edi].pdev_pvBitmapStart ! 2074: add edi,ulLeftDest ! 2075: ! 2076: SET_UP_UNROLL_AND_BRANCH ebx,eax,pfnMonoLeft_rw_1,LOOP_UNROLL_SHIFT ! 2077: ! 2078: UNROLL_LOOP_ENTRY_TABLE pfnMonoLeft_rw_1,LEFT_RW1,LOOP_UNROLL_COUNT ! 2079: ! 2080: MONO_LEFT_1_RW_M macro ENTRY_LABEL,ENTRY_INDEX ! 2081: &ENTRY_LABEL&ENTRY_INDEX&: ! 2082: ! 2083: mov eax,[ecx+esi*4] ;load pattern for this scan ! 2084: and [edi],al ;write the low byte ! 2085: inc esi ;advance to next scan of pattern ! 2086: and esi,7 ! 2087: add edi,edx ;advance to next scan ! 2088: endm ;-----------------------------------; ! 2089: ! 2090: ; EBX = count of unrolled loop iterations ! 2091: ; ECX = pointer to start of pattern ! 2092: ; EDX = offset to next scan ! 2093: ; ESI = current offset into pattern ! 2094: ; EDI = target address to which to write ! 2095: ! 2096: align 4 ! 2097: dual_left_1_rw_loop: ! 2098: UNROLL_LOOP MONO_LEFT_1_RW_M,LEFT_RW1,LOOP_UNROLL_COUNT ! 2099: dec ebx ! 2100: jnz short dual_left_1_rw_loop ! 2101: ! 2102: ; get ready for next time: ! 2103: ! 2104: mov ecx,ppdev ! 2105: sub edi,[ecx].pdev_pvBitmapStart ! 2106: mov ulLeftDest,edi ! 2107: ! 2108: PLAIN_RET ! 2109: ! 2110: ;-----------------------------------------------------------------------; ! 2111: ; dual_left_0_rw ! 2112: ; ! 2113: ; Draws a left edge when the next byte is word aligned. ! 2114: ; ! 2115: ; Input: ! 2116: ; ppdev - pointer to physical device structure ! 2117: ; ulBlockHeight - # of scans to draw ! 2118: ; lDelta - distance from end of current scan to start of next ! 2119: ; ulLeftDest - offset in bitmap at which to start drawing ! 2120: ; yBrush - current y brush alignment ! 2121: ; ! 2122: ; Output: ! 2123: ; esi - new y brush alignment ! 2124: ; ulLeftDest - new bitmap offset ! 2125: ;-----------------------------------------------------------------------; ! 2126: ! 2127: align 4 ! 2128: public dual_left_0_rw ! 2129: dual_left_0_rw: ! 2130: ! 2131: ; Set left mask by disabling some planes: ! 2132: ! 2133: mov edx,VGA_BASE + SEQ_DATA ! 2134: mov eax,ulLeftMask ! 2135: out dx,al ! 2136: ! 2137: ; Calculate full start addresses: ! 2138: ! 2139: mov edi,ppdev ! 2140: mov ebx,ulBlockHeight ! 2141: mov ecx,pulPattern ! 2142: mov edx,lDelta ! 2143: mov esi,yBrush ! 2144: mov edi,[edi].pdev_pvBitmapStart ! 2145: add edi,ulLeftDest ! 2146: ! 2147: SET_UP_UNROLL_AND_BRANCH ebx,eax,pfnMonoLeft_rw_0,LOOP_UNROLL_SHIFT ! 2148: ! 2149: UNROLL_LOOP_ENTRY_TABLE pfnMonoLeft_rw_0,LEFT_RW0,LOOP_UNROLL_COUNT ! 2150: ! 2151: MONO_LEFT_0_RW_M macro ENTRY_LABEL,ENTRY_INDEX ! 2152: &ENTRY_LABEL&ENTRY_INDEX&: ! 2153: ! 2154: mov eax,[ecx+esi*4] ;load pattern for this scan ! 2155: and [edi],ah ;write the high byte ! 2156: inc esi ;advance to next scan of pattern ! 2157: and esi,7 ! 2158: add edi,edx ;advance to next scan ! 2159: endm ;-----------------------------------; ! 2160: ! 2161: ; EBX = count of unrolled loop iterations ! 2162: ; ECX = pointer to start of pattern ! 2163: ; EDX = offset to next scan ! 2164: ; ESI = current offset into pattern ! 2165: ; EDI = target address to which to write ! 2166: ! 2167: align 4 ! 2168: dual_left_0_rw_loop: ! 2169: UNROLL_LOOP MONO_LEFT_0_RW_M,LEFT_RW0,LOOP_UNROLL_COUNT ! 2170: dec ebx ! 2171: jnz short dual_left_0_rw_loop ! 2172: ! 2173: ; get ready for next time: ! 2174: ! 2175: mov ecx,ppdev ! 2176: sub edi,[ecx].pdev_pvBitmapStart ! 2177: mov ulLeftDest,edi ! 2178: ! 2179: PLAIN_RET ! 2180: ! 2181: ;-----------------------------------------------------------------------; ! 2182: ; dual_right_1_rw ! 2183: ; ! 2184: ; Draws a right edge when not word aligned. ! 2185: ; ! 2186: ; Input: ! 2187: ; ppdev - pointer to physical device structure ! 2188: ; ulBlockHeight - # of scans to draw ! 2189: ; lDelta - distance from end of current scan to start of next ! 2190: ; ulRightDest - offset in bitmap at which to start drawing ! 2191: ; yBrush - current y brush alignment ! 2192: ; ! 2193: ; Output: ! 2194: ; esi - new y brush alignment ! 2195: ; ulRightDest - new bitmap offset ! 2196: ;-----------------------------------------------------------------------; ! 2197: ! 2198: align 4 ! 2199: public dual_right_1_rw ! 2200: dual_right_1_rw: ! 2201: ! 2202: ; Set right mask by disabling some planes: ! 2203: ! 2204: mov edx,VGA_BASE + SEQ_DATA ! 2205: mov eax,ulRightMask ! 2206: out dx,al ! 2207: ! 2208: ; Calculate full start addresses: ! 2209: ! 2210: mov edi,ppdev ! 2211: mov ebx,ulBlockHeight ! 2212: mov ecx,pulPattern ! 2213: mov edx,lDelta ! 2214: mov esi,yBrush ! 2215: mov edi,[edi].pdev_pvBitmapStart ! 2216: add edi,ulRightDest ! 2217: ! 2218: SET_UP_UNROLL_AND_BRANCH ebx,eax,pfnMonoRight_rw_1,LOOP_UNROLL_SHIFT ! 2219: ! 2220: UNROLL_LOOP_ENTRY_TABLE pfnMonoRight_rw_1,RIGHT_RW1,LOOP_UNROLL_COUNT ! 2221: ! 2222: MONO_RIGHT_1_RW_M macro ENTRY_LABEL,ENTRY_INDEX ! 2223: &ENTRY_LABEL&ENTRY_INDEX&: ! 2224: ! 2225: mov eax,[ecx+esi*4] ;load pattern for this scan ! 2226: and [edi],ah ;write the high byte ! 2227: inc esi ;advance to next scan of pattern ! 2228: and esi,7 ! 2229: add edi,edx ;advance to next scan ! 2230: endm ;-----------------------------------; ! 2231: ! 2232: ; EBX = count of unrolled loop iterations ! 2233: ; ECX = pointer to start of pattern ! 2234: ; EDX = offset to next scan ! 2235: ; ESI = current offset into pattern ! 2236: ; EDI = target address to which to write ! 2237: ! 2238: align 4 ! 2239: dual_right_1_rw_loop: ! 2240: UNROLL_LOOP MONO_RIGHT_1_RW_M,RIGHT_RW1,LOOP_UNROLL_COUNT ! 2241: dec ebx ! 2242: jnz short dual_right_1_rw_loop ! 2243: ! 2244: ; get ready for next time: ! 2245: ! 2246: mov ecx,ppdev ! 2247: sub edi,[ecx].pdev_pvBitmapStart ! 2248: mov ulRightDest,edi ! 2249: ! 2250: PLAIN_RET ! 2251: ! 2252: ;-----------------------------------------------------------------------; ! 2253: ; dual_right_0_rw ! 2254: ; ! 2255: ; Draws a right edge when word aligned. ! 2256: ; ! 2257: ; Input: ! 2258: ; ppdev - pointer to physical device structure ! 2259: ; ulBlockHeight - # of scans to draw ! 2260: ; lDelta - distance from end of current scan to start of next ! 2261: ; ulRightDest - offset in bitmap at which to start drawing ! 2262: ; yBrush - current y brush alignment ! 2263: ; ! 2264: ; Output: ! 2265: ; esi - new y brush alignment ! 2266: ; ulRightDest - new bitmap offset ! 2267: ;-----------------------------------------------------------------------; ! 2268: ! 2269: align 4 ! 2270: public dual_right_0_rw ! 2271: dual_right_0_rw: ! 2272: ! 2273: ; Set right mask by disabling some planes: ! 2274: ! 2275: mov edx,VGA_BASE + SEQ_DATA ! 2276: mov eax,ulRightMask ! 2277: out dx,al ! 2278: ! 2279: ; Calculate full start addresses: ! 2280: ! 2281: mov edi,ppdev ! 2282: mov ebx,ulBlockHeight ! 2283: mov ecx,pulPattern ! 2284: mov edx,lDelta ! 2285: mov esi,yBrush ! 2286: mov edi,[edi].pdev_pvBitmapStart ! 2287: add edi,ulRightDest ! 2288: ! 2289: SET_UP_UNROLL_AND_BRANCH ebx,eax,pfnMonoRight_rw_0,LOOP_UNROLL_SHIFT ! 2290: ! 2291: UNROLL_LOOP_ENTRY_TABLE pfnMonoRight_rw_0,RIGHT_RW0,LOOP_UNROLL_COUNT ! 2292: ! 2293: MONO_RIGHT_0_RW_M macro ENTRY_LABEL,ENTRY_INDEX ! 2294: &ENTRY_LABEL&ENTRY_INDEX&: ! 2295: ! 2296: mov eax,[ecx+esi*4] ;load pattern for this scan ! 2297: and [edi],al ;write the low byte ! 2298: inc esi ;advance to next scan of pattern ! 2299: and esi,7 ! 2300: add edi,edx ;advance to next scan ! 2301: endm ;-----------------------------------; ! 2302: ! 2303: ; EBX = count of unrolled loop iterations ! 2304: ; ECX = pointer to start of pattern ! 2305: ; EDX = offset to next scan ! 2306: ; ESI = current offset into pattern ! 2307: ; EDI = target address to which to write ! 2308: ! 2309: align 4 ! 2310: dual_right_0_rw_loop: ! 2311: UNROLL_LOOP MONO_RIGHT_0_RW_M,RIGHT_RW0,LOOP_UNROLL_COUNT ! 2312: dec ebx ! 2313: jnz short dual_right_0_rw_loop ! 2314: ! 2315: ; get ready for next time: ! 2316: ! 2317: mov ecx,ppdev ! 2318: sub edi,[ecx].pdev_pvBitmapStart ! 2319: mov ulRightDest,edi ! 2320: ! 2321: PLAIN_RET ! 2322: ! 2323: ;-----------------------------------------------------------------------; ! 2324: ! 2325: endProc vMonoPat ! 2326: ! 2327: ;-----------------------------------------------------------------------; ! 2328: ; BOOL b2ColorBrush(pjBits, pjFgColor, pjBkColor) ! 2329: ; ! 2330: ; Determines if the 8x8x8bpp packed brush pointed to by pjBits has only ! 2331: ; two colors, and if so returns the 1bpp bitmap. ! 2332: ; ! 2333: ; Returns: ! 2334: ; eax = 1 if two (or one) color brush, 0 otherwise ! 2335: ; pjBits = pointer to packed 1bpp bitmap if a 2-color brush ! 2336: ; *pjFgColor = foreground color for returned 1bpp bitmap (i.e., ! 2337: ; used to color-expand '1' bits) ! 2338: ; *pjBkColor = backgroun color for returned 1bpp bitmap (i.e., ! 2339: ; used to color-expand '0' bits) ! 2340: ;-----------------------------------------------------------------------; ! 2341: ! 2342: cProc b2ColorBrush,12,< \ ! 2343: uses esi edi ebx, \ ! 2344: pjBits: ptr BYTE, \ ! 2345: pjFgColor: ptr BYTE, \ ! 2346: pjBkColor: ptr BYTE > ! 2347: ! 2348: ; al = first color ! 2349: ; ah = second color ! 2350: ; ecx = number of unrolled loops ! 2351: ! 2352: mov esi,pjBits ! 2353: mov ecx,(BRUSH_SIZE shr 1) ! 2354: mov al,[esi] ! 2355: ! 2356: align 4 ! 2357: b2col_find_2nd_color_loop: ! 2358: mov ah,[esi+1] ! 2359: cmp ah,al ! 2360: jne short b2col_find_consecutive_2nd_color_loop_part_1 ! 2361: ! 2362: add esi,2 ! 2363: dec ecx ! 2364: jz short b2col_is_2_colors ;actually, it's only one color ! 2365: ! 2366: mov ah,[esi] ! 2367: cmp ah,al ! 2368: jne short b2col_find_consecutive_2nd_color_loop_part_2 ! 2369: jmp short b2col_find_2nd_color_loop ! 2370: ! 2371: ;------------------------------------; ! 2372: ! 2373: align 4 ! 2374: b2col_find_consecutive_1st_color_loop_part_1: ! 2375: add esi,2 ! 2376: dec ecx ! 2377: jz short b2col_is_2_colors ! 2378: ! 2379: mov bl,[esi] ! 2380: cmp bl,ah ! 2381: je short b2col_find_consecutive_2nd_color_loop_part_2 ! 2382: cmp bl,al ! 2383: jne short b2col_isnt_2_colors ! 2384: ! 2385: b2col_find_consecutive_1st_color_loop_part_2: ! 2386: mov bl,[esi+1] ! 2387: cmp bl,ah ! 2388: je short b2col_find_consecutive_2nd_color_loop_part_1 ! 2389: cmp bl,al ! 2390: je short b2col_find_consecutive_1st_color_loop_part_1 ! 2391: ! 2392: xor eax,eax ! 2393: cRet b2ColorBrush ;return FALSE ! 2394: ! 2395: ;------------------------------------; ! 2396: ! 2397: align 4 ! 2398: b2col_find_consecutive_2nd_color_loop_part_1: ! 2399: add esi,2 ! 2400: dec ecx ! 2401: jz short b2col_is_2_colors ! 2402: ! 2403: mov bl,[esi] ! 2404: cmp bl,al ! 2405: je short b2col_find_consecutive_1st_color_loop_part_2 ! 2406: cmp bl,ah ! 2407: jne short b2col_isnt_2_colors ! 2408: ! 2409: b2col_find_consecutive_2nd_color_loop_part_2: ! 2410: mov bl,[esi+1] ! 2411: cmp bl,al ! 2412: je short b2col_find_consecutive_1st_color_loop_part_1 ! 2413: cmp bl,ah ! 2414: je short b2col_find_consecutive_2nd_color_loop_part_1 ! 2415: ! 2416: b2col_isnt_2_colors: ! 2417: xor eax,eax ! 2418: cRet b2ColorBrush ;return FALSE ! 2419: ! 2420: ;------------------------------------; ! 2421: ! 2422: public b2col_is_2_colors ! 2423: b2col_is_2_colors: ! 2424: ! 2425: ; Here, we want the color with the lesser value to be in 'al', and the ! 2426: ; other to be in 'ah'. ! 2427: ! 2428: cmp al,ah ! 2429: jb short b2col_ordered_colors ! 2430: xchg al,ah ! 2431: ! 2432: b2col_ordered_colors: ! 2433: mov ecx,(BRUSH_SIZE shr 3) ! 2434: mov esi,pjBits ! 2435: mov edi,esi ! 2436: ! 2437: ; Colors matching 'al' will get mapped to '1' bits, and colors matching ! 2438: ; 'ah' will get mapped to '0' bits: ! 2439: ! 2440: b2col_monochrome_bitmap_loop: ! 2441: cmp [esi+7],ah ! 2442: adc bl,bl ! 2443: cmp [esi+6],ah ! 2444: adc bl,bl ! 2445: cmp [esi+5],ah ! 2446: adc bl,bl ! 2447: cmp [esi+4],ah ! 2448: adc bl,bl ! 2449: cmp [esi+3],ah ! 2450: adc bl,bl ! 2451: cmp [esi+2],ah ! 2452: adc bl,bl ! 2453: cmp [esi+1],ah ! 2454: adc bl,bl ! 2455: cmp [esi],ah ! 2456: adc bl,bl ! 2457: ! 2458: ; At this point, where the 8 bytes of the bitmap were ordered 0 1 2 3 4 5 6 7, ! 2459: ; we've got the monochrome byte in 'bl' ordered 7 6 5 4 3 2 1 0. We want ! 2460: ; the word ordered '3 2 1 0 7 6 5 4 | 7 6 5 4 3 2 1 0' where the lower 4 bits ! 2461: ; of every bit are the planes mask, and the upper 4 bits are ordered to ! 2462: ; facilitate easy rotating. ! 2463: ; ! 2464: ; The word is actually written into a dword in the destination buffer. ! 2465: ! 2466: mov bh,bl ! 2467: ror bh,4 ! 2468: mov [edi],ebx ;save this dword of monochrome bitmap ! 2469: add edi,4 ! 2470: add esi,8 ! 2471: dec ecx ! 2472: jnz b2col_monochrome_bitmap_loop ! 2473: ! 2474: ; Aside: because of the way this is written, if the two colors are black ! 2475: ; and white (i.e., 0x00 and 0xff), the foreground color will be black (0x00), ! 2476: ; and the background will be white (0xff). ! 2477: ! 2478: mov esi,pjFgColor ! 2479: mov edi,pjBkColor ! 2480: mov [esi],al ;save foreground color ! 2481: mov [edi],ah ;save background color ! 2482: mov eax,1 ! 2483: cRet b2ColorBrush ! 2484: ! 2485: endProc b2ColorBrush ! 2486: ! 2487: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.