|
|
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.