Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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. ;
  15. ;   Use [flat assembler 1.56] to compile.
  16. ;
  17. ;---------------------------------------------------------------------
  18.  
  19.   use32          ; turn on 32 bit mode
  20.   org     0x0         ; the program is placed at 0 offset
  21.  
  22.   db     'MENUET01'     ; 8-byte identifier of MenuetOS application
  23.   dd     0x01         ; header version (always 1)
  24.   dd     START         ; address of the beginning of the code
  25.   dd     IMAGE_END     ; size of the program's image
  26.   dd     MEMORY_END     ; how much memory does it need
  27.   dd     STACK_P     ; a pointer to the top of the stack
  28.   dd     textbox_string
  29. ;  dd     0x0             ; address of buffer for parameters (not used)
  30.   dd     0x0         ; reserved
  31.  
  32. ;---------------------------------------------------------------------
  33.  
  34. include "lang.inc"
  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
  453.     mov    [fileinfo.first_block], 0
  454.     mcall    MF_SYSTREE, fileinfo ; load a block, returns error code in eax
  455.                      ;   and size of the file in ebx
  456.     test    eax, eax         ; 0 - successful
  457.     jz    @f
  458.     print    "AC97: File not found!"
  459.     mov    [status], ST_STOP
  460.     jmp    .exit
  461.      @@:
  462.     shr    ebx, 9             ; size_of_file / 512 = number_of_blocks
  463.     mov    [file_size], ebx
  464.  
  465.  
  466.     mov    al, [LOAD_BUFFER+32] ; bytes per sample
  467.     dec    al
  468.     jz    @f
  469.     cmp    al, 3
  470.     je    @f
  471.     sub    al, [LOAD_BUFFER+22] ; channels
  472.     add    al, 2
  473.       @@:
  474.     mov    [wav_mode], al
  475.  
  476.     pusha
  477.     movzx    ebx,word [LOAD_BUFFER+24]
  478.     mov   eax,48000
  479.     xor   edx,edx
  480.     div   ebx
  481.     mov   [difference_of_frequency],al
  482. ;        dph   eax
  483.     mov   ecx,edx
  484.     imul  eax,ecx,10
  485.     xor   edx,edx
  486.     div   ebx
  487.     mov   ecx,edx
  488.     imul  ecx,10
  489.     push  eax
  490.     mov   eax,ecx
  491.     xor   edx,edx
  492.     div   ebx
  493. ;        dph   eax
  494.     cmp   eax,5
  495.     jl    .temp_15
  496.     pop   eax
  497. ;        dph   eax
  498.  
  499.     inc   eax
  500.     jmp   .temp_16
  501.      .temp_15:
  502.     pop   eax
  503.      .temp_16:
  504.     mov   [difference_of_frequency_1],al
  505. ;        dph   eax
  506.     xor   edx,edx
  507.     movzx  ebx,[difference_of_frequency]
  508.     imul   ebx,10
  509.     add    bl,[difference_of_frequency_1]
  510.     mov   [difference_of_frequency_2],bl
  511. ;        dph   ebx
  512.     popa
  513.  
  514.     movzx    eax, word [LOAD_BUFFER+24]
  515.     ;dps "Freq: "
  516.     ;dpd eax
  517.     ;newline
  518.     call    set_sample_rate
  519.  
  520.  
  521.     ; change the last_valid_index to the (current_index-1)
  522.     ; the LVI register tells the DMA engine where to stop playing
  523.     call    updateLVI
  524.  
  525.     ; if current index is odd, load buffer 1 then 0, jump to tuneLoop
  526.     ; if it is even, buffers 0 then 1; tuneLoop1
  527.     call    getCurrentIndex
  528.     and    eax, BIT0
  529.  
  530.     mov    esi, eax
  531.     push    eax
  532.     call    update_next_buffer
  533.     pop    eax
  534.     xor    eax, 1
  535.     call    update_next_buffer
  536.  
  537.     ; start playing!
  538.     mov    edx, PO_CR_REG
  539.     mov    al, RPBM
  540.     call    NABMBAR_write_byte
  541.  
  542.     jmp    [jumpto+esi*4]
  543.  
  544.  
  545.    .tuneLoop:
  546.     ; wait while the current_index is even
  547.     @@:
  548. ;        dps     "a"
  549.     mcall    MF_DELAY, 7
  550.     call    getCurrentIndex
  551.     test    al, BIT0
  552.     jz    @b       ; loop if not ready yet
  553. ;        print   "fa"
  554.  
  555.     call    updateLVI
  556.  
  557.     mov    eax, 0
  558.     call    update_next_buffer
  559.     test    al, al
  560.     jnz    .exit_wait
  561.  
  562.     cmp    [status], ST_PLAY
  563.     jne    .exit
  564.  
  565.     test    [volume], 0x10000000 ; test volume_changed bit
  566.     je    @f
  567.     mov    al, byte [volume]
  568.     call    setVolume
  569.     and    [volume], 0x0FFFFFFF ; clear vloume_changed bit
  570.      @@:
  571.  
  572.      .tuneLoop1:
  573.      @@:
  574. ;        dps     "b"
  575.     mcall    MF_DELAY, 7
  576.     call    getCurrentIndex
  577.     test    al, BIT0
  578.     jnz    @b       ; loop if not ready yet
  579. ;        print   "fb"
  580.  
  581.     cmp    [status], ST_PLAY
  582.     jne    .exit
  583.  
  584.     call    updateLVI
  585.  
  586.     mov    eax, 1
  587.     call    update_next_buffer
  588.     test    al, al
  589.     jnz    .exit_wait
  590.  
  591.     jmp    .tuneLoop
  592.    .exit_wait:
  593.     mcall    MF_DELAY, 30 ; a little pause - let the player finish
  594.    .exit:
  595. ret
  596. attempts db 0
  597.  
  598. buffers dd WAV_BUFFER1, WAV_BUFFER2
  599. jumpto    dd play.tuneLoop, play.tuneLoop1
  600.  
  601.  
  602. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  603. ;; update_first_buffer - load a chunk into the first buffer, increments offset
  604. ;; in:  eax = number - 0 or 1
  605. ;; out: error code, 0 - successful
  606. update_next_buffer:
  607.     push   esi edi
  608.  
  609.     movzx  edx, byte [wav_mode]
  610.     mov    ecx, [blocks + edx * 4]
  611.     mov    [fileinfo.blocks], ecx
  612.  
  613.     mov    esi, LOAD_BUFFER
  614.     mov    edi, [buffers+eax*4]
  615.     push   eax              ;save buffer index
  616.   start_attempts:
  617.     mcall  MF_SYSTREE, fileinfo
  618.     test eax, eax
  619.     jz @f
  620.     cmp   [attempts],100
  621.     je   @f
  622.     inc   [attempts]
  623.     jmp   start_attempts
  624.     dpd eax
  625.     newline
  626.     dpd [fileinfo.first_block]
  627.     newline
  628.        @@:
  629. ;        print  " loaded!"
  630.  
  631.     push   eax ebx edx
  632.     mov    eax,ecx
  633.     xor    edx,edx
  634.     imul   eax,10
  635.     movzx     ebx,[difference_of_frequency_2]
  636.  
  637.     div    ebx
  638.     mov    ecx,eax
  639.  
  640. ;    mov   ebx,10
  641. ;    mov   eax,edx
  642. ;    xor   edx,edx
  643. ;    div   ebx
  644. ;   cmp   edx,5
  645. ;    jb   temp_12_7
  646. ;    inc   ecx
  647. ;  temp_12_7:
  648.    cmp   edx,0
  649.     je   temp_12_7
  650.     inc   ecx
  651.   temp_12_7:
  652.  
  653.     pop    edx ebx
  654.     mov    eax,[esp+4]            ;restore buffer index
  655.     add    [fileinfo.first_block], ecx ; +60Kb
  656.     call   [convert + edx * 4]
  657. ;start fix for MM (4)    
  658.     mov    eax,[esp+4]            ;restore buffer index
  659.     test   eax,not 1
  660.     jz     .ok
  661.     print  "buffer index out of range"
  662.     dpd    eax
  663.     jmp    .ret
  664.   .ok:
  665.     push   ebp
  666.     mov    ebp,[phys_wav_buffer1+eax*4]
  667.     mov    edi,[buffers+eax*4]
  668.     mcall  MF_INTERNAL_SERVICES,SET_PHYS_BUFFER,ebp,edi,60*1024
  669.     pop    ebp
  670. .ret:
  671.     pop    eax
  672.     add    esp,4                  ;pop buffer index    
  673. ;end fix for MM (4)    
  674.  
  675.     pop    edi esi
  676. ret
  677.  
  678. c8mono:
  679.     mov   [type_of_conversion],1
  680.     jmp   for_all_type
  681.  
  682. c8mono_1:
  683.     lodsb
  684.     call  c8mono_2
  685.     push  ax
  686.     shl   eax,16
  687.     pop   ax
  688.     push  eax
  689.     mov al,[esi]
  690.     call  c8mono_2
  691.     push  ax
  692.     shl   eax,16
  693.     pop   ax
  694.     mov  ebx,eax
  695.     pop  eax
  696.     jmp  for_all_type_1
  697.  
  698. c8mono_2:
  699.     sub    al, 0x80
  700.     cbw
  701.     imul   ax, 255
  702.     ret
  703.  
  704. c8stereo:
  705.     mov   [type_of_conversion],2
  706.     jmp   for_all_type
  707.  
  708. c8stereo_1:
  709.     lodsb
  710.     call  c8stereo_2
  711.     shl eax,16
  712.     lodsb
  713.     call  c8stereo_2
  714.     push  eax
  715.     mov al,[esi]
  716.     call  c8stereo_2
  717.     shl eax,16
  718.     mov al,[esi+1]
  719.     call  c8stereo_2
  720.     mov   ebx,eax
  721.     pop  eax
  722.     jmp   for_all_type_1
  723.  
  724. c8stereo_2:
  725.     sub    al, 0x80
  726.     cbw
  727.     imul   ax, 255
  728.     ret
  729.  
  730. c16mono:
  731.     mov   [type_of_conversion],3
  732.     jmp   for_all_type
  733.  
  734. c16mono_1:
  735.         lodsw
  736.         push  ax
  737.         shl eax,16
  738.         pop   ax
  739.         mov bx,[esi]
  740.         shl ebx,16
  741.         mov bx,[esi]
  742.         jmp  for_all_type_1
  743.  
  744. c16stereo:
  745.  for_all_type:
  746.     xor   edx,edx
  747.     mov    eax, 15*1024*10
  748.     movzx     ebx,[difference_of_frequency_2]
  749.     xor    edx,edx
  750.     div    ebx
  751.     mov    ecx,eax
  752.  
  753. ;    mov   ebx,10
  754. ;    mov   eax,edx
  755. ;    xor   edx,edx
  756. ;    div   ebx
  757. ;    cmp   edx,5
  758. ;    jb   temp_12_6
  759. ;    inc   ecx
  760. ;  temp_12_6:
  761.    cmp   edx,0
  762.     je   temp_12_6
  763.     inc   ecx
  764.   temp_12_6:
  765.  
  766.   c16stereo_1:
  767.     mov  [znak],0
  768.  
  769.     cmp  [type_of_conversion],1
  770.     je   c8mono_1
  771.     cmp  [type_of_conversion],2
  772.     je   c8stereo_1
  773.     cmp  [type_of_conversion],3
  774.     je   c16mono_1
  775.     lodsd
  776.  
  777.     mov ebx,[esi]
  778. for_all_type_1:
  779.     cmp eax,ebx
  780.     jne  c16stereo_2
  781.     inc  [znak]
  782.     c16stereo_2:
  783.     push eax
  784.     push ecx
  785.     sub  eax,ebx
  786.     push eax
  787.     shl  eax,16
  788.     movzx  ebx,[difference_of_frequency]
  789.     inc   ebx
  790.     xor  edx,edx
  791.     div  ebx
  792.     shr  eax,16
  793.     mov  ecx,eax
  794.     pop  eax
  795.     xor  ax,ax
  796.     xor  edx,edx
  797.     div  ebx
  798.     shl  eax,16
  799.     mov  cx,ax
  800.     mov  ebx,ecx
  801.     pop  ecx
  802.     pop   eax
  803.     mov    dl,[difference_of_frequency]
  804.     inc   dl
  805.     @@:
  806. temp_12:
  807.     cmp   [difference_of_frequency_1],0
  808.     je    temp_12_3
  809.     cmp   [difference_of_frequency_1],5
  810.     jne   temp_12_4
  811.     cmp  [difference_of_frequency_4],2
  812.     jne  temp_12_3
  813.     jmp  temp_12_5
  814.  temp_12_4:
  815.     cmp  [difference_of_frequency_4],10
  816.     jne  temp_12_3
  817.  
  818.  temp_12_5:
  819.  
  820.     cmp  [znak],0
  821.     jne   temp_12_5_1
  822.     sub  eax,ebx
  823.     jmp  temp_12_5_2
  824.  temp_12_5_1:
  825.     add  eax,ebx
  826.  temp_12_5_2:
  827.  
  828.  
  829.     stosd
  830.     inc  [schetchik]
  831.     mov    [difference_of_frequency_4],0
  832.  temp_12_3:
  833.     cmp  [znak],0
  834.     jne   temp_13
  835.     sub  eax,ebx
  836.     jmp  temp_14
  837.  temp_13:
  838.     add  eax,ebx
  839.  
  840.  temp_14:
  841.     cld
  842.     dec    dl
  843.     jz    temp_14_1
  844.     stosd
  845.     inc   [schetchik]
  846.     inc   [difference_of_frequency_4]
  847.     jmp   temp_12
  848.  temp_14_1:
  849.     dec    ecx
  850.     cmp   ecx,0
  851. ;    jnz    c16stereo_1
  852.     jg    c16stereo_1
  853.     newline
  854.     dph [schetchik]
  855.  temp_14_2:
  856.     cmp   [schetchik],15360
  857.     jge   temp_14_3
  858.     stosd
  859.     inc  [schetchik]
  860.     jmp  temp_14_2
  861.  
  862.   temp_14_3:
  863.     newline
  864.     dph [schetchik]
  865.     cmp   [schetchik],15360
  866.     je    temp_14_4
  867. ;    mov  [edi-4],dword 0
  868.     sub   edi,4
  869. ;    sub   esi,4
  870.  temp_14_4:
  871.     mov   [schetchik],0
  872.     ret
  873.  
  874.  
  875. difference_of_frequency db 0
  876. difference_of_frequency_1 db 0
  877. difference_of_frequency_2 db 0
  878. difference_of_frequency_4 db 0
  879. schetchik dd 0
  880. znak db 0
  881. type_of_conversion db 0
  882.  
  883. convert dd c8mono, c8stereo, c16mono, c16stereo
  884. blocks    dd 30, 60, 60, 120
  885.  
  886.  
  887. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  888. ;; get_my_address - get base address of the program in physical memory
  889. ;;   in:  nothing
  890. ;;   out: eax = address
  891. ;start fix for MM (8)
  892. ;function shouldn't used.
  893. ;get_my_address:
  894. ;    pushad
  895. ;    mcall    MF_PROCINFO, procinfo, PN_MYSELF
  896. ;    popad
  897. ;    mov    eax, [procinfo.memory_start]
  898. ;ret
  899. ;end fix for MM (8)
  900.  
  901.  
  902. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  903. ;; set the last valid index to something other than we're currently playing
  904. ;; so that we never end
  905. ;;
  906. ;; this routine just sets the last valid index to 1 less than the index
  907. ;; that we're currently playing, thus keeping it in and endless loop
  908. ;; input:  none
  909. ;; output: none
  910. updateLVI:
  911.     push    eax
  912.     call    getCurrentIndex
  913.      ; dps "index "
  914.      ; dpd eax
  915.      ; newline
  916.     dec    al
  917.     and    al, INDEX_MASK
  918.     call    setLastValidIndex
  919.     pop    eax
  920. ret
  921.  
  922. ;---------------------------------------------------------------------
  923.  
  924. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  925. ;; returns AL = current index value
  926. getCurrentIndex:
  927.     push    edx
  928.     mov    edx, PO_CIV_REG
  929.     call    NABMBAR_read_byte
  930.     pop    edx
  931. ret
  932.  
  933. ;---------------------------------------------------------------------
  934.  
  935. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  936. ;; input AL = index # to stop on
  937. setLastValidIndex:
  938.     push    edx
  939.     mov    edx, PO_LVI_REG
  940.     call    NABMBAR_write_byte
  941.     pop    edx
  942. ret
  943.  
  944. ;---------------------------------------------------------------------
  945.  
  946. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  947. ;; print_info - outputs debug information
  948. ;;  in:  nothing
  949. ;;  out: nothing
  950. print_info:
  951.     dps    "BUS: "
  952.     movzx    eax, [bus]
  953.     dph    eax
  954.  
  955.     dps    " DEVFN: "
  956.     movzx    eax, [devfn]
  957.     dph    eax
  958.  
  959.     dps    " IRQ: "
  960.     movzx    eax, [AC97IRQ]
  961.     dpd    eax
  962.     newline
  963.  
  964.  
  965.     dps    "CODEC_POWER_CTRL: "
  966.     mov    edx, CODEC_POWER_CTRL_REG
  967.     call    NAMBAR_read_word
  968.     dph    eax
  969.     dps    " (bits 0-3 should be set)"
  970.     newline
  971.  
  972.     mov    edx, 0x28
  973.     call    NAMBAR_read_word
  974.     dph    eax
  975.     dps    " - supported features"
  976.     newline
  977.     mov    edx, 0x2A
  978.     call    NAMBAR_read_word
  979.     dph    eax
  980.     dps    " - config"
  981.     newline
  982.     mov    edx, 0x2C
  983.     call    NAMBAR_read_word
  984.     dph    eax
  985.     dps    " - PCM rate"
  986.  
  987.     newline
  988. ret
  989.  
  990.  
  991. ;---------------------------------------------------------------------
  992. ;---  DATA OF PROGRAM  -----------------------------------------------
  993. ;---------------------------------------------------------------------
  994. volume           dd  15
  995.  
  996. fileinfo:
  997.  .mode           dd  0           ; READ
  998.  .first_block  dd  0
  999.  .blocks       dd  120           ; 120 Kb
  1000.  .dest           dd  LOAD_BUFFER ;file_data
  1001.  .work           dd  work_area
  1002.          ;  db  "/HD/1/WINDOWS/MEDIA/WICEB7~1.WAV",0
  1003. ;sz textbox_string, "/hd/1/testmuz/menuet11.wav",0
  1004. sz textbox_string, "                                                        ",0
  1005. ;   rb 256
  1006. ;---------------------------------------------------------------------
  1007.  
  1008. IMAGE_END:               ; end of program's image
  1009.    rb 100-textbox_string.size
  1010. ;     textbox_string.size
  1011.  
  1012. ;---------------------------------------------------------------------
  1013.  
  1014. device_id dd ?    ; (device_id << 16) + vendor_id
  1015. lastbus   db ?    ; pci coordinates
  1016. bus      db ?
  1017. devfn      db ?
  1018.  
  1019. AC97ICH4  db ?    ; Intel ICH4 codec flag
  1020. SI7012      db ?    ; SiS SI7012 codec flag
  1021. NAMBAR      dw ?    ; Audio Mixers Registers (base)
  1022. NABMBAR   dw ?    ; Bus Master Registers   (base)
  1023.  
  1024. AC97IRQ   db ?    ; Interrupt request
  1025. AC97INT   db ?    ; Interrupt pin
  1026.  
  1027. wav_mode  db ?    ; bits per sample & channels
  1028.  
  1029. ;---------------------------------------------------------------------
  1030.  
  1031. ST_DONE = 0x0    ; for interacting with player's window
  1032. ST_PLAY = 0x1
  1033. ST_EXIT = 0x2
  1034. ST_STOP = 0x4
  1035.  
  1036. status      db ?
  1037.  
  1038. ;---------------------------------------------------------------------
  1039. phys_bdl_buffer rd 1
  1040. phys_wav_buffer1 rd 1
  1041. phys_wav_buffer2 rd 1
  1042. align 32
  1043.  
  1044.  
  1045. ; Buffer Descriptors List
  1046. ;  ___________________________
  1047. ;  |     physical address    | dword
  1048. ;  |_________________________|
  1049. ;  | attr       |   length   | dword     max. length = 65535 samples
  1050. ;  |_________________________|
  1051.  
  1052. BDL_BUFFER:
  1053.  rb 32*8     ; 32 descriptors, 8 bytes each
  1054.  
  1055.  
  1056. ;---------------------------------------------------------------------
  1057.  
  1058. file_data:
  1059.  
  1060. WAV_BUFFER1:
  1061.  rb 60 * 1024  ; 60 Kb
  1062.  
  1063. WAV_BUFFER2:
  1064.  rb 60 * 1024
  1065.  
  1066. LOAD_BUFFER:
  1067.  rb 60 * 1024
  1068.  
  1069. ;---------------------------------------------------------------------
  1070.  
  1071. procinfo process_information
  1072.  
  1073. work_area:
  1074.  rb 0x10000
  1075.  
  1076. ;---------------------------------------------------------------------
  1077.  
  1078. rb 0x800
  1079. thread_stack:
  1080.  
  1081. rb 0x1000 ; for stack
  1082. STACK_P:
  1083.  
  1084. MEMORY_END:
  1085.