snd_mixa.s */ // // 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