Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. format MS COFF
  9.  
  10. DEBUG           equ 1
  11.  
  12. include 'proc32.inc'
  13. include 'imports.inc'
  14.  
  15. API_VERSION     equ 0x01000100
  16.  
  17. USE_COM_IRQ     equ 0    ;make irq 3 and irq 4 available for PCI devices
  18. IRQ_REMAP       equ 0
  19. IRQ_LINE        equ 0
  20.  
  21.  
  22. ;irq 0,1,2,8,12,13 ­¥¤®áâ㯭ë
  23. ;                   FEDCBA9876543210
  24. VALID_IRQ       equ 1100111011111000b
  25. ATTCH_IRQ       equ 0000111010100000b
  26.  
  27. if USE_COM_IRQ
  28. ATTCH_IRQ       equ 0000111010111000b
  29. end if
  30.  
  31. CPU_FREQ        equ  2600d
  32.  
  33. BIT0  EQU 0x00000001
  34. BIT1  EQU 0x00000002
  35. BIT5  EQU 0x00000020
  36. BIT10 EQU 0x00000400
  37.  
  38. VID_Creative      equ 0x1102
  39.  
  40. CTRL_CT0200       equ 0x0006  ; Dell OEM version (EMU10K1X)
  41.  
  42.  
  43. CODEC_MASTER_VOL_REG         equ 0x02
  44. CODEC_AUX_VOL                equ 0x04 ;
  45. CODEC_PCM_OUT_REG            equ 0x18 ; PCM output volume
  46. CODEC_EXT_AUDIO_REG          equ 0x28 ; extended audio
  47. CODEC_EXT_AUDIO_CTRL_REG     equ 0x2a ; extended audio control
  48. CODEC_PCM_FRONT_DACRATE_REG  equ 0x2c ; PCM out sample rate
  49. CODEC_PCM_SURND_DACRATE_REG  equ 0x2e ; surround sound sample rate
  50. CODEC_PCM_LFE_DACRATE_REG    equ 0x30 ; LFE sample rate
  51.  
  52.  
  53. ;EMU10K1(X) host controller registers set
  54. ;; common offsets
  55. ;; some definitions were borrowed from emu10k1 driver as they seem to be the same
  56. ;;**********************************************************************************************;;
  57. ;; PCI function 0 registers, address = <val> + PCIBASE0                                         ;;
  58. ;;**********************************************************************************************;;
  59.  
  60. PTR                     equ  0x00            ;; Indexed register set pointer register        ;;
  61.                                                 ;; NOTE: The CHANNELNUM and ADDRESS words can   ;;
  62.                                                 ;; be modified independently of each other.     ;;
  63.  
  64. DATA                    equ  0x04            ;; Indexed register set data register           ;;
  65.  
  66. IPR                     equ  0x08            ;; Global interrupt pending register            ;;
  67.                                                 ;; Clear pending interrupts by writing a 1 to   ;;
  68.                                                 ;; the relevant bits and zero to the other bits ;;
  69. IPR_MIDITRANSBUFEMPTY   equ  0x00000001      ;; MIDI UART transmit buffer empty              ;;
  70. IPR_MIDIRECVBUFEMPTY    equ  0x00000002      ;; MIDI UART receive buffer empty               ;;
  71. IPR_CH_0_LOOP           equ  0x00000800      ;; Channel 0 loop                               ;;
  72. IPR_CH_0_HALF_LOOP      equ  0x00000100      ;; Channel 0 half loop                          ;;
  73. IPR_CAP_0_LOOP          equ  0x00080000      ;; Channel capture loop                         ;;
  74. IPR_CAP_0_HALF_LOOP     equ  0x00010000      ;; Channel capture half loop                    ;;
  75.  
  76. INTE                    equ  0x0c            ;; Interrupt enable register                    ;;
  77. INTE_MIDITXENABLE       equ  0x00000001      ;; Enable MIDI transmit-buffer-empty interrupts ;;
  78. INTE_MIDIRXENABLE       equ  0x00000002      ;; Enable MIDI receive-buffer-empty interrupts  ;;
  79. INTE_CH_0_LOOP          equ  0x00000800      ;; Channel 0 loop                               ;;
  80. INTE_CH_0_HALF_LOOP     equ  0x00000100      ;; Channel 0 half loop                          ;;
  81. INTE_CAP_0_LOOP         equ  0x00080000      ;; Channel capture loop                         ;;
  82. INTE_CAP_0_HALF_LOOP    equ  0x00010000      ;; Channel capture half loop                    ;;
  83.  
  84. HCFG                    equ  0x14            ;; Hardware config register                     ;;
  85.  
  86. HCFG_LOCKSOUNDCACHE     equ  0x00000008      ;; 1 = Cancel bustmaster accesses to soundcache ;;
  87.                                                 ;; NOTE: This should generally never be used.   ;;
  88. HCFG_AUDIOENABLE        equ  0x00000001      ;; 0 = CODECs transmit zero-valued samples      ;;
  89.                                                 ;; Should be set to 1 when the EMU10K1 is       ;;
  90.                                                 ;; completely initialized.                      ;;
  91. GPIO                    equ  0x18            ;; Defaults: 00001080-Analog, 00001000-SPDIF.   ;;
  92.  
  93.  
  94. AC97DATA                equ  0x1c            ;; AC97 register set data register (16 bit)     ;;
  95.  
  96. AC97ADDRESS             equ  0x1e            ;; AC97 register set address register (8 bit)   ;;
  97.  
  98. ;;******************************************************************************************************;;
  99. ;; Emu10k1x pointer-offset register set, accessed through the PTR and DATA registers                    ;;
  100. ;;******************************************************************************************************;;
  101. PLAYBACK_LIST_ADDR      equ  0x00            ;; Base DMA address of a list of pointers to each period/size ;;
  102.                                                 ;; One list entry: 4 bytes for DMA address,
  103.                                                  ;; 4 bytes for period_size << 16.
  104.                                                  ;; One list entry is 8 bytes long.
  105.                                                  ;; One list entry for each period in the buffer.
  106.                                                  ;;
  107. PLAYBACK_LIST_SIZE      equ  0x01            ;; Size of list in bytes << 19. E.g. 8 periods -> 0x00380000  ;;
  108. PLAYBACK_LIST_PTR       equ  0x02            ;; Pointer to the current period being played ;;
  109. PLAYBACK_DMA_ADDR       equ  0x04            ;; Playback DMA addresss ;;
  110. PLAYBACK_PERIOD_SIZE    equ  0x05            ;; Playback period size ;;
  111. PLAYBACK_POINTER        equ  0x06            ;; Playback period pointer. Sample currently in DAC ;;
  112. PLAYBACK_UNKNOWN1       equ  0x07
  113. PLAYBACK_UNKNOWN2       equ  0x08
  114.  
  115. ;; Only one capture channel supported ;;
  116. CAPTURE_DMA_ADDR        equ  0x10            ;; Capture DMA address ;;
  117. CAPTURE_BUFFER_SIZE     equ  0x11            ;; Capture buffer size ;;
  118. CAPTURE_POINTER         equ  0x12            ;; Capture buffer pointer. Sample currently in ADC ;;
  119. CAPTURE_UNKNOWN         equ  0x13
  120.  
  121. ;; From 0x20 - 0x3f, last samples played on each channel ;;
  122.  
  123. TRIGGER_CHANNEL         equ  0x40            ;; Trigger channel playback                     ;;
  124. TRIGGER_CHANNEL_0       equ  0x00000001      ;; Trigger channel 0                            ;;
  125. TRIGGER_CHANNEL_1       equ  0x00000002      ;; Trigger channel 1                            ;;
  126. TRIGGER_CHANNEL_2       equ  0x00000004      ;; Trigger channel 2                            ;;
  127. TRIGGER_CAPTURE         equ  0x00000100      ;; Trigger capture channel                      ;;
  128.  
  129. ROUTING                 equ  0x41            ;; Setup sound routing ?                        ;;
  130. ROUTING_FRONT_LEFT      equ  0x00000001
  131. ROUTING_FRONT_RIGHT     equ  0x00000002
  132. ROUTING_REAR_LEFT       equ  0x00000004
  133. ROUTING_REAR_RIGHT      equ  0x00000008
  134. ROUTING_CENTER_LFE      equ  0x00010000
  135.  
  136. SPCS0                   equ  0x42            ;; SPDIF output Channel Status 0 register       ;;
  137. SPCS1                   equ  0x43            ;; SPDIF output Channel Status 1 register       ;;
  138. SPCS2                   equ  0x44            ;; SPDIF output Channel Status 2 register       ;;
  139.  
  140. SPCS_CLKACCYMASK        equ  0x30000000      ;; Clock accuracy                               ;;
  141. SPCS_CLKACCY_1000PPM    equ  0x00000000      ;; 1000 parts per million                       ;;
  142. SPCS_CLKACCY_50PPM      equ  0x10000000      ;; 50 parts per million                         ;;
  143. SPCS_CLKACCY_VARIABLE   equ  0x20000000      ;; Variable accuracy                            ;;
  144. SPCS_SAMPLERATEMASK     equ  0x0f000000      ;; Sample rate                                  ;;
  145. SPCS_SAMPLERATE_44      equ  0x00000000      ;; 44.1kHz sample rate                          ;;
  146. SPCS_SAMPLERATE_48      equ  0x02000000      ;; 48kHz sample rate                            ;;
  147. SPCS_SAMPLERATE_32      equ  0x03000000      ;; 32kHz sample rate                            ;;
  148. SPCS_CHANNELNUMMASK     equ  0x00f00000      ;; Channel number                               ;;
  149. SPCS_CHANNELNUM_UNSPEC  equ  0x00000000      ;; Unspecified channel number                   ;;
  150. SPCS_CHANNELNUM_LEFT    equ  0x00100000      ;; Left channel                                 ;;
  151. SPCS_CHANNELNUM_RIGHT   equ  0x00200000      ;; Right channel                                ;;
  152. SPCS_SOURCENUMMASK      equ  0x000f0000      ;; Source number                                ;;
  153. SPCS_SOURCENUM_UNSPEC   equ  0x00000000      ;; Unspecified source number                    ;;
  154. SPCS_GENERATIONSTATUS   equ  0x00008000      ;; Originality flag (see IEC-958 spec)          ;;
  155. SPCS_CATEGORYCODEMASK   equ  0x00007f00      ;; Category code (see IEC-958 spec)             ;;
  156. SPCS_MODEMASK           equ  0x000000c0      ;; Mode (see IEC-958 spec)                      ;;
  157. SPCS_EMPHASISMASK       equ  0x00000038      ;; Emphasis                                     ;;
  158. SPCS_EMPHASIS_NONE      equ  0x00000000      ;; No emphasis                                  ;;
  159. SPCS_EMPHASIS_50_15     equ  0x00000008      ;; 50/15 usec 2 channel                         ;;
  160. SPCS_COPYRIGHT          equ  0x00000004      ;; Copyright asserted flag -- do not modify     ;;
  161. SPCS_NOTAUDIODATA       equ  0x00000002      ;; 0 = Digital audio, 1 = not audio             ;;
  162. SPCS_PROFESSIONAL       equ  0x00000001      ;; 0 = Consumer (IEC-958), 1 = pro (AES3-1992)  ;;
  163.  
  164. SPDIF_SELECT            equ  0x45            ;; Enables SPDIF or Analogue outputs 0-Analogue, 0x700-SPDIF ;;
  165.  
  166. ;; This is the MPU port on the card                                                             ;;
  167. MUDATA          equ  0x47
  168. MUCMD           equ  0x48
  169. MUSTAT          equ  MUCMD
  170.  
  171. ;; From 0x50 - 0x5f, last samples captured ;;
  172.  
  173.  
  174. SRV_GETVERSION        equ  0
  175. DEV_PLAY              equ  1
  176. DEV_STOP              equ  2
  177. DEV_CALLBACK          equ  3
  178. DEV_SET_BUFF          equ  4
  179. DEV_NOTIFY            equ  5
  180. DEV_SET_MASTERVOL     equ  6
  181. DEV_GET_MASTERVOL     equ  7
  182. DEV_GET_INFO          equ  8
  183.  
  184. struc AC_CNTRL              ;AC controller base class
  185. { .bus                dd ?
  186.   .devfn              dd ?
  187.  
  188.   .vendor             dd ?
  189.   .dev_id             dd ?
  190.   .pci_cmd            dd ?
  191.   .pci_stat           dd ?
  192.  
  193.   .codec_io_base      dd ?
  194.   .codec_mem_base     dd ?
  195.  
  196.   .ctrl_io_base       dd ?
  197.   .ctrl_mem_base      dd ?
  198.   .cfg_reg            dd ?
  199.   .int_line           dd ?
  200.  
  201.   .vendor_ids         dd ?    ;vendor id string
  202.   .ctrl_ids           dd ?    ;hub id string
  203.  
  204.   .buffer             dd ?
  205.  
  206.   .notify_pos         dd ?
  207.   .notify_task        dd ?
  208.  
  209.   .lvi_reg            dd ?
  210.   .ctrl_setup         dd ?
  211.   .user_callback      dd ?
  212.   .codec_read16       dd ?
  213.   .codec_write16      dd ?
  214.  
  215.   .ctrl_read8         dd ?
  216.   .ctrl_read16        dd ?
  217.   .ctrl_read32        dd ?
  218.  
  219.   .ctrl_write8        dd ?
  220.   .ctrl_write16       dd ?
  221.   .ctrl_write32       dd ?
  222. }
  223.  
  224. struc CODEC                ;Audio Chip base class
  225. {
  226.   .chip_id            dd ?
  227.   .flags              dd ?
  228.   .status             dd ?
  229.  
  230.   .ac_vendor_ids      dd ?    ;ac vendor id string
  231.   .chip_ids           dd ?    ;chip model string
  232.  
  233.   .shadow_flag        dd ?
  234.                       dd ?
  235.  
  236.   .regs               dw ?     ; codec registers
  237.   .reg_master_vol     dw ?     ;0x02
  238.   .reg_aux_out_vol    dw ?     ;0x04
  239.   .reg_mone_vol       dw ?     ;0x06
  240.   .reg_master_tone    dw ?     ;0x08
  241.   .reg_beep_vol       dw ?     ;0x0A
  242.   .reg_phone_vol      dw ?     ;0x0C
  243.   .reg_mic_vol        dw ?     ;0x0E
  244.   .reg_line_in_vol    dw ?     ;0x10
  245.   .reg_cd_vol         dw ?     ;0x12
  246.   .reg_video_vol      dw ?     ;0x14
  247.   .reg_aux_in_vol     dw ?     ;0x16
  248.   .reg_pcm_out_vol    dw ?     ;0x18
  249.   .reg_rec_select     dw ?     ;0x1A
  250.   .reg_rec_gain       dw ?     ;0x1C
  251.   .reg_rec_gain_mic   dw ?     ;0x1E
  252.   .reg_gen            dw ?     ;0x20
  253.   .reg_3d_ctrl        dw ?     ;0X22
  254.   .reg_page           dw ?     ;0X24
  255.   .reg_powerdown      dw ?     ;0x26
  256.   .reg_ext_audio      dw ?     ;0x28
  257.   .reg_ext_st         dw ?     ;0x2a
  258.   .reg_pcm_front_rate dw ?     ;0x2c
  259.   .reg_pcm_surr_rate  dw ?     ;0x2e
  260.   .reg_lfe_rate       dw ?     ;0x30
  261.   .reg_pcm_in_rate    dw ?     ;0x32
  262.                       dw ?     ;0x34
  263.   .reg_cent_lfe_vol   dw ?     ;0x36
  264.   .reg_surr_vol       dw ?     ;0x38
  265.   .reg_spdif_ctrl     dw ?     ;0x3A
  266.                       dw ?     ;0x3C
  267.                       dw ?     ;0x3E
  268.                       dw ?     ;0x40
  269.                       dw ?     ;0x42
  270.                       dw ?     ;0x44
  271.                       dw ?     ;0x46
  272.                       dw ?     ;0x48
  273.                       dw ?     ;0x4A
  274.                       dw ?     ;0x4C
  275.                       dw ?     ;0x4E
  276.                       dw ?     ;0x50
  277.                       dw ?     ;0x52
  278.                       dw ?     ;0x54
  279.                       dw ?     ;0x56
  280.                       dw ?     ;0x58
  281.                       dw ?     ;0x5A
  282.                       dw ?     ;0x5C
  283.                       dw ?     ;0x5E
  284.   .reg_page_0         dw ?     ;0x60
  285.   .reg_page_1         dw ?     ;0x62
  286.   .reg_page_2         dw ?     ;0x64
  287.   .reg_page_3         dw ?     ;0x66
  288.   .reg_page_4         dw ?     ;0x68
  289.   .reg_page_5         dw ?     ;0x6A
  290.   .reg_page_6         dw ?     ;0x6C
  291.   .reg_page_7         dw ?     ;0x6E
  292.                       dw ?     ;0x70
  293.                       dw ?     ;0x72
  294.                       dw ?     ;0x74
  295.                       dw ?     ;0x76
  296.                       dw ?     ;0x78
  297.                       dw ?     ;0x7A
  298.   .reg_vendor_id_1    dw ?     ;0x7C
  299.   .reg_vendor_id_2    dw ?     ;0x7E
  300.  
  301.  
  302.   .reset              dd ?    ;virual
  303.   .set_master_vol     dd ?
  304. }
  305.  
  306. struc CTRL_INFO
  307. {   .pci_cmd          dd ?
  308.     .irq              dd ?
  309.     .glob_cntrl       dd ?
  310.     .glob_sta         dd ?
  311.     .codec_io_base    dd ?
  312.     .ctrl_io_base     dd ?
  313.     .codec_mem_base   dd ?
  314.     .ctrl_mem_base    dd ?
  315.     .codec_id         dd ?
  316. }
  317.  
  318. struc IOCTL
  319. {  .handle            dd ?
  320.    .io_code           dd ?
  321.    .input             dd ?
  322.    .inp_size          dd ?
  323.    .output            dd ?
  324.    .out_size          dd ?
  325. }
  326.  
  327. virtual at 0
  328.   IOCTL IOCTL
  329. end virtual
  330.  
  331. EVENT_NOTIFY    equ 0x00000200
  332.  
  333. public START
  334. public service_proc
  335. public version
  336.  
  337. section '.flat' code readable align 16
  338.  
  339. proc START stdcall, state:dword
  340.  
  341.         cmp     [state], 1
  342.         jne     .stop
  343.  
  344.      if DEBUG
  345.         mov     esi, msgInit
  346.         call    SysMsgBoardStr
  347.      end if
  348.  
  349.         call    detect_controller
  350.         test    eax, eax
  351.         jz      .fail
  352.  
  353.      if DEBUG
  354.         mov     esi, [ctrl.vendor_ids]
  355.         call    SysMsgBoardStr
  356.         mov     esi, [ctrl.ctrl_ids]
  357.         call    SysMsgBoardStr
  358.      end if
  359.  
  360.         call    init_controller
  361.         test    eax, eax
  362.         jz      .fail
  363.  
  364.         call    init_codec
  365.         test    eax, eax
  366.         jz      .fail
  367.  
  368.         call    setup_codec
  369.  
  370.         mov     esi, msgPrimBuff
  371.         call    SysMsgBoardStr
  372.         call    create_primary_buff
  373.         mov     esi, msgDone
  374.         call    SysMsgBoardStr
  375.  
  376.   if IRQ_REMAP
  377.         pushf
  378.         cli
  379.  
  380.         mov     ebx, [ctrl.int_line]
  381.         in      al, 0xA1
  382.         mov     ah, al
  383.         in      al, 0x21
  384.         test    ebx, ebx
  385.         jz      .skip
  386.         bts     ax, bx                          ;mask old line
  387. .skip:
  388.         bts     ax, IRQ_LINE                    ;mask new ine
  389.         out     0x21, al
  390.         mov     al, ah
  391.         out     0xA1, al
  392.  
  393.         stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE      ;remap IRQ
  394.  
  395.         mov     dx, 0x4d0                       ;8259 ELCR1
  396.         in      al, dx
  397.         bts     ax, IRQ_LINE
  398.         out     dx, al                          ;set level-triggered mode
  399.         mov     [ctrl.int_line], IRQ_LINE
  400.         popf
  401.         mov     esi, msgRemap
  402.         call    SysMsgBoardStr
  403.   end if
  404.  
  405.         mov     eax, VALID_IRQ
  406.         mov     ebx, [ctrl.int_line]
  407.         mov     esi, msgInvIRQ
  408.         bt      eax, ebx
  409.         jnc     .fail_msg
  410.         mov     eax, ATTCH_IRQ
  411.         mov     esi, msgAttchIRQ
  412.         bt      eax, ebx
  413.         jnc     .fail_msg
  414.  
  415.         stdcall AttachIntHandler, ebx, ac97_irq, dword 0
  416.         stdcall create
  417.  
  418. .reg:
  419.         stdcall RegService, sz_sound_srv, service_proc
  420.         ret
  421. .fail:
  422.      if DEBUG
  423.         mov     esi, msgFail
  424.         call    SysMsgBoardStr
  425.      end if
  426.         xor     eax, eax
  427.         ret
  428. .fail_msg:
  429.         call    SysMsgBoardStr
  430.         xor     eax, eax
  431.         ret
  432. .stop:
  433.         call    stop
  434.         xor     eax, eax
  435.         ret
  436. endp
  437.  
  438. handle     equ  IOCTL.handle
  439. io_code    equ  IOCTL.io_code
  440. input      equ  IOCTL.input
  441. inp_size   equ  IOCTL.inp_size
  442. output     equ  IOCTL.output
  443. out_size   equ  IOCTL.out_size
  444.  
  445. align 4
  446. proc service_proc stdcall, ioctl:dword
  447.  
  448.         mov     edi, [ioctl]
  449.         mov     eax, [edi+io_code]
  450.  
  451.         cmp     eax, SRV_GETVERSION
  452.         jne     @F
  453.         mov     eax, [edi+output]
  454.         cmp     [edi+out_size], 4
  455.         jne     .fail
  456.  
  457.         mov     [eax], dword API_VERSION
  458.         xor     eax, eax
  459.         ret
  460. @@:
  461.         cmp     eax, DEV_PLAY
  462.         jne     @F
  463.      if DEBUG
  464.         mov     esi, msgPlay
  465.         call    SysMsgBoardStr
  466.      end if
  467.         call    play
  468.         ret
  469. @@:
  470.         cmp     eax, DEV_STOP
  471.         jne     @F
  472.      if DEBUG
  473.         mov     esi, msgStop
  474.         call    SysMsgBoardStr
  475.      end if
  476.         call    stop
  477.         ret
  478. @@:
  479.         cmp     eax, DEV_CALLBACK
  480.         jne     @F
  481.         mov     ebx, [edi+input]
  482.         stdcall set_callback, [ebx]
  483.         ret
  484. @@:
  485.         cmp     eax, DEV_SET_MASTERVOL
  486.         jne     @F
  487.         mov     eax, [edi+input]
  488.         mov     eax, [eax]
  489.         call    set_master_vol          ;eax= vol
  490.         ret
  491. @@:
  492.         cmp     eax, DEV_GET_MASTERVOL
  493.         jne     @F
  494.         mov     ebx, [edi+output]
  495.         stdcall get_master_vol, ebx
  496.         ret
  497. @@:
  498.         cmp     eax, DEV_GET_INFO
  499.         jne     @F
  500.         mov     ebx, [edi+output]
  501.         stdcall get_dev_info, ebx
  502.         ret
  503. @@:
  504. .fail:
  505.         or      eax, -1
  506.         ret
  507. endp
  508.  
  509. restore   handle
  510. restore   io_code
  511. restore   input
  512. restore   inp_size
  513. restore   output
  514. restore   out_size
  515.  
  516.  
  517. align 4
  518. proc ac97_irq
  519.            locals
  520.              status dd 0
  521.            endl
  522.  
  523. ;        status = inl(chip->port + IPR);
  524.         mov     edx, IPR
  525.         call    [ctrl.ctrl_read32]
  526.         test    eax, eax
  527.         jz      @f
  528.  
  529.         mov     dword [status], eax
  530.  
  531.         mov     ebx, dword [buff_list]
  532.         cmp     [ctrl.user_callback], 0
  533.         je      @f
  534.         stdcall [ctrl.user_callback], ebx
  535.        @@:
  536.         mov     eax, dword [status]               ;; ack ;;
  537.         mov     edx, IPR
  538.         call    [ctrl.ctrl_write32]
  539.         ret
  540. endp
  541.  
  542.  
  543. align 4
  544. proc create_primary_buff
  545.  
  546.         stdcall KernelAlloc, 0x10000
  547.         mov     [ctrl.buffer], eax
  548.  
  549.         mov     edi, eax
  550.         mov     ecx, 0x10000/4
  551.         xor     eax, eax
  552.         cld
  553.         rep stosd
  554.  
  555.         mov     eax, [ctrl.buffer]
  556.         call    GetPgAddr
  557.  
  558.         mov     edi, pcmout_bdl
  559.         stosd
  560.         mov     eax, 0x4000000
  561.         stosd
  562.  
  563.         mov     edi, buff_list
  564.         mov     eax, [ctrl.buffer]
  565.         stosd                        ;1.]
  566.  
  567.         mov     eax, [ctrl.buffer]
  568.         call    GetPgAddr
  569.  
  570.         stdcall ptr_write, PLAYBACK_POINTER, 0, 0
  571.         stdcall ptr_write, PLAYBACK_UNKNOWN1, 0, 0
  572.         stdcall ptr_write, PLAYBACK_UNKNOWN2, 0, 0
  573.         stdcall ptr_write, PLAYBACK_DMA_ADDR, 0, eax
  574.  
  575.         mov     eax, pcmout_bdl
  576.         mov     ebx, eax
  577.         call    GetPgAddr
  578.         and     ebx, 0xFFF
  579.         add     eax, ebx
  580.  
  581.         stdcall ptr_write, PLAYBACK_LIST_ADDR, 0, eax
  582.         stdcall ptr_write, PLAYBACK_LIST_SIZE, 0, 0
  583.         stdcall ptr_write, PLAYBACK_LIST_PTR, 0, 0
  584.  
  585.            ;mov     eax, 0x00004000
  586.            ;shl     eax, 16
  587.         stdcall ptr_write, PLAYBACK_PERIOD_SIZE, 0, 0x40000000    ;eax
  588.  
  589.         ret
  590. endp
  591.  
  592.  
  593. align 4
  594. proc detect_controller
  595.            locals
  596.              last_bus dd ?
  597.              bus      dd ?
  598.              devfn    dd ?
  599.            endl
  600.  
  601.         xor     eax, eax
  602.         mov     [bus], eax
  603.         inc     eax
  604.         call    PciApi
  605.         cmp     eax, -1
  606.         je      .err
  607.  
  608.         mov     [last_bus], eax
  609.  
  610. .next_bus:
  611.         and     [devfn], 0
  612. .next_dev:
  613.         stdcall PciRead32, [bus], [devfn], dword 0
  614.         test    eax, eax
  615.         jz      .next
  616.         cmp     eax, -1
  617.         je      .next
  618.  
  619.         mov     edi, devices
  620. @@:
  621.         mov     ebx, [edi]
  622.         test    ebx, ebx
  623.         jz      .next
  624.  
  625.         cmp     eax, ebx
  626.         je      .found
  627.         add     edi, 12
  628.         jmp     @B
  629. .next:
  630.         inc     [devfn]
  631.         cmp     [devfn], 256
  632.         jb      .next_dev
  633.         mov     eax, [bus]
  634.         inc     eax
  635.         mov     [bus], eax
  636.         cmp     eax, [last_bus]
  637.         jna     .next_bus
  638.         xor     eax, eax
  639.         ret
  640. .found:
  641.         mov     ebx, [bus]
  642.         mov     [ctrl.bus], ebx
  643.  
  644.         mov     ecx, [devfn]
  645.         mov     [ctrl.devfn], ecx
  646.  
  647.         mov     edx, eax
  648.         and     edx, 0xFFFF
  649.         mov     [ctrl.vendor], edx
  650.         shr     eax, 16
  651.         mov     [ctrl.dev_id], eax
  652.  
  653.         mov     ebx, [edi+4]
  654.         mov     [ctrl.ctrl_ids], ebx
  655.         mov     esi, [edi+8]
  656.         mov     [ctrl.ctrl_setup], esi
  657.  
  658.         cmp     edx, VID_Creative
  659.         jne     @F
  660.         mov     [ctrl.vendor_ids], msg_Creative
  661.         ret
  662. @@:
  663.  
  664. .err:
  665.         xor     eax, eax
  666.         mov     [ctrl.vendor_ids], eax    ;something  wrong ?
  667.         ret
  668. endp
  669.  
  670. align 4
  671. proc init_controller
  672.  
  673.         stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x2C
  674.         mov     esi, msgPciSubsys
  675.         call    SysMsgBoardStr
  676.         call    dword2str
  677.         call    SysMsgBoardStr
  678.  
  679.         stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
  680.         mov     ebx, eax
  681.         and     eax, 0xFFFF
  682.         mov     [ctrl.pci_cmd], eax
  683.         shr     ebx, 16
  684.         mov     [ctrl.pci_stat], ebx
  685.  
  686.         mov     esi, msgPciCmd
  687.         call    SysMsgBoardStr
  688.         call    dword2str
  689.         call    SysMsgBoardStr
  690.  
  691.         mov     esi, msgPciStat
  692.         call    SysMsgBoardStr
  693.         mov     eax, [ctrl.pci_stat]
  694.         call    dword2str
  695.         call    SysMsgBoardStr
  696.  
  697.         mov     esi, msgCtrlIsaIo
  698.         call    SysMsgBoardStr
  699.         stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
  700.         call    dword2str
  701.         call    SysMsgBoardStr
  702.  
  703.         and     eax, 0xFFC0
  704.         mov     [ctrl.ctrl_io_base], eax
  705.  
  706. .default:
  707.         stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
  708.         and     eax, 0xFF
  709. @@:
  710.         mov     [ctrl.int_line], eax
  711.  
  712.         call    [ctrl.ctrl_setup]
  713.         xor     eax, eax
  714.         inc     eax
  715.         ret
  716. endp
  717.  
  718. align 4
  719. proc set_Creative
  720.         mov     [ctrl.codec_read16], codec_io_r16         ;virtual
  721.         mov     [ctrl.codec_write16], codec_io_w16        ;virtual
  722.  
  723.         mov     [ctrl.ctrl_read8 ], ctrl_io_r8            ;virtual
  724.         mov     [ctrl.ctrl_read16], ctrl_io_r16           ;virtual
  725.         mov     [ctrl.ctrl_read32], ctrl_io_r32           ;virtual
  726.  
  727.         mov     [ctrl.ctrl_write8 ], ctrl_io_w8           ;virtual
  728.         mov     [ctrl.ctrl_write16], ctrl_io_w16          ;virtual
  729.         mov     [ctrl.ctrl_write32], ctrl_io_w32          ;virtual
  730.         ret
  731. endp
  732.  
  733.  
  734. align 4
  735. proc init_codec
  736.         call    reset_codec
  737.         test    eax, eax
  738.         jz      .err
  739.         call    detect_codec
  740.         xor     eax, eax
  741.         inc     eax
  742.         ret
  743.      .err:
  744.         xor     eax, eax
  745.         ret
  746. endp
  747.  
  748. align 4
  749. proc reset_codec
  750.            locals
  751.              counter dd ?
  752.            endl
  753.  
  754.      if DEBUG
  755.         mov     esi, msgCold
  756.         call    SysMsgBoardStr
  757.      end if
  758.  
  759.         mov     eax, 100000         ; wait 100 ms ;400000     ; wait 400 ms
  760.         call    StallExec
  761.  
  762.         stdcall ptr_read, TRIGGER_CHANNEL, 0
  763.  
  764.         mov     [counter], 16        ; total 20*100 ms = 2s
  765. .wait:
  766.         stdcall codec_read, dword 0x26
  767.         test    eax, 1
  768.         jnz     .ok
  769.  
  770.         mov     eax, 100000        ; wait 100 ms
  771.         call    StallExec
  772.  
  773.         dec     [counter]
  774.         jnz     .wait
  775.  
  776.      if DEBUG
  777.         mov     esi, msgCRFail
  778.         call    SysMsgBoardStr
  779.      end if
  780.  
  781. .fail:
  782.         stc
  783.         ret
  784. .ok:
  785.  
  786.  
  787.         xor     eax, eax
  788.         inc     eax
  789.         ret
  790. endp
  791.  
  792.  
  793. align 4
  794. play:
  795.         mov     eax, INTE_CH_0_LOOP
  796.         stdcall intr_enable, eax
  797.  
  798.         stdcall ptr_read, TRIGGER_CHANNEL, 0
  799.         mov     ebx, TRIGGER_CHANNEL_0
  800.         or      eax, ebx
  801.         stdcall ptr_write, TRIGGER_CHANNEL, 0, eax
  802.  
  803.         xor     eax, eax
  804.         ret
  805.  
  806. align 4
  807. stop:
  808.         mov     eax, INTE_CH_0_LOOP or INTE_CH_0_HALF_LOOP
  809.         stdcall intr_disable, eax
  810.  
  811.         stdcall ptr_read, TRIGGER_CHANNEL, 0
  812.         mov     ebx, TRIGGER_CHANNEL_0
  813.         xor     ebx, -1
  814.         or      eax, ebx
  815.         stdcall ptr_write, TRIGGER_CHANNEL, 0, eax
  816.         xor     eax, eax
  817.         ret
  818.  
  819. align 4
  820. proc get_dev_info stdcall, p_info:dword
  821.            virtual at esi
  822.              CTRL_INFO CTRL_INFO
  823.            end virtual
  824.  
  825.         mov     esi, [p_info]
  826.         mov     eax, [ctrl.int_line]
  827.         mov     ecx, [ctrl.ctrl_io_base]
  828.         mov     [CTRL_INFO.irq], eax
  829.         mov     [CTRL_INFO.ctrl_io_base], ecx
  830.         mov     eax, [codec.chip_id]
  831.         mov     [CTRL_INFO.codec_id], eax
  832.         mov     ebx, [ctrl.pci_cmd]
  833.         mov     [CTRL_INFO.pci_cmd], ebx
  834.  
  835.         xor     eax, eax
  836.         mov     [CTRL_INFO.codec_io_base], eax
  837.         mov     [CTRL_INFO.codec_mem_base], eax
  838.         mov     [CTRL_INFO.ctrl_mem_base], eax
  839.         mov     [CTRL_INFO.glob_cntrl], eax
  840.         mov     [CTRL_INFO.glob_sta], eax
  841.         ret
  842. endp
  843.  
  844. align 4
  845. proc set_callback stdcall, handler:dword
  846.         mov     eax, [handler]
  847.         mov     [ctrl.user_callback], eax
  848.         ret
  849. endp
  850.  
  851.  
  852. align 4
  853. proc create stdcall
  854.         stdcall PciRead16, [ctrl.bus], [ctrl.devfn], dword 4
  855.         test    eax, 4     ; test master bit
  856.         jnz     @f
  857.         or      eax, 4
  858.         stdcall PciWrite16, [ctrl.bus], [ctrl.devfn], dword 4, eax     ; set master bit
  859.          @@:
  860.  
  861.         xor     eax, eax
  862.         mov     edx, INTE
  863.         call    [ctrl.ctrl_write32]
  864.  
  865.         stdcall ptr_write, SPCS0, 0, \
  866.                 SPCS_CLKACCY_1000PPM or SPCS_SAMPLERATE_48 or \
  867.                 SPCS_CHANNELNUM_LEFT or SPCS_SOURCENUM_UNSPEC or \
  868.                 SPCS_GENERATIONSTATUS or 0x00001200 or \
  869.                 0x00000000 or SPCS_EMPHASIS_NONE or SPCS_COPYRIGHT
  870.         stdcall ptr_write, SPCS1, 0, \
  871.                 SPCS_CLKACCY_1000PPM or SPCS_SAMPLERATE_48 or \
  872.                 SPCS_CHANNELNUM_LEFT or SPCS_SOURCENUM_UNSPEC or \
  873.                 SPCS_GENERATIONSTATUS or 0x00001200 or \
  874.                 0x00000000 or SPCS_EMPHASIS_NONE or SPCS_COPYRIGHT
  875.         stdcall ptr_write, SPCS2, 0, \
  876.                 SPCS_CLKACCY_1000PPM or SPCS_SAMPLERATE_48 or \
  877.                 SPCS_CHANNELNUM_LEFT or SPCS_SOURCENUM_UNSPEC or \
  878.                 SPCS_GENERATIONSTATUS or 0x00001200 or \
  879.                 0x00000000 or SPCS_EMPHASIS_NONE or SPCS_COPYRIGHT
  880.  
  881.         stdcall ptr_write, SPDIF_SELECT, 0, 0x700      ; disable SPDIF
  882.         stdcall ptr_write, ROUTING, 0, 0x1003F         ; routing
  883.         stdcall gpio_write, 0x1080                     ; analog mode
  884.  
  885.         mov     eax, dword HCFG_LOCKSOUNDCACHE or HCFG_AUDIOENABLE
  886.         mov     edx, HCFG
  887.         call    [ctrl.ctrl_write32]
  888.         ret
  889. endp
  890.  
  891. align 4
  892. proc codec_read stdcall, reg:dword
  893.         stdcall ac97_read, dword [reg]
  894.         ret
  895. endp
  896.  
  897.  
  898. align 4
  899. proc codec_write stdcall, reg:dword
  900.         stdcall ac97_write, dword [reg], eax
  901.         ret
  902. endp
  903.  
  904.  
  905. align 4
  906. proc ac97_read stdcall, reg:dword
  907.         push    edx
  908.         mov     eax, dword [reg]
  909.         mov     edx, AC97ADDRESS
  910.         call    [ctrl.ctrl_write8]
  911.  
  912.         mov     edx, AC97DATA
  913.         call    [ctrl.ctrl_read16]
  914.         and     eax, 0xFFFF
  915.         pop     edx
  916.         ret
  917. endp
  918.  
  919. align 4
  920. proc ac97_write stdcall, reg:dword, val:dword
  921.         push    eax edx
  922.         mov     eax, dword [reg]
  923.         mov     edx, AC97ADDRESS
  924.         call    [ctrl.ctrl_write8]
  925.  
  926.         mov     eax, dword [val]
  927.         mov     edx, AC97DATA
  928.         call    [ctrl.ctrl_write16]
  929.         pop     edx eax
  930.         ret
  931. endp
  932.  
  933. align 4
  934. proc ptr_read stdcall, reg:dword, chn:dword
  935.         push    edx
  936.         mov     eax, dword [reg]
  937.         shl     eax, 16
  938.         or      eax, dword [chn]
  939.  
  940.         mov     edx, PTR
  941.         call    [ctrl.ctrl_write32]
  942.  
  943.         mov     edx, DATA
  944.         call    [ctrl.ctrl_read32]
  945.         pop     edx
  946.         ret
  947. endp
  948.  
  949. align 4
  950. proc ptr_write stdcall, reg:dword, chn:dword, data:dword
  951.         push    eax edx
  952.         mov     eax, dword [reg]
  953.         shl     eax, 16
  954.         or      eax, dword [chn]
  955.  
  956.         mov     edx, PTR
  957.         call    [ctrl.ctrl_write32]
  958.  
  959.         mov     eax, dword [data]
  960.         mov     edx, DATA
  961.         call    [ctrl.ctrl_write32]
  962.         pop     edx eax
  963.         ret
  964. endp
  965.  
  966. align 4
  967. proc intr_enable stdcall, intrenb:dword
  968.         push    edx
  969.         mov     edx, INTE
  970.         call    [ctrl.ctrl_read32]
  971.  
  972.         or      eax, dword [intrenb]
  973.         mov     edx, INTE
  974.         call    [ctrl.ctrl_write32]
  975.         pop     edx
  976.         ret
  977. endp
  978.  
  979. align 4
  980. proc intr_disable stdcall, intrenb:dword
  981.         push    eax ebx edx
  982.         mov     edx, INTE
  983.         call    [ctrl.ctrl_read32]
  984.  
  985.         mov     ebx, dword [intrenb]
  986.         xor     ebx, -1
  987.         and     eax, ebx
  988.         mov     edx, INTE
  989.         call    [ctrl.ctrl_write32]
  990.         pop     edx ebx eax
  991.         ret
  992. endp
  993.  
  994. align 4
  995. proc gpio_write stdcall, value:dword
  996.         push    eax edx
  997.         mov     eax, dword [value]
  998.         mov     edx, GPIO
  999.         call    [ctrl.ctrl_write32]
  1000.         pop     edx eax
  1001.         ret
  1002. endp
  1003.  
  1004.  
  1005. align 4
  1006. proc StallExec
  1007.         push    ecx
  1008.         push    edx
  1009.         push    ebx
  1010.         push    eax
  1011.  
  1012.         mov     ecx, CPU_FREQ
  1013.         mul     ecx
  1014.         mov     ebx, eax           ;low
  1015.         mov     ecx, edx           ;high
  1016.         rdtsc
  1017.         add     ebx, eax
  1018.         adc     ecx, edx
  1019. @@:
  1020.         rdtsc
  1021.         sub     eax, ebx
  1022.         sbb     edx, ecx
  1023.         js      @B
  1024.  
  1025.         pop     eax
  1026.         pop     ebx
  1027.         pop     edx
  1028.         pop     ecx
  1029.         ret
  1030. endp
  1031.  
  1032. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1033. ;          CONTROLLER IO functions
  1034. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1035.  
  1036. align 4
  1037. proc codec_io_r16 ;Not used.
  1038.            ;mov      edx, [ctrl.ctrl_io_base]
  1039.            ;in       eax, dx
  1040.         ret
  1041. endp
  1042.  
  1043. align 4
  1044. proc codec_io_w16 ;Not used.
  1045.            ;mov      edx, [ctrl.ctrl_io_base]
  1046.            ;out      dx,  eax
  1047.         ret
  1048. endp
  1049.  
  1050. align 4
  1051. proc ctrl_io_r8
  1052.         add     edx, [ctrl.ctrl_io_base]
  1053.         in      al, dx
  1054.         ret
  1055. endp
  1056.  
  1057. align 4
  1058. proc ctrl_io_r16
  1059.         add     edx, [ctrl.ctrl_io_base]
  1060.         in      ax, dx
  1061.         ret
  1062. endp
  1063.  
  1064. align 4
  1065. proc ctrl_io_r32
  1066.         add     edx, [ctrl.ctrl_io_base]
  1067.         in      eax, dx
  1068.         ret
  1069. endp
  1070.  
  1071. align 4
  1072. proc ctrl_io_w8
  1073.         add     edx, [ctrl.ctrl_io_base]
  1074.         out     dx, al
  1075.         ret
  1076. endp
  1077.  
  1078. align 4
  1079. proc ctrl_io_w16
  1080.         add     edx, [ctrl.ctrl_io_base]
  1081.         out     dx, ax
  1082.         ret
  1083. endp
  1084.  
  1085. align 4
  1086. proc ctrl_io_w32
  1087.         add     edx, [ctrl.ctrl_io_base]
  1088.         out     dx, eax
  1089.         ret
  1090. endp
  1091.  
  1092.  
  1093. align 4
  1094. dword2str:
  1095.         push    eax ebx ecx
  1096.         mov     esi, hex_buff
  1097.         mov     ecx, -8
  1098.    @@:
  1099.         rol     eax, 4
  1100.         mov     ebx, eax
  1101.         and     ebx, 0x0F
  1102.         mov     bl, [ebx+hexletters]
  1103.         mov     [8+esi+ecx], bl
  1104.         inc     ecx
  1105.         jnz     @B
  1106.         pop     ecx ebx eax
  1107.         ret
  1108.  
  1109. hexletters   db '0123456789ABCDEF'
  1110. hex_buff     db 8 dup(0),13,10,0
  1111.  
  1112.  
  1113. include "codec.inc"
  1114.  
  1115. align 4
  1116. devices dd (CTRL_CT0200 shl 16)+VID_Creative,msg_CT_EMU10K1X,set_Creative
  1117.         dd 0    ;terminator
  1118.  
  1119.  
  1120. version      dd (5 shl 16) or (API_VERSION and 0xFFFF)
  1121.  
  1122. msg_CT_EMU10K1X  db 'SB Live! Dell OEM', 13,10, 0
  1123. msg_Creative     db 'Creative ', 0
  1124.  
  1125. szKernel            db 'KERNEL', 0
  1126. sz_sound_srv        db 'SOUND',0
  1127.  
  1128. msgInit      db 'detect hardware...',13,10,0
  1129. msgFail      db 'device not found',13,10,0
  1130. msgAttchIRQ  db 'IRQ line not supported', 13,10, 0
  1131. msgInvIRQ    db 'IRQ line not assigned or invalid', 13,10, 0
  1132. msgPlay      db 'start play', 13,10,0
  1133. msgStop      db 'stop play',  13,10,0
  1134. msgIRQ       db 'AC97 IRQ', 13,10,0
  1135. ;msgInitCtrl  db 'init controller',13,10,0
  1136. ;msgInitCodec db 'init codec',13,10,0
  1137. msgPrimBuff  db 'create primary buffer ...',0
  1138. msgDone      db 'done',13,10,0
  1139. msgRemap     db 'Remap IRQ',13,10,0
  1140. ;msgReg       db 'set service handler',13,10,0
  1141. ;msgOk        db 'service installed',13,10,0
  1142. msgCold      db 'cold reset',13,10,0
  1143. ;msgWarm      db 'warm reset',13,10,0
  1144. ;msgWRFail    db 'warm reset failed',13,10,0
  1145. msgCRFail    db 'cold reset failed',13,10,0
  1146. ;msgCFail     db 'codec not ready',13,10,0
  1147. ;msgCInvalid  db 'codec is not valid',13,10,0 ;Asper
  1148. ;msgResetOk   db 'reset complete',13,10,0
  1149. ;msgStatus    db 'global status   ',0
  1150. ;msgControl   db 'global control  ',0
  1151. msgPciCmd    db 'PCI command     ',0
  1152. msgPciStat   db 'PCI status      ',0
  1153. msgPciSubsys db 'PCI subsystem   ',0
  1154. msgCtrlIsaIo db 'controller io base   ',0
  1155. ;msgMixIsaIo  db 'codec io base        ',0
  1156. ;msgCtrlMMIo  db 'controller mmio base ',0
  1157. ;msgMixMMIo   db 'codec mmio base      ',0
  1158. ;msgIrqMap    db 'AC97 irq map as      ',0
  1159.  
  1160. section '.data' data readable writable align 16
  1161.  
  1162. pcmout_bdl       rq 32
  1163. buff_list        rd 32
  1164.  
  1165. codec CODEC
  1166. ctrl AC_CNTRL
  1167.