Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. ;alpha version
  9.  
  10. format MS COFF
  11.  
  12.  
  13. include 'proc32.inc'
  14. include 'imports.inc'
  15.  
  16. DEBUG       equ 1
  17.  
  18. REMAP_IRQ   equ 0
  19.  
  20. ;irq 0,1,2,8,12,13 эхфюёЄєяэ√
  21. ;               FEDCBA9876543210
  22. VALID_IRQ   equ 1100111011111000b
  23. ATTCH_IRQ   equ 0000111010101000b
  24.  
  25. IRQ_LINE   equ 0
  26.  
  27. CPU_FREQ   equ  2600d
  28.  
  29. BIT0 EQU 0x00000001
  30. BIT1 EQU 0x00000002
  31. BIT2 EQU 0x00000004
  32. BIT3 EQU 0x00000008
  33. BIT4 EQU 0x00000010
  34. BIT5 EQU 0x00000020
  35. BIT6 EQU 0x00000040
  36. BIT7 EQU 0x00000080
  37. BIT8 EQU 0x00000100
  38. BIT9 EQU 0x00000200
  39. BIT10 EQU 0x00000400
  40. BIT11 EQU 0x00000800
  41. BIT12 EQU 0x00001000
  42. BIT13 EQU 0x00002000
  43. BIT14 EQU 0x00004000
  44. BIT15 EQU 0x00008000
  45. BIT16 EQU 0x00010000
  46. BIT17 EQU 0x00020000
  47. BIT18 EQU 0x00040000
  48. BIT19 EQU 0x00080000
  49. BIT20 EQU 0x00100000
  50. BIT21 EQU 0x00200000
  51. BIT22 EQU 0x00400000
  52. BIT23 EQU 0x00800000
  53. BIT24 EQU 0x00100000
  54. BIT25 EQU 0x02000000
  55. BIT26 EQU 0x04000000
  56. BIT27 EQU 0x08000000
  57. BIT28 EQU 0x10000000
  58. BIT29 EQU 0x20000000
  59. BIT30 EQU 0x40000000
  60. BIT31 EQU 0x80000000
  61.  
  62.  
  63. PCM_OUT_BDL       equ  0x10      ; PCM out buffer descriptors list
  64. PCM_OUT_CR_REG    equ  0x1b      ; PCM out Control Register
  65. PCM_OUT_LVI_REG   equ  0x15      ; PCM last valid index
  66. PCM_OUT_SR_REG    equ  0x16      ; PCM out Status register
  67. PCM_OUT_PIV_REG   equ  0x1a
  68. PCM_OUT_CIV_REG   equ  0x14      ; PCM out current index
  69.  
  70. PCM_IN_CR_REG     equ  0x0b      ; PCM in Control Register
  71. MC_IN_CR_REG      equ  0x2b      ; MIC in Control Register
  72. RR                equ  BIT1      ; reset registers.  Nukes all regs
  73.  
  74. CODEC_MASTER_VOL_REG            equ     0x02
  75. CODEC_AUX_VOL                   equ     0x04    ;
  76. CODEC_PCM_OUT_REG               equ     18h     ; PCM output volume
  77. CODEC_EXT_AUDIO_REG             equ     28h     ; extended audio
  78. CODEC_EXT_AUDIO_CTRL_REG        equ     2ah     ; extended audio control
  79. CODEC_PCM_FRONT_DACRATE_REG     equ     2ch     ; PCM out sample rate
  80. CODEC_PCM_SURND_DACRATE_REG     equ     2eh     ; surround sound sample rate
  81. CODEC_PCM_LFE_DACRATE_REG       equ     30h     ; LFE sample rate
  82.  
  83. GLOB_CTRL     equ  0x2C        ;   Global Control
  84. CTRL_STAT       equ  0x30        ;   Global Status
  85. CTRL_CAS        equ  0x34        ;   Codec Access Semiphore
  86.  
  87. CAS_FLAG        equ  0x01        ;   Codec Access Semiphore Bit
  88.  
  89. CTRL_ST_CREADY  equ  BIT8+BIT9+BIT28 ;   Primary Codec Ready
  90.  
  91. CTRL_ST_RCS     equ  0x00008000  ;   Read Completion Status
  92.  
  93. CTRL_CNT_CRIE   equ  BIT4+BIT5+BIT6  ;   Codecs Resume Interrupt Enable
  94. CTRL_CNT_AC_OFF equ  0x00000008  ;   ACLINK Off
  95. CTRL_CNT_WARM   equ  0x00000004  ;   AC97 Warm Reset
  96. CTRL_CNT_COLD   equ  0x00000002  ;   AC97 Cold Reset
  97. CTRL_CNT_GIE    equ  0x00000001  ;   GPI Interrupt Enable
  98.  
  99. CODEC_REG_POWERDOWN   equ 0x26
  100. CODEC_REG_ST          equ 0x26
  101.  
  102. DEV_PLAY              equ  1
  103. DEV_STOP              equ  2
  104. DEV_CALLBACK          equ  3
  105. DEV_SET_BUFF          equ  4
  106. DEV_NOTIFY            equ  5
  107. DEV_SET_MASTERVOL     equ  6
  108. DEV_GET_MASTERVOL     equ  7
  109. DEV_GET_INFO          equ  8
  110.  
  111. struc AC_CNTRL              ;AC controller base class
  112. { .bus                dd ?
  113.   .devfn              dd ?
  114.  
  115.   .vendor             dd ?
  116.   .dev_id             dd ?
  117.   .pci_cmd            dd ?
  118.   .pci_stat           dd ?
  119.  
  120.   .codec_io_base      dd ?
  121.   .codec_mem_base     dd ?
  122.  
  123.   .ctrl_io_base       dd ?
  124.   .ctrl_mem_base      dd ?
  125.   .cfg_reg            dd ?
  126.   .int_line           dd ?
  127.  
  128.   .vendor_ids         dd ?    ;vendor id string
  129.   .ctrl_ids           dd ?    ;hub id string
  130.  
  131.   .buffer             dd ?
  132.  
  133.   .notify_pos         dd ?
  134.   .notify_task        dd ?
  135.  
  136.   .lvi_reg            dd ?
  137.   .ctrl_setup         dd ?
  138.   .user_callback      dd ?
  139.   .codec_read16       dd ?
  140.   .codec_write16      dd ?
  141.  
  142.   .ctrl_read8         dd ?
  143.   .ctrl_read16        dd ?
  144.   .ctrl_read32        dd ?
  145.  
  146.   .ctrl_write8        dd ?
  147.   .ctrl_write16       dd ?
  148.   .ctrl_write32       dd ?
  149. }
  150.  
  151. struc CODEC                ;Audio Chip base class
  152. {
  153.   .chip_id            dd ?
  154.   .flags              dd ?
  155.   .status             dd ?
  156.  
  157.   .ac_vendor_ids      dd ?    ;ac vendor id string
  158.   .chip_ids           dd ?    ;chip model string
  159.  
  160.   .shadow_flag        dd ?
  161.                       dd ?
  162.  
  163.   .regs               dw ?     ; codec registers
  164.   .reg_master_vol     dw ?     ;0x02
  165.   .reg_aux_out_vol    dw ?     ;0x04
  166.   .reg_mone_vol       dw ?     ;0x06
  167.   .reg_master_tone    dw ?     ;0x08
  168.   .reg_beep_vol       dw ?     ;0x0A
  169.   .reg_phone_vol      dw ?     ;0x0C
  170.   .reg_mic_vol        dw ?     ;0x0E
  171.   .reg_line_in_vol    dw ?     ;0x10
  172.   .reg_cd_vol         dw ?     ;0x12
  173.   .reg_video_vol      dw ?     ;0x14
  174.   .reg_aux_in_vol     dw ?     ;0x16
  175.   .reg_pcm_out_vol    dw ?     ;0x18
  176.   .reg_rec_select     dw ?     ;0x1A
  177.   .reg_rec_gain       dw ?     ;0x1C
  178.   .reg_rec_gain_mic   dw ?     ;0x1E
  179.   .reg_gen            dw ?     ;0x20
  180.   .reg_3d_ctrl        dw ?     ;0X22
  181.   .reg_page           dw ?     ;0X24
  182.   .reg_powerdown      dw ?     ;0x26
  183.   .reg_ext_audio      dw ?     ;0x28
  184.   .reg_ext_st         dw ?     ;0x2a
  185.   .reg_pcm_front_rate dw ?     ;0x2c
  186.   .reg_pcm_surr_rate  dw ?     ;0x2e
  187.   .reg_lfe_rate       dw ?     ;0x30
  188.   .reg_pcm_in_rate    dw ?     ;0x32
  189.                       dw ?     ;0x34
  190.   .reg_cent_lfe_vol   dw ?     ;0x36
  191.   .reg_surr_vol       dw ?     ;0x38
  192.   .reg_spdif_ctrl     dw ?     ;0x3A
  193.                       dw ?     ;0x3C
  194.                       dw ?     ;0x3E
  195.                       dw ?     ;0x40
  196.                       dw ?     ;0x42
  197.                       dw ?     ;0x44
  198.                       dw ?     ;0x46
  199.                       dw ?     ;0x48
  200.                       dw ?     ;0x4A
  201.                       dw ?     ;0x4C
  202.                       dw ?     ;0x4E
  203.                       dw ?     ;0x50
  204.                       dw ?     ;0x52
  205.                       dw ?     ;0x54
  206.                       dw ?     ;0x56
  207.                       dw ?     ;0x58
  208.                       dw ?     ;0x5A
  209.                       dw ?     ;0x5C
  210.                       dw ?     ;0x5E
  211.   .reg_page_0         dw ?     ;0x60
  212.   .reg_page_1         dw ?     ;0x62
  213.   .reg_page_2         dw ?     ;0x64
  214.   .reg_page_3         dw ?     ;0x66
  215.   .reg_page_4         dw ?     ;0x68
  216.   .reg_page_5         dw ?     ;0x6A
  217.   .reg_page_6         dw ?     ;0x6C
  218.   .reg_page_7         dw ?     ;0x6E
  219.                       dw ?     ;0x70
  220.                       dw ?     ;0x72
  221.                       dw ?     ;0x74
  222.                       dw ?     ;0x76
  223.                       dw ?     ;0x78
  224.                       dw ?     ;0x7A
  225.   .reg_vendor_id_1    dw ?     ;0x7C
  226.   .reg_vendor_id_2    dw ?     ;0x7E
  227.  
  228.  
  229.   .reset              dd ?    ;virual
  230.   .set_master_vol     dd ?
  231. }
  232.  
  233. struc CTRL_INFO
  234. {   .pci_cmd        dd  ?
  235.     .irq            dd  ?
  236.     .glob_cntrl     dd  ?
  237.     .glob_sta       dd  ?
  238.     .codec_io_base  dd  ?
  239.     .ctrl_io_base   dd  ?
  240.     .codec_mem_base dd  ?
  241.     .ctrl_mem_base  dd  ?
  242.     .codec_id       dd  ?
  243. }
  244.  
  245. struc IOCTL
  246. {  .handle           dd ?
  247.    .io_code          dd ?
  248.    .input            dd ?
  249.    .inp_size         dd ?
  250.    .output           dd ?
  251.    .out_size         dd ?
  252. }
  253.  
  254. virtual at 0
  255.   IOCTL IOCTL
  256. end virtual
  257.  
  258. EVENT_NOTIFY          equ 0x00000200
  259.  
  260. OS_BASE         equ 0;
  261. SLOT_BASE       equ OS_BASE+0x0080000
  262. new_app_base   equ 0x80000000
  263.  
  264. public START
  265. public service_proc
  266. public version
  267.  
  268. section '.flat' code readable align 16
  269.  
  270. proc START stdcall, state:dword
  271.  
  272.            cmp [state], 1
  273.            jne .stop
  274.  
  275.      if DEBUG
  276.            mov esi, msgDetect
  277.            call SysMsgBoardStr
  278.      end if
  279.  
  280.            call detect_controller
  281.            test eax, eax
  282.            jz .fail
  283.  
  284.      if DEBUG
  285.            mov esi,[ctrl.vendor_ids]
  286.            call SysMsgBoardStr
  287.            mov   esi, [ctrl.ctrl_ids]
  288.            call SysMsgBoardStr
  289.  
  290.      end if
  291.            call init_controller
  292.            test eax, eax
  293.            jz .fail
  294.  
  295.            jmp .fail      ;force fail
  296.  
  297.      if DEBUG
  298.            mov esi, msgInitCodec
  299.            call SysMsgBoardStr
  300.      end if
  301.  
  302.            call init_codec
  303.            test eax, eax
  304.            jz .fail
  305.  
  306.      if DEBUG
  307.            mov esi, [codec.ac_vendor_ids]
  308.            call SysMsgBoardStr
  309.  
  310.            mov esi, [codec.chip_ids]
  311.            call SysMsgBoardStr
  312.      end if
  313.  
  314.            call reset_controller
  315.            call setup_codec
  316.  
  317.            mov esi, msgPrimBuff
  318.            call SysMsgBoardStr
  319.  
  320.            call create_primary_buff
  321.  
  322.            mov eax, VALID_IRQ
  323.            mov ebx, [ctrl.int_line]
  324.            mov esi, msgInvIRQ
  325.            bt eax, ebx
  326.            jnc .fail
  327.            mov eax, ATTCH_IRQ
  328.            mov esi, msgAttchIRQ
  329.            bt eax, ebx
  330.            jnc .fail
  331.  
  332.            stdcall AttachIntHandler, ebx, ac97_irq
  333.            stdcall RegService, sz_sound_srv, service_proc
  334.            ret
  335. .fail:
  336.      if DEBUG
  337.            mov esi, msgFail
  338.            call SysMsgBoardStr
  339.      end if
  340.            xor eax, eax
  341.            ret
  342. .stop:
  343.            call stop
  344.            xor eax, eax
  345.            ret
  346. endp
  347.  
  348. handle     equ  IOCTL.handle
  349. io_code   equ  IOCTL.io_code
  350. input     equ  IOCTL.input
  351. inp_size   equ  IOCTL.inp_size
  352. output     equ  IOCTL.output
  353. out_size   equ  IOCTL.out_size
  354.  
  355. align 4
  356. proc service_proc stdcall, ioctl:dword
  357.  
  358.            mov edi, [ioctl]
  359.            mov eax, [edi+io_code]
  360.            cmp eax, DEV_PLAY
  361.            jne @F
  362.      if DEBUG
  363.            mov esi, msgPlay
  364.            call SysMsgBoardStr
  365.      end if
  366.            call play
  367.            ret
  368. @@:
  369.            cmp eax, DEV_STOP
  370.            jne @F
  371.      if DEBUG
  372.            mov esi, msgStop
  373.            call SysMsgBoardStr
  374.      end if
  375.            call stop
  376.            ret
  377. @@:
  378.            cmp eax, DEV_CALLBACK
  379.            jne @F
  380.            mov ebx, [edi+input]
  381.            stdcall set_callback, [ebx]
  382.            ret
  383. @@:
  384.            cmp eax, DEV_SET_MASTERVOL
  385.            jne @F
  386.            mov eax, [edi+input]
  387.            mov eax, [eax]
  388.            call set_master_vol      ;eax= vol
  389.            ret
  390. @@:
  391.            cmp eax, DEV_GET_MASTERVOL
  392.            jne @F
  393.            mov ebx, [edi+output]
  394.            add ebx, new_app_base
  395.            stdcall get_master_vol, ebx
  396.            ret
  397. ;@@:
  398. ;           cmp eax, DEV_GET_INFO
  399. ;           jne @F
  400. ;           mov ebx, [edi+output]
  401. ;           stdcall get_dev_info, ebx
  402. ;           ret
  403. @@:
  404. .fail:
  405.            or eax, -1
  406.            ret
  407. endp
  408.  
  409. restore   handle
  410. restore   io_code
  411. restore   input
  412. restore   inp_size
  413. restore   output
  414. restore   out_size
  415.  
  416.  
  417. align 4
  418. proc ac97_irq
  419.  
  420. ;     if DEBUG
  421. ;           mov esi, msgIRQ
  422. ;           call SysMsgBoardStr
  423. ;     end if
  424.  
  425.  
  426.            cmp [ctrl.user_callback], 0
  427.            je @f
  428.  
  429.            stdcall [ctrl.user_callback], ebx
  430. @@:
  431.            ret
  432.  
  433. .skip:
  434.            mov edx, PCM_OUT_CR_REG
  435.            mov ax, 0x11               ;0x1D
  436.            call [ctrl.ctrl_write8]
  437.            ret
  438. endp
  439.  
  440. align 4
  441. proc create_primary_buff
  442.  
  443.            stdcall KernelAlloc, 0x10000
  444.            mov [ctrl.buffer], eax
  445.  
  446.            mov edi, eax
  447.            mov ecx, 0x10000/4
  448.            xor eax, eax
  449.            cld
  450.            rep stosd
  451.  
  452.            mov eax, [ctrl.buffer]
  453.            call GetPgAddr
  454.  
  455.            mov ebx, 0xC0002000
  456.            mov ecx, 4
  457.            mov edi, pcmout_bdl
  458. @@:
  459.            mov [edi], eax
  460.            mov [edi+4], ebx
  461.  
  462.            mov [edi+32], eax
  463.            mov [edi+4+32], ebx
  464.  
  465.            mov [edi+64], eax
  466.            mov [edi+4+64], ebx
  467.  
  468.            mov [edi+96], eax
  469.            mov [edi+4+96], ebx
  470.  
  471.            mov [edi+128], eax
  472.            mov [edi+4+128], ebx
  473.  
  474.            mov [edi+160], eax
  475.            mov [edi+4+160], ebx
  476.  
  477.            mov [edi+192], eax
  478.            mov [edi+4+192], ebx
  479.  
  480.            mov [edi+224], eax
  481.            mov [edi+4+224], ebx
  482.  
  483.            add eax, 0x4000
  484.            add edi, 8
  485.            loop @B
  486.  
  487.            mov edi, buff_list
  488.            mov eax, [ctrl.buffer]
  489.            mov ecx, 4
  490. @@:
  491.            mov [edi], eax
  492.            mov [edi+16], eax
  493.            mov [edi+32], eax
  494.            mov [edi+48], eax
  495.            mov [edi+64], eax
  496.            mov [edi+80], eax
  497.            mov [edi+96], eax
  498.            mov [edi+112], eax
  499.  
  500.            add eax, 0x4000
  501.            add edi, 4
  502.            loop @B
  503.  
  504.            mov eax, pcmout_bdl
  505.            mov ebx, eax
  506.            call GetPgAddr     ;eax
  507.            and ebx, 0xFFF
  508.            add eax, ebx
  509.  
  510.            mov edx, PCM_OUT_BDL
  511.            call [ctrl.ctrl_write32]
  512.  
  513.            mov eax, 16
  514.            mov [ctrl.lvi_reg], eax
  515.            mov edx, PCM_OUT_LVI_REG
  516.            call [ctrl.ctrl_write8]
  517.            ret
  518. endp
  519.  
  520. align 4
  521. proc detect_controller
  522.          locals
  523.            last_bus dd ?
  524.            bus      dd ?
  525.            devfn    dd ?
  526.          endl
  527.  
  528.            xor eax, eax
  529.            mov [bus], eax
  530.            inc eax
  531.            call PciApi
  532.            cmp eax, -1
  533.            je .err
  534.  
  535.            mov [last_bus], eax
  536.  
  537. .next_bus:
  538.            and [devfn], 0
  539. .next_dev:
  540.            stdcall PciRead32, [bus], [devfn], dword 0
  541.            test eax, eax
  542.            jz .next
  543.            cmp eax, -1
  544.            je .next
  545.  
  546.            mov edi, devices
  547. @@:
  548.            mov ebx, [edi]
  549.            test ebx, ebx
  550.            jz .next
  551.  
  552.            cmp eax, ebx
  553.            je .found
  554.            add edi, 12
  555.            jmp @B
  556.  
  557. .next:
  558.            inc [devfn]
  559.            cmp [devfn], 256
  560.            jb  .next_dev
  561.            mov eax, [bus]
  562.            inc eax
  563.            mov [bus], eax
  564.            cmp eax, [last_bus]
  565.            jna .next_bus
  566.            xor eax, eax
  567.            ret
  568. .found:
  569.            mov ebx, [bus]
  570.            mov [ctrl.bus], ebx
  571.  
  572.            mov ecx, [devfn]
  573.            mov [ctrl.devfn], ecx
  574.  
  575.            mov edx, eax
  576.            and edx, 0xFFFF
  577.            mov [ctrl.vendor], edx
  578.            shr eax, 16
  579.            mov [ctrl.dev_id], eax
  580.  
  581.            mov ebx, [edi+4]
  582.            mov [ctrl.ctrl_ids], ebx
  583.            mov esi, [edi+8]
  584.            mov [ctrl.ctrl_setup], esi
  585.  
  586.            cmp ebx, 0x1274
  587.            jne @F
  588.            mov [ctrl.vendor_ids], msgEnsoniq
  589.            ret
  590. @@:
  591.            mov [ctrl.vendor_ids], 0     ;something  wrong ?
  592.            ret
  593. .err:
  594.            xor eax, eax
  595.            ret
  596. endp
  597.  
  598. align 4
  599. proc init_controller
  600.  
  601.            mov esi, msgPCIcmd
  602.            call SysMsgBoardStr
  603.  
  604.            stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
  605.            mov ebx, eax
  606.            and eax, 0xFFFF
  607.            mov [ctrl.pci_cmd], eax
  608.            shr ebx, 16
  609.            mov [ctrl.pci_stat], ebx
  610.  
  611.            call dword2str
  612.            call SysMsgBoardStr
  613.  
  614.            mov esi, msgIObase
  615.            call SysMsgBoardStr
  616.  
  617.            stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
  618. ;           and eax, -16
  619.            mov [ctrl.ctrl_io_base], eax
  620.  
  621.            call dword2str
  622.            call SysMsgBoardStr
  623.  
  624.            mov esi, msgIRQline
  625.            call SysMsgBoardStr
  626.  
  627.            stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
  628.            and eax, 0xFF
  629.            mov [ctrl.int_line], eax
  630.  
  631.            call dword2str
  632.            call SysMsgBoardStr
  633.  
  634.            call [ctrl.ctrl_setup]
  635.            xor eax, eax
  636.            inc eax
  637.            ret
  638. endp
  639.  
  640. align 4
  641. proc set_ICH
  642.            mov [ctrl.codec_read16],  codec_io_r16    ;virtual
  643.            mov [ctrl.codec_write16], codec_io_w16    ;virtual
  644.  
  645.            mov [ctrl.ctrl_read8 ],  ctrl_io_r8      ;virtual
  646.            mov [ctrl.ctrl_read16],  ctrl_io_r16      ;virtual
  647.            mov [ctrl.ctrl_read32],  ctrl_io_r32      ;virtual
  648.  
  649.            mov [ctrl.ctrl_write8 ], ctrl_io_w8      ;virtual
  650.            mov [ctrl.ctrl_write16], ctrl_io_w16      ;virtual
  651.            mov [ctrl.ctrl_write32], ctrl_io_w32      ;virtual
  652.            ret
  653. endp
  654.  
  655. align 4
  656. proc reset_controller
  657.  
  658.            xor eax, eax
  659.            mov edx, PCM_IN_CR_REG
  660.            call [ctrl.ctrl_write8]
  661.  
  662.            mov edx, PCM_OUT_CR_REG
  663.            call [ctrl.ctrl_write8]
  664.  
  665.            mov edx, MC_IN_CR_REG
  666.            call [ctrl.ctrl_write8]
  667.  
  668.            mov eax, RR
  669.            mov edx, PCM_IN_CR_REG
  670.            call [ctrl.ctrl_write8]
  671.  
  672.            mov edx, PCM_OUT_CR_REG
  673.            call [ctrl.ctrl_write8]
  674.  
  675.            mov edx, MC_IN_CR_REG
  676.            call [ctrl.ctrl_write8]
  677.            ret
  678. endp
  679.  
  680. align 4
  681. proc init_codec
  682.          locals
  683.            counter dd ?
  684.          endl
  685.  
  686.            mov esi, msgControl
  687.            call SysMsgBoardStr
  688.  
  689.            mov edx, GLOB_CTRL
  690.            call [ctrl.ctrl_read32]
  691.            call dword2str
  692.            call SysMsgBoardStr
  693.  
  694.            mov esi, msgStatus
  695.            call SysMsgBoardStr
  696.  
  697.            mov edx, CTRL_STAT
  698.            call [ctrl.ctrl_read32]
  699.  
  700.            call dword2str
  701.            call SysMsgBoardStr
  702.  
  703.            test eax, CTRL_ST_CREADY
  704.            jnz .ready
  705.  
  706.            call reset_codec
  707.            and eax, eax
  708.            jz .err
  709.  
  710.            xor edx, edx     ;ac_reg_0
  711.            call [ctrl.codec_write16]
  712.  
  713.            xor eax, eax
  714.            mov edx, CODEC_REG_POWERDOWN
  715.            call [ctrl.codec_write16]
  716.  
  717.            mov [counter], 200     ; total 200*5 ms = 1s
  718. .wait:
  719.            mov edx, CODEC_REG_POWERDOWN
  720.            call [ctrl.codec_read16]
  721.            and eax, 0x0F
  722.            cmp eax, 0x0F
  723.            jz .ready
  724.  
  725.            mov eax, 5000   ; wait 5 ms
  726.            call StallExec
  727.            sub [counter] , 1
  728.            jnz .wait
  729. .err:
  730.            xor eax, eax        ; timeout error
  731.            ret
  732. .ready:
  733.            call detect_codec
  734.  
  735.            xor eax, eax
  736.            inc eax
  737.            ret
  738. endp
  739.  
  740. align 4
  741. proc reset_codec
  742.            mov edx, GLOB_CTRL
  743.            call [ctrl.ctrl_read32]
  744.  
  745.            test eax, 0x02
  746.            jz .cold
  747.  
  748.            call warm_reset
  749.            jnc .ok
  750. .cold:
  751.            call cold_reset
  752.            jnc .ok
  753.  
  754.      if DEBUG
  755.            mov esi, msgCFail
  756.            call SysMsgBoardStr
  757.      end if
  758.            xor eax, eax     ; timeout error
  759.            ret
  760. .ok:
  761.      if DEBUG
  762.            mov esi, msgResetOk
  763.            call SysMsgBoardStr
  764.      end if
  765.  
  766.            xor eax, eax
  767.            inc eax
  768.            ret
  769. endp
  770.  
  771. align 4
  772. proc warm_reset
  773.            locals
  774.              counter dd ?
  775.            endl
  776.  
  777.            mov eax, 0x06
  778.            mov edx, GLOB_CTRL
  779.            call [ctrl.ctrl_write32]
  780.  
  781.      if DEBUG
  782.            mov esi, msgWarm
  783.            call SysMsgBoardStr
  784.      end if
  785.  
  786.            mov [counter], 10       ; total 10*100 ms = 1s
  787. .wait:
  788.            mov eax, 100000         ; wait 100 ms
  789.            call StallExec
  790.  
  791.            mov edx, GLOB_CTRL
  792.            call [ctrl.ctrl_read32]
  793.            test eax, 4
  794.            jz .ok
  795.            sub [counter], 1
  796.            jnz .wait
  797.  
  798.      if DEBUG
  799.            mov esi, msgWRFail
  800.            call SysMsgBoardStr
  801.      end if
  802.  
  803.            stc
  804.            ret
  805. .ok:
  806.            mov edx, CTRL_STAT
  807.            call [ctrl.ctrl_read32]
  808.            and eax, CTRL_ST_CREADY
  809.            jz .fail
  810.            clc
  811.            ret
  812. .fail:
  813.            stc
  814.            ret
  815. endp
  816.  
  817. align 4
  818. proc cold_reset
  819.            locals
  820.              counter dd ?
  821.            endl
  822.  
  823.            xor eax, eax
  824.            mov edx, GLOB_CTRL
  825.            call [ctrl.ctrl_write32]
  826.  
  827.      if DEBUG
  828.            mov esi, msgCold
  829.            call SysMsgBoardStr
  830.      end if
  831.  
  832.            mov eax, 1000000        ; wait 1 s
  833.            call StallExec
  834.  
  835.            mov eax, 2
  836.            mov edx, GLOB_CTRL
  837.            call [ctrl.ctrl_write32]
  838.  
  839.            mov [counter], 10       ; total 10*100 ms = 1s
  840. .wait:
  841.            mov eax, 100000         ; wait 100 ms
  842.            call StallExec
  843.  
  844.            mov edx, GLOB_CTRL
  845.            call [ctrl.ctrl_read32]
  846.            test eax, 4
  847.            jz .ok
  848.            sub [counter], 1
  849.            jnz .wait
  850.  
  851.      if DEBUG
  852.            mov esi, msgCRFail
  853.            call SysMsgBoardStr
  854.      end if
  855.            stc
  856.            ret
  857. .ok:
  858.            mov edx, CTRL_STAT
  859.            call [ctrl.ctrl_read32]
  860.            and eax, CTRL_ST_CREADY
  861.            jz .fail
  862.            clc
  863.            ret
  864. .fail:
  865.            stc
  866.            ret
  867. endp
  868.  
  869. align 4
  870. play:
  871.            mov eax, 16
  872.            mov [ctrl.lvi_reg], eax
  873.            mov edx, PCM_OUT_LVI_REG
  874.            call [ctrl.ctrl_write8]
  875.  
  876.            mov edx, PCM_OUT_CR_REG
  877.            mov ax, 0x1D
  878.            call [ctrl.ctrl_write8]
  879.            xor eax, eax
  880.            ret
  881.  
  882. align 4
  883. stop:
  884.            mov edx, PCM_OUT_CR_REG
  885.            mov ax, 0x0
  886.            call [ctrl.ctrl_write8]
  887.  
  888.            mov ax, 0x1c
  889.            mov edx, PCM_OUT_SR_REG
  890.            call [ctrl.ctrl_write16]
  891.            xor eax, eax
  892.            ret
  893.  
  894. align 4
  895. proc get_dev_info stdcall, p_info:dword
  896.            virtual at esi
  897.              CTRL_INFO CTRL_INFO
  898.            end virtual
  899.  
  900.            mov esi, [p_info]
  901.            mov eax, [ctrl.int_line]
  902.            mov ebx, [ctrl.codec_io_base]
  903.            mov ecx, [ctrl.ctrl_io_base]
  904.            mov edx, [ctrl.codec_mem_base]
  905.            mov edi, [ctrl.ctrl_mem_base]
  906.  
  907.            mov [CTRL_INFO.irq], eax
  908.            mov [CTRL_INFO.codec_io_base], ebx
  909.            mov [CTRL_INFO.ctrl_io_base], ecx
  910.            mov [CTRL_INFO.codec_mem_base], edx
  911.            mov [CTRL_INFO.ctrl_mem_base], edi
  912.  
  913.            mov eax, [codec.chip_id]
  914.            mov [CTRL_INFO.codec_id], eax
  915.  
  916.            mov edx, GLOB_CTRL
  917.            call [ctrl.ctrl_read32]
  918.            mov [CTRL_INFO.glob_cntrl], eax
  919.  
  920.            mov edx, CTRL_STAT
  921.            call [ctrl.ctrl_read32]
  922.            mov [CTRL_INFO.glob_sta], eax
  923.  
  924.            mov ebx, [ctrl.pci_cmd]
  925.            mov [CTRL_INFO.pci_cmd], ebx
  926.            ret
  927. endp
  928.  
  929. align 4
  930. proc set_callback stdcall, handler:dword
  931.            mov eax, [handler]
  932.            mov [ctrl.user_callback], eax
  933.            ret
  934. endp
  935.  
  936. align 4
  937. proc codec_read stdcall, ac_reg:dword      ; reg = edx, reval = eax
  938.  
  939.            mov edx, [ac_reg]
  940.  
  941.            mov ebx, edx
  942.            shr ebx, 1
  943.            bt [codec.shadow_flag], ebx
  944.            jc .use_shadow
  945.  
  946.            call [ctrl.codec_read16]  ;change edx !!!
  947.            mov ecx, eax
  948.  
  949.            mov edx, CTRL_STAT
  950.            call [ctrl.ctrl_read32]
  951.            test eax, CTRL_ST_RCS
  952.            jz .read_ok
  953.  
  954.            mov edx, CTRL_STAT
  955.            call [ctrl.ctrl_write32]
  956.            xor eax,eax
  957.            not eax              ;timeout
  958.            ret
  959. .read_ok:
  960.            mov edx, [ac_reg]
  961.            mov [codec.regs+edx], cx
  962.            bts [codec.shadow_flag], ebx
  963.            mov eax, ecx
  964.            ret
  965. .use_shadow:
  966.            movzx eax, word [codec.regs+edx]
  967.            ret
  968. endp
  969.  
  970. align 4
  971. proc codec_write stdcall, ac_reg:dword
  972.            push eax
  973.            call check_semafore
  974.            and eax, eax
  975.            jz .err
  976.            pop eax
  977.  
  978.            mov esi, [ac_reg]
  979.            mov edx, esi
  980.            call [ctrl.codec_write16]
  981.            mov [codec.regs+esi], ax
  982.            shr esi, 1
  983.            bts [codec.shadow_flag], esi
  984.            ret
  985. .err:
  986.            pop eax
  987.            ret
  988. endp
  989.  
  990. align 4
  991. proc codec_check_ready
  992.  
  993.            mov edx, CTRL_ST
  994.            call [ctrl.ctrl_read32]
  995.            and eax, CTRL_ST_CREADY
  996.            jz .not_ready
  997.  
  998.            xor eax, wax
  999.            inc eax
  1000.            ret
  1001. .not_ready:
  1002.            xor eax, eax
  1003.            ret
  1004. endp
  1005.  
  1006. align 4
  1007. proc check_semafore
  1008.            local counter:DWORD
  1009.  
  1010.            mov [counter], 100
  1011. .l1:
  1012.            mov edx, CTRL_CAS
  1013.            call [ctrl.ctrl_read8]
  1014.            and eax, CAS_FLAG
  1015.            jz .ok
  1016.  
  1017.            mov eax, 1
  1018.            call StallExec
  1019.            sub [counter], 1
  1020.            jnz .l1
  1021.            xor eax, eax
  1022.            ret
  1023. align 4
  1024. .ok:
  1025.            xor eax,eax
  1026.            inc eax
  1027.            ret
  1028. endp
  1029.  
  1030. align 4
  1031. proc StallExec
  1032.            push ecx
  1033.            push edx
  1034.            push ebx
  1035.            push eax
  1036.  
  1037.            mov ecx, CPU_FREQ
  1038.            mul ecx
  1039.            mov ebx, eax       ;low
  1040.            mov ecx, edx       ;high
  1041.            rdtsc
  1042.            add ebx, eax
  1043.            adc ecx,edx
  1044. @@:
  1045.            rdtsc
  1046.            sub eax, ebx
  1047.            sbb edx, ecx
  1048.            js @B
  1049.  
  1050.            pop eax
  1051.            pop ebx
  1052.            pop edx
  1053.            pop ecx
  1054.            ret
  1055. endp
  1056.  
  1057. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1058. ;          CONTROLLER IO functions
  1059. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1060.  
  1061. align 4
  1062. codec_io_r16:
  1063.            add edx, [ctrl.codec_io_base]
  1064.            in  ax, dx
  1065.            ret
  1066.  
  1067. align 4
  1068. codec_io_w16:
  1069.            add edx, [ctrl.codec_io_base]
  1070.            out dx, ax
  1071.            ret
  1072.  
  1073. align 4
  1074. ctrl_io_r8:
  1075.            add edx, [ctrl.ctrl_io_base]
  1076.            in  al, dx
  1077.            ret
  1078.  
  1079. align 4
  1080. ctrl_io_r16:
  1081.           add edx, [ctrl.ctrl_io_base]
  1082.           in  ax, dx
  1083.           ret
  1084.  
  1085. align 4
  1086. ctrl_io_r32:
  1087.           add edx, [ctrl.ctrl_io_base]
  1088.           in  eax, dx
  1089.           ret
  1090.  
  1091. align 4
  1092. ctrl_io_w8:
  1093.           add edx, [ctrl.ctrl_io_base]
  1094.           out dx, al
  1095.           ret
  1096.  
  1097. align 4
  1098. ctrl_io_w16:
  1099.           add edx, [ctrl.ctrl_io_base]
  1100.           out dx, ax
  1101.           ret
  1102.  
  1103. align 4
  1104. ctrl_io_w32:
  1105.           add edx, [ctrl.ctrl_io_base]
  1106.           out dx, eax
  1107.           ret
  1108.  
  1109.  
  1110. align 4
  1111. dword2str:
  1112.           mov  esi, hex_buff
  1113.           mov ecx, -8
  1114. @@:
  1115.           rol eax, 4
  1116.           mov ebx, eax
  1117.           and ebx, 0x0F
  1118.           mov bl, [ebx+hexletters]
  1119.           mov [8+esi+ecx], bl
  1120.           inc ecx
  1121.           jnz @B
  1122.           ret
  1123.  
  1124. hexletters   db '0123456789ABCDEF'
  1125. hex_buff     db 8 dup(0),13,10,0
  1126.  
  1127.  
  1128. include "codec.inc"
  1129.  
  1130. align 4
  1131. devices dd (0x5000 shl 16)+0x1274,msgEnsoniq,set_ICH
  1132.         dd (0x5880 shl 16)+0x1274,msgVibra128,set_ICH
  1133.         dd 0    ;terminator
  1134.  
  1135. version      dd 0x00040004
  1136.  
  1137. msgEnsoniq   db 'Ensonic 1371',13,10,0
  1138. msgVibra128  db 'Sound Blaster AudioPCI Vibra 128',13,10,0
  1139.  
  1140. sz_sound_srv db 'SOUND',0
  1141.  
  1142. msgDetect    db 'detect hardware...',13,10,0
  1143. msgFail      db 'device not found',13,10,0
  1144. msgAttchIRQ  db 'IRQ line not supported', 13,10, 0
  1145. msgInvIRQ    db 'IRQ line not assigned or invalid', 13,10, 0
  1146. msgPlay      db 'start play', 13,10,0
  1147. msgStop      db 'stop play',  13,10,0
  1148. msgNotify    db 'call notify',13,10,0
  1149. msgIRQ       db 'AC97 IRQ', 13,10,0
  1150. msgInitCtrl  db 'init controller',13,10,0
  1151. msgInitCodec db 'init codec',13,10,0
  1152. msgPrimBuff  db 'create primary buffer',13,10,0
  1153. msgReg       db 'set service handler',13,10,0
  1154. msgOk        db 'service installed',13,10,0
  1155. msgCold      db 'cold reset',13,10,0
  1156. msgWarm      db 'warm reset',13,10,0
  1157. msgWRFail    db 'warm reset failed',13,10,0
  1158. msgCRFail    db 'cold reset failed',13,10,0
  1159. msgCFail     db 'codec not ready',13,10,0
  1160. msgResetOk   db 'reset complete',13,10,0
  1161. msgStatus    db 'global status   ',0
  1162. msgControl   db 'global control  ',0
  1163. msgPCIcmd    db 'PCI command     ',0
  1164. msgIObase    db 'IO base         ',0
  1165. msgIRQline   db 'IRQ line        ',0
  1166.  
  1167. section '.data' data readable writable align 16
  1168.  
  1169. pcmout_bdl       rq 32
  1170. buff_list        rd 32
  1171.  
  1172. codec CODEC
  1173. ctrl AC_CNTRL
  1174.  
  1175. lpc_bus  rd 1
  1176. civ_val  rd 1
  1177.  
  1178.  
  1179.