Subversion Repositories Kolibri OS

Rev

Rev 139 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;---------------------------------------------------------------------
  2. ;
  3. ;   MenuetOS AC97 WAV Player
  4. ;
  5. ;    0.03  November 10, 2004  doesn't halt if file not found
  6. ;    0.04  November 11, 2004  better positioning (with mouse)
  7. ;    0.05  November 14, 2004  internals clean up
  8. ;                             fixed cutting sound at the edges
  9. ;    0.06  November 17, 2004  fixed many bugs
  10. ;    0.07  Nov      20, 2004  deactivates text box when 'play' pressed
  11. ;                             stops playing before closing a window
  12. ;    0.08  Nov      24, 2004  added support for 8bit and mono modes
  13. ;                             +variable rate for some chipsets
  14. ;    0.09  August   26, 2006  modified to use function 70
  15. ;
  16. ;   Use [flat assembler 1.64] to compile.
  17. ;
  18. ;---------------------------------------------------------------------
  19.  
  20.   use32          ; turn on 32 bit mode
  21.   org     0x0         ; the program is placed at 0 offset
  22.  
  23.   db     'MENUET01'     ; 8-byte identifier of MenuetOS application
  24.   dd     0x01         ; header version (always 1)
  25.   dd     START         ; address of the beginning of the code
  26.   dd     IMAGE_END     ; size of the program's image
  27.   dd     MEMORY_END     ; how much memory does it need
  28.   dd     STACK_P     ; a pointer to the top of the stack
  29.   dd     textbox_string
  30. ;  dd     0x0             ; address of buffer for parameters (not used)
  31.   dd     0x0         ; reserved
  32.  
  33. ;---------------------------------------------------------------------
  34.  
  35. include "MACROS.INC"     ; standart macros & constants
  36. include "MEOSFUNC.INC"     ; MenuetOS API functions names
  37. include "DEBUG.INC"     ; printing to debug board
  38. include "CONSTANT.INC"     ; BIT?? constants
  39. include "AC97.INC"     ; AC'97 constants
  40. include "PCI.INC"     ; PCI interface
  41. include "CODEC.INC"     ; functions for configuring codec
  42. include "FRONTEND.INC"     ; main window
  43.  
  44. ;---------------------------------------------------------------------
  45.  
  46. ;  Uncomment these strings if you don't want to receive debug messages:
  47.  
  48. ;  macro dps str   {}    ; dps prints a string without CRLF
  49. ;  macro dpd num   {}    ; prints unsigned decimal number
  50. ;  macro pregs     {}    ; outputs EAX, EBX, ECX, EDX
  51. ;  macro newline   {}    ; CRLF
  52. ;  macro print str {}    ; output a string with CRLF
  53. ;  macro dph arg   {}    ; print hex number
  54.  
  55. ;---------------------------------------------------------------------
  56.  
  57. ;macro device id, addr { dd id, addr }
  58. macro devices [id, str]
  59. {
  60.   common
  61.     label supported_devices dword
  62.   forward
  63.     local string
  64.     dd id
  65.     dd string
  66.   forward
  67.     string db str
  68.     db 0
  69. }
  70.  
  71.  
  72. devices \
  73.   (ICH_DID shl 16) + INTEL_VID,      "ICH"    ,\
  74.   (ICH0_DID shl 16) + INTEL_VID,     "ICH0"   ,\
  75.   (ICH2_DID shl 16) + INTEL_VID,     "ICH2"   ,\
  76.   (ICH3_DID shl 16) + INTEL_VID,     "ICH2"   ,\
  77.   (ICH4_DID shl 16) + INTEL_VID,     "ICH4"   ,\
  78.   (ICH5_DID shl 16) + INTEL_VID,     "ICH5"   ,\
  79.   (MX440_DID shl 16) + INTEL_VID,    "440MX"  ,\
  80.   (SI7012_DID shl 16) + SIS_VID,     "SI7012" ,\
  81.   (NFORCE_DID shl 16) + NVIDIA_VID,  "NForce" ,\
  82.   (NFORCE2_DID shl 16) + NVIDIA_VID, "NForce2",\
  83.   (AMD8111_DID shl 16) + AMD_VID,    "AMD8111",\
  84.   (AMD768_DID shl 16) + AMD_VID,     "AMD768"
  85. dd    0
  86.  
  87.  
  88. ;---------------------------------------------------------------------
  89. ;---  MAIN PROGRAM  --------------------------------------------------
  90. ;---------------------------------------------------------------------
  91.  
  92. START:
  93.  
  94. ; Print PCI version (for example, 2.16)
  95. ;        mcall   MF_PCI, 0
  96. ;        mov     bl, al
  97. ;        movzx   eax, ah
  98. ;        dps    "PCI version: "
  99. ;        dpd     eax
  100. ;        movzx   eax, bl
  101. ;        dpd     eax
  102. ;        newline
  103.  
  104. ; Check PCI access mechanism (must be 1 or 2)
  105.     mcall    MF_PCI, 2
  106.     dec    al
  107.     cmp    al, 1
  108.     jna    @f
  109.     print    "Error: cannot access PCI bus."
  110.     jmp    exit
  111. ;        dps     "PCI returned "
  112. ;        movzx   eax, al
  113. ;        dpd     eax
  114. ;        newline
  115.      @@:
  116.  
  117.  
  118. ; Get last bus & then check all buses & devices
  119.     mcall    MF_PCI, 1
  120.     mov    [lastbus], al
  121.  
  122.      ; looking for a compatible device
  123.     mov    [bus], -1
  124.   .next_bus:
  125.     inc    [bus]
  126.  
  127.     mov    al, [lastbus]
  128.     cmp    al, [bus]
  129.     jb    .device_not_found
  130.  
  131.     mov    [devfn], 0
  132.   .next_devfn:
  133.  
  134.     mov    cl, 0
  135.     call    pciRegRead32
  136.  
  137.     mov    edi, supported_devices
  138.       @@:
  139.     mov    ebx, [edi]
  140.     test    ebx, ebx
  141.     jz    @f
  142.     cmp    eax, ebx
  143.     jnz    .skip
  144.     add    edi, 4
  145.     mov    [device_id], eax
  146.     mov    edx, [edi]
  147.     call    debug_outstr
  148.     jmp    proceed
  149.        .skip:
  150.     add    edi, 8
  151.     jmp    @b
  152.       @@:
  153.  
  154.     inc    [devfn]
  155.     cmp    [devfn], 255
  156.     jb    .next_devfn
  157.  
  158.     jmp    .next_bus
  159.  
  160.  
  161.   .device_not_found:
  162.     print    "Could not find Intel AC'97 compatible codec!"
  163.     print    "1) Check if it's enabled in BIOS."
  164.     print    "2) Check if your device is included in the device list."
  165.     jmp    exit
  166.  
  167.  
  168.  proceed:
  169.     print    " integrated AC97 audio codec detected."
  170.     mov    eax, [device_id]
  171.     cmp    eax, (ICH4_DID shl 16) + INTEL_VID
  172.     je    .newich
  173.     cmp    eax, (ICH5_DID shl 16) + INTEL_VID
  174.     jne    .nonewich
  175.       .newich:
  176.     mov    [AC97ICH4], 1
  177.       .nonewich:
  178.  
  179.     cmp    eax, (SI7012_DID shl 16) + SIS_VID
  180.     jne    @f
  181.     mov    [SI7012], 1
  182.       @@:
  183.  
  184. ;---------------------------------------------------------------------
  185.  
  186. ; Get NAMBAR register base port address & save it
  187.     mov    cl, NAMBAR_REG
  188.     call    pciRegRead16
  189.  
  190.     and    eax, 0xFFFE
  191.     mov    [NAMBAR], ax
  192.     test    eax, eax
  193.     jnz    .mixer_base_ok
  194.  
  195.     print    "Error: Intel ICH based AC97 audio codec disabled in BIOS!"
  196.     jmp    exit
  197.  
  198.  .mixer_base_ok:
  199.     dps    "NAMBAR: "
  200.     dph    eax
  201.  
  202. ; Get NABMBAR & save it
  203.     mov    cl, NABMBAR_REG
  204.     call    pciRegRead16
  205.     and    eax, 0xFFC0
  206.     mov    [NABMBAR], ax
  207.     test    eax, eax
  208.     jnz    .bm_base_ok
  209.  
  210.     print    "Error: Intel ICH based AC97 audio codec disabled in BIOS!"
  211.     jmp    exit
  212.  
  213.  .bm_base_ok:
  214.     dps    " NABMBAR: "
  215.     dph    eax
  216.     newline
  217.  
  218. ;---------------------------------------------------------------------
  219.  
  220. ; Get IRQ (not used)
  221.     mov    cl, IRQ_REG
  222.     call    pciRegRead8
  223.     mov    [AC97IRQ], al
  224.  
  225. ; Get Interrupt pin (not used)
  226.     mov    cl, INT_REG
  227.     call    pciRegRead8
  228.     mov    [AC97INT], al
  229.  
  230. ; AC97ICH4 should work then...
  231.     cmp    [AC97ICH4], 1
  232.     jne    .skip_ich4_init
  233.  
  234.     mov    cl, ICH4_CFG_REG  ; 0x41
  235.     call    pciRegRead8
  236.     or    al, 0x1
  237.     mov    dl, al
  238.     call    pciRegWrite8
  239.  
  240.     mov    cl, 0x54
  241.     call    pciRegRead16
  242.     and    eax, 0xFFFF
  243.     dps    "Power Control & Status: "
  244.     dph    eax
  245.     newline
  246.  .skip_ich4_init:
  247.  
  248. ;---------------------------------------------------------------------
  249.  
  250.     mov    cl, PCI_CMD_REG
  251.     call    pciRegRead16           ; read PCI command register
  252.     mov    dx, ax
  253.     or    dx, IO_ENA+BM_ENA+BIT10    ; enable IO and bus master + disable
  254.                        ;  interrupts
  255.     call    pciRegWrite16
  256.  
  257. ;---------------------------------------------------------------------
  258.  
  259.     print    "Enabling access to ports..."
  260.  
  261.     movzx    ecx, [NAMBAR]
  262.     mov    edx, ecx
  263.     add    edx, NAM_SIZE
  264.     mcall    MF_PORTS, PRT_RESERVE
  265.     test    eax, eax
  266.     jz    @f
  267.     print    "Error: couldn't enable access to ports"
  268.     jmp    exit
  269.      @@:
  270.  
  271.     movzx    ecx, [NABMBAR]
  272.     mov    edx, ecx
  273.     add    edx, NABM_SIZE
  274.     mcall    MF_PORTS, PRT_RESERVE
  275.     test    eax, eax
  276.     jz    @f
  277.     print    "Error: couldn't enable access to ports"
  278.     jmp    exit
  279.      @@:
  280.  
  281. ;---------------------------------------------------------------------
  282.  
  283. ; setup the Codec
  284.     mov    eax, 48000
  285.     call    codecConfig          ; unmute codec, set rates.
  286.     test    eax, eax
  287.     jnz    @f
  288.     print    "Error: cannot initialize AC97 device."
  289.     jmp    fpexit
  290.        @@:
  291.  
  292.     print    "Congrutalations! Your device has been initialized properly!"
  293.     call    print_info
  294.  
  295. ;---------------------------------------------------------------------
  296.  
  297. ; register reset the DMA engine.
  298.     mov    edx, PO_CR_REG    ; PCM out control register
  299.     mov    al, RR        ; reset
  300.     call    NABMBAR_write_byte
  301.    
  302. ;start fix for MM (1)
  303.     mcall  MF_INTERNAL_SERVICES,ALLOC_PHYS_MEM,120*1024
  304.     test   eax,eax
  305.     jz     no_phys_buffers             ;not enough memory
  306.     mov    [phys_wav_buffer1],eax
  307.     add    eax,60*1024
  308.     mov    [phys_wav_buffer2],eax
  309.     mcall  MF_INTERNAL_SERVICES,ALLOC_PHYS_MEM,32*8
  310.     test   eax,eax
  311.     jnz    @f
  312.     mcall  MF_INTERNAL_SERVICES,FREE_PHYS_MEM,[phys_wav_buffer1]
  313.     jmp    no_phys_buffers
  314. @@:
  315.     mov    [phys_bdl_buffer],eax
  316. ;end fix for MM (1)
  317.  
  318. ; create Buffer Descriptors List
  319.     call    prepare_BDL
  320.  
  321. ; open player's window
  322.     mcall    MF_THREAD, THR_CREATE, thread, thread_stack
  323.  
  324. ; wait for command
  325.   .new_check:
  326.     cmp    [status], ST_PLAY
  327.     jne    @f
  328.     call    play
  329.       @@:
  330.     cmp    [status], ST_STOP
  331.     jne    @f
  332.     call    stop
  333.       @@:
  334.     cmp    [status], ST_EXIT
  335.     je    stopexit
  336.  
  337.     mcall    MF_DELAY, 10
  338.     jmp    .new_check
  339.  
  340. stopexit:
  341.     call    stop
  342.  
  343. fpexit:
  344.  
  345. ; free ports
  346.     movzx    ecx, [NAMBAR]
  347.     mov    edx, ecx
  348.     add    edx, NAM_SIZE
  349.     mcall    MF_PORTS, PRT_FREE
  350.  
  351.     movzx    ecx, [NABMBAR]
  352.     mov    edx, ecx
  353.     add    edx, NABM_SIZE
  354.     mcall    MF_PORTS, PRT_FREE
  355.  
  356. ;---------------------------------------------------------------------
  357. ;start fix for MM (2)
  358.     mcall  MF_INTERNAL_SERVICES,FREE_PHYS_MEM,[phys_bdl_buffer]
  359.     mcall  MF_INTERNAL_SERVICES,FREE_PHYS_MEM,[phys_wav_buffer1]
  360. ;end fix for MM (2)
  361. exit:
  362.     mcall    MF_EXIT
  363. no_phys_buffers:
  364.     print  "allocation of physical buffers failed"
  365.     jmp    exit
  366.  
  367. ;---------------------------------------------------------------------
  368. ;---  FUNCTIONS  -----------------------------------------------------
  369. ;---------------------------------------------------------------------
  370.  
  371. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  372. ;; prepare_BDL - initializes BUFFER DESCRIPTORS LIST
  373. prepare_BDL:
  374.     mov    ecx, 32 / 2    ; make 32 entries in BDL
  375.     mov    edi, BDL_BUFFER
  376. ;    call   get_my_address
  377.     mov    ebx, 30*1024
  378.     cmp    [SI7012], 1
  379.     jne    @f
  380.     add    ebx, ebx
  381. @@:
  382.     ; set buf. desc. 0 to start of data file in memory
  383.     push   eax
  384. ;    add    eax, WAV_BUFFER1
  385. ;start fix for MM (6)
  386.     mov    eax,[phys_wav_buffer1]
  387. ;end fix for MM (6)    
  388.     stosd
  389.     ; set length to 60k samples. 1 sample is 16 bit or 2 bytes.
  390.     mov    eax, ebx ;60*1024   ; number of samples
  391.     or     eax, BUP
  392.     stosd
  393.  
  394.     mov    eax, [esp]
  395. ;    add    eax, WAV_BUFFER2
  396. ;start fix for MM (7)
  397.     mov    eax,[phys_wav_buffer2]
  398. ;end fix for MM (7)
  399.     stosd
  400.     mov    eax, ebx ;60*1024
  401.     or     eax, BUP
  402.     stosd
  403.  
  404.     pop    eax
  405.     loop   @b
  406.        
  407.  
  408.     ; tell the DMA engine where to find our list of Buffer Descriptors.
  409.     ; eax = base addr!
  410. ;start fix for MM (3)
  411.   ;copy to physical memory
  412.     mcall  MF_INTERNAL_SERVICES,SET_PHYS_BUFFER,[phys_bdl_buffer],BDL_BUFFER,32*8
  413.   ;physical address of bdl    
  414.     mov    eax,[phys_bdl_buffer]                                
  415. ;end fix for MM (3)    
  416.     mov    edx, PO_BDBAR_REG
  417. ;    add    eax, BDL_BUFFER
  418.     call   NABMBAR_write_dword
  419.  
  420. ret
  421.  
  422.  
  423. ;---------------------------------------------------------------------
  424.  
  425. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  426. ;; stop - stops current music
  427. ;; in:  nothing
  428. ;; out: nothing
  429. stop:
  430. ;        print   "STOP!"
  431.     push    eax edx
  432.  
  433.     mcall    MF_DELAY, 10
  434.     mov    edx, PO_CR_REG
  435.     mov    al, 0
  436.     call    NABMBAR_write_byte
  437.     cmp    [status], ST_STOP
  438.     jne    .exit
  439.     mov    [status], ST_DONE
  440.       .exit:
  441.  
  442.     pop    edx eax
  443. ret
  444.  
  445. ;---------------------------------------------------------------------
  446.  
  447. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  448. ;; play - plays wav file!
  449. ;; in:  nothing
  450. ;; out: nothing (but sound :)   !corrupts registers!
  451. play:
  452.     ; at first, reset file and get file size
  453.         mcall   MF_SYSTREE, attrinfo
  454.         test    eax, eax
  455.         jnz     .notfound
  456.         mov     eax, [fileattr+32]
  457.         mov     [file_size], eax
  458.     mov    [fileinfo.first_byte], 0
  459.     mcall    MF_SYSTREE, fileinfo ; load a block, returns error code in eax
  460.                      ;   and size of the file in ebx
  461.     test    eax, eax         ; 0 - successful
  462.     jz    @f
  463.         cmp     eax, 6          ; 6 = eof - successful too
  464.         jz      @f
  465. .notfound:
  466.     print    "AC97: File not found!"
  467.     mov    [status], ST_STOP
  468.     jmp    .exit
  469.      @@:
  470.  
  471.     mov    al, [LOAD_BUFFER+32] ; bytes per sample
  472.     dec    al
  473.     jz    @f
  474.     cmp    al, 3
  475.     je    @f
  476.     sub    al, [LOAD_BUFFER+22] ; channels
  477.     add    al, 2
  478.       @@:
  479.     mov    [wav_mode], al
  480.  
  481.     pusha
  482.     movzx    ebx,word [LOAD_BUFFER+24]
  483.     mov   eax,48000
  484.     xor   edx,edx
  485.     div   ebx
  486.     mov   [difference_of_frequency],al
  487. ;        dph   eax
  488.     mov   ecx,edx
  489.     imul  eax,ecx,10
  490.     xor   edx,edx
  491.     div   ebx
  492.     mov   ecx,edx
  493.     imul  ecx,10
  494.     push  eax
  495.     mov   eax,ecx
  496.     xor   edx,edx
  497.     div   ebx
  498. ;        dph   eax
  499.     cmp   eax,5
  500.     jl    .temp_15
  501.     pop   eax
  502. ;        dph   eax
  503.  
  504.     inc   eax
  505.     jmp   .temp_16
  506.      .temp_15:
  507.     pop   eax
  508.      .temp_16:
  509.     mov   [difference_of_frequency_1],al
  510. ;        dph   eax
  511.     xor   edx,edx
  512.     movzx  ebx,[difference_of_frequency]
  513.     imul   ebx,10
  514.     add    bl,[difference_of_frequency_1]
  515.     mov   [difference_of_frequency_2],bl
  516. ;        dph   ebx
  517.     popa
  518.  
  519.     movzx    eax, word [LOAD_BUFFER+24]
  520.     ;dps "Freq: "
  521.     ;dpd eax
  522.     ;newline
  523.     call    set_sample_rate
  524.  
  525.  
  526.     ; change the last_valid_index to the (current_index-1)
  527.     ; the LVI register tells the DMA engine where to stop playing
  528.     call    updateLVI
  529.  
  530.     ; if current index is odd, load buffer 1 then 0, jump to tuneLoop
  531.     ; if it is even, buffers 0 then 1; tuneLoop1
  532.     call    getCurrentIndex
  533.     and    eax, BIT0
  534.  
  535.     mov    esi, eax
  536.     push    eax
  537.     call    update_next_buffer
  538.     pop    eax
  539.     xor    eax, 1
  540.     call    update_next_buffer
  541.  
  542.     ; start playing!
  543.     mov    edx, PO_CR_REG
  544.     mov    al, RPBM
  545.     call    NABMBAR_write_byte
  546.  
  547.     jmp    [jumpto+esi*4]
  548.  
  549.  
  550.    .tuneLoop:
  551.     ; wait while the current_index is even
  552.     @@:
  553. ;        dps     "a"
  554.     mcall    MF_DELAY, 7
  555.     call    getCurrentIndex
  556.     test    al, BIT0
  557.     jz    @b       ; loop if not ready yet
  558. ;        print   "fa"
  559.  
  560.     call    updateLVI
  561.  
  562.     mov    eax, 0
  563.     call    update_next_buffer
  564.     test    al, al
  565.     jnz    .exit_wait
  566.  
  567.     cmp    [status], ST_PLAY
  568.     jne    .exit
  569.  
  570.     test    [volume], 0x10000000 ; test volume_changed bit
  571.     je    @f
  572.     mov    al, byte [volume]
  573.     call    setVolume
  574.     and    [volume], 0x0FFFFFFF ; clear vloume_changed bit
  575.      @@:
  576.  
  577.      .tuneLoop1:
  578.      @@:
  579. ;        dps     "b"
  580.     mcall    MF_DELAY, 7
  581.     call    getCurrentIndex
  582.     test    al, BIT0
  583.     jnz    @b       ; loop if not ready yet
  584. ;        print   "fb"
  585.  
  586.     cmp    [status], ST_PLAY
  587.     jne    .exit
  588.  
  589.     call    updateLVI
  590.  
  591.     mov    eax, 1
  592.     call    update_next_buffer
  593.     test    al, al
  594.     jnz    .exit_wait
  595.  
  596.     jmp    .tuneLoop
  597.    .exit_wait:
  598.     mcall    MF_DELAY, 30 ; a little pause - let the player finish
  599.    .exit:
  600. ret
  601. attempts db 0
  602.  
  603. buffers dd WAV_BUFFER1, WAV_BUFFER2
  604. jumpto    dd play.tuneLoop, play.tuneLoop1
  605.  
  606.  
  607. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  608. ;; update_first_buffer - load a chunk into the first buffer, increments offset
  609. ;; in:  eax = number - 0 or 1
  610. ;; out: error code, 0 - successful
  611. update_next_buffer:
  612.     push   esi edi
  613.  
  614.     movzx  edx, byte [wav_mode]
  615.     mov    ecx, [blocks + edx * 4]
  616.     mov    [fileinfo.bytes], ecx
  617.  
  618.     mov    esi, LOAD_BUFFER
  619.     mov    edi, [buffers+eax*4]
  620.     push   eax              ;save buffer index
  621.   start_attempts:
  622.     mcall  MF_SYSTREE, fileinfo
  623.     test eax, eax
  624.     jz @f
  625.         cmp     eax, 6
  626.         jz      @f
  627.     cmp   [attempts],100
  628.     je   @f
  629.     inc   [attempts]
  630.     jmp   start_attempts
  631. ;    dpd eax
  632. ;    newline
  633. ;    dpd [fileinfo.first_block]
  634. ;    newline
  635.        @@:
  636. ;        print  " loaded!"
  637.  
  638.     push   eax ebx edx
  639.     mov    eax,ecx
  640.     xor    edx,edx
  641.     imul   eax,10
  642.     movzx     ebx,[difference_of_frequency_2]
  643.  
  644.     div    ebx
  645.     mov    ecx,eax
  646.  
  647. ;    mov   ebx,10
  648. ;    mov   eax,edx
  649. ;    xor   edx,edx
  650. ;    div   ebx
  651. ;   cmp   edx,5
  652. ;    jb   temp_12_7
  653. ;    inc   ecx
  654. ;  temp_12_7:
  655. ;   cmp  edx,0
  656. ;    je  temp_12_7
  657. ;    inc   ecx
  658. ;  temp_12_7:
  659.  
  660.     pop    edx ebx
  661.     mov    eax,[esp+4]            ;restore buffer index
  662.     and    ecx, not 511
  663.     add    [fileinfo.first_byte], ecx ; +60Kb
  664.     call   [convert + edx * 4]
  665. ;start fix for MM (4)    
  666.     mov    eax,[esp+4]            ;restore buffer index
  667.     test   eax,not 1
  668.     jz     .ok
  669.     print  "buffer index out of range"
  670.     dpd    eax
  671.     jmp    .ret
  672.   .ok:
  673.     push   ebp
  674.     mov    ebp,[phys_wav_buffer1+eax*4]
  675.     mov    edi,[buffers+eax*4]
  676.     mcall  MF_INTERNAL_SERVICES,SET_PHYS_BUFFER,ebp,edi,60*1024
  677.     pop    ebp
  678. .ret:
  679.     pop    eax
  680.     add    esp,4                  ;pop buffer index    
  681. ;end fix for MM (4)    
  682.  
  683.     pop    edi esi
  684. ret
  685.  
  686. c8mono:
  687.     mov   [type_of_conversion],1
  688.     jmp   for_all_type
  689.  
  690. c8mono_1:
  691.     lodsb
  692.     call  c8mono_2
  693.     push  ax
  694.     shl   eax,16
  695.     pop   ax
  696.     push  eax
  697.     mov al,[esi]
  698.     call  c8mono_2
  699.     push  ax
  700.     shl   eax,16
  701.     pop   ax
  702.     mov  ebx,eax
  703.     pop  eax
  704.     jmp  for_all_type_1
  705.  
  706. c8mono_2:
  707.     sub    al, 0x80
  708.     cbw
  709.     imul   ax, 255
  710.     ret
  711.  
  712. c8stereo:
  713.     mov   [type_of_conversion],2
  714.     jmp   for_all_type
  715.  
  716. c8stereo_1:
  717.     lodsb
  718.     call  c8stereo_2
  719.     shl eax,16
  720.     lodsb
  721.     call  c8stereo_2
  722.     push  eax
  723.     mov al,[esi]
  724.     call  c8stereo_2
  725.     shl eax,16
  726.     mov al,[esi+1]
  727.     call  c8stereo_2
  728.     mov   ebx,eax
  729.     pop  eax
  730.     jmp   for_all_type_1
  731.  
  732. c8stereo_2:
  733.     sub    al, 0x80
  734.     cbw
  735.     imul   ax, 255
  736.     ret
  737.  
  738. c16mono:
  739.     mov   [type_of_conversion],3
  740.     jmp   for_all_type
  741.  
  742. c16mono_1:
  743.         lodsw
  744.         push  ax
  745.         shl eax,16
  746.         pop   ax
  747.         mov bx,[esi]
  748.         shl ebx,16
  749.         mov bx,[esi]
  750.         jmp  for_all_type_1
  751.  
  752. c16stereo:
  753.  for_all_type:
  754.     xor   edx,edx
  755.     mov    eax, 15*1024*10
  756.     movzx     ebx,[difference_of_frequency_2]
  757.     xor    edx,edx
  758.     div    ebx
  759.     mov    ecx,eax
  760.  
  761. ;    mov   ebx,10
  762. ;    mov   eax,edx
  763. ;    xor   edx,edx
  764. ;    div   ebx
  765. ;    cmp   edx,5
  766. ;    jb   temp_12_6
  767. ;    inc   ecx
  768. ;  temp_12_6:
  769.    cmp   edx,0
  770.     je   temp_12_6
  771.     inc   ecx
  772.   temp_12_6:
  773.  
  774.   c16stereo_1:
  775.     mov  [znak],0
  776.  
  777.     cmp  [type_of_conversion],1
  778.     je   c8mono_1
  779.     cmp  [type_of_conversion],2
  780.     je   c8stereo_1
  781.     cmp  [type_of_conversion],3
  782.     je   c16mono_1
  783.     lodsd
  784.  
  785.     mov ebx,[esi]
  786. for_all_type_1:
  787.     cmp eax,ebx
  788.     jne  c16stereo_2
  789.     inc  [znak]
  790.     c16stereo_2:
  791.     push eax
  792.     push ecx
  793.     sub  eax,ebx
  794.     push eax
  795.     shl  eax,16
  796.     movzx  ebx,[difference_of_frequency]
  797.     inc   ebx
  798.     xor  edx,edx
  799.     div  ebx
  800.     shr  eax,16
  801.     mov  ecx,eax
  802.     pop  eax
  803.     xor  ax,ax
  804.     xor  edx,edx
  805.     div  ebx
  806.     shl  eax,16
  807.     mov  cx,ax
  808.     mov  ebx,ecx
  809.     pop  ecx
  810.     pop   eax
  811.     mov    dl,[difference_of_frequency]
  812.     inc   dl
  813.     @@:
  814. temp_12:
  815.     cmp   [difference_of_frequency_1],0
  816.     je    temp_12_3
  817.     cmp   [difference_of_frequency_1],5
  818.     jne   temp_12_4
  819.     cmp  [difference_of_frequency_4],2
  820.     jne  temp_12_3
  821.     jmp  temp_12_5
  822.  temp_12_4:
  823.     cmp  [difference_of_frequency_4],10
  824.     jne  temp_12_3
  825.  
  826.  temp_12_5:
  827.  
  828.     cmp  [znak],0
  829.     jne   temp_12_5_1
  830.     sub  eax,ebx
  831.     jmp  temp_12_5_2
  832.  temp_12_5_1:
  833.     add  eax,ebx
  834.  temp_12_5_2:
  835.  
  836.  
  837.     stosd
  838.     inc  [schetchik]
  839.     mov    [difference_of_frequency_4],0
  840.  temp_12_3:
  841.     cmp  [znak],0
  842.     jne   temp_13
  843.     sub  eax,ebx
  844.     jmp  temp_14
  845.  temp_13:
  846.     add  eax,ebx
  847.  
  848.  temp_14:
  849.     cld
  850.     dec    dl
  851.     jz    temp_14_1
  852.     stosd
  853.     inc   [schetchik]
  854.     inc   [difference_of_frequency_4]
  855.     jmp   temp_12
  856.  temp_14_1:
  857.     dec    ecx
  858.     cmp   ecx,0
  859. ;    jnz    c16stereo_1
  860.     jg    c16stereo_1
  861.     newline
  862.     dph [schetchik]
  863.  temp_14_2:
  864.     cmp   [schetchik],15360
  865.     jge   temp_14_3
  866.     stosd
  867.     inc  [schetchik]
  868.     jmp  temp_14_2
  869.  
  870.   temp_14_3:
  871.     newline
  872.     dph [schetchik]
  873.     cmp   [schetchik],15360
  874.     je    temp_14_4
  875. ;    mov  [edi-4],dword 0
  876.     sub   edi,4
  877. ;    sub   esi,4
  878.  temp_14_4:
  879.     mov   [schetchik],0
  880.     ret
  881.  
  882.  
  883. difference_of_frequency db 0
  884. difference_of_frequency_1 db 0
  885. difference_of_frequency_2 db 0
  886. difference_of_frequency_4 db 0
  887. schetchik dd 0
  888. znak db 0
  889. type_of_conversion db 0
  890.  
  891. convert dd c8mono, c8stereo, c16mono, c16stereo
  892. blocks    dd 30*512, 60*512, 60*512, 120*512
  893.  
  894.  
  895. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  896. ;; get_my_address - get base address of the program in physical memory
  897. ;;   in:  nothing
  898. ;;   out: eax = address
  899. ;start fix for MM (8)
  900. ;function shouldn't used.
  901. ;get_my_address:
  902. ;    pushad
  903. ;    mcall    MF_PROCINFO, procinfo, PN_MYSELF
  904. ;    popad
  905. ;    mov    eax, [procinfo.memory_start]
  906. ;ret
  907. ;end fix for MM (8)
  908.  
  909.  
  910. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  911. ;; set the last valid index to something other than we're currently playing
  912. ;; so that we never end
  913. ;;
  914. ;; this routine just sets the last valid index to 1 less than the index
  915. ;; that we're currently playing, thus keeping it in and endless loop
  916. ;; input:  none
  917. ;; output: none
  918. updateLVI:
  919.     push    eax
  920.     call    getCurrentIndex
  921.      ; dps "index "
  922.      ; dpd eax
  923.      ; newline
  924.     dec    al
  925.     and    al, INDEX_MASK
  926.     call    setLastValidIndex
  927.     pop    eax
  928. ret
  929.  
  930. ;---------------------------------------------------------------------
  931.  
  932. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  933. ;; returns AL = current index value
  934. getCurrentIndex:
  935.     push    edx
  936.     mov    edx, PO_CIV_REG
  937.     call    NABMBAR_read_byte
  938.     pop    edx
  939. ret
  940.  
  941. ;---------------------------------------------------------------------
  942.  
  943. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  944. ;; input AL = index # to stop on
  945. setLastValidIndex:
  946.     push    edx
  947.     mov    edx, PO_LVI_REG
  948.     call    NABMBAR_write_byte
  949.     pop    edx
  950. ret
  951.  
  952. ;---------------------------------------------------------------------
  953.  
  954. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  955. ;; print_info - outputs debug information
  956. ;;  in:  nothing
  957. ;;  out: nothing
  958. print_info:
  959.     dps    "BUS: "
  960.     movzx    eax, [bus]
  961.     dph    eax
  962.  
  963.     dps    " DEVFN: "
  964.     movzx    eax, [devfn]
  965.     dph    eax
  966.  
  967.     dps    " IRQ: "
  968.     movzx    eax, [AC97IRQ]
  969.     dpd    eax
  970.     newline
  971.  
  972.  
  973.     dps    "CODEC_POWER_CTRL: "
  974.     mov    edx, CODEC_POWER_CTRL_REG
  975.     call    NAMBAR_read_word
  976.     dph    eax
  977.     dps    " (bits 0-3 should be set)"
  978.     newline
  979.  
  980.     mov    edx, 0x28
  981.     call    NAMBAR_read_word
  982.     dph    eax
  983.     dps    " - supported features"
  984.     newline
  985.     mov    edx, 0x2A
  986.     call    NAMBAR_read_word
  987.     dph    eax
  988.     dps    " - config"
  989.     newline
  990.     mov    edx, 0x2C
  991.     call    NAMBAR_read_word
  992.     dph    eax
  993.     dps    " - PCM rate"
  994.  
  995.     newline
  996. ret
  997.  
  998.  
  999. ;---------------------------------------------------------------------
  1000. ;---  DATA OF PROGRAM  -----------------------------------------------
  1001. ;---------------------------------------------------------------------
  1002. volume           dd  15
  1003.  
  1004. attrinfo:
  1005.         dd      5
  1006.         dd      0
  1007.         dd      0
  1008.         dd      0
  1009.         dd      fileattr
  1010.         db      0
  1011.         dd      textbox_string
  1012.  
  1013. fileinfo:
  1014.  .mode          dd      0                ; READ
  1015.  .first_byte    dd      0
  1016.                 dd      0
  1017.  .bytes         dd      60*1024          ; 60 Kb
  1018.  .dest           dd  LOAD_BUFFER ;file_data
  1019.          ;  db  "/HD/1/WINDOWS/MEDIA/WICEB7~1.WAV",0
  1020. ;sz textbox_string, "/hd/1/testmuz/menuet11.wav",0
  1021. textbox_string:
  1022. ;---------------------------------------------------------------------
  1023.  
  1024. IMAGE_END:               ; end of program's image
  1025.    rb 257
  1026. ;   rb 257-textbox_string.size
  1027. ;     textbox_string.size
  1028.  
  1029. ;---------------------------------------------------------------------
  1030.  
  1031. device_id dd ?    ; (device_id << 16) + vendor_id
  1032. lastbus   db ?    ; pci coordinates
  1033. bus      db ?
  1034. devfn      db ?
  1035.  
  1036. AC97ICH4  db ?    ; Intel ICH4 codec flag
  1037. SI7012      db ?    ; SiS SI7012 codec flag
  1038. NAMBAR      dw ?    ; Audio Mixers Registers (base)
  1039. NABMBAR   dw ?    ; Bus Master Registers   (base)
  1040.  
  1041. AC97IRQ   db ?    ; Interrupt request
  1042. AC97INT   db ?    ; Interrupt pin
  1043.  
  1044. wav_mode  db ?    ; bits per sample & channels
  1045.  
  1046. ;---------------------------------------------------------------------
  1047.  
  1048. ST_DONE = 0x0    ; for interacting with player's window
  1049. ST_PLAY = 0x1
  1050. ST_EXIT = 0x2
  1051. ST_STOP = 0x4
  1052.  
  1053. status      db ?
  1054.  
  1055. fileattr: rb 40
  1056.  
  1057. ;---------------------------------------------------------------------
  1058. phys_bdl_buffer rd 1
  1059. phys_wav_buffer1 rd 1
  1060. phys_wav_buffer2 rd 1
  1061. align 32
  1062.  
  1063.  
  1064. ; Buffer Descriptors List
  1065. ;  ___________________________
  1066. ;  |     physical address    | dword
  1067. ;  |_________________________|
  1068. ;  | attr       |   length   | dword     max. length = 65535 samples
  1069. ;  |_________________________|
  1070.  
  1071. BDL_BUFFER:
  1072.  rb 32*8     ; 32 descriptors, 8 bytes each
  1073.  
  1074.  
  1075. ;---------------------------------------------------------------------
  1076.  
  1077. file_data:
  1078.  
  1079. WAV_BUFFER1:
  1080.  rb 60 * 1024  ; 60 Kb
  1081.  
  1082. WAV_BUFFER2:
  1083.  rb 60 * 1024
  1084.  
  1085. LOAD_BUFFER:
  1086.  rb 60 * 1024
  1087.  
  1088. ;---------------------------------------------------------------------
  1089.  
  1090. procinfo process_information
  1091.  
  1092. work_area:
  1093.  rb 0x10000
  1094.  
  1095. ;---------------------------------------------------------------------
  1096.  
  1097. rb 0x800
  1098. thread_stack:
  1099.  
  1100. rb 0x1000 ; for stack
  1101. STACK_P:
  1102.  
  1103. MEMORY_END:
  1104.