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