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