|
|
1.1 root 1: //
2: // d_spr8.s
3: // x86 assembly-language horizontal 8-bpp transparent span-drawing code.
4: //
5:
6: #include "qasm.h"
7:
8: #if id386
9:
10: //----------------------------------------------------------------------
11: // 8-bpp horizontal span drawing code for polygons, with transparency.
12: //----------------------------------------------------------------------
13:
14: .text
15:
16: // out-of-line, rarely-needed clamping code
17:
18: LClampHigh0:
19: movl C(bbextents),%esi
20: jmp LClampReentry0
21: LClampHighOrLow0:
22: jg LClampHigh0
23: xorl %esi,%esi
24: jmp LClampReentry0
25:
26: LClampHigh1:
27: movl C(bbextentt),%edx
28: jmp LClampReentry1
29: LClampHighOrLow1:
30: jg LClampHigh1
31: xorl %edx,%edx
32: jmp LClampReentry1
33:
34: LClampLow2:
35: movl $2048,%ebp
36: jmp LClampReentry2
37: LClampHigh2:
38: movl C(bbextents),%ebp
39: jmp LClampReentry2
40:
41: LClampLow3:
42: movl $2048,%ecx
43: jmp LClampReentry3
44: LClampHigh3:
45: movl C(bbextentt),%ecx
46: jmp LClampReentry3
47:
48: LClampLow4:
49: movl $2048,%eax
50: jmp LClampReentry4
51: LClampHigh4:
52: movl C(bbextents),%eax
53: jmp LClampReentry4
54:
55: LClampLow5:
56: movl $2048,%ebx
57: jmp LClampReentry5
58: LClampHigh5:
59: movl C(bbextentt),%ebx
60: jmp LClampReentry5
61:
62:
63: #define pspans 4+16
64:
65: .align 4
66: .globl C(D_SpriteDrawSpans)
67: C(D_SpriteDrawSpans):
68: pushl %ebp // preserve caller's stack frame
69: pushl %edi
70: pushl %esi // preserve register variables
71: pushl %ebx
72:
73: //
74: // set up scaled-by-8 steps, for 8-long segments; also set up cacheblock
75: // and span list pointers, and 1/z step in 0.32 fixed-point
76: //
77: // FIXME: any overlap from rearranging?
78: flds C(d_sdivzstepu)
79: fmuls fp_8
80: movl C(cacheblock),%edx
81: flds C(d_tdivzstepu)
82: fmuls fp_8
83: movl pspans(%esp),%ebx // point to the first span descriptor
84: flds C(d_zistepu)
85: fmuls fp_8
86: movl %edx,pbase // pbase = cacheblock
87: flds C(d_zistepu)
88: fmuls fp_64kx64k
89: fxch %st(3)
90: fstps sdivz8stepu
91: fstps zi8stepu
92: fstps tdivz8stepu
93: fistpl izistep
94: movl izistep,%eax
95: rorl $16,%eax // put upper 16 bits in low word
96: movl sspan_t_count(%ebx),%ecx
97: movl %eax,izistep
98:
99: cmpl $0,%ecx
100: jle LNextSpan
101:
102: LSpanLoop:
103:
104: //
105: // set up the initial s/z, t/z, and 1/z on the FP stack, and generate the
106: // initial s and t values
107: //
108: // FIXME: pipeline FILD?
109: fildl sspan_t_v(%ebx)
110: fildl sspan_t_u(%ebx)
111:
112: fld %st(1) // dv | du | dv
113: fmuls C(d_sdivzstepv) // dv*d_sdivzstepv | du | dv
114: fld %st(1) // du | dv*d_sdivzstepv | du | dv
115: fmuls C(d_sdivzstepu) // du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
116: fld %st(2) // du | du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
117: fmuls C(d_tdivzstepu) // du*d_tdivzstepu | du*d_sdivzstepu |
118: // dv*d_sdivzstepv | du | dv
119: fxch %st(1) // du*d_sdivzstepu | du*d_tdivzstepu |
120: // dv*d_sdivzstepv | du | dv
121: faddp %st(0),%st(2) // du*d_tdivzstepu |
122: // du*d_sdivzstepu + dv*d_sdivzstepv | du | dv
123: fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv |
124: // du*d_tdivzstepu | du | dv
125: fld %st(3) // dv | du*d_sdivzstepu + dv*d_sdivzstepv |
126: // du*d_tdivzstepu | du | dv
127: fmuls C(d_tdivzstepv) // dv*d_tdivzstepv |
128: // du*d_sdivzstepu + dv*d_sdivzstepv |
129: // du*d_tdivzstepu | du | dv
130: fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv |
131: // dv*d_tdivzstepv | du*d_tdivzstepu | du | dv
132: fadds C(d_sdivzorigin) // sdivz = d_sdivzorigin + dv*d_sdivzstepv +
133: // du*d_sdivzstepu; stays in %st(2) at end
134: fxch %st(4) // dv | dv*d_tdivzstepv | du*d_tdivzstepu | du |
135: // s/z
136: fmuls C(d_zistepv) // dv*d_zistepv | dv*d_tdivzstepv |
137: // du*d_tdivzstepu | du | s/z
138: fxch %st(1) // dv*d_tdivzstepv | dv*d_zistepv |
139: // du*d_tdivzstepu | du | s/z
140: faddp %st(0),%st(2) // dv*d_zistepv |
141: // dv*d_tdivzstepv + du*d_tdivzstepu | du | s/z
142: fxch %st(2) // du | dv*d_tdivzstepv + du*d_tdivzstepu |
143: // dv*d_zistepv | s/z
144: fmuls C(d_zistepu) // du*d_zistepu |
145: // dv*d_tdivzstepv + du*d_tdivzstepu |
146: // dv*d_zistepv | s/z
147: fxch %st(1) // dv*d_tdivzstepv + du*d_tdivzstepu |
148: // du*d_zistepu | dv*d_zistepv | s/z
149: fadds C(d_tdivzorigin) // tdivz = d_tdivzorigin + dv*d_tdivzstepv +
150: // du*d_tdivzstepu; stays in %st(1) at end
151: fxch %st(2) // dv*d_zistepv | du*d_zistepu | t/z | s/z
152: faddp %st(0),%st(1) // dv*d_zistepv + du*d_zistepu | t/z | s/z
153:
154: flds fp_64k // fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z
155: fxch %st(1) // dv*d_zistepv + du*d_zistepu | fp_64k | t/z | s/z
156: fadds C(d_ziorigin) // zi = d_ziorigin + dv*d_zistepv +
157: // du*d_zistepu; stays in %st(0) at end
158: // 1/z | fp_64k | t/z | s/z
159:
160: fld %st(0) // FIXME: get rid of stall on FMUL?
161: fmuls fp_64kx64k
162: fxch %st(1)
163:
164: //
165: // calculate and clamp s & t
166: //
167: fdivr %st(0),%st(2) // 1/z | z*64k | t/z | s/z
168: fxch %st(1)
169:
170: fistpl izi // 0.32 fixed-point 1/z
171: movl izi,%ebp
172:
173: //
174: // set pz to point to the first z-buffer pixel in the span
175: //
176: rorl $16,%ebp // put upper 16 bits in low word
177: movl sspan_t_v(%ebx),%eax
178: movl %ebp,izi
179: movl sspan_t_u(%ebx),%ebp
180: imull C(d_zrowbytes)
181: shll $1,%ebp // a word per pixel
182: addl C(d_pzbuffer),%eax
183: addl %ebp,%eax
184: movl %eax,pz
185:
186: //
187: // point %edi to the first pixel in the span
188: //
189: movl C(d_viewbuffer),%ebp
190: movl sspan_t_v(%ebx),%eax
191: pushl %ebx // preserve spans pointer
192: movl C(tadjust),%edx
193: movl C(sadjust),%esi
194: movl C(d_scantable)(,%eax,4),%edi // v * screenwidth
195: addl %ebp,%edi
196: movl sspan_t_u(%ebx),%ebp
197: addl %ebp,%edi // pdest = &pdestspan[scans->u];
198:
199: //
200: // now start the FDIV for the end of the span
201: //
202: cmpl $8,%ecx
203: ja LSetupNotLast1
204:
205: decl %ecx
206: jz LCleanup1 // if only one pixel, no need to start an FDIV
207: movl %ecx,spancountminus1
208:
209: // finish up the s and t calcs
210: fxch %st(1) // z*64k | 1/z | t/z | s/z
211:
212: fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
213: fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
214: fxch %st(1) // z*64k | s | 1/z | t/z | s/z
215: fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
216: fxch %st(1) // s | t | 1/z | t/z | s/z
217: fistpl s // 1/z | t | t/z | s/z
218: fistpl t // 1/z | t/z | s/z
219:
220: fildl spancountminus1
221:
222: flds C(d_tdivzstepu) // _d_tdivzstepu | spancountminus1
223: flds C(d_zistepu) // _d_zistepu | _d_tdivzstepu | spancountminus1
224: fmul %st(2),%st(0) // _d_zistepu*scm1 | _d_tdivzstepu | scm1
225: fxch %st(1) // _d_tdivzstepu | _d_zistepu*scm1 | scm1
226: fmul %st(2),%st(0) // _d_tdivzstepu*scm1 | _d_zistepu*scm1 | scm1
227: fxch %st(2) // scm1 | _d_zistepu*scm1 | _d_tdivzstepu*scm1
228: fmuls C(d_sdivzstepu) // _d_sdivzstepu*scm1 | _d_zistepu*scm1 |
229: // _d_tdivzstepu*scm1
230: fxch %st(1) // _d_zistepu*scm1 | _d_sdivzstepu*scm1 |
231: // _d_tdivzstepu*scm1
232: faddp %st(0),%st(3) // _d_sdivzstepu*scm1 | _d_tdivzstepu*scm1
233: fxch %st(1) // _d_tdivzstepu*scm1 | _d_sdivzstepu*scm1
234: faddp %st(0),%st(3) // _d_sdivzstepu*scm1
235: faddp %st(0),%st(3)
236:
237: flds fp_64k
238: fdiv %st(1),%st(0) // this is what we've gone to all this trouble to
239: // overlap
240: jmp LFDIVInFlight1
241:
242: LCleanup1:
243: // finish up the s and t calcs
244: fxch %st(1) // z*64k | 1/z | t/z | s/z
245:
246: fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
247: fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
248: fxch %st(1) // z*64k | s | 1/z | t/z | s/z
249: fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
250: fxch %st(1) // s | t | 1/z | t/z | s/z
251: fistpl s // 1/z | t | t/z | s/z
252: fistpl t // 1/z | t/z | s/z
253: jmp LFDIVInFlight1
254:
255: .align 4
256: LSetupNotLast1:
257: // finish up the s and t calcs
258: fxch %st(1) // z*64k | 1/z | t/z | s/z
259:
260: fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
261: fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
262: fxch %st(1) // z*64k | s | 1/z | t/z | s/z
263: fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
264: fxch %st(1) // s | t | 1/z | t/z | s/z
265: fistpl s // 1/z | t | t/z | s/z
266: fistpl t // 1/z | t/z | s/z
267:
268: fadds zi8stepu
269: fxch %st(2)
270: fadds sdivz8stepu
271: fxch %st(2)
272: flds tdivz8stepu
273: faddp %st(0),%st(2)
274: flds fp_64k
275: fdiv %st(1),%st(0) // z = 1/1/z
276: // this is what we've gone to all this trouble to
277: // overlap
278: LFDIVInFlight1:
279:
280: addl s,%esi
281: addl t,%edx
282: movl C(bbextents),%ebx
283: movl C(bbextentt),%ebp
284: cmpl %ebx,%esi
285: ja LClampHighOrLow0
286: LClampReentry0:
287: movl %esi,s
288: movl pbase,%ebx
289: shll $16,%esi
290: cmpl %ebp,%edx
291: movl %esi,sfracf
292: ja LClampHighOrLow1
293: LClampReentry1:
294: movl %edx,t
295: movl s,%esi // sfrac = scans->sfrac;
296: shll $16,%edx
297: movl t,%eax // tfrac = scans->tfrac;
298: sarl $16,%esi
299: movl %edx,tfracf
300:
301: //
302: // calculate the texture starting address
303: //
304: sarl $16,%eax
305: addl %ebx,%esi
306: imull C(cachewidth),%eax // (tfrac >> 16) * cachewidth
307: addl %eax,%esi // psource = pbase + (sfrac >> 16) +
308: // ((tfrac >> 16) * cachewidth);
309:
310: //
311: // determine whether last span or not
312: //
313: cmpl $8,%ecx
314: jna LLastSegment
315:
316: //
317: // not the last segment; do full 8-wide segment
318: //
319: LNotLastSegment:
320:
321: //
322: // advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
323: // get there
324: //
325:
326: // pick up after the FDIV that was left in flight previously
327:
328: fld %st(0) // duplicate it
329: fmul %st(4),%st(0) // s = s/z * z
330: fxch %st(1)
331: fmul %st(3),%st(0) // t = t/z * z
332: fxch %st(1)
333: fistpl snext
334: fistpl tnext
335: movl snext,%eax
336: movl tnext,%edx
337:
338: subl $8,%ecx // count off this segments' pixels
339: movl C(sadjust),%ebp
340: pushl %ecx // remember count of remaining pixels
341: movl C(tadjust),%ecx
342:
343: addl %eax,%ebp
344: addl %edx,%ecx
345:
346: movl C(bbextents),%eax
347: movl C(bbextentt),%edx
348:
349: cmpl $2048,%ebp
350: jl LClampLow2
351: cmpl %eax,%ebp
352: ja LClampHigh2
353: LClampReentry2:
354:
355: cmpl $2048,%ecx
356: jl LClampLow3
357: cmpl %edx,%ecx
358: ja LClampHigh3
359: LClampReentry3:
360:
361: movl %ebp,snext
362: movl %ecx,tnext
363:
364: subl s,%ebp
365: subl t,%ecx
366:
367: //
368: // set up advancetable
369: //
370: movl %ecx,%eax
371: movl %ebp,%edx
372: sarl $19,%edx // sstep >>= 16;
373: movl C(cachewidth),%ebx
374: sarl $19,%eax // tstep >>= 16;
375: jz LIsZero
376: imull %ebx,%eax // (tstep >> 16) * cachewidth;
377: LIsZero:
378: addl %edx,%eax // add in sstep
379: // (tstep >> 16) * cachewidth + (sstep >> 16);
380: movl tfracf,%edx
381: movl %eax,advancetable+4 // advance base in t
382: addl %ebx,%eax // ((tstep >> 16) + 1) * cachewidth +
383: // (sstep >> 16);
384: shll $13,%ebp // left-justify sstep fractional part
385: movl %ebp,sstep
386: movl sfracf,%ebx
387: shll $13,%ecx // left-justify tstep fractional part
388: movl %eax,advancetable // advance extra in t
389: movl %ecx,tstep
390:
391: movl pz,%ecx
392: movl izi,%ebp
393:
394: cmpw (%ecx),%bp
395: jl Lp1
396: movb (%esi),%al // get first source texel
397: cmpb $(TRANSPARENT_COLOR),%al
398: jz Lp1
399: movw %bp,(%ecx)
400: movb %al,(%edi) // store first dest pixel
401: Lp1:
402: addl izistep,%ebp
403: adcl $0,%ebp
404: addl tstep,%edx // advance tfrac fractional part by tstep frac
405:
406: sbbl %eax,%eax // turn tstep carry into -1 (0 if none)
407: addl sstep,%ebx // advance sfrac fractional part by sstep frac
408: adcl advancetable+4(,%eax,4),%esi // point to next source texel
409:
410: cmpw 2(%ecx),%bp
411: jl Lp2
412: movb (%esi),%al
413: cmpb $(TRANSPARENT_COLOR),%al
414: jz Lp2
415: movw %bp,2(%ecx)
416: movb %al,1(%edi)
417: Lp2:
418: addl izistep,%ebp
419: adcl $0,%ebp
420: addl tstep,%edx
421: sbbl %eax,%eax
422: addl sstep,%ebx
423: adcl advancetable+4(,%eax,4),%esi
424:
425: cmpw 4(%ecx),%bp
426: jl Lp3
427: movb (%esi),%al
428: cmpb $(TRANSPARENT_COLOR),%al
429: jz Lp3
430: movw %bp,4(%ecx)
431: movb %al,2(%edi)
432: Lp3:
433: addl izistep,%ebp
434: adcl $0,%ebp
435: addl tstep,%edx
436: sbbl %eax,%eax
437: addl sstep,%ebx
438: adcl advancetable+4(,%eax,4),%esi
439:
440: cmpw 6(%ecx),%bp
441: jl Lp4
442: movb (%esi),%al
443: cmpb $(TRANSPARENT_COLOR),%al
444: jz Lp4
445: movw %bp,6(%ecx)
446: movb %al,3(%edi)
447: Lp4:
448: addl izistep,%ebp
449: adcl $0,%ebp
450: addl tstep,%edx
451: sbbl %eax,%eax
452: addl sstep,%ebx
453: adcl advancetable+4(,%eax,4),%esi
454:
455: cmpw 8(%ecx),%bp
456: jl Lp5
457: movb (%esi),%al
458: cmpb $(TRANSPARENT_COLOR),%al
459: jz Lp5
460: movw %bp,8(%ecx)
461: movb %al,4(%edi)
462: Lp5:
463: addl izistep,%ebp
464: adcl $0,%ebp
465: addl tstep,%edx
466: sbbl %eax,%eax
467: addl sstep,%ebx
468: adcl advancetable+4(,%eax,4),%esi
469:
470: //
471: // start FDIV for end of next segment in flight, so it can overlap
472: //
473: popl %eax
474: cmpl $8,%eax // more than one segment after this?
475: ja LSetupNotLast2 // yes
476:
477: decl %eax
478: jz LFDIVInFlight2 // if only one pixel, no need to start an FDIV
479: movl %eax,spancountminus1
480: fildl spancountminus1
481:
482: flds C(d_zistepu) // _d_zistepu | spancountminus1
483: fmul %st(1),%st(0) // _d_zistepu*scm1 | scm1
484: flds C(d_tdivzstepu) // _d_tdivzstepu | _d_zistepu*scm1 | scm1
485: fmul %st(2),%st(0) // _d_tdivzstepu*scm1 | _d_zistepu*scm1 | scm1
486: fxch %st(1) // _d_zistepu*scm1 | _d_tdivzstepu*scm1 | scm1
487: faddp %st(0),%st(3) // _d_tdivzstepu*scm1 | scm1
488: fxch %st(1) // scm1 | _d_tdivzstepu*scm1
489: fmuls C(d_sdivzstepu) // _d_sdivzstepu*scm1 | _d_tdivzstepu*scm1
490: fxch %st(1) // _d_tdivzstepu*scm1 | _d_sdivzstepu*scm1
491: faddp %st(0),%st(3) // _d_sdivzstepu*scm1
492: flds fp_64k // 64k | _d_sdivzstepu*scm1
493: fxch %st(1) // _d_sdivzstepu*scm1 | 64k
494: faddp %st(0),%st(4) // 64k
495:
496: fdiv %st(1),%st(0) // this is what we've gone to all this trouble to
497: // overlap
498: jmp LFDIVInFlight2
499:
500: .align 4
501: LSetupNotLast2:
502: fadds zi8stepu
503: fxch %st(2)
504: fadds sdivz8stepu
505: fxch %st(2)
506: flds tdivz8stepu
507: faddp %st(0),%st(2)
508: flds fp_64k
509: fdiv %st(1),%st(0) // z = 1/1/z
510: // this is what we've gone to all this trouble to
511: // overlap
512: LFDIVInFlight2:
513: pushl %eax
514:
515: cmpw 10(%ecx),%bp
516: jl Lp6
517: movb (%esi),%al
518: cmpb $(TRANSPARENT_COLOR),%al
519: jz Lp6
520: movw %bp,10(%ecx)
521: movb %al,5(%edi)
522: Lp6:
523: addl izistep,%ebp
524: adcl $0,%ebp
525: addl tstep,%edx
526: sbbl %eax,%eax
527: addl sstep,%ebx
528: adcl advancetable+4(,%eax,4),%esi
529:
530: cmpw 12(%ecx),%bp
531: jl Lp7
532: movb (%esi),%al
533: cmpb $(TRANSPARENT_COLOR),%al
534: jz Lp7
535: movw %bp,12(%ecx)
536: movb %al,6(%edi)
537: Lp7:
538: addl izistep,%ebp
539: adcl $0,%ebp
540: addl tstep,%edx
541: sbbl %eax,%eax
542: addl sstep,%ebx
543: adcl advancetable+4(,%eax,4),%esi
544:
545: cmpw 14(%ecx),%bp
546: jl Lp8
547: movb (%esi),%al
548: cmpb $(TRANSPARENT_COLOR),%al
549: jz Lp8
550: movw %bp,14(%ecx)
551: movb %al,7(%edi)
552: Lp8:
553: addl izistep,%ebp
554: adcl $0,%ebp
555: addl tstep,%edx
556: sbbl %eax,%eax
557: addl sstep,%ebx
558: adcl advancetable+4(,%eax,4),%esi
559:
560: addl $8,%edi
561: addl $16,%ecx
562: movl %edx,tfracf
563: movl snext,%edx
564: movl %ebx,sfracf
565: movl tnext,%ebx
566: movl %edx,s
567: movl %ebx,t
568:
569: movl %ecx,pz
570: movl %ebp,izi
571:
572: popl %ecx // retrieve count
573:
574: //
575: // determine whether last span or not
576: //
577: cmpl $8,%ecx // are there multiple segments remaining?
578: ja LNotLastSegment // yes
579:
580: //
581: // last segment of scan
582: //
583: LLastSegment:
584:
585: //
586: // advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
587: // get there. The number of pixels left is variable, and we want to land on the
588: // last pixel, not step one past it, so we can't run into arithmetic problems
589: //
590: testl %ecx,%ecx
591: jz LNoSteps // just draw the last pixel and we're done
592:
593: // pick up after the FDIV that was left in flight previously
594:
595:
596: fld %st(0) // duplicate it
597: fmul %st(4),%st(0) // s = s/z * z
598: fxch %st(1)
599: fmul %st(3),%st(0) // t = t/z * z
600: fxch %st(1)
601: fistpl snext
602: fistpl tnext
603:
604: movl C(tadjust),%ebx
605: movl C(sadjust),%eax
606:
607: addl snext,%eax
608: addl tnext,%ebx
609:
610: movl C(bbextents),%ebp
611: movl C(bbextentt),%edx
612:
613: cmpl $2048,%eax
614: jl LClampLow4
615: cmpl %ebp,%eax
616: ja LClampHigh4
617: LClampReentry4:
618: movl %eax,snext
619:
620: cmpl $2048,%ebx
621: jl LClampLow5
622: cmpl %edx,%ebx
623: ja LClampHigh5
624: LClampReentry5:
625:
626: cmpl $1,%ecx // don't bother
627: je LOnlyOneStep // if two pixels in segment, there's only one step,
628: // of the segment length
629: subl s,%eax
630: subl t,%ebx
631:
632: addl %eax,%eax // convert to 15.17 format so multiply by 1.31
633: addl %ebx,%ebx // reciprocal yields 16.48
634: imull reciprocal_table-8(,%ecx,4) // sstep = (snext - s) / (spancount-1)
635: movl %edx,%ebp
636:
637: movl %ebx,%eax
638: imull reciprocal_table-8(,%ecx,4) // tstep = (tnext - t) / (spancount-1)
639:
640: LSetEntryvec:
641: //
642: // set up advancetable
643: //
644: movl spr8entryvec_table(,%ecx,4),%ebx
645: movl %edx,%eax
646: pushl %ebx // entry point into code for RET later
647: movl %ebp,%ecx
648: sarl $16,%ecx // sstep >>= 16;
649: movl C(cachewidth),%ebx
650: sarl $16,%edx // tstep >>= 16;
651: jz LIsZeroLast
652: imull %ebx,%edx // (tstep >> 16) * cachewidth;
653: LIsZeroLast:
654: addl %ecx,%edx // add in sstep
655: // (tstep >> 16) * cachewidth + (sstep >> 16);
656: movl tfracf,%ecx
657: movl %edx,advancetable+4 // advance base in t
658: addl %ebx,%edx // ((tstep >> 16) + 1) * cachewidth +
659: // (sstep >> 16);
660: shll $16,%ebp // left-justify sstep fractional part
661: movl sfracf,%ebx
662: shll $16,%eax // left-justify tstep fractional part
663: movl %edx,advancetable // advance extra in t
664:
665: movl %eax,tstep
666: movl %ebp,sstep
667: movl %ecx,%edx
668:
669: movl pz,%ecx
670: movl izi,%ebp
671:
672: ret // jump to the number-of-pixels handler
673:
674: //----------------------------------------
675:
676: LNoSteps:
677: movl pz,%ecx
678: subl $7,%edi // adjust for hardwired offset
679: subl $14,%ecx
680: jmp LEndSpan
681:
682:
683: LOnlyOneStep:
684: subl s,%eax
685: subl t,%ebx
686: movl %eax,%ebp
687: movl %ebx,%edx
688: jmp LSetEntryvec
689:
690: //----------------------------------------
691:
692: .globl Spr8Entry2_8
693: Spr8Entry2_8:
694: subl $6,%edi // adjust for hardwired offsets
695: subl $12,%ecx
696: movb (%esi),%al
697: jmp LLEntry2_8
698:
699: //----------------------------------------
700:
701: .globl Spr8Entry3_8
702: Spr8Entry3_8:
703: subl $5,%edi // adjust for hardwired offsets
704: subl $10,%ecx
705: jmp LLEntry3_8
706:
707: //----------------------------------------
708:
709: .globl Spr8Entry4_8
710: Spr8Entry4_8:
711: subl $4,%edi // adjust for hardwired offsets
712: subl $8,%ecx
713: jmp LLEntry4_8
714:
715: //----------------------------------------
716:
717: .globl Spr8Entry5_8
718: Spr8Entry5_8:
719: subl $3,%edi // adjust for hardwired offsets
720: subl $6,%ecx
721: jmp LLEntry5_8
722:
723: //----------------------------------------
724:
725: .globl Spr8Entry6_8
726: Spr8Entry6_8:
727: subl $2,%edi // adjust for hardwired offsets
728: subl $4,%ecx
729: jmp LLEntry6_8
730:
731: //----------------------------------------
732:
733: .globl Spr8Entry7_8
734: Spr8Entry7_8:
735: decl %edi // adjust for hardwired offsets
736: subl $2,%ecx
737: jmp LLEntry7_8
738:
739: //----------------------------------------
740:
741: .globl Spr8Entry8_8
742: Spr8Entry8_8:
743: cmpw (%ecx),%bp
744: jl Lp9
745: movb (%esi),%al
746: cmpb $(TRANSPARENT_COLOR),%al
747: jz Lp9
748: movw %bp,(%ecx)
749: movb %al,(%edi)
750: Lp9:
751: addl izistep,%ebp
752: adcl $0,%ebp
753: addl tstep,%edx
754: sbbl %eax,%eax
755: addl sstep,%ebx
756: adcl advancetable+4(,%eax,4),%esi
757: LLEntry7_8:
758: cmpw 2(%ecx),%bp
759: jl Lp10
760: movb (%esi),%al
761: cmpb $(TRANSPARENT_COLOR),%al
762: jz Lp10
763: movw %bp,2(%ecx)
764: movb %al,1(%edi)
765: Lp10:
766: addl izistep,%ebp
767: adcl $0,%ebp
768: addl tstep,%edx
769: sbbl %eax,%eax
770: addl sstep,%ebx
771: adcl advancetable+4(,%eax,4),%esi
772: LLEntry6_8:
773: cmpw 4(%ecx),%bp
774: jl Lp11
775: movb (%esi),%al
776: cmpb $(TRANSPARENT_COLOR),%al
777: jz Lp11
778: movw %bp,4(%ecx)
779: movb %al,2(%edi)
780: Lp11:
781: addl izistep,%ebp
782: adcl $0,%ebp
783: addl tstep,%edx
784: sbbl %eax,%eax
785: addl sstep,%ebx
786: adcl advancetable+4(,%eax,4),%esi
787: LLEntry5_8:
788: cmpw 6(%ecx),%bp
789: jl Lp12
790: movb (%esi),%al
791: cmpb $(TRANSPARENT_COLOR),%al
792: jz Lp12
793: movw %bp,6(%ecx)
794: movb %al,3(%edi)
795: Lp12:
796: addl izistep,%ebp
797: adcl $0,%ebp
798: addl tstep,%edx
799: sbbl %eax,%eax
800: addl sstep,%ebx
801: adcl advancetable+4(,%eax,4),%esi
802: LLEntry4_8:
803: cmpw 8(%ecx),%bp
804: jl Lp13
805: movb (%esi),%al
806: cmpb $(TRANSPARENT_COLOR),%al
807: jz Lp13
808: movw %bp,8(%ecx)
809: movb %al,4(%edi)
810: Lp13:
811: addl izistep,%ebp
812: adcl $0,%ebp
813: addl tstep,%edx
814: sbbl %eax,%eax
815: addl sstep,%ebx
816: adcl advancetable+4(,%eax,4),%esi
817: LLEntry3_8:
818: cmpw 10(%ecx),%bp
819: jl Lp14
820: movb (%esi),%al
821: cmpb $(TRANSPARENT_COLOR),%al
822: jz Lp14
823: movw %bp,10(%ecx)
824: movb %al,5(%edi)
825: Lp14:
826: addl izistep,%ebp
827: adcl $0,%ebp
828: addl tstep,%edx
829: sbbl %eax,%eax
830: addl sstep,%ebx
831: adcl advancetable+4(,%eax,4),%esi
832: LLEntry2_8:
833: cmpw 12(%ecx),%bp
834: jl Lp15
835: movb (%esi),%al
836: cmpb $(TRANSPARENT_COLOR),%al
837: jz Lp15
838: movw %bp,12(%ecx)
839: movb %al,6(%edi)
840: Lp15:
841: addl izistep,%ebp
842: adcl $0,%ebp
843: addl tstep,%edx
844: sbbl %eax,%eax
845: addl sstep,%ebx
846: adcl advancetable+4(,%eax,4),%esi
847:
848: LEndSpan:
849: cmpw 14(%ecx),%bp
850: jl Lp16
851: movb (%esi),%al // load first texel in segment
852: cmpb $(TRANSPARENT_COLOR),%al
853: jz Lp16
854: movw %bp,14(%ecx)
855: movb %al,7(%edi)
856: Lp16:
857:
858: //
859: // clear s/z, t/z, 1/z from FP stack
860: //
861: fstp %st(0)
862: fstp %st(0)
863: fstp %st(0)
864:
865: popl %ebx // restore spans pointer
866: LNextSpan:
867: addl $(sspan_t_size),%ebx // point to next span
868: movl sspan_t_count(%ebx),%ecx
869: cmpl $0,%ecx // any more spans?
870: jg LSpanLoop // yes
871: jz LNextSpan // yes, but this one's empty
872:
873: popl %ebx // restore register variables
874: popl %esi
875: popl %edi
876: popl %ebp // restore the caller's stack frame
877: ret
878:
879: #endif // id386
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.