snd_mixa.s 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. //
  2. // snd_mixa.s
  3. // x86 assembly-language sound code
  4. //
  5. #include "qasm.h"
  6. #if id386
  7. .text
  8. //----------------------------------------------------------------------
  9. // 8-bit sound-mixing code
  10. //----------------------------------------------------------------------
  11. #define ch 4+16
  12. #define sc 8+16
  13. #define count 12+16
  14. .globl C(S_PaintChannelFrom8)
  15. C(S_PaintChannelFrom8):
  16. pushl %esi // preserve register variables
  17. pushl %edi
  18. pushl %ebx
  19. pushl %ebp
  20. // int data;
  21. // short *lscale, *rscale;
  22. // unsigned char *sfx;
  23. // int i;
  24. movl ch(%esp),%ebx
  25. movl sc(%esp),%esi
  26. // if (ch->leftvol > 255)
  27. // ch->leftvol = 255;
  28. // if (ch->rightvol > 255)
  29. // ch->rightvol = 255;
  30. movl ch_leftvol(%ebx),%eax
  31. movl ch_rightvol(%ebx),%edx
  32. cmpl $255,%eax
  33. jna LLeftSet
  34. movl $255,%eax
  35. LLeftSet:
  36. cmpl $255,%edx
  37. jna LRightSet
  38. movl $255,%edx
  39. LRightSet:
  40. // lscale = snd_scaletable[ch->leftvol >> 3];
  41. // rscale = snd_scaletable[ch->rightvol >> 3];
  42. // sfx = (signed char *)sc->data + ch->pos;
  43. // ch->pos += count;
  44. andl $0xF8,%eax
  45. addl $(sfxc_data),%esi
  46. andl $0xF8,%edx
  47. movl ch_pos(%ebx),%edi
  48. movl count(%esp),%ecx
  49. addl %edi,%esi
  50. shll $7,%eax
  51. addl %ecx,%edi
  52. shll $7,%edx
  53. movl %edi,ch_pos(%ebx)
  54. addl $(C(snd_scaletable)),%eax
  55. addl $(C(snd_scaletable)),%edx
  56. subl %ebx,%ebx
  57. movb -1(%esi,%ecx,1),%bl
  58. testl $1,%ecx
  59. jz LMix8Loop
  60. movl (%eax,%ebx,4),%edi
  61. movl (%edx,%ebx,4),%ebp
  62. addl C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size),%edi
  63. addl C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size),%ebp
  64. movl %edi,C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size)
  65. movl %ebp,C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size)
  66. movb -2(%esi,%ecx,1),%bl
  67. decl %ecx
  68. jz LDone
  69. // for (i=0 ; i<count ; i++)
  70. // {
  71. LMix8Loop:
  72. // data = sfx[i];
  73. // paintbuffer[i].left += lscale[data];
  74. // paintbuffer[i].right += rscale[data];
  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. movb -2(%esi,%ecx,1),%bl
  80. movl %edi,C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size)
  81. movl %ebp,C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size)
  82. movl (%eax,%ebx,4),%edi
  83. movl (%edx,%ebx,4),%ebp
  84. movb -3(%esi,%ecx,1),%bl
  85. addl C(paintbuffer)+psp_left-psp_size*2(,%ecx,psp_size),%edi
  86. addl C(paintbuffer)+psp_right-psp_size*2(,%ecx,psp_size),%ebp
  87. movl %edi,C(paintbuffer)+psp_left-psp_size*2(,%ecx,psp_size)
  88. movl %ebp,C(paintbuffer)+psp_right-psp_size*2(,%ecx,psp_size)
  89. // }
  90. subl $2,%ecx
  91. jnz LMix8Loop
  92. LDone:
  93. popl %ebp
  94. popl %ebx
  95. popl %edi
  96. popl %esi
  97. ret
  98. //----------------------------------------------------------------------
  99. // Transfer of stereo buffer to 16-bit DMA buffer code
  100. //----------------------------------------------------------------------
  101. .globl C(S_WriteLinearBlastStereo16)
  102. C(S_WriteLinearBlastStereo16):
  103. pushl %edi
  104. pushl %ebx
  105. // int i;
  106. // int val;
  107. movl C(snd_linear_count),%ecx
  108. movl C(snd_p),%ebx
  109. movl C(snd_out),%edi
  110. // for (i=0 ; i<snd_linear_count ; i+=2)
  111. // {
  112. LWLBLoopTop:
  113. // val = (snd_p[i]*snd_vol)>>8;
  114. // if (val > 0x7fff)
  115. // snd_out[i] = 0x7fff;
  116. // else if (val < (short)0x8000)
  117. // snd_out[i] = (short)0x8000;
  118. // else
  119. // snd_out[i] = val;
  120. movl -8(%ebx,%ecx,4),%eax
  121. sarl $8,%eax
  122. cmpl $0x7FFF,%eax
  123. jg LClampHigh
  124. cmpl $0xFFFF8000,%eax
  125. jnl LClampDone
  126. movl $0xFFFF8000,%eax
  127. jmp LClampDone
  128. LClampHigh:
  129. movl $0x7FFF,%eax
  130. LClampDone:
  131. // val = (snd_p[i+1]*snd_vol)>>8;
  132. // if (val > 0x7fff)
  133. // snd_out[i+1] = 0x7fff;
  134. // else if (val < (short)0x8000)
  135. // snd_out[i+1] = (short)0x8000;
  136. // else
  137. // snd_out[i+1] = val;
  138. movl -4(%ebx,%ecx,4),%edx
  139. sarl $8,%edx
  140. cmpl $0x7FFF,%edx
  141. jg LClampHigh2
  142. cmpl $0xFFFF8000,%edx
  143. jnl LClampDone2
  144. movl $0xFFFF8000,%edx
  145. jmp LClampDone2
  146. LClampHigh2:
  147. movl $0x7FFF,%edx
  148. LClampDone2:
  149. shll $16,%edx
  150. andl $0xFFFF,%eax
  151. orl %eax,%edx
  152. movl %edx,-4(%edi,%ecx,2)
  153. // }
  154. subl $2,%ecx
  155. jnz LWLBLoopTop
  156. // snd_p += snd_linear_count;
  157. popl %ebx
  158. popl %edi
  159. ret
  160. #endif // id386