Subversion Repositories Kolibri OS

Rev

Rev 291 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;
  2. ;   This file is part of the Infinity sound library.
  3. ;   (C) copyright Serge 2006
  4. ;   email: infinity_sound@mail.ru
  5. ;
  6. ;   This program is free software; you can redistribute it and/or modify
  7. ;   it under the terms of the GNU General Public License as published by
  8. ;   the Free Software Foundation; either version 2 of the License, or
  9. ;   (at your option) any later version.
  10. ;
  11. ;   This program is distributed in the hope that it will be useful,
  12. ;   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ;   GNU General Public License for more details.
  15.  
  16. align 4
  17. proc new_mix stdcall, output:dword
  18.            locals
  19.              mixCounter  dd ?
  20.              mixIndex  dd ?
  21.              streamIndex dd ?
  22.              inputCount  dd ?
  23.              main_count  dd ?
  24.              blockCount  dd ?
  25.              mix_out  dd ?
  26.            endl
  27.  
  28.            call prepare_playlist
  29.  
  30.            cmp [play_count], 0
  31.            je .exit
  32.            call FpuSave
  33.            mov [main_count], 32;
  34. .l00:
  35.            mov [mix_buff_map], 0x0000FFFF;
  36.            xor eax, eax
  37.            mov [mixCounter], eax
  38.            mov [mixIndex],eax
  39.            mov [streamIndex], eax;
  40.            mov ebx, [play_count]
  41.            mov [inputCount], ebx
  42. .l0:
  43.            mov ecx, 4
  44. .l1:
  45.            mov ebx, [streamIndex]
  46.            mov esi, [play_list+ebx*4]
  47.            mov eax, [esi+STREAM.work_read]
  48.            add [esi+STREAM.work_read], 512
  49.  
  50.            mov ebx, [mixIndex]
  51.            mov [mix_input+ebx*4], eax
  52.            inc [mixCounter]
  53.            inc [mixIndex]
  54.            inc [streamIndex]
  55.            dec [inputCount]
  56.            jz .m2
  57.  
  58.            dec ecx
  59.            jnz .l1
  60.  
  61.            cmp [mixCounter], 4
  62.            jnz .m2
  63.  
  64.            stdcall mix_4_1, [mix_input],[mix_input+4],[mix_input+8],[mix_input+12]
  65.            sub [mixIndex],4
  66.            mov ebx, [mixIndex]
  67.            mov [mix_input+ebx*4], eax
  68.            inc [mixIndex]
  69.            mov [mixCounter], 0
  70.  
  71.            cmp [inputCount], 0
  72.            jnz .l0
  73. .m2:
  74.            cmp [mixIndex], 1
  75.            jne @f
  76.            stdcall copy_mem, [output], [mix_input]
  77.            jmp .m3
  78. @@:
  79.            cmp [mixIndex], 2
  80.            jne @f
  81.            stdcall mix_2_1, [output], [mix_input], [mix_input+4]
  82.            jmp .m3
  83. @@:
  84.            cmp [mixIndex], 3
  85.            jne @f
  86.            stdcall mix_3_1, [output],[mix_input],[mix_input+4],[mix_input+8]
  87.            jmp .m3
  88. @@:
  89.            stdcall final_mix, [output],[mix_input],[mix_input+4],[mix_input+8], [mix_input+12]
  90. .m3:
  91.            add [output],512
  92.  
  93.            dec [main_count]
  94.            jnz .l00
  95.  
  96.            call update_stream
  97.            emms
  98.            call FpuRestore
  99.            ret
  100. .exit:
  101.            mov edi, [output]
  102.            mov ecx, 0x1000
  103.            xor eax, eax
  104.            cld
  105.            rep stosd
  106.            ret
  107. endp
  108.  
  109. align 4
  110. proc update_stream
  111.            locals
  112.              stream_index  dd ?
  113.              ev_code       dd ?  ;EVENT
  114.              ev_offs       dd ?
  115.                            rd 4
  116.            endl
  117.  
  118.            mov [stream_index], 0
  119. .l1:
  120.            mov edx, [stream_index]
  121.            mov esi, [play_list+edx*4]
  122.  
  123.            mov eax, [esi+STREAM.work_read]
  124.            cmp eax, [esi+STREAM.work_top]
  125.            jb @f
  126.            mov eax, [esi+STREAM.work_buff]
  127. @@:
  128.            mov [esi+STREAM.work_read], eax
  129.  
  130.            cmp [esi+STREAM.format], PCM_2_16_48
  131.            je .copy
  132.  
  133.            sub [esi+STREAM.work_count], 16384
  134.  
  135.            cmp [esi+STREAM.work_count], 32768
  136.            ja @f
  137.  
  138.            stdcall refill, esi
  139. @@:
  140.            inc [stream_index]
  141.            dec [play_count]
  142.            jnz .l1
  143.            ret
  144. .copy:
  145.            mov ebx, esi
  146.            mov edi, [ebx+STREAM.work_write]
  147.            cmp edi, [ebx+STREAM.work_top]
  148.            jb @f
  149.            mov edi, [ebx+STREAM.work_buff]
  150.            mov [ebx+STREAM.work_write], edi
  151. @@:
  152.            mov esi, [ebx+STREAM.curr_seg]
  153.            mov ecx, 16384/4
  154.            cld
  155.            rep movsd
  156.  
  157.            mov [ebx+STREAM.work_write], edi
  158.  
  159.            cmp esi, [ebx+STREAM.lim_0]
  160.            jb @f
  161.  
  162.            mov esi, [ebx+STREAM.seg_0]
  163.            mov eax, [ebx+STREAM.lim_0]
  164.            xchg esi, [ebx+STREAM.seg_1]
  165.            xchg eax, [ebx+STREAM.lim_1]
  166.            mov [ebx+STREAM.seg_0], esi
  167.            mov [ebx+STREAM.lim_0], eax
  168. @@:
  169.            mov [ebx+STREAM.curr_seg], esi
  170.  
  171.            xor ecx, ecx
  172.            cmp esi, [ebx+STREAM.notify_off2]
  173.            je @f
  174.  
  175.            mov ecx,0x8000
  176.            cmp esi, [ebx+STREAM.notify_off1]
  177.            je @f
  178.  
  179.            inc [stream_index]
  180.            dec [play_count]
  181.            jnz .l1
  182.            ret
  183. @@:
  184.            mov [ev_code], 0xFF000001
  185.            mov [ev_offs], ecx
  186.            mov eax, [ebx+STREAM.pid]
  187.  
  188.            lea edx, [ev_code]
  189.            push ebx
  190.            stdcall SendEvent, eax, edx
  191.            pop ebx
  192.            test eax, eax
  193.            jnz .l_end
  194.  
  195.            not eax
  196.            mov [ebx+STREAM.pid], eax      ;-1
  197. .l_end:
  198.            inc [stream_index]
  199.            dec [play_count]
  200.            jnz .l1
  201.            ret
  202. endp
  203.  
  204. align 4
  205. proc refill stdcall, str:dword
  206.            locals
  207.              ev_code       dd ?  ;EVENT
  208.              ev_offs       dd ?
  209.                            rd 4
  210.            endl
  211.  
  212.            mov ebx, [str]
  213.            mov ecx, [ebx+STREAM.work_write]
  214.            cmp ecx, [ebx+STREAM.work_top]
  215.            jbe .m2
  216.            mov esi, [ebx+STREAM.work_top]
  217.            sub ecx, esi
  218.            mov edi, [ebx+STREAM.work_buff]
  219.            shr ecx, 2
  220.            rep movsd    ;call memcpy
  221.  
  222.            mov [ebx+STREAM.work_write], edi
  223. .m2:
  224.            mov esi, [ebx+STREAM.curr_seg]
  225.            mov edi, [ebx+STREAM.work_write]
  226.  
  227.            stdcall [ebx+STREAM.resample], edi, esi, \
  228.            [ebx+STREAM.r_dt],[ebx+STREAM.r_size],[ebx+STREAM.r_end]
  229.  
  230.            mov ebx, [str]
  231.  
  232.            add [ebx+STREAM.work_count], eax;
  233.            add [ebx+STREAM.work_write], eax;
  234.  
  235.            mov eax, [ebx+STREAM.curr_seg]
  236.            add eax, [ebx+STREAM.r_size]
  237.            cmp eax, [ebx+STREAM.lim_0]
  238.            jb @f
  239.  
  240.            mov esi, [ebx+STREAM.seg_0]
  241.            lea edi, [esi-128]
  242.            add esi, 0x7F80
  243.            mov ecx, 128/4
  244.            cld
  245.            rep movsd
  246.  
  247.            mov eax, [ebx+STREAM.seg_0]
  248.            mov ecx, [ebx+STREAM.lim_0]
  249.            xchg eax, [ebx+STREAM.seg_1]
  250.            xchg ecx, [ebx+STREAM.lim_1]
  251.            mov [ebx+STREAM.seg_0], eax
  252.            mov [ebx+STREAM.lim_0], ecx
  253. @@:
  254.            mov [ebx+STREAM.curr_seg], eax
  255.  
  256.            xor ecx, ecx
  257.            cmp eax, [ebx+STREAM.notify_off2]
  258.            je @f
  259.  
  260.            mov ecx,0x8000
  261.            cmp eax, [ebx+STREAM.notify_off1]
  262.            je @f
  263.            ret
  264. @@:
  265.            mov [ev_code], 0xFF000001
  266.            mov [ev_offs], ecx
  267.            mov eax, [ebx+STREAM.pid]
  268.  
  269.            lea edx, [ev_code]
  270.            push ebx
  271.            stdcall SendEvent, eax, edx
  272.            pop ebx
  273.            test eax, eax
  274.            jnz @F
  275.            not eax
  276.            mov [ebx+STREAM.pid], eax      ;-1
  277. @@:
  278.            ret
  279. endp
  280.  
  281. align 4
  282. proc resample_1 stdcall, dest:dword,src:dword,\
  283.                        r_dt:dword, r_size:dword,r_end:dword
  284.  
  285. ; dest equ esp+8
  286. ; src  equ esp+12
  287. ; r_dt equ esp+16
  288. ; r_size equ esp+20
  289. ;r_end equ esp+24
  290.  
  291.            mov edi, [dest]
  292.            mov edx, [src]
  293.            sub edx, 32*2
  294.            mov eax, 16
  295.  
  296. align 16
  297. .l1:
  298.            mov ecx, eax
  299.            mov esi, eax
  300.            and ecx, 0x7FFF
  301.            shr esi, 15
  302.            lea esi, [edx+esi*2]
  303.  
  304.            movsx ebp, word [esi]
  305.            movsx esi, word [esi+2]
  306.            mov ebx, 32768
  307.            imul esi, ecx
  308.            sub ebx, ecx
  309.            imul ebx, ebp
  310.            lea ecx, [ebx+esi+16384]
  311.            sar ecx, 15
  312.            cmp ecx, 32767         ; 00007fffH
  313.            jle @f
  314.            mov ecx, 32767         ; 00007fffH
  315.            jmp .write
  316. @@:
  317.            cmp ecx, -32768        ; ffff8000H
  318.            jge .write
  319.            mov ecx, -32768        ; ffff8000H
  320. .write:
  321.            mov ebx, ecx
  322.            shl ebx, 16
  323.            mov bx, cx
  324.            mov [edi], ebx
  325.            add edi, 4
  326.  
  327.            add eax, [esp+16]
  328.            cmp eax, [esp+24]
  329.            jb .l1
  330.  
  331.            mov ebp, esp
  332.  
  333.            sub edi, [dest]
  334.            mov eax, edi
  335.            ret
  336. endp
  337.  
  338. align 4
  339. proc resample_18 stdcall, dest:dword,src:dword,\
  340.                        r_dt:dword, r_size:dword,r_end:dword
  341.  
  342.  
  343.            mov edi, [dest]
  344.            mov edx, [src]
  345.            sub edx, 32
  346.  
  347.            mov esi, 16
  348.  
  349. align 16
  350. .l1:
  351.            mov ecx, esi
  352.            mov eax, esi
  353.            and ecx, 0x7FFF
  354.            shr eax, 15
  355.            lea eax, [edx+eax]
  356.  
  357.            mov bx, word [eax]
  358.            sub bh, 0x80
  359.            sub bl, 0x80
  360.            movsx eax, bh
  361.            shl eax,8
  362.            movsx ebp, bl
  363.            shl ebp,8
  364.            mov ebx, 32768
  365.            imul eax, ecx
  366.            sub ebx, ecx
  367.            imul ebx, ebp
  368.            lea ecx, [ebx+eax+16384]
  369.            sar ecx, 15
  370.            cmp ecx, 32767         ; 00007fffH
  371.            jle @f
  372.            mov ecx, 32767         ; 00007fffH
  373.            jmp .write
  374. @@:
  375.            cmp ecx, -32768        ; ffff8000H
  376.            jge .write
  377.            mov ecx, -32768        ; ffff8000H
  378. .write:
  379.            mov ebx, ecx
  380.            shl ebx, 16
  381.            mov bx, cx
  382.            mov [edi], ebx
  383.            add edi, 4
  384.  
  385.            add esi, [esp+16]
  386.            cmp esi, [esp+24]
  387.            jb .l1
  388.  
  389.            mov ebp, esp
  390.            sub edi, [dest]
  391.            mov eax, edi
  392.            ret
  393. endp
  394.  
  395. align 4
  396. proc copy_stream stdcall, dest:dword,src:dword,\
  397.                        r_dt:dword, r_size:dword,r_end:dword
  398.  
  399.            mov ecx, [r_size]
  400.            mov eax, ecx
  401.            shr ecx, 2
  402.            mov esi, [src]
  403.            mov edi, [dest]
  404.            rep movsd
  405.            mov eax, 16384
  406.            ret
  407. endp
  408.  
  409. align 4
  410. proc resample_2 stdcall, dest:dword,src:dword,\
  411.                        r_dt:dword, r_size:dword,r_end:dword
  412.  
  413.            mov edx, [src]
  414.            sub edx, 32*4
  415.            mov edi, [dest]
  416.            mov ebx, [r_dt]
  417.            mov eax, 16
  418.            emms
  419.  
  420. align 16
  421. .l1:
  422.            mov ecx, eax
  423.            mov esi, eax
  424.            and ecx, 0x7FFF
  425.            shr esi, 15
  426.            lea esi, [edx+esi*4]
  427.  
  428.            movq mm0, [esi]
  429.            movq mm1, mm0
  430.  
  431.            movd mm2, ecx
  432.            punpcklwd mm2, mm2
  433.            movq mm3, qword [m7]    ;0x8000
  434.  
  435.            psubw mm3, mm2 ;        ;0x8000 - iconst
  436.            punpckldq mm3, mm2
  437.  
  438.            pmulhw mm0, mm3
  439.            pmullw mm1, mm3
  440.  
  441.            movq mm4, mm1
  442.            punpcklwd mm1, mm0
  443.            punpckhwd mm4, mm0
  444.            paddd mm1, mm4
  445.            psrad  mm1, 15
  446.            packssdw mm1, mm1
  447.            movd [edi], mm1
  448.            add edi, 4
  449.  
  450.            add eax, ebx
  451.            cmp eax, [r_end]
  452.            jb .l1
  453.            emms
  454.  
  455.            sub edi, [dest]
  456.            mov eax, edi
  457.            ret
  458. endp
  459.  
  460. align 4
  461. proc resample_28 stdcall, dest:dword,src:dword,\
  462.                        r_dt:dword, r_size:dword,r_end:dword
  463.  
  464.            mov edx, [src]
  465.            sub edx, 32*2
  466.            mov edi, [dest]
  467.            mov ebx, [r_dt]
  468.            mov eax, 16
  469.            emms
  470.            movq mm7,[mm80]
  471.            movq mm6,[mm_mask]
  472.  
  473. align 16
  474. .l1:
  475.            mov ecx, eax
  476.            mov esi, eax
  477.            and ecx, 0x7FFF
  478.            shr esi, 15
  479.            lea esi, [edx+esi*2]
  480.  
  481.            movq mm0, [esi]
  482.            psubb mm0,mm7
  483.            punpcklbw mm0,mm0
  484.            pand mm0,mm6
  485.  
  486.            movq mm1, mm0
  487.  
  488.            movd mm2, ecx
  489.            punpcklwd mm2, mm2
  490.            movq mm3, qword [m7] ;                  // 0x8000
  491.  
  492.            psubw mm3, mm2       ;         // 0x8000 - iconst
  493.            punpckldq mm3, mm2
  494.  
  495.            pmulhw mm0, mm3
  496.            pmullw mm1, mm3
  497.  
  498.            movq mm4, mm1
  499.            punpcklwd mm1, mm0
  500.            punpckhwd mm4, mm0
  501.            paddd mm1, mm4
  502.            psrad  mm1, 15
  503.            packssdw mm1, mm1
  504.            movd [edi], mm1
  505.            add edi, 4
  506.  
  507.            add eax, ebx
  508.            cmp eax, [r_end]
  509.            jb .l1
  510.            emms
  511.  
  512.  
  513.            sub edi, [dest]
  514.            mov eax, edi
  515.            ret
  516. endp
  517.  
  518.  
  519. proc m16_stereo stdcall, dest:dword,src:dword,\
  520.                        r_dt:dword, r_size:dword,r_end:dword
  521.  
  522.            mov esi, [src]
  523.            mov edi, [dest]
  524.            mov ecx, [r_size]
  525.            shr ecx,8
  526. @@:
  527.            call m16_s_mmx
  528.            add edi, 128
  529.            add esi, 64
  530.            call m16_s_mmx
  531.            add edi, 128
  532.            add esi, 64
  533.            call m16_s_mmx
  534.            add edi, 128
  535.            add esi, 64
  536.            call m16_s_mmx
  537.            add edi, 128
  538.            add esi, 64
  539.            dec ecx
  540.            jnz @b
  541.  
  542.            mov eax, [r_size]
  543.            add eax, eax
  544.            ret
  545. endp
  546.  
  547. align 4
  548. proc s8_stereo stdcall, dest:dword,src:dword,\
  549.                        r_dt:dword, r_size:dword,r_end:dword
  550.  
  551.            mov esi, [src]
  552.            mov edi, [dest]
  553.            mov ecx, [r_size]
  554.            shr ecx, 7
  555.  
  556.            movq mm7, [mm80]
  557.            movq mm6, [mm_mask]
  558. @@:
  559.            call s8_s_mmx
  560.            add edi, 64
  561.            add esi, 32
  562.            call s8_s_mmx
  563.            add edi, 64
  564.            add esi, 32
  565.            call s8_s_mmx
  566.            add edi, 64
  567.            add esi, 32
  568.            call s8_s_mmx
  569.            add edi, 64
  570.            add esi, 32
  571.            dec ecx
  572.            jnz @b
  573.  
  574.            mov eax, [r_size]
  575.            add eax, eax
  576.            ret
  577. endp
  578.  
  579. proc m8_stereo stdcall, dest:dword,src:dword,\
  580.                        r_dt:dword, r_size:dword,r_end:dword
  581.  
  582.            mov esi, [src]
  583.            mov edi, [dest]
  584.            mov ecx, [r_size]
  585.            shr ecx, 6
  586.  
  587.            movq mm7, [mm80]
  588.            movq mm6, [mm_mask]
  589. @@:
  590.            call m8_s_mmx
  591.            add edi, 64
  592.            add esi, 16
  593.            call m8_s_mmx
  594.            add edi, 64
  595.            add esi, 16
  596.            call m8_s_mmx
  597.            add edi, 64
  598.            add esi, 16
  599.            call m8_s_mmx
  600.            add edi, 64
  601.            add esi, 16
  602.                   dec ecx
  603.            jnz @b
  604.  
  605.            mov eax, [r_size]
  606.            add eax, eax
  607.            add eax, eax
  608.            ret
  609. endp
  610.  
  611. align 4
  612. proc alloc_mix_buff
  613.  
  614.            bsf eax, [mix_buff_map]
  615.            jnz .find
  616.            xor eax, eax
  617.            ret
  618. .find:
  619.            btr [mix_buff_map], eax
  620.            shl eax, 9
  621.            add eax, [mix_buff]
  622.            ret
  623. endp
  624.  
  625. align 4
  626. proc m16_s_mmx
  627.  
  628.            movq    mm0, [esi]
  629.            movq    mm1, mm0
  630.            punpcklwd mm0, mm0
  631.            punpckhwd mm1, mm1
  632.            movq    [edi], mm0
  633.            movq    [edi+8], mm1
  634.  
  635.            movq    mm0, [esi+8]
  636.            movq    mm1, mm0
  637.            punpcklwd mm0, mm0
  638.            punpckhwd mm1, mm1
  639.            movq    [edi+16], mm0
  640.            movq    [edi+24], mm1
  641.  
  642.            movq    mm0, [esi+16]
  643.            movq    mm1, mm0
  644.            punpcklwd mm0, mm0
  645.            punpckhwd mm1, mm1
  646.            movq    [edi+32], mm0
  647.            movq    [edi+40], mm1
  648.  
  649.            movq    mm0, [esi+24]
  650.            movq    mm1, mm0
  651.            punpcklwd mm0, mm0
  652.            punpckhwd mm1, mm1
  653.            movq    [edi+48], mm0
  654.            movq    [edi+56], mm1
  655.  
  656.            movq    mm0, [esi+32]
  657.            movq    mm1, mm0
  658.            punpcklwd mm0, mm0
  659.            punpckhwd mm1, mm1
  660.            movq    [edi+64], mm0
  661.            movq    [edi+72], mm1
  662.  
  663.            movq    mm0, [esi+40]
  664.            movq    mm1, mm0
  665.            punpcklwd mm0, mm0
  666.            punpckhwd mm1, mm1
  667.            movq    [edi+80], mm0
  668.            movq    [edi+88], mm1
  669.  
  670.  
  671.            movq    mm0, [esi+48]
  672.            movq    mm1, mm0
  673.            punpcklwd mm0, mm0
  674.            punpckhwd mm1, mm1
  675.            movq    [edi+96], mm0
  676.            movq    [edi+104], mm1
  677.  
  678.            movq    mm0, [esi+56]
  679.            movq    mm1, mm0
  680.            punpcklwd mm0, mm0
  681.            punpckhwd mm1, mm1
  682.            movq    [edi+112], mm0
  683.            movq    [edi+120], mm1
  684.  
  685.            ret
  686. endp
  687.  
  688. align 4
  689. proc s8_s_mmx
  690.  
  691.            movq    mm0, [esi]
  692.            psubb   mm0, mm7
  693.            movq    mm1, mm0
  694.            punpcklbw mm0, mm0
  695.            pand mm0, mm6
  696.            punpckhbw mm1, mm1
  697.            pand mm1, mm6
  698.            movq    [edi], mm0
  699.            movq    [edi+8], mm1
  700.  
  701.            movq    mm0, [esi+8]
  702.            psubb   mm0, mm7
  703.            movq    mm1, mm0
  704.            punpcklbw mm0, mm0
  705.            pand mm0, mm6
  706.            punpckhbw mm1, mm1
  707.            pand mm1, mm6
  708.            movq    [edi+16], mm0
  709.            movq    [edi+24], mm1
  710.  
  711.            movq    mm0, [esi+16]
  712.            psubb   mm0, mm7
  713.            movq    mm1, mm0
  714.            punpcklbw mm0, mm0
  715.            pand mm0, mm6
  716.            punpckhbw mm1, mm1
  717.            pand mm1, mm6
  718.            movq    [edi+32], mm0
  719.            movq    [edi+40], mm1
  720.  
  721.            movq    mm0, [esi+24]
  722.            psubb   mm0, mm7
  723.            movq    mm1, mm0
  724.            punpcklbw mm0, mm0
  725.            pand    mm0, mm6
  726.            punpckhbw mm1, mm1
  727.            pand    mm1, mm6
  728.            movq    [edi+48], mm0
  729.            movq    [edi+56], mm1
  730.  
  731.            ret
  732.  
  733. endp
  734.  
  735. align 4
  736. proc m8_s_mmx
  737.  
  738.            movq    mm0, [esi]
  739.            psubb   mm0, mm7
  740.            movq    mm1, mm0
  741.            punpcklbw mm0, mm0
  742.            pand mm0, mm6
  743.            punpckhbw mm1, mm1
  744.            pand mm1, mm6
  745.            movq mm2, mm0
  746.            punpcklwd mm0, mm0
  747.            punpckhwd mm2, mm2
  748.  
  749.            movq mm3, mm1
  750.            punpcklwd mm1, mm1
  751.            punpckhwd mm3, mm3
  752.  
  753.            movq    [edi], mm0
  754.            movq    [edi+8], mm2
  755.            movq    [edi+16], mm1
  756.            movq    [edi+24], mm3
  757.  
  758.            movq    mm0, [esi+8]
  759.            psubb   mm0, mm7
  760.            movq    mm1, mm0
  761.            punpcklbw mm0, mm0
  762.            pand mm0, mm6
  763.            punpckhbw mm1, mm1
  764.            pand mm1, mm6
  765.            movq mm2, mm0
  766.            punpcklwd mm0, mm0
  767.            punpckhwd mm2, mm2
  768.  
  769.            movq mm3, mm1
  770.            punpcklwd mm1, mm1
  771.            punpckhwd mm3, mm3
  772.  
  773.            movq    [edi+32], mm0
  774.            movq    [edi+40], mm2
  775.            movq    [edi+48], mm1
  776.            movq    [edi+56], mm3
  777.  
  778.            ret
  779. endp
  780.  
  781. align 4
  782. proc mix_2_1 stdcall, output:dword, str0:dword, str1:dword
  783.  
  784.            mov edi, [output]
  785.            mov eax, [str0]
  786.            mov ebx, [str1]
  787.            mov esi, 128
  788.            call [mix_2_core]   ;edi, eax, ebx
  789.  
  790.            add edi, esi
  791.            add eax, esi
  792.            add ebx, esi
  793.            call [mix_2_core]   ;edi, eax, ebx
  794.  
  795.            add edi, esi
  796.            add eax, esi
  797.            add ebx, esi
  798.            call [mix_2_core]   ;edi, eax, ebx
  799.  
  800.            add edi, esi
  801.            add eax, esi
  802.            add ebx, esi
  803.            call [mix_2_core]   ;edi, eax, ebx
  804.            ret
  805. endp
  806.  
  807. align 4
  808. proc mix_3_1 stdcall, output:dword, str0:dword, str1:dword, str2:dword
  809.  
  810.            mov edi, [output]
  811.            mov eax, [str0]
  812.            mov ebx, [str1]
  813.            mov ecx, [str2]
  814.            mov esi, 128
  815.            call [mix_3_core]
  816.  
  817.            add edi, esi
  818.            add eax, esi
  819.            add ebx, esi
  820.            add ecx, esi
  821.            call [mix_3_core]
  822.  
  823.            add edi, esi
  824.            add eax, esi
  825.            add ebx, esi
  826.            add ecx, esi
  827.            call [mix_3_core]
  828.  
  829.            add edi, esi
  830.            add eax, esi
  831.            add ebx, esi
  832.            add ecx, esi
  833.            call [mix_3_core]
  834.            ret
  835. endp
  836.  
  837. align 4
  838. proc mix_4_1 stdcall, str0:dword, str1:dword,\
  839.                       str2:dword, str3:dword
  840.  
  841.            local output:DWORD
  842.  
  843.            call alloc_mix_buff
  844.            and eax, eax
  845.            jz .err
  846.  
  847.            mov edi, eax
  848.            mov eax, [str0]
  849.            mov ebx, [str1]
  850.            mov ecx, [str2]
  851.            mov edx, [str3]
  852.            mov esi, 128
  853.            call [mix_4_core]  ;edi, eax, ebx, ecx, edx
  854.  
  855.            add edi, esi
  856.            add eax, esi
  857.            add ebx, esi
  858.            add ecx, esi
  859.            add edx, esi
  860.            call [mix_4_core]  ;edi, eax, ebx, ecx, edx
  861.  
  862.            add edi, esi
  863.            add eax, esi
  864.            add ebx, esi
  865.            add ecx, esi
  866.            add edx, esi
  867.            call [mix_4_core]  ;edi, eax, ebx, ecx, edx
  868.  
  869.            add edi, esi
  870.            add eax, esi
  871.            add ebx, esi
  872.            add ecx, esi
  873.            add edx, esi
  874.            call [mix_4_core]  ;edi, eax, ebx, ecx, edx
  875.            mov eax, [output]
  876.            ret
  877. .err:
  878.            xor eax, eax
  879.            ret
  880. endp
  881.  
  882.  
  883. align 4
  884. proc final_mix stdcall, output:dword, str0:dword, str1:dword,\
  885.                         str2:dword, str3:dword
  886.  
  887.            mov edi, [output]
  888.  
  889.            mov eax, [str0]
  890.            mov ebx, [str1]
  891.            mov ecx, [str2]
  892.            mov edx, [str3]
  893.            mov esi, 128
  894.            call [mix_4_core]  ;edi, eax, ebx, ecx, edx
  895.  
  896.            add edi, esi
  897.            add eax, esi
  898.            add ebx, esi
  899.            add ecx, esi
  900.            add edx, esi
  901.            call [mix_4_core]  ;edi, eax, ebx, ecx, edx
  902.  
  903.            add edi, esi
  904.            add eax, esi
  905.            add ebx, esi
  906.            add ecx, esi
  907.            add edx, esi
  908.            call [mix_4_core]  ;edi, eax, ebx, ecx, edx
  909.  
  910.            add edi, esi
  911.            add eax, esi
  912.            add ebx, esi
  913.            add ecx, esi
  914.            add edx, esi
  915.            call [mix_4_core]  ;edi, eax, ebx, ecx, edx
  916.            ret
  917. endp
  918.  
  919. align 4
  920. proc copy_mem stdcall, output:dword, input:dword
  921.  
  922.            mov edi, [output]
  923.            mov esi, [input]
  924.            mov ecx, 0x80
  925. .l1:
  926.            mov eax, [esi]
  927.            mov [edi], eax
  928.            add esi, 4
  929.            add edi, 4
  930.            loop .l1
  931.  
  932.            ret
  933. endp
  934.  
  935. proc memcpy
  936. @@:
  937.            mov eax, [esi]
  938.            mov [edi], eax
  939.            add esi, 4
  940.            add edi, 4
  941.            dec ecx
  942.            jnz @B
  943.            ret
  944. endp
  945.  
  946.  
  947.