/* snd_mixa.S (description) Copyright (C) 1996-1997 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA $Id$ */ // snd_mixa.s // x86 assembly-language sound code #include "asm_i386.h" #include "quakeasm.h" #if id386 .text //---------------------------------------------------------------------- // 8-bit sound-mixing code //---------------------------------------------------------------------- #define ch 4+16 #define sc 8+16 #define count 12+16 .globl C(SND_PaintChannelFrom8) C(SND_PaintChannelFrom8): pushl %esi // preserve register variables pushl %edi pushl %ebx pushl %ebp // int data; // short *lscale, *rscale; // unsigned char *sfx; // int i; movl ch(%esp),%ebx movl sc(%esp),%esi // if (ch->leftvol > 255) // ch->leftvol = 255; // if (ch->rightvol > 255) // ch->rightvol = 255; movl ch_leftvol(%ebx),%eax movl ch_rightvol(%ebx),%edx cmpl $255,%eax jna LLeftSet movl $255,%eax LLeftSet: cmpl $255,%edx jna LRightSet movl $255,%edx LRightSet: // lscale = snd_scaletable[ch->leftvol >> 3]; // rscale = snd_scaletable[ch->rightvol >> 3]; // sfx = (signed char *)sc->data + ch->pos; // ch->pos += count; andl $0xF8,%eax addl $(sfxc_data),%esi andl $0xF8,%edx movl ch_pos(%ebx),%edi movl count(%esp),%ecx addl %edi,%esi shll $7,%eax addl %ecx,%edi shll $7,%edx movl %edi,ch_pos(%ebx) addl $(C(snd_scaletable)),%eax addl $(C(snd_scaletable)),%edx subl %ebx,%ebx movb -1(%esi,%ecx,1),%bl testl $1,%ecx jz LMix8Loop movl (%eax,%ebx,4),%edi movl (%edx,%ebx,4),%ebp addl C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size),%edi addl C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size),%ebp movl %edi,C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size) movl %ebp,C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size) movb -2(%esi,%ecx,1),%bl decl %ecx jz LDone // for (i=0 ; i>8; // if (val > 0x7fff) // snd_out[i] = 0x7fff; // else if (val < (short)0x8000) // snd_out[i] = (short)0x8000; // else // snd_out[i] = val; movl -8(%ebx,%ecx,4),%eax imull %esi,%eax sarl $8,%eax cmpl $0x7FFF,%eax jg LClampHigh cmpl $0xFFFF8000,%eax jnl LClampDone movl $0xFFFF8000,%eax jmp LClampDone LClampHigh: movl $0x7FFF,%eax LClampDone: // val = (snd_p[i+1]*snd_vol)>>8; // if (val > 0x7fff) // snd_out[i+1] = 0x7fff; // else if (val < (short)0x8000) // snd_out[i+1] = (short)0x8000; // else // snd_out[i+1] = val; movl -4(%ebx,%ecx,4),%edx imull %esi,%edx sarl $8,%edx cmpl $0x7FFF,%edx jg LClampHigh2 cmpl $0xFFFF8000,%edx jnl LClampDone2 movl $0xFFFF8000,%edx jmp LClampDone2 LClampHigh2: movl $0x7FFF,%edx LClampDone2: shll $16,%edx andl $0xFFFF,%eax orl %eax,%edx movl %edx,-4(%edi,%ecx,2) // } subl $2,%ecx jnz LWLBLoopTop // snd_p += snd_linear_count; popl %ebx popl %edi popl %esi ret #endif // id386