Subversion Repositories Kolibri OS

Rev

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

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