|
|
1.1 ! root 1: ;---------------------------Module-Header------------------------------; ! 2: ; Module Name: vgastrps.asm ! 3: ; ! 4: ; Routines used by line code to draw strips of pixels. ! 5: ; ! 6: ; Copyright (c) 1992 Microsoft Corporation ! 7: ;-----------------------------------------------------------------------; ! 8: ! 9: .386 ! 10: ! 11: .model small,c ! 12: ! 13: assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT ! 14: assume fs:nothing,gs:nothing ! 15: ! 16: ; Set LOOP_UNROLL_SHIFT to the log2 of the number of times you want loops in ! 17: ; this module unrolled. For example, LOOP_UNROLL_SHIFT of 3 yields 2**3 = 8 ! 18: ; times unrolling. This is the only thing you need to change to control ! 19: ; unrolling. ! 20: ! 21: LOOP_UNROLL_SHIFT equ 2 ! 22: ! 23: .xlist ! 24: include stdcall.inc ;calling convention cmacros ! 25: include i386\egavga.inc ! 26: include i386\strucs.inc ! 27: include i386\lines.inc ! 28: include i386\unroll.inc ! 29: .list ! 30: ! 31: .code ! 32: ! 33: _TEXT$04 SEGMENT DWORD USE32 PUBLIC 'CODE' ! 34: ASSUME CS:FLAT, DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING ! 35: ! 36: ;---------------------------Public-Routine------------------------------; ! 37: ; vSetStrips ! 38: ; ! 39: ; Set the VGA into the appropriate mode for line drawing. ! 40: ; ! 41: ;-----------------------------------------------------------------------; ! 42: ! 43: cProc vSetStrips,8,< \ ! 44: clr: dword, \ ! 45: mode: dword > ! 46: ! 47: mov edx, VGA_BASE + GRAF_ADDR ! 48: ! 49: mov al, GRAF_SET_RESET ! 50: mov ah, byte ptr clr ! 51: out dx, ax ! 52: ! 53: cmp mode, DR_SET ! 54: je @F ! 55: ! 56: mov al, GRAF_DATA_ROT ! 57: mov ah, byte ptr mode ! 58: out dx, ax ! 59: ! 60: @@: ! 61: mov eax, GRAF_MODE + ((M_AND_WRITE + M_COLOR_READ) SHL 8) ! 62: out dx, ax ;write mode 3 so we can do the masking ! 63: ; without OUTs, read mode 1 so we can ! 64: ; read 0xFF from memory always, for ! 65: ; ANDing (because Color Don't Care is ! 66: ; all zeros) ! 67: cRet vSetStrips ! 68: ! 69: endProc vSetStrips ! 70: ! 71: ;---------------------------Public-Routine------------------------------; ! 72: ; vClearStrips ! 73: ; ! 74: ; Restore the VGA to its default state. ! 75: ; ! 76: ;-----------------------------------------------------------------------; ! 77: ! 78: cProc vClearStrips,4,< \ ! 79: oldmode: dword > ! 80: ! 81: ; Restore the EGA/VGA to its default state: ! 82: ! 83: mov edx, VGA_BASE + GRAF_ADDR ! 84: ! 85: cmp oldmode, DR_SET ! 86: je @F ! 87: mov eax, (DR_SET shl 8) + GRAF_DATA_ROT ! 88: out dx, ax ! 89: ! 90: @@: ! 91: mov eax, GRAF_MODE + ((M_PROC_WRITE + M_DATA_READ) SHL 8) ! 92: out dx, ax ;restore read mode 0 and write mode 0 ! 93: ! 94: cRet vClearStrips ! 95: ! 96: endProc vClearStrips ! 97: ! 98: ;--------------------------Private-Routine------------------------------; ! 99: ; vStripSolidDiagonalHorizontal ! 100: ; ! 101: ; Draw an x-major near-diagonal strip left-to-right ! 102: ; ! 103: ;-----------------------------------------------------------------------; ! 104: ! 105: cProc vStripSolidDiagonalHorizontal,12,< \ ! 106: uses esi edi ebx, \ ! 107: pStrips: ptr STRIPS, \ ! 108: pls: ptr LINESTATE, \ ! 109: plStripEnd: ptr > ! 110: ! 111: mov esi, pStrips ! 112: push ebp ! 113: mov ebp, plStripEnd ! 114: mov ecx, [esi].ST_lNextScan ! 115: mov al, [esi].ST_jBitMask ! 116: mov edi, [esi].ST_pjScreen ! 117: add esi, offset ST_alStrips ! 118: ! 119: ; al = bit mask ! 120: ; ebx = pixel count ! 121: ; ecx = delta ! 122: ; edx = port # ! 123: ; esi = strip pointer ! 124: ; edi = memory pointer ! 125: ; ebp = end of strips pointer ! 126: ! 127: next_diagonal: ! 128: mov ebx, [esi] ! 129: add esi, 4 ! 130: ! 131: align 4 ! 132: diagonal_loop: ! 133: and [edi], al ! 134: ror al, 1 ! 135: adc edi, ecx ! 136: dec ebx ! 137: jnz short diagonal_loop ! 138: ! 139: sub edi, ecx ; side step ! 140: cmp esi, ebp ! 141: jl short next_diagonal ! 142: ! 143: pop ebp ! 144: mov esi, pStrips ! 145: mov [esi].ST_pjScreen, edi ! 146: mov [esi].ST_jBitmask, al ! 147: cRet vStripSolidDiagonalHorizontal ! 148: ! 149: endProc vStripSolidDiagonalHorizontal ! 150: ! 151: ;--------------------------Private-Routine------------------------------; ! 152: ; vStripSolidDiagonalVertical ! 153: ; ! 154: ; Draw a y-major near-diagonal strip left-to-right ! 155: ; ! 156: ;-----------------------------------------------------------------------; ! 157: ! 158: cProc vStripSolidDiagonalVertical,12,< \ ! 159: uses esi edi ebx, \ ! 160: pStrips: ptr STRIPS, \ ! 161: pls: ptr LINESTATE, \ ! 162: plStripEnd: ptr > ! 163: ! 164: mov esi, pStrips ! 165: push ebp ! 166: mov ebp, plStripEnd ! 167: mov ecx, [esi].ST_lNextScan ! 168: mov al, [esi].ST_jBitMask ! 169: mov edi, [esi].ST_pjScreen ! 170: add esi, offset ST_alStrips ! 171: ! 172: ; al = bit mask ! 173: ; ebx = pixel count ! 174: ; ecx = delta ! 175: ; edx = port # ! 176: ; esi = strip pointer ! 177: ; edi = memory pointer ! 178: ; ebp = end of strips pointer ! 179: ! 180: next_diagonal: ! 181: mov ebx, [esi] ! 182: add esi, 4 ! 183: ! 184: align 4 ! 185: diagonal_loop: ! 186: and [edi], al ! 187: ror al, 1 ! 188: adc edi, ecx ! 189: dec ebx ! 190: jnz short diagonal_loop ! 191: ! 192: rol al, 1 ; side step ! 193: sbb edi, 0 ! 194: cmp esi, ebp ! 195: jl short next_diagonal ! 196: ! 197: pop ebp ! 198: mov esi, pStrips ! 199: mov [esi].ST_pjScreen, edi ! 200: mov [esi].ST_jBitmask, al ! 201: cRet vStripSolidDiagonalVertical ! 202: ! 203: endProc vStripSolidDiagonalVertical ! 204: ! 205: ;--------------------------Private-Routine------------------------------; ! 206: ; vStripSolidHorizontal ! 207: ; ! 208: ; Draw a horizontal strip left to right ! 209: ; ! 210: ;-----------------------------------------------------------------------; ! 211: ! 212: cProc vStripSolidHorizontal,12,< \ ! 213: uses esi edi ebx, \ ! 214: pStrips: ptr STRIPS, \ ! 215: pls: ptr LINESTATE, \ ! 216: plStripEnd: ptr > ! 217: ! 218: ; Do some initializing: ! 219: ! 220: mov esi, pStrips ! 221: push ebp ! 222: mov ebp, plStripEnd ! 223: mov edx, [esi].ST_lNextScan ! 224: mov al, [esi].ST_jBitMask ! 225: mov edi, [esi].ST_pjScreen ! 226: add esi, offset ST_alStrips ! 227: ! 228: ; (al) = rotating bit ! 229: ; (bl) = current mask ! 230: ; (ecx) = pixel count ! 231: ; (edx) = delta ! 232: ; (esi) = strip pointer ! 233: ; (edi) = display pointer ! 234: ; (ebp) = end of strips pointer ! 235: ! 236: next_horizontal: ! 237: mov ecx, [esi] ! 238: add esi, 4 ! 239: ! 240: lea ebx, [2 * eax - 1] ; bl = start mask ! 241: ror al, cl ; rotate bit ! 242: shr ecx, 3 ; compute # bytes to lay down ! 243: cmp bl, al ; we have to adjust for wrap ! 244: adc ecx, 0 ! 245: jnz short extends_out_of_first_byte ! 246: ! 247: sub bl, al ; zero out end bits ! 248: sub bl, al ! 249: inc bl ! 250: and [edi], bl ; write result ! 251: add edi, edx ; increment to next scan ! 252: cmp esi, ebp ; see if done strips ! 253: jb short next_horizontal ! 254: ! 255: pop ebp ; we're done ! 256: mov esi, pStrips ! 257: mov [esi].ST_pjScreen, edi ! 258: mov [esi].ST_jBitmask, al ! 259: cRet vStripSolidHorizontal ! 260: ! 261: extends_out_of_first_byte: ! 262: ! 263: ; This part gets called when the current strip doesn't fit entirely ! 264: ; into one byte: ! 265: ! 266: and [edi], bl ; output with start mask ! 267: inc edi ; go on to next byte ! 268: ! 269: dec ecx ; see if there's any bytes in ! 270: jnz short output_bunch ; between start and end byte ! 271: ! 272: last_byte: ! 273: lea ebx, [2 * eax - 1] ; compute end mask ! 274: not bl ! 275: and [edi], bl ; write result ! 276: add edi, edx ; increment to next scan ! 277: cmp esi, ebp ; see if done strips ! 278: jb short next_horizontal ! 279: ! 280: pop ebp ; we're done ! 281: mov esi, pStrips ! 282: mov [esi].ST_pjScreen, edi ! 283: mov [esi].ST_jBitmask, al ! 284: cRet vStripSolidHorizontal ! 285: ! 286: output_bunch: ! 287: ! 288: ; We have a bunch of complete bytes to lay down. ! 289: ! 290: mov ebx, esi ; we're gonna overwrite esi ! 291: mov esi, edi ! 292: rep movsb ; Write the bytes. Mask is 0ffh because ! 293: ; we're in read mode 1, reading 0ffh, ! 294: ; which becomes the write mode 3 mask. ! 295: ! 296: mov esi, ebx ; restore esi ! 297: ! 298: jmp short last_byte ; do last byte in scan ! 299: ! 300: endProc vStripSolidHorizontal ! 301: ! 302: ;--------------------------Private-Routine------------------------------; ! 303: ; vStripSolidHorizontalSet ! 304: ; ! 305: ; Draw horizontal strips left to right for SRCCOPY lines. ! 306: ; ! 307: ;-----------------------------------------------------------------------; ! 308: ! 309: cProc vStripSolidHorizontalSet,12,< \ ! 310: uses esi edi ebx, \ ! 311: pStrips: ptr STRIPS, \ ! 312: pls: ptr LINESTATE, \ ! 313: plStripEnd: ptr > ! 314: ! 315: ; Do some initializing: ! 316: ! 317: mov esi, pStrips ! 318: push ebp ! 319: mov ebp, plStripEnd ! 320: mov edx, [esi].ST_lNextScan ! 321: mov al, [esi].ST_jBitMask ! 322: mov edi, [esi].ST_pjScreen ! 323: add esi, offset ST_alStrips ! 324: ! 325: ; (al) = rotating bit ! 326: ; (bl) = current mask ! 327: ; (ecx) = pixel count ! 328: ; (edx) = delta ! 329: ; (esi) = strip pointer ! 330: ; (edi) = display pointer ! 331: ; (ebp) = end of strips pointer ! 332: ! 333: next_horizontal: ! 334: mov ecx, [esi] ! 335: add esi, 4 ! 336: ! 337: lea ebx, [2 * eax - 1] ; bl = start mask ! 338: ror al, cl ; rotate bit ! 339: shr ecx, 3 ; compute # bytes to lay down ! 340: cmp bl, al ; we have to adjust for wrap ! 341: adc ecx, 0 ! 342: jnz short extends_out_of_first_byte ! 343: ! 344: sub bl, al ; zero out end bits ! 345: sub bl, al ! 346: inc bl ! 347: and [edi], bl ; write result ! 348: add edi, edx ; increment to next scan ! 349: cmp esi, ebp ; see if done strips ! 350: jb short next_horizontal ! 351: ! 352: pop ebp ; we're done ! 353: mov esi, pStrips ! 354: mov [esi].ST_pjScreen, edi ! 355: mov [esi].ST_jBitmask, al ! 356: cRet vStripSolidHorizontalSet ! 357: ! 358: extends_out_of_first_byte: ! 359: ! 360: ; This part gets called when the current strip doesn't fit entirely ! 361: ; into one byte: ! 362: ! 363: and [edi], bl ; output with start mask ! 364: inc edi ; go on to next byte ! 365: ! 366: dec ecx ; see if there's any bytes in ! 367: jnz short output_bunch ; between start and end byte ! 368: ! 369: last_byte: ! 370: lea ebx, [2 * eax - 1] ; compute end mask ! 371: not bl ! 372: and [edi], bl ; write result ! 373: add edi, edx ; increment to next scan ! 374: cmp esi, ebp ; see if done strips ! 375: jb short next_horizontal ! 376: ! 377: pop ebp ; we're done ! 378: mov esi, pStrips ! 379: mov [esi].ST_pjScreen, edi ! 380: mov [esi].ST_jBitmask, al ! 381: cRet vStripSolidHorizontalSet ! 382: ! 383: output_bunch: ! 384: ! 385: ; We have a bunch of complete bytes to lay down. Since we're doing ! 386: ; the interior of the line and we have a SRCCOPY ROP, we don't have ! 387: ; to worry about loading the latches properly, so we can do this ! 388: ; without reading the VGA memory. We also use 16 bit writes since ! 389: ; on some devices it's faster to write a single word than to write ! 390: ; two bytes -- doing so means we must be word-aligned. ! 391: ! 392: test edi, 1 ! 393: jz now_aligned ! 394: mov byte ptr [edi], 0ffh ; write a byte to get alignment right ! 395: inc edi ! 396: dec ecx ! 397: jz short last_byte ; maybe that was only byte we had to do ! 398: ! 399: now_aligned: ! 400: shr ecx, 1 ; divide by 2 to determine the number ! 401: ; of words to write ! 402: ; NOTE: We check the carry later on! ! 403: ! 404: jz short last_byte_in_bunch ; small optimization: skip word stuff ! 405: ; if we've only got a single byte ! 406: ! 407: mov ebx, eax ; save eax ! 408: mov eax, 0ffffh ; prepare ax ! 409: rep stosw ; lay those words down ! 410: mov eax, ebx ; restore eax ! 411: jnc short last_byte ; NOTE: NOW we're checking the carry! ! 412: ! 413: last_byte_in_bunch: ! 414: mov byte ptr [edi], 0ffh ; write that last byte ! 415: inc edi ! 416: jmp short last_byte ! 417: ! 418: endProc vStripSolidHorizontalSet ! 419: ! 420: ! 421: ;--------------------------Private-Routine------------------------------; ! 422: ; vStripSolidVertical ! 423: ; ! 424: ; Draw a vertical strip left to right ! 425: ; ! 426: ;-----------------------------------------------------------------------; ! 427: ! 428: cProc vStripSolidVertical,12,< \ ! 429: uses esi edi ebx, \ ! 430: pStrips: ptr STRIPS, \ ! 431: pls: ptr LINESTATE, \ ! 432: plStripEnd: ptr > ! 433: ! 434: ; So some initialization: ! 435: ! 436: mov esi, pStrips ! 437: mov edx, plStripEnd ! 438: mov ecx, [esi].ST_lNextScan ! 439: mov al, [esi].ST_jBitmask ! 440: mov edi, [esi].ST_pjScreen ! 441: add esi, offset ST_alStrips ! 442: mov [edx], ebp ; save ebp ! 443: ! 444: align 4 ! 445: next_vertical: ! 446: mov ebx, [esi] ; ebx = # bits to set ! 447: add esi, 4 ! 448: ! 449: SET_UP_UNROLL_VARS ebx,ebp,ebx,pfnWriteVerticalStripEntry, \ ! 450: LOOP_UNROLL_SHIFT ! 451: jmp ebp ! 452: ! 453: ; Table of entry points for writing a vertical strip scan: ! 454: ! 455: UNROLL_LOOP_ENTRY_TABLE pfnWriteVerticalStripEntry,VERTICAL_STRIP, \ ! 456: LOOP_UNROLL_COUNT ! 457: ! 458: ; Unrolled loop for writing a single vertical strip scan: ! 459: ! 460: WRITE_VERTICAL_STRIP macro ENTRY_LABEL,ENTRY_INDEX ! 461: &ENTRY_LABEL&ENTRY_INDEX&: ! 462: and [edi], al ; write the byte ! 463: add edi, ecx ; go to next scan ! 464: endm ;-----------------------------; ! 465: ! 466: align 4 ! 467: vertical_strip_loop: ! 468: ! 469: ; Now we're going to paste the bytes to the screen. ! 470: ; ! 471: ; (al) = rotating bit ! 472: ; (ebx) = # of complete unrolled loops to do ! 473: ; (ecx) = minor add ! 474: ; (edx) = end of strips pointer ! 475: ; (esi) = strip pointer ! 476: ; (edi) = address of byte to write ! 477: ; (ebp) = garbage ! 478: ! 479: UNROLL_LOOP WRITE_VERTICAL_STRIP,VERTICAL_STRIP,LOOP_UNROLL_COUNT ! 480: dec ebx ! 481: jnz vertical_strip_loop ! 482: ! 483: ; Adjust address and rotating bit for sidestep: ! 484: ! 485: ror al, 1 ; one to the right ! 486: adc edi, 0 ! 487: ! 488: cmp esi, edx ! 489: jl short next_vertical ; hit end of array? ! 490: ! 491: ; Remember where we left off, for next time: ! 492: ! 493: mov ebp, [edx] ; restore ebp ! 494: mov esi, pStrips ! 495: mov [esi].ST_pjScreen, edi ! 496: mov [esi].ST_jBitmask, al ! 497: cRet vStripSolidVertical ! 498: ! 499: endProc vStripSolidVertical ! 500: ! 501: ;--------------------------Private-Routine------------------------------; ! 502: ; vStripStyledHorizontal ! 503: ; ! 504: ; Draws an arbitrarily styled horizontal strip left-to-right. ! 505: ; ! 506: ;-----------------------------------------------------------------------; ! 507: ! 508: cProc vStripStyledHorizontal,12,< \ ! 509: uses esi edi ebx, \ ! 510: pStrips: ptr STRIPS, \ ! 511: pls: ptr LINESTATE, \ ! 512: plStripEnd: ptr > ! 513: ! 514: local aEnd:dword ; end of length array ! 515: local minoradd:dword ! 516: local spToGo:dword ! 517: ! 518: ; So some initialization: ! 519: ! 520: mov esi, pStrips ! 521: mov eax, plStripEnd ! 522: mov aEnd, eax ! 523: ! 524: mov eax, [esi].ST_lNextScan ! 525: mov bl, [esi].ST_jBitmask ! 526: mov edi, [esi].ST_pjScreen ! 527: mov minoradd, eax ! 528: ! 529: ; Initialize styling: ! 530: ! 531: mov eax, [esi].ST_spRemaining ! 532: mov bh, [esi].ST_jStyleMask ! 533: mov spToGo, eax ! 534: add esi, offset ST_alStrips ! 535: ! 536: Strip_loop: ! 537: mov ecx, [esi] ; ecx = # bits to write ! 538: add esi, 4 ! 539: ! 540: ; Now we're going to paste the bytes to the screen ! 541: ; ! 542: ; (al) = used to accumulate the mask ! 543: ; (bl) = rotating bit ! 544: ; (bh) = jStyleMask ! 545: ; (ecx) = # of bits to write ! 546: ; (edx) = ! 547: ; (esi) = ptr to spot in ST_alStrips ! 548: ; (edi) = address of byte to write ! 549: ! 550: xor al, al ; clear style mask ! 551: ! 552: Strip_count: ! 553: xor al, bh ; set bit in output mask if style bit 0 ! 554: or al, bl ! 555: xor al, bh ! 556: ! 557: dec spToGo ! 558: jz short Next_style_entry ! 559: ! 560: Next_bit: ! 561: ror bl, 1 ! 562: jc short Output_byte ! 563: dec ecx ! 564: jnz short Strip_count ! 565: ! 566: ; Do sidestep ! 567: ! 568: Side_step: ! 569: and byte ptr [edi], al ! 570: add edi, minoradd ! 571: ! 572: cmp esi, aEnd ! 573: jl short Strip_loop ! 574: ! 575: mov esi, pStrips ! 576: mov [esi].ST_pjScreen, edi ! 577: mov [esi].ST_jBitmask, bl ! 578: mov [esi].ST_jStyleMask, bh ! 579: mov eax, spToGo ! 580: mov [esi].ST_spRemaining, eax ! 581: ! 582: cRet vStripStyledHorizontal ! 583: ! 584: Output_byte: ! 585: and byte ptr [edi], al ! 586: xor al, al ! 587: inc edi ; Moved one byte to right on screen ! 588: dec ecx ! 589: jnz short Strip_count ! 590: jz short Side_step ! 591: ! 592: ; We're on to a new entry in the style array: ! 593: ! 594: Next_style_entry: ! 595: push eax ! 596: mov edx, pStrips ! 597: mov eax, [edx].ST_psp ! 598: add eax, 4 ! 599: cmp [edx].ST_pspEnd, eax ! 600: jae short @F ! 601: mov eax, [edx].ST_pspStart ; Go back to start of array ! 602: @@: ! 603: mov [edx].ST_psp, eax ! 604: mov edx, [eax] ; Load up new style entry ! 605: ! 606: add spToGo, edx ! 607: not bh ; jStyleMask = !jStyleMask ! 608: ! 609: pop eax ! 610: jmp short Next_bit ! 611: ! 612: endProc vStripStyledHorizontal ! 613: ! 614: ! 615: ;--------------------------Private-Routine------------------------------; ! 616: ; vStripStyledVertical ! 617: ; ! 618: ; Draw an arbitrarily styled vertical strip left-to-right. ! 619: ; ! 620: ;-----------------------------------------------------------------------; ! 621: ! 622: cProc vStripStyledVertical,12,< \ ! 623: uses esi edi ebx, \ ! 624: pStrips: ptr STRIPS, \ ! 625: pls: ptr LINESTATE, \ ! 626: plStripEnd: ptr > ! 627: ! 628: local aEnd:dword ; end of length array ! 629: local minoradd:dword ! 630: local spToGo:dword ! 631: ! 632: ; So some initialization: ! 633: ! 634: mov esi, pStrips ! 635: mov eax, plStripEnd ! 636: mov aEnd, eax ! 637: ! 638: mov ecx, [esi].ST_lNextScan ! 639: mov al, [esi].ST_jBitmask ! 640: mov edi, [esi].ST_pjScreen ! 641: mov minoradd, ecx ! 642: ! 643: ; Initialize styling: ! 644: ! 645: mov ebx, [esi].ST_spRemaining ! 646: mov ah, [esi].ST_jStyleMask ! 647: mov spToGo, ebx ! 648: add esi, offset ST_alStrips ! 649: ! 650: Strip_loop: ! 651: mov ebx, [esi] ; ebx = # bits to set ! 652: add esi, 4 ! 653: ! 654: ; Now we're going to paste the bytes to the screen ! 655: ; ! 656: ; (al) = rotating bit ! 657: ; (ah) = jStyleMask ! 658: ; (ebx) = # of bits to write ! 659: ; (ecx) = minor add ! 660: ; (edx) = ! 661: ; (esi) = ptr to spot in ST_alStrips ! 662: ; (edi) = address of byte to write ! 663: ! 664: Strip_count: ! 665: or ah, ah ! 666: jnz short @F ; Don't output pixel if in a gap ! 667: and [edi], al ! 668: @@: ! 669: dec spToGo ! 670: jz short Next_style_entry ! 671: ! 672: Minor_add: ! 673: add edi, ecx ! 674: dec ebx ! 675: jnz short Strip_count ! 676: ! 677: ; Adjust address and rotating bit for sidestep ! 678: ! 679: ror al, 1 ; one to the right ! 680: adc edi, 0 ! 681: ! 682: cmp esi, aEnd ! 683: jl short Strip_loop ; hit end of array? ! 684: ! 685: mov esi, pStrips ! 686: mov [esi].ST_pjScreen, edi ! 687: mov [esi].ST_jBitmask, al ! 688: mov [esi].ST_jStyleMask, ah ! 689: mov eax, spToGo ! 690: mov [esi].ST_spRemaining, eax ! 691: ! 692: cRet vStripStyledVertical ! 693: ! 694: Next_style_entry: ! 695: mov edx, pStrips ! 696: mov ecx, [edx].ST_psp ! 697: add ecx, 4 ! 698: cmp [edx].ST_pspEnd, ecx ! 699: jae short @F ! 700: mov ecx, [edx].ST_pspStart ; Go back to start of array ! 701: @@: ! 702: mov [edx].ST_psp, ecx ; Save our pointer ! 703: mov edx, [ecx] ; Load up new style entry ! 704: add spToGo, edx ! 705: not ah ; jStyleMask = !jStyleMask ! 706: ! 707: ; Restore the registers we used: ! 708: ! 709: mov ecx, minoradd ! 710: jmp short Minor_add ! 711: ! 712: endProc vStripStyledVertical ! 713: ! 714: ! 715: ;--------------------------Private-Routine------------------------------; ! 716: ; vStripMaskedHorizontal ! 717: ; ! 718: ; Draws a mask-styled horizontal strip left to right. ! 719: ; ! 720: ;-----------------------------------------------------------------------; ! 721: ! 722: cProc vStripMaskedHorizontal,12,< \ ! 723: uses esi edi ebx, \ ! 724: pStrips: ptr STRIPS, \ ! 725: pls: ptr LINESTATE, \ ! 726: plStripEnd: ptr > ! 727: ! 728: local aEnd:dword ; end of length array ! 729: local minoradd:dword ! 730: local density:dword ! 731: ! 732: ; So some initialization: ! 733: ! 734: mov esi, pStrips ! 735: mov eax, plStripEnd ! 736: mov aEnd, eax ! 737: mov eax, [esi].ST_lNextScan ! 738: mov bl, [esi].ST_jBitmask ! 739: mov edi, [esi].ST_pjScreen ! 740: mov minoradd, eax ! 741: ! 742: ; Initialize styling: ! 743: ! 744: mov ecx, [esi].ST_xyDensity ! 745: mov ah, byte ptr [esi].ST_spRemaining ! 746: mov bh, [esi].ST_jStyleMask ! 747: mov density, ecx ! 748: add esi, offset ST_alStrips ! 749: ! 750: Strip_loop: ! 751: mov ecx, [esi] ; ecx = # bits to write ! 752: add esi, 4 ! 753: ! 754: ; Now we're going to paste the bytes to the screen ! 755: ; ! 756: ; (al) = used to accumulate style mask ! 757: ; (ah) = # pixels left in style ! 758: ; (bl) = rotating bit ! 759: ; (bh) = style mask ! 760: ; (ecx) = # of bits to write ! 761: ; (esi) = ptr to spot in ST_alStrips ! 762: ; (edi) = address of byte to write ! 763: ! 764: xor al, al ; clear output mask ! 765: ! 766: Strip_count: ! 767: xor al, bh ; set bit in output mask if style bit 0 ! 768: or al, bl ! 769: xor al, bh ! 770: ! 771: dec ah ! 772: jnz short @F ! 773: rol bh, 1 ! 774: mov ah, byte ptr density ! 775: @@: ror bh, 1 ! 776: ror bl, 1 ! 777: jc short Output_byte ! 778: dec ecx ! 779: jnz short Strip_count ! 780: ! 781: ; Do sidestep ! 782: ! 783: Side_step: ! 784: and byte ptr [edi], al ! 785: add edi, minoradd ! 786: ! 787: cmp esi, aEnd ! 788: jl short Strip_loop ! 789: ! 790: mov esi, pStrips ! 791: ! 792: mov [esi].ST_pjScreen, edi ! 793: mov [esi].ST_jBitmask, bl ! 794: mov [esi].ST_jStyleMask, bh ! 795: mov byte ptr [esi].ST_spRemaining, ah ! 796: ! 797: cRet vStripMaskedHorizontal ! 798: ! 799: Output_byte: ! 800: and byte ptr [edi], al ! 801: xor al, al ! 802: inc edi ! 803: dec ecx ! 804: jnz short Strip_count ! 805: jz short Side_step ! 806: ! 807: endProc vStripMaskedHorizontal ! 808: ! 809: ;--------------------------Private-Routine------------------------------; ! 810: ; vStripMaskedVertical ! 811: ; ! 812: ; Draw a mask-styled vertical strip left to right. ! 813: ; ! 814: ;-----------------------------------------------------------------------; ! 815: ! 816: cProc vStripMaskedVertical,12,< \ ! 817: uses esi edi ebx, \ ! 818: pStrips: ptr STRIPS, \ ! 819: pls: ptr LINESTATE, \ ! 820: plStripEnd: ptr > ! 821: ! 822: local aEnd:dword ; end of length array ! 823: local minoradd:dword ! 824: local density:dword ! 825: ! 826: ; So some initialization: ! 827: ! 828: mov esi, pStrips ! 829: mov al, [esi].ST_jBitmask ! 830: mov edi, [esi].ST_pjScreen ! 831: mov ebx, [esi].ST_lNextScan ! 832: mov ecx, plStripEnd ! 833: mov minoradd, ebx ! 834: mov aEnd, ecx ! 835: ! 836: ; Initialize styling: ! 837: ! 838: mov ecx, [esi].ST_xyDensity ! 839: mov ah, byte ptr [esi].ST_spRemaining ! 840: mov bh, [esi].ST_jStyleMask ! 841: mov density, ecx ! 842: add esi, offset ST_alStrips ! 843: ! 844: Strip_loop: ! 845: mov ecx, [esi] ; ecx = # bits to set ! 846: add esi, 4 ! 847: ! 848: ; Now we're going to paste the bytes to the screen ! 849: ; (al) = rotating bit ! 850: ; (ah) = # pixels left in style ! 851: ; (bh) = style mask ! 852: ; (ecx) = # bits to write ! 853: ; (dx) = io address of mask register ! 854: ; (esi) = ptr to spot in ST_alStrips ! 855: ; (edi) = address of byte to write ! 856: ! 857: Strip_count: ! 858: test bh, al ! 859: jnz short @F ; don't output pixel if style bit is 1 ! 860: and [edi], al ! 861: @@: ! 862: dec ah ; we've advanced 1 pel in the style ! 863: jnz short @F ! 864: mov ah, byte ptr density ! 865: rol bh, 1 ! 866: @@: ! 867: add edi, minoradd ! 868: ! 869: dec ecx ! 870: jnz short Strip_count ! 871: ! 872: ; Adjust address, style mask and rotating bit for sidestep: ! 873: ! 874: ror bh, 1 ; rotate style mask to stay in sync ! 875: ror al, 1 ; move rotating bit one to the right ! 876: adc edi, 0 ! 877: ! 878: cmp esi, aEnd ! 879: jl short Strip_loop ; hit end of array? ! 880: ! 881: mov esi, pStrips ! 882: ! 883: mov [esi].ST_pjScreen, edi ! 884: mov [esi].ST_jBitmask, al ! 885: mov [esi].ST_jStyleMask, bh ! 886: mov byte ptr [esi].ST_spRemaining, ah ! 887: ! 888: cRet vStripMaskedVertical ! 889: ! 890: endProc vStripMaskedVertical ! 891: ! 892: _TEXT$04 ends ! 893: ! 894: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.