Subversion Repositories Kolibri OS

Rev

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