snd_mixa.s 4.8 KB

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