Subversion Repositories Kolibri OS

Rev

Rev 109 | Blame | 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.     add    [fileinfo.first_byte], ecx ; +60Kb
  663.     call   [convert + edx * 4]
  664. ;start fix for MM (4)    
  665.     mov    eax,[esp+4]            ;restore buffer index
  666.     test   eax,not 1
  667.     jz     .ok
  668.     print  "buffer index out of range"
  669.     dpd    eax
  670.     jmp    .ret
  671.   .ok:
  672.     push   ebp
  673.     mov    ebp,[phys_wav_buffer1+eax*4]
  674.     mov    edi,[buffers+eax*4]
  675.     mcall  MF_INTERNAL_SERVICES,SET_PHYS_BUFFER,ebp,edi,60*1024
  676.     pop    ebp
  677. .ret:
  678.     pop    eax
  679.     add    esp,4                  ;pop buffer index    
  680. ;end fix for MM (4)    
  681.  
  682.     pop    edi esi
  683. ret
  684.  
  685. c8mono:
  686.     mov   [type_of_conversion],1
  687.     jmp   for_all_type
  688.  
  689. c8mono_1:
  690.     lodsb
  691.     call  c8mono_2
  692.     push  ax
  693.     shl   eax,16
  694.     pop   ax
  695.     push  eax
  696.     mov al,[esi]
  697.     call  c8mono_2
  698.     push  ax
  699.     shl   eax,16
  700.     pop   ax
  701.     mov  ebx,eax
  702.     pop  eax
  703.     jmp  for_all_type_1
  704.  
  705. c8mono_2:
  706.     sub    al, 0x80
  707.     cbw
  708.     imul   ax, 255
  709.     ret
  710.  
  711. c8stereo:
  712.     mov   [type_of_conversion],2
  713.     jmp   for_all_type
  714.  
  715. c8stereo_1:
  716.     lodsb
  717.     call  c8stereo_2
  718.     shl eax,16
  719.     lodsb
  720.     call  c8stereo_2
  721.     push  eax
  722.     mov al,[esi]
  723.     call  c8stereo_2
  724.     shl eax,16
  725.     mov al,[esi+1]
  726.     call  c8stereo_2
  727.     mov   ebx,eax
  728.     pop  eax
  729.     jmp   for_all_type_1
  730.  
  731. c8stereo_2:
  732.     sub    al, 0x80
  733.     cbw
  734.     imul   ax, 255
  735.     ret
  736.  
  737. c16mono:
  738.     mov   [type_of_conversion],3
  739.     jmp   for_all_type
  740.  
  741. c16mono_1:
  742.         lodsw
  743.         push  ax
  744.         shl eax,16
  745.         pop   ax
  746.         mov bx,[esi]
  747.         shl ebx,16
  748.         mov bx,[esi]
  749.         jmp  for_all_type_1
  750.  
  751. c16stereo:
  752.  for_all_type:
  753.     xor   edx,edx
  754.     mov    eax, 15*1024*10
  755.     movzx     ebx,[difference_of_frequency_2]
  756.     xor    edx,edx
  757.     div    ebx
  758.     mov    ecx,eax
  759.  
  760. ;    mov   ebx,10
  761. ;    mov   eax,edx
  762. ;    xor   edx,edx
  763. ;    div   ebx
  764. ;    cmp   edx,5
  765. ;    jb   temp_12_6
  766. ;    inc   ecx
  767. ;  temp_12_6:
  768.    cmp   edx,0
  769.     je   temp_12_6
  770.     inc   ecx
  771.   temp_12_6:
  772.  
  773.   c16stereo_1:
  774.     mov  [znak],0
  775.  
  776.     cmp  [type_of_conversion],1
  777.     je   c8mono_1
  778.     cmp  [type_of_conversion],2
  779.     je   c8stereo_1
  780.     cmp  [type_of_conversion],3
  781.     je   c16mono_1
  782.     lodsd
  783.  
  784.     mov ebx,[esi]
  785. for_all_type_1:
  786.     cmp eax,ebx
  787.     jne  c16stereo_2
  788.     inc  [znak]
  789.     c16stereo_2:
  790.     push eax
  791.     push ecx
  792.     sub  eax,ebx
  793.     push eax
  794.     shl  eax,16
  795.     movzx  ebx,[difference_of_frequency]
  796.     inc   ebx
  797.     xor  edx,edx
  798.     div  ebx
  799.     shr  eax,16
  800.     mov  ecx,eax
  801.     pop  eax
  802.     xor  ax,ax
  803.     xor  edx,edx
  804.     div  ebx
  805.     shl  eax,16
  806.     mov  cx,ax
  807.     mov  ebx,ecx
  808.     pop  ecx
  809.     pop   eax
  810.     mov    dl,[difference_of_frequency]
  811.     inc   dl
  812.     @@:
  813. temp_12:
  814.     cmp   [difference_of_frequency_1],0
  815.     je    temp_12_3
  816.     cmp   [difference_of_frequency_1],5
  817.     jne   temp_12_4
  818.     cmp  [difference_of_frequency_4],2
  819.     jne  temp_12_3
  820.     jmp  temp_12_5
  821.  temp_12_4:
  822.     cmp  [difference_of_frequency_4],10
  823.     jne  temp_12_3
  824.  
  825.  temp_12_5:
  826.  
  827.     cmp  [znak],0
  828.     jne   temp_12_5_1
  829.     sub  eax,ebx
  830.     jmp  temp_12_5_2
  831.  temp_12_5_1:
  832.     add  eax,ebx
  833.  temp_12_5_2:
  834.  
  835.  
  836.     stosd
  837.     inc  [schetchik]
  838.     mov    [difference_of_frequency_4],0
  839.  temp_12_3:
  840.     cmp  [znak],0
  841.     jne   temp_13
  842.     sub  eax,ebx
  843.     jmp  temp_14
  844.  temp_13:
  845.     add  eax,ebx
  846.  
  847.  temp_14:
  848.     cld
  849.     dec    dl
  850.     jz    temp_14_1
  851.     stosd
  852.     inc   [schetchik]
  853.     inc   [difference_of_frequency_4]
  854.     jmp   temp_12
  855.  temp_14_1:
  856.     dec    ecx
  857.     cmp   ecx,0
  858. ;    jnz    c16stereo_1
  859.     jg    c16stereo_1
  860.     newline
  861.     dph [schetchik]
  862.  temp_14_2:
  863.     cmp   [schetchik],15360
  864.     jge   temp_14_3
  865.     stosd
  866.     inc  [schetchik]
  867.     jmp  temp_14_2
  868.  
  869.   temp_14_3:
  870.     newline
  871.     dph [schetchik]
  872.     cmp   [schetchik],15360
  873.     je    temp_14_4
  874. ;    mov  [edi-4],dword 0
  875.     sub   edi,4
  876. ;    sub   esi,4
  877.  temp_14_4:
  878.     mov   [schetchik],0
  879.     ret
  880.  
  881.  
  882. difference_of_frequency db 0
  883. difference_of_frequency_1 db 0
  884. difference_of_frequency_2 db 0
  885. difference_of_frequency_4 db 0
  886. schetchik dd 0
  887. znak db 0
  888. type_of_conversion db 0
  889.  
  890. convert dd c8mono, c8stereo, c16mono, c16stereo
  891. blocks    dd 30*512, 60*512, 60*512, 120*512
  892.  
  893.  
  894. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  895. ;; get_my_address - get base address of the program in physical memory
  896. ;;   in:  nothing
  897. ;;   out: eax = address
  898. ;start fix for MM (8)
  899. ;function shouldn't used.
  900. ;get_my_address:
  901. ;    pushad
  902. ;    mcall    MF_PROCINFO, procinfo, PN_MYSELF
  903. ;    popad
  904. ;    mov    eax, [procinfo.memory_start]
  905. ;ret
  906. ;end fix for MM (8)
  907.  
  908.  
  909. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  910. ;; set the last valid index to something other than we're currently playing
  911. ;; so that we never end
  912. ;;
  913. ;; this routine just sets the last valid index to 1 less than the index
  914. ;; that we're currently playing, thus keeping it in and endless loop
  915. ;; input:  none
  916. ;; output: none
  917. updateLVI:
  918.     push    eax
  919.     call    getCurrentIndex
  920.      ; dps "index "
  921.      ; dpd eax
  922.      ; newline
  923.     dec    al
  924.     and    al, INDEX_MASK
  925.     call    setLastValidIndex
  926.     pop    eax
  927. ret
  928.  
  929. ;---------------------------------------------------------------------
  930.  
  931. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  932. ;; returns AL = current index value
  933. getCurrentIndex:
  934.     push    edx
  935.     mov    edx, PO_CIV_REG
  936.     call    NABMBAR_read_byte
  937.     pop    edx
  938. ret
  939.  
  940. ;---------------------------------------------------------------------
  941.  
  942. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  943. ;; input AL = index # to stop on
  944. setLastValidIndex:
  945.     push    edx
  946.     mov    edx, PO_LVI_REG
  947.     call    NABMBAR_write_byte
  948.     pop    edx
  949. ret
  950.  
  951. ;---------------------------------------------------------------------
  952.  
  953. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  954. ;; print_info - outputs debug information
  955. ;;  in:  nothing
  956. ;;  out: nothing
  957. print_info:
  958.     dps    "BUS: "
  959.     movzx    eax, [bus]
  960.     dph    eax
  961.  
  962.     dps    " DEVFN: "
  963.     movzx    eax, [devfn]
  964.     dph    eax
  965.  
  966.     dps    " IRQ: "
  967.     movzx    eax, [AC97IRQ]
  968.     dpd    eax
  969.     newline
  970.  
  971.  
  972.     dps    "CODEC_POWER_CTRL: "
  973.     mov    edx, CODEC_POWER_CTRL_REG
  974.     call    NAMBAR_read_word
  975.     dph    eax
  976.     dps    " (bits 0-3 should be set)"
  977.     newline
  978.  
  979.     mov    edx, 0x28
  980.     call    NAMBAR_read_word
  981.     dph    eax
  982.     dps    " - supported features"
  983.     newline
  984.     mov    edx, 0x2A
  985.     call    NAMBAR_read_word
  986.     dph    eax
  987.     dps    " - config"
  988.     newline
  989.     mov    edx, 0x2C
  990.     call    NAMBAR_read_word
  991.     dph    eax
  992.     dps    " - PCM rate"
  993.  
  994.     newline
  995. ret
  996.  
  997.  
  998. ;---------------------------------------------------------------------
  999. ;---  DATA OF PROGRAM  -----------------------------------------------
  1000. ;---------------------------------------------------------------------
  1001. volume           dd  15
  1002.  
  1003. attrinfo:
  1004.         dd      5
  1005.         dd      0
  1006.         dd      0
  1007.         dd      0
  1008.         dd      fileattr
  1009.         db      0
  1010.         dd      textbox_string
  1011.  
  1012. fileinfo:
  1013.  .mode          dd      0                ; READ
  1014.  .first_byte    dd      0
  1015.                 dd      0
  1016.  .bytes         dd      60*1024          ; 60 Kb
  1017.  .dest           dd  LOAD_BUFFER ;file_data
  1018.          ;  db  "/HD/1/WINDOWS/MEDIA/WICEB7~1.WAV",0
  1019. ;sz textbox_string, "/hd/1/testmuz/menuet11.wav",0
  1020. textbox_string:
  1021. ;---------------------------------------------------------------------
  1022.  
  1023. IMAGE_END:               ; end of program's image
  1024.    rb 257
  1025. ;   rb 257-textbox_string.size
  1026. ;     textbox_string.size
  1027.  
  1028. ;---------------------------------------------------------------------
  1029.  
  1030. device_id dd ?    ; (device_id << 16) + vendor_id
  1031. lastbus   db ?    ; pci coordinates
  1032. bus      db ?
  1033. devfn      db ?
  1034.  
  1035. AC97ICH4  db ?    ; Intel ICH4 codec flag
  1036. SI7012      db ?    ; SiS SI7012 codec flag
  1037. NAMBAR      dw ?    ; Audio Mixers Registers (base)
  1038. NABMBAR   dw ?    ; Bus Master Registers   (base)
  1039.  
  1040. AC97IRQ   db ?    ; Interrupt request
  1041. AC97INT   db ?    ; Interrupt pin
  1042.  
  1043. wav_mode  db ?    ; bits per sample & channels
  1044.  
  1045. ;---------------------------------------------------------------------
  1046.  
  1047. ST_DONE = 0x0    ; for interacting with player's window
  1048. ST_PLAY = 0x1
  1049. ST_EXIT = 0x2
  1050. ST_STOP = 0x4
  1051.  
  1052. status      db ?
  1053.  
  1054. fileattr: rb 40
  1055.  
  1056. ;---------------------------------------------------------------------
  1057. phys_bdl_buffer rd 1
  1058. phys_wav_buffer1 rd 1
  1059. phys_wav_buffer2 rd 1
  1060. align 32
  1061.  
  1062.  
  1063. ; Buffer Descriptors List
  1064. ;  ___________________________
  1065. ;  |     physical address    | dword
  1066. ;  |_________________________|
  1067. ;  | attr       |   length   | dword     max. length = 65535 samples
  1068. ;  |_________________________|
  1069.  
  1070. BDL_BUFFER:
  1071.  rb 32*8     ; 32 descriptors, 8 bytes each
  1072.  
  1073.  
  1074. ;---------------------------------------------------------------------
  1075.  
  1076. file_data:
  1077.  
  1078. WAV_BUFFER1:
  1079.  rb 60 * 1024  ; 60 Kb
  1080.  
  1081. WAV_BUFFER2:
  1082.  rb 60 * 1024
  1083.  
  1084. LOAD_BUFFER:
  1085.  rb 60 * 1024
  1086.  
  1087. ;---------------------------------------------------------------------
  1088.  
  1089. procinfo process_information
  1090.  
  1091. work_area:
  1092.  rb 0x10000
  1093.  
  1094. ;---------------------------------------------------------------------
  1095.  
  1096. rb 0x800
  1097. thread_stack:
  1098.  
  1099. rb 0x1000 ; for stack
  1100. STACK_P:
  1101.  
  1102. MEMORY_END:
  1103.