1/* 2Copyright (C) 1996-1997 Id Software, Inc. 3 4This program is free software; you can redistribute it and/or 5modify it under the terms of the GNU General Public License 6as published by the Free Software Foundation; either version 2 7of the License, or (at your option) any later version. 8 9This program is distributed in the hope that it will be useful, 10but WITHOUT ANY WARRANTY; without even the implied warranty of 11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 13See the GNU General Public License for more details. 14 15You should have received a copy of the GNU General Public License 16along with this program; if not, write to the Free Software 17Foundation, 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) 41C(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 64LLeftSet: 65 cmpl $255,%edx 66 jna LRightSet 67 movl $255,%edx 68LRightSet: 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// { 105LMix8Loop: 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 130LDone: 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) 144C(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// { 158LWLBLoopTop: 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 176LClampHigh: 177 movl $0x7FFF,%eax 178LClampDone: 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 196LClampHigh2: 197 movl $0x7FFF,%edx 198LClampDone2: 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