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