Subversion Repositories Kolibri OS

Rev

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