1/*
2===========================================================================
3Copyright (C) 1999-2005 Id Software, Inc.
4
5This file is part of Quake III Arena source code.
6
7Quake III Arena source code is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 2 of the License,
10or (at your option) any later version.
11
12Quake III Arena source code is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with Quake III Arena source code; if not, write to the Free Software
19Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20===========================================================================
21*/
22//
23// snd_mixa.s
24// x86 assembly-language sound code
25//
26
27#include "qasm.h"
28
29#if	id386
30
31	.text
32
33#if 0
34//----------------------------------------------------------------------
35// 8-bit sound-mixing code
36//----------------------------------------------------------------------
37
38#define ch		4+16
39#define sc		8+16
40#define count	12+16
41
42.globl C(S_PaintChannelFrom8)
43C(S_PaintChannelFrom8):
44	pushl	%esi				// preserve register variables
45	pushl	%edi
46	pushl	%ebx
47	pushl	%ebp
48
49//	int 	data;
50//	short	*lscale, *rscale;
51//	unsigned char *sfx;
52//	int		i;
53
54	movl	ch(%esp),%ebx
55	movl	sc(%esp),%esi
56
57//	if (ch->leftvol > 255)
58//		ch->leftvol = 255;
59//	if (ch->rightvol > 255)
60//		ch->rightvol = 255;
61	movl	ch_leftvol(%ebx),%eax
62	movl	ch_rightvol(%ebx),%edx
63	cmpl	$255,%eax
64	jna		LLeftSet
65	movl	$255,%eax
66LLeftSet:
67	cmpl	$255,%edx
68	jna		LRightSet
69	movl	$255,%edx
70LRightSet:
71
72//	lscale = snd_scaletable[ch->leftvol >> 3];
73//	rscale = snd_scaletable[ch->rightvol >> 3];
74//	sfx = (signed char *)sc->data + ch->pos;
75//	ch->pos += count;
76	andl	$0xF8,%eax
77	addl	$20,%esi
78	movl	(%esi),%esi
79	andl	$0xF8,%edx
80	movl	ch_pos(%ebx),%edi
81	movl	count(%esp),%ecx
82	addl	%edi,%esi
83	shll	$7,%eax
84	addl	%ecx,%edi
85	shll	$7,%edx
86	movl	%edi,ch_pos(%ebx)
87	addl	$(C(snd_scaletable)),%eax
88	addl	$(C(snd_scaletable)),%edx
89	subl	%ebx,%ebx
90	movb	-1(%esi,%ecx,1),%bl
91
92	testl	$1,%ecx
93	jz		LMix8Loop
94
95	movl	(%eax,%ebx,4),%edi
96	movl	(%edx,%ebx,4),%ebp
97	addl	C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size),%edi
98	addl	C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size),%ebp
99	movl	%edi,C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size)
100	movl	%ebp,C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size)
101	movb	-2(%esi,%ecx,1),%bl
102
103	decl	%ecx
104	jz		LDone
105
106//	for (i=0 ; i<count ; i++)
107//	{
108LMix8Loop:
109
110//		data = sfx[i];
111//		paintbuffer[i].left += lscale[data];
112//		paintbuffer[i].right += rscale[data];
113	movl	(%eax,%ebx,4),%edi
114	movl	(%edx,%ebx,4),%ebp
115	addl	C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size),%edi
116	addl	C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size),%ebp
117	movb	-2(%esi,%ecx,1),%bl
118	movl	%edi,C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size)
119	movl	%ebp,C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size)
120
121	movl	(%eax,%ebx,4),%edi
122	movl	(%edx,%ebx,4),%ebp
123	movb	-3(%esi,%ecx,1),%bl
124	addl	C(paintbuffer)+psp_left-psp_size*2(,%ecx,psp_size),%edi
125	addl	C(paintbuffer)+psp_right-psp_size*2(,%ecx,psp_size),%ebp
126	movl	%edi,C(paintbuffer)+psp_left-psp_size*2(,%ecx,psp_size)
127	movl	%ebp,C(paintbuffer)+psp_right-psp_size*2(,%ecx,psp_size)
128
129//	}
130	subl	$2,%ecx
131	jnz		LMix8Loop
132
133LDone:
134	popl	%ebp
135	popl	%ebx
136	popl	%edi
137	popl	%esi
138
139	ret
140
141
142#endif
143
144//----------------------------------------------------------------------
145// Transfer of stereo buffer to 16-bit DMA buffer code
146//----------------------------------------------------------------------
147
148.globl C(S_WriteLinearBlastStereo16)
149C(S_WriteLinearBlastStereo16):
150	pushl	%edi
151	pushl	%ebx
152
153//	int		i;
154//	int		val;
155	movl	C(snd_linear_count),%ecx
156	movl	C(snd_p),%ebx
157	movl	C(snd_out),%edi
158
159//	for (i=0 ; i<snd_linear_count ; i+=2)
160//	{
161LWLBLoopTop:
162
163//		val = (snd_p[i]*snd_vol)>>8;
164//		if (val > 0x7fff)
165//			snd_out[i] = 0x7fff;
166//		else if (val < (short)0x8000)
167//			snd_out[i] = (short)0x8000;
168//		else
169//			snd_out[i] = val;
170	movl	-8(%ebx,%ecx,4),%eax
171	sarl	$8,%eax
172	cmpl	$0x7FFF,%eax
173	jg		LClampHigh
174	cmpl	$0xFFFF8000,%eax
175	jnl		LClampDone
176	movl	$0xFFFF8000,%eax
177	jmp		LClampDone
178LClampHigh:
179	movl	$0x7FFF,%eax
180LClampDone:
181
182//		val = (snd_p[i+1]*snd_vol)>>8;
183//		if (val > 0x7fff)
184//			snd_out[i+1] = 0x7fff;
185//		else if (val < (short)0x8000)
186//			snd_out[i+1] = (short)0x8000;
187//		else
188//			snd_out[i+1] = val;
189	movl	-4(%ebx,%ecx,4),%edx
190	sarl	$8,%edx
191	cmpl	$0x7FFF,%edx
192	jg		LClampHigh2
193	cmpl	$0xFFFF8000,%edx
194	jnl		LClampDone2
195	movl	$0xFFFF8000,%edx
196	jmp		LClampDone2
197LClampHigh2:
198	movl	$0x7FFF,%edx
199LClampDone2:
200	shll	$16,%edx
201	andl	$0xFFFF,%eax
202	orl		%eax,%edx
203	movl	%edx,-4(%edi,%ecx,2)
204
205//	}
206	subl	$2,%ecx
207	jnz		LWLBLoopTop
208
209//	snd_p += snd_linear_count;
210
211	popl	%ebx
212	popl	%edi
213
214	ret
215
216#endif	// id386
217
218