1//
2// surf8.s
3// x86 assembly-language 8 bpp surface block drawing code.
4//
5
6#include "qasm.h"
7
8#if	id386
9
10	.data
11
12sb_v:		.long	0
13
14	.text
15
16	.align 4
17.globl C(R_Surf8Start)
18C(R_Surf8Start):
19
20//----------------------------------------------------------------------
21// Surface block drawer for mip level 0
22//----------------------------------------------------------------------
23
24	.align 4
25.globl C(R_DrawSurfaceBlock8_mip0)
26C(R_DrawSurfaceBlock8_mip0):
27	pushl	%ebp				// preserve caller's stack frame
28	pushl	%edi
29	pushl	%esi				// preserve register variables
30	pushl	%ebx
31
32//		for (v=0 ; v<numvblocks ; v++)
33//		{
34	movl	C(r_lightptr),%ebx
35	movl	C(r_numvblocks),%eax
36
37	movl	%eax,sb_v
38	movl	C(prowdestbase),%edi
39
40	movl	C(pbasesource),%esi
41
42Lv_loop_mip0:
43
44//			lightleft = lightptr[0];
45//			lightright = lightptr[1];
46//			lightdelta = (lightleft - lightright) & 0xFFFFF;
47	movl	(%ebx),%eax			// lightleft
48	movl	4(%ebx),%edx		// lightright
49
50	movl	%eax,%ebp
51	movl	C(r_lightwidth),%ecx
52
53	movl	%edx,C(lightright)
54	subl	%edx,%ebp
55
56	andl	$0xFFFFF,%ebp
57	leal	(%ebx,%ecx,4),%ebx
58
59//			lightptr += lightwidth;
60	movl	%ebx,C(r_lightptr)
61
62//			lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
63//			lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
64//			lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
65//					0xF0000000;
66	movl	4(%ebx),%ecx	// lightptr[1]
67	movl	(%ebx),%ebx		// lightptr[0]
68
69	subl	%eax,%ebx
70	subl	%edx,%ecx
71
72	sarl	$4,%ecx
73	orl		$0xF0000000,%ebp
74
75	sarl	$4,%ebx
76	movl	%ecx,C(lightrightstep)
77
78	subl	%ecx,%ebx
79	andl	$0xFFFFF,%ebx
80
81	orl		$0xF0000000,%ebx
82	subl	%ecx,%ecx	// high word must be 0 in loop for addressing
83
84	movl	%ebx,C(lightdeltastep)
85	subl	%ebx,%ebx	// high word must be 0 in loop for addressing
86
87Lblockloop8_mip0:
88	movl	%ebp,C(lightdelta)
89	movb	14(%esi),%cl
90
91	sarl	$4,%ebp
92	movb	%dh,%bh
93
94	movb	15(%esi),%bl
95	addl	%ebp,%edx
96
97	movb	%dh,%ch
98	addl	%ebp,%edx
99
100	movb	0x12345678(%ebx),%ah
101LBPatch0:
102	movb	13(%esi),%bl
103
104	movb	0x12345678(%ecx),%al
105LBPatch1:
106	movb	12(%esi),%cl
107
108	movb	%dh,%bh
109	addl	%ebp,%edx
110
111	rorl	$16,%eax
112	movb	%dh,%ch
113
114	addl	%ebp,%edx
115	movb	0x12345678(%ebx),%ah
116LBPatch2:
117
118	movb	11(%esi),%bl
119	movb	0x12345678(%ecx),%al
120LBPatch3:
121
122	movb	10(%esi),%cl
123	movl	%eax,12(%edi)
124
125	movb	%dh,%bh
126	addl	%ebp,%edx
127
128	movb	%dh,%ch
129	addl	%ebp,%edx
130
131	movb	0x12345678(%ebx),%ah
132LBPatch4:
133	movb	9(%esi),%bl
134
135	movb	0x12345678(%ecx),%al
136LBPatch5:
137	movb	8(%esi),%cl
138
139	movb	%dh,%bh
140	addl	%ebp,%edx
141
142	rorl	$16,%eax
143	movb	%dh,%ch
144
145	addl	%ebp,%edx
146	movb	0x12345678(%ebx),%ah
147LBPatch6:
148
149	movb	7(%esi),%bl
150	movb	0x12345678(%ecx),%al
151LBPatch7:
152
153	movb	6(%esi),%cl
154	movl	%eax,8(%edi)
155
156	movb	%dh,%bh
157	addl	%ebp,%edx
158
159	movb	%dh,%ch
160	addl	%ebp,%edx
161
162	movb	0x12345678(%ebx),%ah
163LBPatch8:
164	movb	5(%esi),%bl
165
166	movb	0x12345678(%ecx),%al
167LBPatch9:
168	movb	4(%esi),%cl
169
170	movb	%dh,%bh
171	addl	%ebp,%edx
172
173	rorl	$16,%eax
174	movb	%dh,%ch
175
176	addl	%ebp,%edx
177	movb	0x12345678(%ebx),%ah
178LBPatch10:
179
180	movb	3(%esi),%bl
181	movb	0x12345678(%ecx),%al
182LBPatch11:
183
184	movb	2(%esi),%cl
185	movl	%eax,4(%edi)
186
187	movb	%dh,%bh
188	addl	%ebp,%edx
189
190	movb	%dh,%ch
191	addl	%ebp,%edx
192
193	movb	0x12345678(%ebx),%ah
194LBPatch12:
195	movb	1(%esi),%bl
196
197	movb	0x12345678(%ecx),%al
198LBPatch13:
199	movb	(%esi),%cl
200
201	movb	%dh,%bh
202	addl	%ebp,%edx
203
204	rorl	$16,%eax
205	movb	%dh,%ch
206
207	movb	0x12345678(%ebx),%ah
208LBPatch14:
209	movl	C(lightright),%edx
210
211	movb	0x12345678(%ecx),%al
212LBPatch15:
213	movl	C(lightdelta),%ebp
214
215	movl	%eax,(%edi)
216
217	addl	C(sourcetstep),%esi
218	addl	C(surfrowbytes),%edi
219
220	addl	C(lightrightstep),%edx
221	addl	C(lightdeltastep),%ebp
222
223	movl	%edx,C(lightright)
224	jc		Lblockloop8_mip0
225
226//			if (pbasesource >= r_sourcemax)
227//				pbasesource -= stepback;
228
229	cmpl	C(r_sourcemax),%esi
230	jb		LSkip_mip0
231	subl	C(r_stepback),%esi
232LSkip_mip0:
233
234	movl	C(r_lightptr),%ebx
235	decl	sb_v
236
237	jnz		Lv_loop_mip0
238
239	popl	%ebx				// restore register variables
240	popl	%esi
241	popl	%edi
242	popl	%ebp				// restore the caller's stack frame
243	ret
244
245
246//----------------------------------------------------------------------
247// Surface block drawer for mip level 1
248//----------------------------------------------------------------------
249
250	.align 4
251.globl C(R_DrawSurfaceBlock8_mip1)
252C(R_DrawSurfaceBlock8_mip1):
253	pushl	%ebp				// preserve caller's stack frame
254	pushl	%edi
255	pushl	%esi				// preserve register variables
256	pushl	%ebx
257
258//		for (v=0 ; v<numvblocks ; v++)
259//		{
260	movl	C(r_lightptr),%ebx
261	movl	C(r_numvblocks),%eax
262
263	movl	%eax,sb_v
264	movl	C(prowdestbase),%edi
265
266	movl	C(pbasesource),%esi
267
268Lv_loop_mip1:
269
270//			lightleft = lightptr[0];
271//			lightright = lightptr[1];
272//			lightdelta = (lightleft - lightright) & 0xFFFFF;
273	movl	(%ebx),%eax			// lightleft
274	movl	4(%ebx),%edx		// lightright
275
276	movl	%eax,%ebp
277	movl	C(r_lightwidth),%ecx
278
279	movl	%edx,C(lightright)
280	subl	%edx,%ebp
281
282	andl	$0xFFFFF,%ebp
283	leal	(%ebx,%ecx,4),%ebx
284
285//			lightptr += lightwidth;
286	movl	%ebx,C(r_lightptr)
287
288//			lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
289//			lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
290//			lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
291//					0xF0000000;
292	movl	4(%ebx),%ecx	// lightptr[1]
293	movl	(%ebx),%ebx		// lightptr[0]
294
295	subl	%eax,%ebx
296	subl	%edx,%ecx
297
298	sarl	$3,%ecx
299	orl		$0x70000000,%ebp
300
301	sarl	$3,%ebx
302	movl	%ecx,C(lightrightstep)
303
304	subl	%ecx,%ebx
305	andl	$0xFFFFF,%ebx
306
307	orl		$0xF0000000,%ebx
308	subl	%ecx,%ecx	// high word must be 0 in loop for addressing
309
310	movl	%ebx,C(lightdeltastep)
311	subl	%ebx,%ebx	// high word must be 0 in loop for addressing
312
313Lblockloop8_mip1:
314	movl	%ebp,C(lightdelta)
315	movb	6(%esi),%cl
316
317	sarl	$3,%ebp
318	movb	%dh,%bh
319
320	movb	7(%esi),%bl
321	addl	%ebp,%edx
322
323	movb	%dh,%ch
324	addl	%ebp,%edx
325
326	movb	0x12345678(%ebx),%ah
327LBPatch22:
328	movb	5(%esi),%bl
329
330	movb	0x12345678(%ecx),%al
331LBPatch23:
332	movb	4(%esi),%cl
333
334	movb	%dh,%bh
335	addl	%ebp,%edx
336
337	rorl	$16,%eax
338	movb	%dh,%ch
339
340	addl	%ebp,%edx
341	movb	0x12345678(%ebx),%ah
342LBPatch24:
343
344	movb	3(%esi),%bl
345	movb	0x12345678(%ecx),%al
346LBPatch25:
347
348	movb	2(%esi),%cl
349	movl	%eax,4(%edi)
350
351	movb	%dh,%bh
352	addl	%ebp,%edx
353
354	movb	%dh,%ch
355	addl	%ebp,%edx
356
357	movb	0x12345678(%ebx),%ah
358LBPatch26:
359	movb	1(%esi),%bl
360
361	movb	0x12345678(%ecx),%al
362LBPatch27:
363	movb	(%esi),%cl
364
365	movb	%dh,%bh
366	addl	%ebp,%edx
367
368	rorl	$16,%eax
369	movb	%dh,%ch
370
371	movb	0x12345678(%ebx),%ah
372LBPatch28:
373	movl	C(lightright),%edx
374
375	movb	0x12345678(%ecx),%al
376LBPatch29:
377	movl	C(lightdelta),%ebp
378
379	movl	%eax,(%edi)
380	movl	C(sourcetstep),%eax
381
382	addl	%eax,%esi
383	movl	C(surfrowbytes),%eax
384
385	addl	%eax,%edi
386	movl	C(lightrightstep),%eax
387
388	addl	%eax,%edx
389	movl	C(lightdeltastep),%eax
390
391	addl	%eax,%ebp
392	movl	%edx,C(lightright)
393
394	jc		Lblockloop8_mip1
395
396//			if (pbasesource >= r_sourcemax)
397//				pbasesource -= stepback;
398
399	cmpl	C(r_sourcemax),%esi
400	jb		LSkip_mip1
401	subl	C(r_stepback),%esi
402LSkip_mip1:
403
404	movl	C(r_lightptr),%ebx
405	decl	sb_v
406
407	jnz		Lv_loop_mip1
408
409	popl	%ebx				// restore register variables
410	popl	%esi
411	popl	%edi
412	popl	%ebp				// restore the caller's stack frame
413	ret
414
415
416//----------------------------------------------------------------------
417// Surface block drawer for mip level 2
418//----------------------------------------------------------------------
419
420	.align 4
421.globl C(R_DrawSurfaceBlock8_mip2)
422C(R_DrawSurfaceBlock8_mip2):
423	pushl	%ebp				// preserve caller's stack frame
424	pushl	%edi
425	pushl	%esi				// preserve register variables
426	pushl	%ebx
427
428//		for (v=0 ; v<numvblocks ; v++)
429//		{
430	movl	C(r_lightptr),%ebx
431	movl	C(r_numvblocks),%eax
432
433	movl	%eax,sb_v
434	movl	C(prowdestbase),%edi
435
436	movl	C(pbasesource),%esi
437
438Lv_loop_mip2:
439
440//			lightleft = lightptr[0];
441//			lightright = lightptr[1];
442//			lightdelta = (lightleft - lightright) & 0xFFFFF;
443	movl	(%ebx),%eax			// lightleft
444	movl	4(%ebx),%edx		// lightright
445
446	movl	%eax,%ebp
447	movl	C(r_lightwidth),%ecx
448
449	movl	%edx,C(lightright)
450	subl	%edx,%ebp
451
452	andl	$0xFFFFF,%ebp
453	leal	(%ebx,%ecx,4),%ebx
454
455//			lightptr += lightwidth;
456	movl	%ebx,C(r_lightptr)
457
458//			lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
459//			lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
460//			lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
461//					0xF0000000;
462	movl	4(%ebx),%ecx	// lightptr[1]
463	movl	(%ebx),%ebx		// lightptr[0]
464
465	subl	%eax,%ebx
466	subl	%edx,%ecx
467
468	sarl	$2,%ecx
469	orl		$0x30000000,%ebp
470
471	sarl	$2,%ebx
472	movl	%ecx,C(lightrightstep)
473
474	subl	%ecx,%ebx
475
476	andl	$0xFFFFF,%ebx
477
478	orl		$0xF0000000,%ebx
479	subl	%ecx,%ecx	// high word must be 0 in loop for addressing
480
481	movl	%ebx,C(lightdeltastep)
482	subl	%ebx,%ebx	// high word must be 0 in loop for addressing
483
484Lblockloop8_mip2:
485	movl	%ebp,C(lightdelta)
486	movb	2(%esi),%cl
487
488	sarl	$2,%ebp
489	movb	%dh,%bh
490
491	movb	3(%esi),%bl
492	addl	%ebp,%edx
493
494	movb	%dh,%ch
495	addl	%ebp,%edx
496
497	movb	0x12345678(%ebx),%ah
498LBPatch18:
499	movb	1(%esi),%bl
500
501	movb	0x12345678(%ecx),%al
502LBPatch19:
503	movb	(%esi),%cl
504
505	movb	%dh,%bh
506	addl	%ebp,%edx
507
508	rorl	$16,%eax
509	movb	%dh,%ch
510
511	movb	0x12345678(%ebx),%ah
512LBPatch20:
513	movl	C(lightright),%edx
514
515	movb	0x12345678(%ecx),%al
516LBPatch21:
517	movl	C(lightdelta),%ebp
518
519	movl	%eax,(%edi)
520	movl	C(sourcetstep),%eax
521
522	addl	%eax,%esi
523	movl	C(surfrowbytes),%eax
524
525	addl	%eax,%edi
526	movl	C(lightrightstep),%eax
527
528	addl	%eax,%edx
529	movl	C(lightdeltastep),%eax
530
531	addl	%eax,%ebp
532	movl	%edx,C(lightright)
533
534	jc		Lblockloop8_mip2
535
536//			if (pbasesource >= r_sourcemax)
537//				pbasesource -= stepback;
538
539	cmpl	C(r_sourcemax),%esi
540	jb		LSkip_mip2
541	subl	C(r_stepback),%esi
542LSkip_mip2:
543
544	movl	C(r_lightptr),%ebx
545	decl	sb_v
546
547	jnz		Lv_loop_mip2
548
549	popl	%ebx				// restore register variables
550	popl	%esi
551	popl	%edi
552	popl	%ebp				// restore the caller's stack frame
553	ret
554
555
556//----------------------------------------------------------------------
557// Surface block drawer for mip level 3
558//----------------------------------------------------------------------
559
560	.align 4
561.globl C(R_DrawSurfaceBlock8_mip3)
562C(R_DrawSurfaceBlock8_mip3):
563	pushl	%ebp				// preserve caller's stack frame
564	pushl	%edi
565	pushl	%esi				// preserve register variables
566	pushl	%ebx
567
568//		for (v=0 ; v<numvblocks ; v++)
569//		{
570	movl	C(r_lightptr),%ebx
571	movl	C(r_numvblocks),%eax
572
573	movl	%eax,sb_v
574	movl	C(prowdestbase),%edi
575
576	movl	C(pbasesource),%esi
577
578Lv_loop_mip3:
579
580//			lightleft = lightptr[0];
581//			lightright = lightptr[1];
582//			lightdelta = (lightleft - lightright) & 0xFFFFF;
583	movl	(%ebx),%eax			// lightleft
584	movl	4(%ebx),%edx		// lightright
585
586	movl	%eax,%ebp
587	movl	C(r_lightwidth),%ecx
588
589	movl	%edx,C(lightright)
590	subl	%edx,%ebp
591
592	andl	$0xFFFFF,%ebp
593	leal	(%ebx,%ecx,4),%ebx
594
595	movl	%ebp,C(lightdelta)
596//			lightptr += lightwidth;
597	movl	%ebx,C(r_lightptr)
598
599//			lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
600//			lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
601//			lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
602//					0xF0000000;
603	movl	4(%ebx),%ecx	// lightptr[1]
604	movl	(%ebx),%ebx		// lightptr[0]
605
606	subl	%eax,%ebx
607	subl	%edx,%ecx
608
609	sarl	$1,%ecx
610
611	sarl	$1,%ebx
612	movl	%ecx,C(lightrightstep)
613
614	subl	%ecx,%ebx
615	andl	$0xFFFFF,%ebx
616
617	sarl	$1,%ebp
618	orl		$0xF0000000,%ebx
619
620	movl	%ebx,C(lightdeltastep)
621	subl	%ebx,%ebx	// high word must be 0 in loop for addressing
622
623	movb	1(%esi),%bl
624	subl	%ecx,%ecx	// high word must be 0 in loop for addressing
625
626	movb	%dh,%bh
627	movb	(%esi),%cl
628
629	addl	%ebp,%edx
630	movb	%dh,%ch
631
632	movb	0x12345678(%ebx),%al
633LBPatch16:
634	movl	C(lightright),%edx
635
636	movb	%al,1(%edi)
637	movb	0x12345678(%ecx),%al
638LBPatch17:
639
640	movb	%al,(%edi)
641	movl	C(sourcetstep),%eax
642
643	addl	%eax,%esi
644	movl	C(surfrowbytes),%eax
645
646	addl	%eax,%edi
647	movl	C(lightdeltastep),%eax
648
649	movl	C(lightdelta),%ebp
650	movb	(%esi),%cl
651
652	addl	%eax,%ebp
653	movl	C(lightrightstep),%eax
654
655	sarl	$1,%ebp
656	addl	%eax,%edx
657
658	movb	%dh,%bh
659	movb	1(%esi),%bl
660
661	addl	%ebp,%edx
662	movb	%dh,%ch
663
664	movb	0x12345678(%ebx),%al
665LBPatch30:
666	movl	C(sourcetstep),%edx
667
668	movb	%al,1(%edi)
669	movb	0x12345678(%ecx),%al
670LBPatch31:
671
672	movb	%al,(%edi)
673	movl	C(surfrowbytes),%ebp
674
675	addl	%edx,%esi
676	addl	%ebp,%edi
677
678//			if (pbasesource >= r_sourcemax)
679//				pbasesource -= stepback;
680
681	cmpl	C(r_sourcemax),%esi
682	jb		LSkip_mip3
683	subl	C(r_stepback),%esi
684LSkip_mip3:
685
686	movl	C(r_lightptr),%ebx
687	decl	sb_v
688
689	jnz		Lv_loop_mip3
690
691	popl	%ebx				// restore register variables
692	popl	%esi
693	popl	%edi
694	popl	%ebp				// restore the caller's stack frame
695	ret
696
697
698.globl C(R_Surf8End)
699C(R_Surf8End):
700
701//----------------------------------------------------------------------
702// Code patching routines
703//----------------------------------------------------------------------
704	.data
705
706	.align 4
707LPatchTable8:
708	.long	LBPatch0-4
709	.long	LBPatch1-4
710	.long	LBPatch2-4
711	.long	LBPatch3-4
712	.long	LBPatch4-4
713	.long	LBPatch5-4
714	.long	LBPatch6-4
715	.long	LBPatch7-4
716	.long	LBPatch8-4
717	.long	LBPatch9-4
718	.long	LBPatch10-4
719	.long	LBPatch11-4
720	.long	LBPatch12-4
721	.long	LBPatch13-4
722	.long	LBPatch14-4
723	.long	LBPatch15-4
724	.long	LBPatch16-4
725	.long	LBPatch17-4
726	.long	LBPatch18-4
727	.long	LBPatch19-4
728	.long	LBPatch20-4
729	.long	LBPatch21-4
730	.long	LBPatch22-4
731	.long	LBPatch23-4
732	.long	LBPatch24-4
733	.long	LBPatch25-4
734	.long	LBPatch26-4
735	.long	LBPatch27-4
736	.long	LBPatch28-4
737	.long	LBPatch29-4
738	.long	LBPatch30-4
739	.long	LBPatch31-4
740
741	.text
742
743	.align 4
744.globl C(R_Surf8Patch)
745C(R_Surf8Patch):
746	pushl	%ebx
747
748	movl	C(colormap),%eax
749	movl	$LPatchTable8,%ebx
750	movl	$32,%ecx
751LPatchLoop8:
752	movl	(%ebx),%edx
753	addl	$4,%ebx
754	movl	%eax,(%edx)
755	decl	%ecx
756	jnz		LPatchLoop8
757
758	popl	%ebx
759
760	ret
761
762#endif	// id386
763