|
|
1.1 root 1: ;---------------------------Module-Header------------------------------;
2: ; Module Name: strips.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\driver.inc
28: include i386\lines.inc
29: include i386\unroll.inc
30: .list
31:
32: .code
33:
34: ;--------------------------Private-Routine------------------------------;
35: ; vStripSolid0
36: ;
37: ; Draw lines in the 1st half-octant.
38: ;
39: ;-----------------------------------------------------------------------;
40:
41: cProc vStripSolid0,12,< \
42: uses esi edi ebx, \
43: pStrips: ptr STRIPS, \
44: pls: ptr LINESTATE, \
45: plStripEnd: ptr >
46:
47: ; Do some initializing:
48:
49: mov esi, pStrips
50: push ebp
51: mov ebp, plStripEnd
52:
53: mov eax,[esi].ST_lNextScan
54: mov [ebp],eax ;copy delta
55:
56: mov eax,[esi].ST_chAndXor
57: mov bl,ah
58: mov bh,ah
59: mov ah,al
60:
61: mov edi,[esi].ST_pjScreen
62: add esi,offset ST_alStrips
63:
64: ; ax = and mask
65: ; bx = xor mask
66: ; ecx = pixel count
67: ; dx = temporary register
68: ; esi = strip pointer
69: ; edi = display pointer
70: ; ebp = ends of strips pointer
71: ; [ebp] = delta
72:
73: mov ecx,[esi]
74: add esi,4
75: test edi,1
76: jnz short sol0_unaligned_start
77:
78: align 4
79: sol0_aligned_loop:
80: sub ecx,2
81: jl short sol0_strip_end_unaligned
82: je short sol0_strip_end_aligned
83: mov dx,[edi]
84: and edx,eax
85: xor edx,ebx
86: mov [edi],dx
87: add edi,2
88: jmp short sol0_aligned_loop
89:
90: align 4
91: sol0_strip_end_aligned:
92: mov dx,[edi]
93: and edx,eax
94: xor edx,ebx
95: mov [edi],dx
96: add edi,2
97: add edi,[ebp] ;go to next scan
98:
99: cmp esi,ebp
100: jae short sol0_all_done
101:
102: mov ecx,[esi]
103: add esi,4
104: jmp short sol0_aligned_loop
105:
106: align 4
107: sol0_strip_end_unaligned:
108: mov dl,[edi] ;do last pixel
109: and dl,al
110: xor dl,bl
111: mov [edi],dl
112: inc edi
113: add edi,[ebp] ;go to next scan
114:
115: cmp esi,ebp
116: jae short sol0_all_done
117:
118: mov ecx,[esi] ;do first pixel of next strip
119: add esi,4
120:
121: sol0_unaligned_start:
122: mov dl,[edi]
123: and dl,al
124: xor dl,bl
125: mov [edi],dl
126: inc edi
127: dec ecx
128: jnz short sol0_aligned_loop
129:
130: ; Have to be careful when there is only one pel in the strip and it starts
131: ; on an unaligned address:
132:
133: add edi,[ebp]
134: cmp esi,ebp
135: jae short sol0_all_done
136:
137: mov ecx,[esi]
138: add esi,4
139: jmp short sol0_aligned_loop
140:
141: sol0_all_done:
142: pop ebp
143: mov esi, pStrips
144: mov [esi].ST_pjScreen,edi
145: cRet vStripSolid0
146:
147: endProc vStripSolid0
148:
149: ;--------------------------Private-Routine------------------------------;
150: ; vStripSolid1
151: ;
152: ; Draws lines in the 2nd half-octant.
153: ;
154: ;-----------------------------------------------------------------------;
155:
156: cProc vStripSolid1,12,< \
157: uses esi edi ebx, \
158: pStrips: ptr STRIPS, \
159: pls: ptr LINESTATE, \
160: plStripEnd: ptr >
161:
162: mov esi,pStrips
163: push ebp
164: mov ebp,plStripEnd
165: mov ecx,[esi].ST_lNextScan
166: inc ecx ; Make delta advance 1 to right
167: mov eax,[esi].ST_chAndXor
168: mov edi,[esi].ST_pjScreen
169: add esi,offset ST_alStrips
170:
171: ; al = and mask
172: ; ah = xor mask
173: ; ebx = pixel count
174: ; ecx = delta
175: ; dl = temporary register
176: ; esi = strip pointer
177: ; edi = memory pointer
178: ; ebp = end of strips pointer
179:
180: sol1_next_diagonal:
181: mov ebx,[esi]
182: add esi, 4
183:
184: align 4
185: sol1_diagonal_loop:
186: mov dl,[edi]
187: and dl,al
188: xor dl,ah
189: mov [edi],dl
190:
191: add edi,ecx
192: dec ebx
193: jnz short sol1_diagonal_loop
194:
195: sub edi,ecx
196: inc edi
197: cmp esi,ebp
198: jb short sol1_next_diagonal
199:
200: pop ebp
201: mov esi, pStrips
202: mov [esi].ST_pjScreen,edi
203: cRet vStripSolid1
204:
205: endProc vStripSolid1
206:
207: ;--------------------------Private-Routine------------------------------;
208: ; vStripSolid2
209: ;
210: ; Draws lines in the 3rd half-octant.
211: ;
212: ;-----------------------------------------------------------------------;
213:
214: cProc vStripSolid2,12,< \
215: uses esi edi ebx, \
216: pStrips: ptr STRIPS, \
217: pls: ptr LINESTATE, \
218: plStripEnd: ptr >
219:
220: mov esi,pStrips
221: push ebp
222: mov ebp,plStripEnd
223: mov ecx,[esi].ST_lNextScan
224: inc ecx ; Make delta advance 1 to right
225: mov eax,[esi].ST_chAndXor
226: mov edi,[esi].ST_pjScreen
227: add esi,offset ST_alStrips
228:
229: ; al = and mask
230: ; ah = xor mask
231: ; ebx = pixel count
232: ; ecx = delta
233: ; dl = temporary register
234: ; esi = strip pointer
235: ; edi = memory pointer
236: ; ebp = end of strips pointer
237:
238: align 4
239: sol2_next_diagonal:
240: mov ebx,[esi]
241: add esi,4
242:
243: align 4
244: sol2_diagonal_loop:
245: mov dl,[edi]
246: and dl,al
247: xor dl,ah
248: mov [edi],dl
249:
250: add edi,ecx
251: dec ebx
252: jnz short sol2_diagonal_loop
253:
254: dec edi
255: cmp esi,ebp
256: jb short sol2_next_diagonal
257:
258: pop ebp
259: mov esi, pStrips
260: mov [esi].ST_pjScreen,edi
261: cRet vStripSolid2
262:
263: endProc vStripSolid2
264:
265: ;--------------------------Private-Routine------------------------------;
266: ; vStripSolid3
267: ;
268: ; Draws lines in the 4th half-octant.
269: ;
270: ;-----------------------------------------------------------------------;
271:
272: cProc vStripSolid3,12,< \
273: uses esi edi ebx, \
274: pStrips: ptr STRIPS, \
275: pls: ptr LINESTATE, \
276: plStripEnd: ptr >
277:
278: mov esi,pStrips
279: push ebp
280: mov ebp,plStripEnd
281: mov ecx,[esi].ST_lNextScan
282: mov eax,[esi].ST_chAndXor
283: mov edi,[esi].ST_pjScreen
284: add esi,offset ST_alStrips
285:
286: ; al = and mask
287: ; ah = xor mask
288: ; ebx = pixel count
289: ; ecx = delta
290: ; dl = temporary register
291: ; esi = strip pointer
292: ; edi = memory pointer
293: ; ebp = end of strips pointer
294:
295: align 4
296: sol3_next_vertical:
297: mov ebx,[esi]
298: add esi,4
299:
300: align 4
301: sol3_vertical_loop:
302: mov dl,[edi]
303: and dl,al
304: xor dl,ah
305: mov [edi],dl
306:
307: add edi,ecx
308: dec ebx
309: jnz short sol3_vertical_loop
310:
311: inc edi
312: cmp esi,ebp
313: jb short sol3_next_vertical
314:
315: pop ebp
316: mov esi,pStrips
317: mov [esi].ST_pjScreen,edi
318: cRet vStripSolid3
319:
320: endProc vStripSolid3
321:
322: ;--------------------------Private-Routine------------------------------;
323: ; vStripStyled0
324: ;
325: ; Draws styled lines in the 1st half-octant.
326: ;
327: ;-----------------------------------------------------------------------;
328:
329: cProc vStripStyled0,12,< \
330: uses esi edi ebx, \
331: pStrips: ptr STRIPS, \
332: pls: ptr LINESTATE, \
333: plStripEnd: ptr >
334:
335: local ulSaveEsp: dword ;we need lotsa registers
336: local pspEnd: dword ;pointer to end of style array
337: local cjMajor: dword ;lNextScan for screen
338: local cjStyleDelta: dword ;delta from end of style array to start
339:
340: ; al = and mask
341: ; ah = xor mask
342: ; ebx = # of pixels in current strip
343: ; ecx = style pointer
344: ; edx = temporary register
345: ; esi = strips pointer
346: ; edi = memory pointer
347: ; esp = # of pixels in current style
348:
349: mov esi,pStrips
350: mov ulSaveEsp,esp
351:
352: mov eax,[esi].ST_lNextScan
353: mov cjMajor,eax
354: mov eax,[esi].ST_pspEnd
355: mov pspEnd,eax
356: mov ebx,[esi].ST_pspStart
357: sub ebx,eax ;compute cjStyleDelta
358: sub ebx,4 ;make it exclusive
359: mov cjStyleDelta,ebx
360:
361: mov eax,[esi].ST_chAndXor
362: mov ecx,[esi].ST_psp
363: mov edx,[esi].ST_bIsGap
364: mov edi,[esi].ST_pjScreen
365: mov esp,[esi].ST_spRemaining
366: add esi,offset ST_alStrips
367:
368: mov ebx,[esi]
369: add esi,4
370:
371: or edx,edx
372: jz short sty0_output_loop ;if working on a dash, start there
373: jmp short sty0_skip_loop ;if working on a gap, start there
374:
375: sty0_prepare_for_output:
376: add edi,esp ;adjust to do remainder of strip
377:
378: add ecx,4
379: cmp pspEnd,ecx ;if (ecx == pspEnd + 4)
380: sbb edx,edx ; then ecx = pspStart
381: and edx,cjStyleDelta
382: add ecx,edx
383:
384: mov ebx,esp
385: mov esp,[ecx] ;get next style array element
386: neg ebx
387: jz short sty0_output_get_new_strip
388:
389: align 4
390: sty0_output_loop:
391: mov dl,[edi]
392: and dl,al
393: xor dl,ah
394: mov [edi],dl ;write pixel
395: inc edi ;move one pixel to right
396: dec esp ;might have to go to next style element
397: jz short sty0_prepare_for_skip
398:
399: dec ebx
400: jnz short sty0_output_loop
401:
402: sty0_output_get_new_strip:
403: add edi,cjMajor ;move up one scan
404: cmp esi,plStripEnd
405: jae short sty0_output_all_done
406:
407: mov ebx,[esi] ;get next strip
408: add esi,4
409: jmp short sty0_output_loop
410:
411: sty0_output_all_done:
412: mov esi,pStrips
413: mov [esi].ST_pjScreen,edi
414: mov [esi].ST_bIsGap,0 ;we were working on a dash
415: mov [esi].ST_spRemaining,esp
416: mov [esi].ST_psp,ecx
417: mov esp,ulSaveEsp
418: cRet vStripStyled0
419:
420: sty0_prepare_for_skip:
421: add ecx,4
422: cmp pspEnd,ecx ;if (ecx == pspEnd + 4)
423: sbb edx,edx ; then ecx = pspStart
424: and edx,cjStyleDelta
425: add ecx,edx
426:
427: dec ebx
428: mov esp,[ecx] ;get next style array element
429: jz short sty0_skip_get_new_strip
430:
431: sty0_skip_loop:
432: add edi,ebx ;assume we'll skip entire strip
433: sub esp,ebx ; (we'll correct it if not)
434: jle short sty0_prepare_for_output
435:
436: sty0_skip_get_new_strip:
437: add edi,cjMajor ;move up one scan
438: cmp esi,plStripEnd
439: jae short sty0_skip_all_done
440:
441: mov ebx,[esi] ;get next strip
442: add esi,4
443: jmp short sty0_skip_loop
444:
445: sty0_skip_all_done:
446: mov esi,pStrips
447: mov [esi].ST_pjScreen,edi
448: mov [esi].ST_bIsGap,0ffh ;we were working on a gap
449: mov [esi].ST_spRemaining,esp
450: mov [esi].ST_psp,ecx
451: mov esp,ulSaveEsp
452: cRet vStripStyled0
453:
454: endProc vStripStyled0
455:
456: ;--------------------------Private-Routine------------------------------;
457: ; vStripStyled123
458: ;
459: ; Draws styled lines in the 2nd, 3rd and 4th half-octants.
460: ;
461: ;-----------------------------------------------------------------------;
462:
463: cProc vStripStyled123,12,< \
464: uses esi edi ebx, \
465: pStrips: ptr STRIPS, \
466: pls: ptr LINESTATE, \
467: plStripEnd: ptr >
468:
469: local ulSaveEsp: dword ;we need lotsa registers
470: local pspEnd: dword ;pointer to end of style array
471: local cjMajor: dword ;delta to go in major direction
472: local cjMinor: dword ;delta to go in minor direction
473: local cjStyleDelta: dword ;delta from end of style array to start
474:
475: ; al = and mask
476: ; ah = xor mask
477: ; ebx = # of pixels in current strip
478: ; ecx = style pointer
479: ; edx = temporary register
480: ; esi = strips pointer
481: ; edi = memory pointer
482: ; esp = # of pixels in current style
483:
484: mov esi,pStrips
485: mov ulSaveEsp,esp
486:
487: ; If in half-octant 3, cjMajor = cjDelta and cjMinor = 1
488: ; If in half-octant 2, cjMajor = cjDelta + 1 and cjMinor = -1
489: ; If in half-octant 1, cjMajor = cjDelta + 1 and cjMinor = -cjDelta
490:
491: mov eax,[esi].ST_lNextScan
492: mov ebx,[esi].ST_flFlips
493: test ebx,FL_FLIP_HALF
494: jz short sty3_halfoctant_3
495:
496: inc eax
497: mov cjMajor,eax
498: mov cjMinor,-1
499:
500: test ebx,FL_FLIP_D
501: jnz short sty3_done_major_minor_comp
502:
503: neg eax
504: inc eax
505: mov cjMinor,eax
506: jmp short sty3_done_major_minor_comp
507:
508: sty3_halfoctant_3:
509: mov cjMajor,eax
510: mov cjMinor,1
511:
512: sty3_done_major_minor_comp:
513: mov eax,[esi].ST_pspEnd
514: mov pspEnd,eax
515: mov ebx,[esi].ST_pspStart
516: sub ebx,eax ;compute cjStyleDelta
517: sub ebx,4 ;make it exclusive
518: mov cjStyleDelta,ebx
519:
520: mov eax,[esi].ST_chAndXor
521: mov ecx,[esi].ST_psp
522: mov edx,[esi].ST_bIsGap
523: mov edi,[esi].ST_pjScreen
524: mov esp,[esi].ST_spRemaining
525: add esi,offset ST_alStrips
526:
527: mov ebx,[esi]
528: add esi,4
529:
530: or edx,edx
531: jz short sty3_output_loop ;if working on a dash, start there
532: jmp short sty3_skip_loop ;if working on a gap, start there
533:
534: sty3_prepare_for_output:
535: add ecx,4
536: cmp pspEnd,ecx ;if (ecx == pspEnd + 4)
537: sbb edx,edx ; then ecx = pspStart
538: and edx,cjStyleDelta
539: add ecx,edx
540:
541: mov ebx,esp
542: mov esp,[ecx] ;get next style array element
543: neg ebx ;adjust to do remainder of strip
544:
545: jz short sty3_output_get_new_strip
546:
547: align 4
548: sty3_output_loop:
549: mov dl,[edi]
550: and dl,al
551: xor dl,ah
552: mov [edi],dl ;write pixel
553: add edi,cjMajor ;move to next scan
554: dec esp ;might have to go to next style element
555: jz short sty3_prepare_for_skip
556:
557: dec ebx
558: jnz short sty3_output_loop
559:
560: sty3_output_get_new_strip:
561: add edi,cjMinor ;move one pixel in minor direction
562: cmp esi,plStripEnd
563: jae short sty3_output_all_done
564:
565: mov ebx,[esi] ;get next strip
566: add esi,4
567: jmp short sty3_output_loop
568:
569: sty3_output_all_done:
570: mov esi,pStrips
571: mov [esi].ST_pjScreen,edi
572: mov [esi].ST_bIsGap,0 ;we were working on a dash
573: mov [esi].ST_spRemaining,esp
574: mov [esi].ST_psp,ecx
575: mov esp,ulSaveEsp
576: cRet vStripStyled123
577:
578: sty3_prepare_for_skip:
579: add ecx,4
580: cmp pspEnd,ecx ;if (ecx == pspEnd + 4)
581: sbb edx,edx ; then ecx = pspStart
582: and edx,cjStyleDelta
583: add ecx,edx
584:
585: dec ebx
586: mov esp,[ecx] ;get next style array element
587: jz short sty3_skip_get_new_strip
588:
589: sty3_skip_loop:
590:
591: ; compute min(left in strip, left in style)
592:
593: sub esp,ebx ;esp = # style - # strip
594: sbb edx,edx
595: and edx,esp
596: add ebx,edx ;ebx = min(pels left in strip,
597: ; pels left in style)
598:
599: mov edx,cjMajor
600: imul edx,ebx
601: add edi,edx ;adjust our pointer
602:
603: cmp esp,0
604: jle short sty3_prepare_for_output
605:
606: sty3_skip_get_new_strip:
607: add edi,cjMinor ;move one pixel in minor direction
608: cmp esi,plStripEnd
609: jae short sty3_skip_all_done
610:
611: mov ebx,[esi] ;get next strip
612: add esi,4
613: jmp short sty3_skip_loop
614:
615: sty3_skip_all_done:
616: mov esi,pStrips
617: mov [esi].ST_pjScreen,edi
618: mov [esi].ST_bIsGap,0ffh ;we were working on a gap
619: mov [esi].ST_spRemaining,esp
620: mov [esi].ST_psp,ecx
621: mov esp,ulSaveEsp
622: cRet vStripStyled123
623:
624: endProc vStripStyled123
625:
626: ;--------------------------Private-Routine------------------------------;
627: ; vStripSolidSet0
628: ;
629: ; Draw lines in the 1st half-octant.
630: ;
631: ;-----------------------------------------------------------------------;
632:
633: cProc vStripSolidSet0,12,< \
634: uses esi edi ebx, \
635: pStrips: ptr STRIPS, \
636: pls: ptr LINESTATE, \
637: plStripEnd: ptr >
638:
639: ; Do some initializing:
640:
641: mov esi, pStrips
642: push ebp
643: mov ebp, plStripEnd
644:
645: mov eax,[esi].ST_lNextScan
646: mov [ebp],eax ;copy delta
647:
648: mov eax,[esi].ST_chAndXor
649: mov bl,ah
650: mov bh,ah
651: mov ah,al
652:
653: mov edi,[esi].ST_pjScreen
654: add esi,offset ST_alStrips
655:
656: ; ax = and mask
657: ; bx = xor mask
658: ; ecx = pixel count
659: ; dx = temporary register
660: ; esi = strip pointer
661: ; edi = display pointer
662: ; ebp = ends of strips pointer
663: ; [ebp] = delta
664:
665: mov ecx,[esi]
666: add esi,4
667: test edi,1
668: jnz short sol0s_unaligned_start
669:
670: align 4
671: sol0s_aligned_loop:
672: sub ecx,2
673: jl short sol0s_strip_end_unaligned
674: je short sol0s_strip_end_aligned
675: mov [edi],bx
676: add edi,2
677: jmp short sol0s_aligned_loop
678:
679: align 4
680: sol0s_strip_end_aligned:
681: mov [edi],bx
682: add edi,2
683: add edi,[ebp] ;go to next scan
684:
685: cmp esi,ebp
686: jae short sol0s_all_done
687:
688: mov ecx,[esi]
689: add esi,4
690: jmp short sol0s_aligned_loop
691:
692: align 4
693: sol0s_strip_end_unaligned:
694: mov [edi],bl ;do last pixel
695: inc edi
696: add edi,[ebp] ;go to next scan
697:
698: cmp esi,ebp
699: jae short sol0s_all_done
700:
701: mov ecx,[esi] ;do first pixel of next strip
702: add esi,4
703:
704: sol0s_unaligned_start:
705: mov [edi],bl
706: inc edi
707: dec ecx
708: jnz short sol0s_aligned_loop
709:
710: ; Have to be careful when there is only one pel in the strip and it starts
711: ; on an unaligned address:
712:
713: add edi,[ebp]
714: cmp esi,ebp
715: jae short sol0s_all_done
716:
717: mov ecx,[esi]
718: add esi,4
719: jmp short sol0s_aligned_loop
720:
721: sol0s_all_done:
722: pop ebp
723: mov esi, pStrips
724: mov [esi].ST_pjScreen,edi
725: cRet vStripSolidSet0
726:
727: endProc vStripSolidSet0
728:
729: ;--------------------------Private-Routine------------------------------;
730: ; vStripSolidSet1
731: ;
732: ; Draws lines in the 2nd half-octant.
733: ;
734: ;-----------------------------------------------------------------------;
735:
736: cProc vStripSolidSet1,12,< \
737: uses esi edi ebx, \
738: pStrips: ptr STRIPS, \
739: pls: ptr LINESTATE, \
740: plStripEnd: ptr >
741:
742: mov esi,pStrips
743: push ebp
744: mov ebp,plStripEnd
745: mov ecx,[esi].ST_lNextScan
746: inc ecx ; Make delta advance 1 to right
747: mov eax,[esi].ST_chAndXor
748: mov edi,[esi].ST_pjScreen
749: add esi,offset ST_alStrips
750:
751: ; al = and mask
752: ; ah = xor mask
753: ; ebx = pixel count
754: ; ecx = delta
755: ; dl = temporary register
756: ; esi = strip pointer
757: ; edi = memory pointer
758: ; ebp = end of strips pointer
759:
760: align 4
761: sol1s_next_diagonal:
762: mov ebx,[esi]
763: add esi, 4
764:
765: align 4
766: sol1s_diagonal_loop:
767: mov [edi],ah
768:
769: add edi,ecx
770: dec ebx
771: jnz short sol1s_diagonal_loop
772:
773: sub edi,ecx
774: inc edi
775: cmp esi,ebp
776: jb short sol1s_next_diagonal
777:
778: pop ebp
779: mov esi, pStrips
780: mov [esi].ST_pjScreen,edi
781: cRet vStripSolidSet1
782:
783: endProc vStripSolidSet1
784:
785: ;--------------------------Private-Routine------------------------------;
786: ; vStripSolidSet2
787: ;
788: ; Draws lines in the 3rd half-octant.
789: ;
790: ;-----------------------------------------------------------------------;
791:
792: cProc vStripSolidSet2,12,< \
793: uses esi edi ebx, \
794: pStrips: ptr STRIPS, \
795: pls: ptr LINESTATE, \
796: plStripEnd: ptr >
797:
798: mov esi,pStrips
799: push ebp
800: mov ebp,plStripEnd
801: mov ecx,[esi].ST_lNextScan
802: inc ecx ; Make delta advance 1 to right
803: mov eax,[esi].ST_chAndXor
804: mov edi,[esi].ST_pjScreen
805: add esi,offset ST_alStrips
806:
807: ; al = and mask
808: ; ah = xor mask
809: ; ebx = pixel count
810: ; ecx = delta
811: ; dl = temporary register
812: ; esi = strip pointer
813: ; edi = memory pointer
814: ; ebp = end of strips pointer
815:
816: align 4
817: sol2s_next_diagonal:
818: mov ebx,[esi]
819: add esi,4
820:
821: align 4
822: sol2s_diagonal_loop:
823: mov [edi],ah
824:
825: add edi,ecx
826: dec ebx
827: jnz short sol2s_diagonal_loop
828:
829: dec edi
830: cmp esi,ebp
831: jb short sol2s_next_diagonal
832:
833: pop ebp
834: mov esi, pStrips
835: mov [esi].ST_pjScreen,edi
836: cRet vStripSolidSet2
837:
838: endProc vStripSolidSet2
839:
840: ;--------------------------Private-Routine------------------------------;
841: ; vStripSolidSet3
842: ;
843: ; Draws lines in the 4th half-octant.
844: ;
845: ;-----------------------------------------------------------------------;
846:
847: cProc vStripSolidSet3,12,< \
848: uses esi edi ebx, \
849: pStrips: ptr STRIPS, \
850: pls: ptr LINESTATE, \
851: plStripEnd: ptr >
852:
853: mov esi,pStrips
854: push ebp
855: mov ebp,plStripEnd
856: mov ecx,[esi].ST_lNextScan
857: mov eax,[esi].ST_chAndXor
858: mov edi,[esi].ST_pjScreen
859: add esi,offset ST_alStrips
860:
861: ; al = and mask
862: ; ah = xor mask
863: ; ebx = pixel count
864: ; ecx = delta
865: ; dl = temporary register
866: ; esi = strip pointer
867: ; edi = memory pointer
868: ; ebp = end of strips pointer
869:
870: align 4
871: sol3s_next_vertical:
872: mov ebx,[esi]
873: add esi,4
874:
875: align 4
876: sol3s_vertical_loop:
877: mov [edi],ah
878:
879: add edi,ecx
880: dec ebx
881: jnz short sol3s_vertical_loop
882:
883: inc edi
884: cmp esi,ebp
885: jb short sol3s_next_vertical
886:
887: pop ebp
888: mov esi,pStrips
889: mov [esi].ST_pjScreen,edi
890: cRet vStripSolidSet3
891:
892: endProc vStripSolidSet3
893:
894: ;--------------------------Private-Routine------------------------------;
895: ; vStripStyledSet0
896: ;
897: ; Draws styled lines in the 1st half-octant.
898: ;
899: ;-----------------------------------------------------------------------;
900:
901: cProc vStripStyledSet0,12,< \
902: uses esi edi ebx, \
903: pStrips: ptr STRIPS, \
904: pls: ptr LINESTATE, \
905: plStripEnd: ptr >
906:
907: local ulSaveEsp: dword ;we need lotsa registers
908: local pspEnd: dword ;pointer to end of style array
909: local cjMajor: dword ;lNextScan for screen
910: local cjStyleDelta: dword ;delta from end of style array to start
911:
912: ; al = and mask
913: ; ah = xor mask
914: ; ebx = # of pixels in current strip
915: ; ecx = style pointer
916: ; edx = temporary register
917: ; esi = strips pointer
918: ; edi = memory pointer
919: ; esp = # of pixels in current style
920:
921: mov esi,pStrips
922: mov ulSaveEsp,esp
923:
924: mov eax,[esi].ST_lNextScan
925: mov cjMajor,eax
926: mov eax,[esi].ST_pspEnd
927: mov pspEnd,eax
928: mov ebx,[esi].ST_pspStart
929: sub ebx,eax ;compute cjStyleDelta
930: sub ebx,4 ;make it exclusive
931: mov cjStyleDelta,ebx
932:
933: mov eax,[esi].ST_chAndXor
934: mov ecx,[esi].ST_psp
935: mov edx,[esi].ST_bIsGap
936: mov edi,[esi].ST_pjScreen
937: mov esp,[esi].ST_spRemaining
938: add esi,offset ST_alStrips
939:
940: mov ebx,[esi]
941: add esi,4
942:
943: or edx,edx
944: jz short sty0s_output_loop ;if working on a dash, start there
945: jmp short sty0s_skip_loop ;if working on a gap, start there
946:
947: sty0s_prepare_for_output:
948: add edi,esp ;adjust to do remainder of strip
949:
950: add ecx,4
951: cmp pspEnd,ecx ;if (ecx == pspEnd + 4)
952: sbb edx,edx ; then ecx = pspStart
953: and edx,cjStyleDelta
954: add ecx,edx
955:
956: mov ebx,esp
957: mov esp,[ecx] ;get next style array element
958: neg ebx ;see if we also need a new strip
959: jz short sty0s_output_get_new_strip
960:
961: align 4
962: sty0s_output_loop:
963: mov [edi],ah ;write pixel
964: inc edi ;move one pixel to right
965: dec esp ;might have to go to next style element
966: jz short sty0s_prepare_for_skip
967:
968: dec ebx
969: jnz short sty0s_output_loop
970:
971: sty0s_output_get_new_strip:
972: add edi,cjMajor ;move up one scan
973: cmp esi,plStripEnd
974: jae short sty0s_output_all_done
975:
976: mov ebx,[esi] ;get next strip
977: add esi,4
978: jmp short sty0s_output_loop
979:
980: sty0s_output_all_done:
981: mov esi,pStrips
982: mov [esi].ST_pjScreen,edi
983: mov [esi].ST_bIsGap,0 ;we were working on a dash
984: mov [esi].ST_spRemaining,esp
985: mov [esi].ST_psp,ecx
986: mov esp,ulSaveEsp
987: cRet vStripStyledSet0
988:
989: sty0s_prepare_for_skip:
990: add ecx,4
991: cmp pspEnd,ecx ;if (ecx == pspEnd + 4)
992: sbb edx,edx ; then ecx = pspStart
993: and edx,cjStyleDelta
994: add ecx,edx
995:
996: dec ebx
997: mov esp,[ecx] ;get next style array element
998: jz short sty0s_skip_get_new_strip
999:
1000: sty0s_skip_loop:
1001: add edi,ebx ;assume we'll skip entire strip
1002: sub esp,ebx ; (we'll correct it if not)
1003: jle short sty0s_prepare_for_output
1004:
1005: sty0s_skip_get_new_strip:
1006: add edi,cjMajor ;move up one scan
1007: cmp esi,plStripEnd
1008: jae short sty0s_skip_all_done
1009:
1010: mov ebx,[esi] ;get next strip
1011: add esi,4
1012: jmp short sty0s_skip_loop
1013:
1014: sty0s_skip_all_done:
1015: mov esi,pStrips
1016: mov [esi].ST_pjScreen,edi
1017: mov [esi].ST_bIsGap,0ffh ;we were working on a gap
1018: mov [esi].ST_spRemaining,esp
1019: mov [esi].ST_psp,ecx
1020: mov esp,ulSaveEsp
1021: cRet vStripStyledSet0
1022:
1023: endProc vStripStyledSet0
1024:
1025: ;--------------------------Private-Routine------------------------------;
1026: ; vStripStyledSet123
1027: ;
1028: ; Draws styled lines in the 2nd, 3rd and 4th half-octants.
1029: ;
1030: ;-----------------------------------------------------------------------;
1031:
1032: cProc vStripStyledSet123,12,< \
1033: uses esi edi ebx, \
1034: pStrips: ptr STRIPS, \
1035: pls: ptr LINESTATE, \
1036: plStripEnd: ptr >
1037:
1038: local ulSaveEsp: dword ;we need lotsa registers
1039: local pspEnd: dword ;pointer to end of style array
1040: local cjMajor: dword ;delta to go in major direction
1041: local cjMinor: dword ;delta to go in minor direction
1042: local cjStyleDelta: dword ;delta from end of style array to start
1043:
1044: ; al = and mask
1045: ; ah = xor mask
1046: ; ebx = # of pixels in current strip
1047: ; ecx = style pointer
1048: ; edx = temporary register
1049: ; esi = strips pointer
1050: ; edi = memory pointer
1051: ; esp = # of pixels in current style
1052:
1053: mov esi,pStrips
1054: mov ulSaveEsp,esp
1055:
1056: ; If in half-octant 3, cjMajor = cjDelta and cjMinor = 1
1057: ; If in half-octant 2, cjMajor = cjDelta + 1 and cjMinor = -1
1058: ; If in half-octant 1, cjMajor = cjDelta + 1 and cjMinor = -cjDelta
1059:
1060: mov eax,[esi].ST_lNextScan
1061: mov ebx,[esi].ST_flFlips
1062: test ebx,FL_FLIP_HALF
1063: jz short sty3s_halfoctant_3
1064:
1065: inc eax
1066: mov cjMajor,eax
1067: mov cjMinor,-1
1068:
1069: test ebx,FL_FLIP_D
1070: jnz short sty3s_done_major_minor_comp
1071:
1072: neg eax
1073: inc eax
1074: mov cjMinor,eax
1075: jmp short sty3s_done_major_minor_comp
1076:
1077: sty3s_halfoctant_3:
1078: mov cjMajor,eax
1079: mov cjMinor,1
1080:
1081: sty3s_done_major_minor_comp:
1082: mov eax,[esi].ST_pspEnd
1083: mov pspEnd,eax
1084: mov ebx,[esi].ST_pspStart
1085: sub ebx,eax ;compute cjStyleDelta
1086: sub ebx,4 ;make it exclusive
1087: mov cjStyleDelta,ebx
1088:
1089: mov eax,[esi].ST_chAndXor
1090: mov ecx,[esi].ST_psp
1091: mov edx,[esi].ST_bIsGap
1092: mov edi,[esi].ST_pjScreen
1093: mov esp,[esi].ST_spRemaining
1094: add esi,offset ST_alStrips
1095:
1096: mov ebx,[esi]
1097: add esi,4
1098:
1099: or edx,edx
1100: jz short sty3s_output_loop ;if working on a dash, start there
1101: jmp short sty3s_skip_loop ;if working on a gap, start there
1102:
1103: sty3s_prepare_for_output:
1104: add ecx,4
1105: cmp pspEnd,ecx ;if (ecx == pspEnd + 4)
1106: sbb edx,edx ; then ecx = pspStart
1107: and edx,cjStyleDelta
1108: add ecx,edx
1109:
1110: mov ebx,esp
1111: mov esp,[ecx] ;get next style array element
1112: neg ebx ;adjust to do remainder of strip
1113: jz short sty3s_output_get_new_strip
1114:
1115: align 4
1116: sty3s_output_loop:
1117: mov [edi],ah ;write pixel
1118: add edi,cjMajor ;move to next scan
1119: dec esp ;might have to go to next style element
1120: jz short sty3s_prepare_for_skip
1121:
1122: dec ebx
1123: jnz short sty3s_output_loop
1124:
1125: sty3s_output_get_new_strip:
1126: add edi,cjMinor ;move in minor direction
1127: cmp esi,plStripEnd
1128: jae short sty3s_output_all_done
1129:
1130: mov ebx,[esi] ;get next strip
1131: add esi,4
1132: jmp short sty3s_output_loop
1133:
1134: sty3s_output_all_done:
1135: mov esi,pStrips
1136: mov [esi].ST_pjScreen,edi
1137: mov [esi].ST_bIsGap,0 ;we were working on a dash
1138: mov [esi].ST_spRemaining,esp
1139: mov [esi].ST_psp,ecx
1140: mov esp,ulSaveEsp
1141: cRet vStripStyledSet123
1142:
1143: sty3s_prepare_for_skip:
1144: add ecx,4
1145: cmp pspEnd,ecx ;if (ecx == pspEnd + 4)
1146: sbb edx,edx ; then ecx = pspStart
1147: and edx,cjStyleDelta
1148: add ecx,edx
1149:
1150: dec ebx
1151: mov esp,[ecx] ;get next style array element
1152: jz short sty3s_skip_get_new_strip
1153:
1154: sty3s_skip_loop:
1155:
1156: ; compute min(left in strip, left in style)
1157:
1158: sub esp,ebx ;esp = # style - # strip
1159: sbb edx,edx
1160: and edx,esp
1161: add ebx,edx ;ebx = min(pels left in strip,
1162: ; pels left in style)
1163:
1164: mov edx,cjMajor
1165: imul edx,ebx
1166: add edi,edx ;adjust our pointer
1167:
1168: cmp esp,0
1169: jle short sty3s_prepare_for_output
1170:
1171: sty3s_skip_get_new_strip:
1172: add edi,cjMinor ;move in minor direction
1173: cmp esi,plStripEnd
1174: jae short sty3s_skip_all_done
1175:
1176: mov ebx,[esi] ;get next strip
1177: add esi,4
1178: jmp short sty3s_skip_loop
1179:
1180: sty3s_skip_all_done:
1181: mov esi,pStrips
1182: mov [esi].ST_pjScreen,edi
1183: mov [esi].ST_bIsGap,0ffh ;we were working on a gap
1184: mov [esi].ST_spRemaining,esp
1185: mov [esi].ST_psp,ecx
1186: mov esp,ulSaveEsp
1187: cRet vStripStyledSet123
1188:
1189: endProc vStripStyledSet123
1190:
1191: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.