Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. format MS COFF
  9.  
  10. DEBUG           equ 1
  11.  
  12. include 'proc32.inc'
  13. include 'imports.inc'
  14.  
  15. API_VERSION     equ 0x01000100
  16.  
  17. USE_COM_IRQ     equ 0    ;make irq 3 and irq 4 available for PCI devices
  18. IRQ_REMAP       equ 0
  19. IRQ_LINE        equ 0
  20.  
  21.  
  22. ;irq 0,1,2,8,12,13 unavailable
  23. ;                   FEDCBA9876543210
  24. VALID_IRQ       equ 1100111011111000b
  25. ATTCH_IRQ       equ 0000111010100000b
  26.  
  27. if USE_COM_IRQ
  28. ATTCH_IRQ       equ 0000111010111000b
  29. end if
  30.  
  31. CPU_FREQ        equ  2600d
  32.  
  33. BIT0  EQU 0x00000001
  34. BIT1  EQU 0x00000002
  35. BIT5  EQU 0x00000020
  36. BIT10 EQU 0x00000400
  37.  
  38. VID_VIA           equ 0x1106
  39.  
  40. CTRL_VT82C686     equ 0x3058
  41. CTRL_VT8233_5     equ 0x3059
  42.  
  43.  
  44. CODEC_MASTER_VOL_REG         equ 0x02
  45. CODEC_AUX_VOL                equ 0x04 ;
  46. CODEC_PCM_OUT_REG            equ 0x18 ; PCM output volume
  47. CODEC_EXT_AUDIO_REG          equ 0x28 ; extended audio
  48. CODEC_EXT_AUDIO_CTRL_REG     equ 0x2a ; extended audio control
  49. CODEC_PCM_FRONT_DACRATE_REG  equ 0x2c ; PCM out sample rate
  50. CODEC_PCM_SURND_DACRATE_REG  equ 0x2e ; surround sound sample rate
  51. CODEC_PCM_LFE_DACRATE_REG    equ 0x30 ; LFE sample rate
  52.  
  53.  
  54. ;VIA host controller registers set
  55. ;; common offsets
  56. VIA_REG_OFFSET_STATUS        equ   0x00    ;; byte - channel status
  57.   VIA_REG_STAT_ACTIVE              equ   0x80    ;; RO
  58.   VIA_REG_STAT_PAUSED              equ   0x40    ;; RO
  59.   VIA_REG_STAT_TRIGGER_QUEUED      equ   0x08    ;; RO
  60.   VIA_REG_STAT_STOPPED             equ   0x04    ;; RWC
  61.   VIA_REG_STAT_EOL                 equ   0x02    ;; RWC
  62.   VIA_REG_STAT_FLAG                equ   0x01    ;; RWC
  63. VIA_REG_OFFSET_CONTROL       equ   0x01    ;; byte - channel control
  64.   VIA_REG_CTRL_START               equ   0x80    ;; WO
  65.   VIA_REG_CTRL_TERMINATE           equ   0x40    ;; WO
  66.   VIA_REG_CTRL_AUTOSTART           equ   0x20
  67.   VIA_REG_CTRL_PAUSE               equ   0x08    ;; RW
  68.   VIA_REG_CTRL_INT_STOP            equ   0x04
  69.   VIA_REG_CTRL_INT_EOL             equ   0x02
  70.   VIA_REG_CTRL_INT_FLAG            equ   0x01
  71.   VIA_REG_CTRL_RESET               equ   0x01    ;; RW - probably reset? undocumented
  72.   VIA_REG_CTRL_INT                 equ  (VIA_REG_CTRL_INT_FLAG or \
  73.                                          VIA_REG_CTRL_INT_EOL or \
  74.                                          VIA_REG_CTRL_AUTOSTART)
  75. VIA_REG_OFFSET_TYPE          equ   0x02    ;; byte - channel type (686 only)
  76.   VIA_REG_TYPE_AUTOSTART           equ   0x80    ;; RW - autostart at EOL
  77.   VIA_REG_TYPE_16BIT               equ   0x20    ;; RW
  78.   VIA_REG_TYPE_STEREO              equ   0x10    ;; RW
  79.   VIA_REG_TYPE_INT_LLINE           equ   0x00
  80.   VIA_REG_TYPE_INT_LSAMPLE         equ   0x04
  81.   VIA_REG_TYPE_INT_LESSONE         equ   0x08
  82.   VIA_REG_TYPE_INT_MASK            equ   0x0c
  83.   VIA_REG_TYPE_INT_EOL             equ   0x02
  84.   VIA_REG_TYPE_INT_FLAG            equ   0x01
  85. VIA_REG_OFFSET_TABLE_PTR     equ   0x04    ;; dword - channel table pointer
  86. VIA_REG_OFFSET_CURR_PTR      equ   0x04    ;; dword - channel current pointer
  87. VIA_REG_OFFSET_STOP_IDX      equ   0x08    ;; dword - stop index, channel type, sample rate
  88.   VIA8233_REG_TYPE_16BIT           equ   0x00200000      ;; RW
  89.   VIA8233_REG_TYPE_STEREO          equ   0x00100000      ;; RW
  90. VIA_REG_OFFSET_CURR_COUNT    equ   0x0c    ;; dword - channel current count (24 bit)
  91. VIA_REG_OFFSET_CURR_INDEX    equ   0x0f    ;; byte - channel current index (for via8233 only)
  92.  
  93.  
  94. VIADEV_PLAYBACK         equ   0x00
  95. VIADEV_CAPTURE          equ   0x10
  96. VIADEV_FM               equ   0x20
  97.  
  98. ;; AC'97 ;;
  99. VIA_REG_AC97             equ   0x80    ; dword
  100.   VIA_REG_AC97_CODEC_ID_MASK       equ  0xC0000000 ;(3<<30)
  101.   VIA_REG_AC97_CODEC_ID_SHIFT      equ  30
  102.   VIA_REG_AC97_CODEC_ID_PRIMARY    equ  0x00
  103.   VIA_REG_AC97_CODEC_ID_SECONDARY  equ  0x01
  104.   VIA_REG_AC97_SECONDARY_VALID     equ  0x08000000 ;(1<<27)
  105.   VIA_REG_AC97_PRIMARY_VALID       equ  0x02000000 ;(1<<25)
  106.   VIA_REG_AC97_BUSY                equ  0x01000000 ;(1<<24)
  107.   VIA_REG_AC97_READ                equ  0x00800000 ;(1<<23)
  108.   VIA_REG_AC97_CMD_SHIFT           equ  16
  109.   VIA_REG_AC97_CMD_MASK            equ  0x7E
  110.   VIA_REG_AC97_DATA_SHIFT          equ  0
  111.   VIA_REG_AC97_DATA_MASK           equ  0xFFFF
  112.  
  113. VIA_REG_SGD_SHADOW       equ   0x84    ; dword
  114.  
  115. ;; via8233-specific registers ;;
  116. VIA_REG_OFS_PLAYBACK_VOLUME_L   equ  0x02    ;; byte
  117. VIA_REG_OFS_PLAYBACK_VOLUME_R   equ  0x03    ;; byte
  118. VIA_REG_OFS_MULTPLAY_FORMAT     equ  0x02    ;; byte - format and channels
  119.   VIA_REG_MULTPLAY_FMT_8BIT          equ  0x00
  120.   VIA_REG_MULTPLAY_FMT_16BIT         equ  0x80
  121.   VIA_REG_MULTPLAY_FMT_CH_MASK       equ  0x70    ;; # channels << 4 (valid = 1,2,4,6)
  122. VIA_REG_OFS_CAPTURE_FIFO        equ  0x02    ;; byte - bit 6 = fifo  enable
  123.   VIA_REG_CAPTURE_FIFO_ENABLE        equ  0x40
  124.  
  125. VIA_DXS_MAX_VOLUME              equ  31      ;; max. volume (attenuation) of reg 0x32/33
  126.  
  127. VIA_TBL_BIT_FLAG          equ   0x40000000
  128. VIA_TBL_BIT_EOL           equ   0x80000000
  129.  
  130. ;; pci space ;;
  131. VIA_ACLINK_STAT           equ   0x40
  132.   ;...
  133.   VIA_ACLINK_C00_READY             equ   0x01 ; primary codec ready
  134. VIA_ACLINK_CTRL           equ   0x41
  135.   VIA_ACLINK_CTRL_ENABLE           equ   0x80 ; 0: disable, 1: enable
  136.   VIA_ACLINK_CTRL_RESET            equ   0x40 ; 0: assert, 1: de-assert
  137.   VIA_ACLINK_CTRL_SYNC             equ   0x20 ; 0: release SYNC, 1: force SYNC hi
  138.   VIA_ACLINK_CTRL_SDO              equ   0x10 ; 0: release SDO, 1: force SDO hi
  139.   VIA_ACLINK_CTRL_VRA              equ   0x08 ; 0: disable VRA, 1: enable VRA
  140.   VIA_ACLINK_CTRL_PCM              equ   0x04 ; 0: disable PCM, 1: enable PCM
  141.   VIA_ACLINK_CTRL_FM               equ   0x02 ; via686 only
  142.   VIA_ACLINK_CTRL_SB               equ   0x01 ; via686 only
  143.   VIA_ACLINK_CTRL_INIT             equ  (VIA_ACLINK_CTRL_ENABLE or \
  144.                                          VIA_ACLINK_CTRL_RESET or \
  145.                                          VIA_ACLINK_CTRL_PCM or \
  146.                                          VIA_ACLINK_CTRL_VRA)
  147. VIA_FUNC_ENABLE           equ   0x42
  148.   VIA_FUNC_MIDI_PNP                equ   0x80 ; FIXME: it's 0x40 in the datasheet!
  149.   VIA_FUNC_MIDI_IRQMASK            equ   0x40 ; FIXME: not documented!
  150.   VIA_FUNC_RX2C_WRITE              equ   0x20
  151.   VIA_FUNC_SB_FIFO_EMPTY           equ   0x10
  152.   VIA_FUNC_ENABLE_GAME             equ   0x08
  153.   VIA_FUNC_ENABLE_FM               equ   0x04
  154.   VIA_FUNC_ENABLE_MIDI             equ   0x02
  155.   VIA_FUNC_ENABLE_SB               equ   0x01
  156. VIA_PNP_CONTROL           equ   0x43
  157. VIA_FM_NMI_CTRL           equ   0x48
  158. VIA8233_VOLCHG_CTRL       equ   0x48
  159. VIA8233_SPDIF_CTRL        equ   0x49
  160.   VIA8233_SPDIF_DX3                equ   0x08
  161.   VIA8233_SPDIF_SLOT_MASK          equ   0x03
  162.   VIA8233_SPDIF_SLOT_1011          equ   0x00
  163.   VIA8233_SPDIF_SLOT_34            equ   0x01
  164.   VIA8233_SPDIF_SLOT_78            equ   0x02
  165.   VIA8233_SPDIF_SLOT_69            equ   0x03
  166. ;] Asper
  167.  
  168.  
  169. SRV_GETVERSION        equ  0
  170. DEV_PLAY              equ  1
  171. DEV_STOP              equ  2
  172. DEV_CALLBACK          equ  3
  173. DEV_SET_BUFF          equ  4
  174. DEV_NOTIFY            equ  5
  175. DEV_SET_MASTERVOL     equ  6
  176. DEV_GET_MASTERVOL     equ  7
  177. DEV_GET_INFO          equ  8
  178. DEV_GET_POS           equ  9
  179.  
  180. struc AC_CNTRL              ;AC controller base class
  181. { .bus                dd ?
  182.   .devfn              dd ?
  183.  
  184.   .vendor             dd ?
  185.   .dev_id             dd ?
  186.   .pci_cmd            dd ?
  187.   .pci_stat           dd ?
  188.  
  189.   .codec_io_base      dd ?
  190.   .codec_mem_base     dd ?
  191.  
  192.   .ctrl_io_base       dd ?
  193.   .ctrl_mem_base      dd ?
  194.   .cfg_reg            dd ?
  195.   .int_line           dd ?
  196.  
  197.   .vendor_ids         dd ?    ;vendor id string
  198.   .ctrl_ids           dd ?    ;hub id string
  199.  
  200.   .buffer             dd ?
  201.  
  202.   .notify_pos         dd ?
  203.   .notify_task        dd ?
  204.  
  205.   .lvi_reg            dd ?
  206.   .ctrl_setup         dd ?
  207.   .user_callback      dd ?
  208.   .codec_read16       dd ?
  209.   .codec_write16      dd ?
  210.  
  211.   .ctrl_read8         dd ?
  212.   .ctrl_read16        dd ?
  213.   .ctrl_read32        dd ?
  214.  
  215.   .ctrl_write8        dd ?
  216.   .ctrl_write16       dd ?
  217.   .ctrl_write32       dd ?
  218. }
  219.  
  220. struc CODEC                ;Audio Chip base class
  221. {
  222.   .chip_id            dd ?
  223.   .flags              dd ?
  224.   .status             dd ?
  225.  
  226.   .ac_vendor_ids      dd ?    ;ac vendor id string
  227.   .chip_ids           dd ?    ;chip model string
  228.  
  229.   .shadow_flag        dd ?
  230.                       dd ?
  231.  
  232.   .regs               dw ?     ; codec registers
  233.   .reg_master_vol     dw ?     ;0x02
  234.   .reg_aux_out_vol    dw ?     ;0x04
  235.   .reg_mone_vol       dw ?     ;0x06
  236.   .reg_master_tone    dw ?     ;0x08
  237.   .reg_beep_vol       dw ?     ;0x0A
  238.   .reg_phone_vol      dw ?     ;0x0C
  239.   .reg_mic_vol        dw ?     ;0x0E
  240.   .reg_line_in_vol    dw ?     ;0x10
  241.   .reg_cd_vol         dw ?     ;0x12
  242.   .reg_video_vol      dw ?     ;0x14
  243.   .reg_aux_in_vol     dw ?     ;0x16
  244.   .reg_pcm_out_vol    dw ?     ;0x18
  245.   .reg_rec_select     dw ?     ;0x1A
  246.   .reg_rec_gain       dw ?     ;0x1C
  247.   .reg_rec_gain_mic   dw ?     ;0x1E
  248.   .reg_gen            dw ?     ;0x20
  249.   .reg_3d_ctrl        dw ?     ;0X22
  250.   .reg_page           dw ?     ;0X24
  251.   .reg_powerdown      dw ?     ;0x26
  252.   .reg_ext_audio      dw ?     ;0x28
  253.   .reg_ext_st         dw ?     ;0x2a
  254.   .reg_pcm_front_rate dw ?     ;0x2c
  255.   .reg_pcm_surr_rate  dw ?     ;0x2e
  256.   .reg_lfe_rate       dw ?     ;0x30
  257.   .reg_pcm_in_rate    dw ?     ;0x32
  258.                       dw ?     ;0x34
  259.   .reg_cent_lfe_vol   dw ?     ;0x36
  260.   .reg_surr_vol       dw ?     ;0x38
  261.   .reg_spdif_ctrl     dw ?     ;0x3A
  262.                       dw ?     ;0x3C
  263.                       dw ?     ;0x3E
  264.                       dw ?     ;0x40
  265.                       dw ?     ;0x42
  266.                       dw ?     ;0x44
  267.                       dw ?     ;0x46
  268.                       dw ?     ;0x48
  269.                       dw ?     ;0x4A
  270.                       dw ?     ;0x4C
  271.                       dw ?     ;0x4E
  272.                       dw ?     ;0x50
  273.                       dw ?     ;0x52
  274.                       dw ?     ;0x54
  275.                       dw ?     ;0x56
  276.                       dw ?     ;0x58
  277.                       dw ?     ;0x5A
  278.                       dw ?     ;0x5C
  279.                       dw ?     ;0x5E
  280.   .reg_page_0         dw ?     ;0x60
  281.   .reg_page_1         dw ?     ;0x62
  282.   .reg_page_2         dw ?     ;0x64
  283.   .reg_page_3         dw ?     ;0x66
  284.   .reg_page_4         dw ?     ;0x68
  285.   .reg_page_5         dw ?     ;0x6A
  286.   .reg_page_6         dw ?     ;0x6C
  287.   .reg_page_7         dw ?     ;0x6E
  288.                       dw ?     ;0x70
  289.                       dw ?     ;0x72
  290.                       dw ?     ;0x74
  291.                       dw ?     ;0x76
  292.                       dw ?     ;0x78
  293.                       dw ?     ;0x7A
  294.   .reg_vendor_id_1    dw ?     ;0x7C
  295.   .reg_vendor_id_2    dw ?     ;0x7E
  296.  
  297.  
  298.   .reset              dd ?    ;virtual
  299.   .set_master_vol     dd ?
  300. }
  301.  
  302. struc CTRL_INFO
  303. {   .pci_cmd          dd ?
  304.     .irq              dd ?
  305.     .glob_cntrl       dd ?
  306.     .glob_sta         dd ?
  307.     .codec_io_base    dd ?
  308.     .ctrl_io_base     dd ?
  309.     .codec_mem_base   dd ?
  310.     .ctrl_mem_base    dd ?
  311.     .codec_id         dd ?
  312. }
  313.  
  314. struc IOCTL
  315. {  .handle            dd ?
  316.    .io_code           dd ?
  317.    .input             dd ?
  318.    .inp_size          dd ?
  319.    .output            dd ?
  320.    .out_size          dd ?
  321. }
  322.  
  323. virtual at 0
  324.   IOCTL IOCTL
  325. end virtual
  326.  
  327. EVENT_NOTIFY    equ 0x00000200
  328.  
  329. public START
  330. public service_proc
  331. public version
  332.  
  333. section '.flat' code readable align 16
  334.  
  335. proc START stdcall, state:dword
  336.  
  337.         cmp     [state], 1
  338.         jne     .stop
  339.  
  340.      if DEBUG
  341.         mov     esi, msgInit
  342.         call    SysMsgBoardStr
  343.      end if
  344.  
  345.         call    detect_controller
  346.         test    eax, eax
  347.         jz      .fail
  348.  
  349.      if DEBUG
  350.         mov     esi, [ctrl.vendor_ids]
  351.         call    SysMsgBoardStr
  352.         mov     esi, [ctrl.ctrl_ids]
  353.         call    SysMsgBoardStr
  354.      end if
  355.  
  356.         call    init_controller
  357.         test    eax, eax
  358.         jz      .fail
  359.  
  360.         call    init_codec
  361.         test    eax, eax
  362.         jz      .fail
  363.  
  364.         call    setup_codec
  365.  
  366.         mov     esi, msgPrimBuff
  367.         call    SysMsgBoardStr
  368.         call    create_primary_buff
  369.         mov     esi, msgDone
  370.         call    SysMsgBoardStr
  371.  
  372.   if IRQ_REMAP
  373.         pushf
  374.         cli
  375.  
  376.         mov     ebx, [ctrl.int_line]
  377.         in      al, 0xA1
  378.         mov     ah, al
  379.         in      al, 0x21
  380.         test    ebx, ebx
  381.         jz      .skip
  382.         bts     ax, bx                          ;mask old line
  383. .skip:
  384.         bts     ax, IRQ_LINE                    ;mask new ine
  385.         out     0x21, al
  386.         mov     al, ah
  387.         out     0xA1, al
  388.  
  389.         stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE      ;remap IRQ
  390.  
  391.         mov     dx, 0x4d0                       ;8259 ELCR1
  392.         in      al, dx
  393.         bts     ax, IRQ_LINE
  394.         out     dx, al                          ;set level-triggered mode
  395.         mov     [ctrl.int_line], IRQ_LINE
  396.         popf
  397.         mov     esi, msgRemap
  398.         call    SysMsgBoardStr
  399.   end if
  400.  
  401.         mov     eax, VALID_IRQ
  402.         mov     ebx, [ctrl.int_line]
  403.         mov     esi, msgInvIRQ
  404.         bt      eax, ebx
  405.         jnc     .fail_msg
  406.         mov     eax, ATTCH_IRQ
  407.         mov     esi, msgAttchIRQ
  408.         bt      eax, ebx
  409.         jnc     .fail_msg
  410.  
  411.         stdcall AttachIntHandler, ebx, ac97_irq_VIA, dword 0
  412. .reg:
  413.         stdcall RegService, sz_sound_srv, service_proc
  414.         ret
  415. .fail:
  416.      if DEBUG
  417.         mov     esi, msgFail
  418.         call    SysMsgBoardStr
  419.      end if
  420.         xor     eax, eax
  421.         ret
  422. .fail_msg:
  423.         call    SysMsgBoardStr
  424.         xor     eax, eax
  425.         ret
  426. .stop:
  427.         call    stop
  428.         xor     eax, eax
  429.         ret
  430. endp
  431.  
  432. handle     equ  IOCTL.handle
  433. io_code    equ  IOCTL.io_code
  434. input      equ  IOCTL.input
  435. inp_size   equ  IOCTL.inp_size
  436. output     equ  IOCTL.output
  437. out_size   equ  IOCTL.out_size
  438.  
  439. align 4
  440. proc service_proc stdcall, ioctl:dword
  441.  
  442.         mov     edi, [ioctl]
  443.         mov     eax, [edi+io_code]
  444.  
  445.         cmp     eax, SRV_GETVERSION
  446.         jne     @F
  447.         mov     eax, [edi+output]
  448.         cmp     [edi+out_size], 4
  449.         jne     .fail
  450.  
  451.         mov     [eax], dword API_VERSION
  452.         xor     eax, eax
  453.         ret
  454. @@:
  455.         cmp     eax, DEV_PLAY
  456.         jne     @F
  457.      if DEBUG
  458.         mov     esi, msgPlay
  459.         call    SysMsgBoardStr
  460.      end if
  461.         call    play
  462.         ret
  463. @@:
  464.         cmp     eax, DEV_STOP
  465.         jne     @F
  466.      if DEBUG
  467.         mov     esi, msgStop
  468.         call    SysMsgBoardStr
  469.      end if
  470.         call    stop
  471.         ret
  472. @@:
  473.         cmp     eax, DEV_CALLBACK
  474.         jne     @F
  475.         mov     ebx, [edi+input]
  476.         stdcall set_callback, [ebx]
  477.         ret
  478. @@:
  479.         cmp     eax, DEV_SET_MASTERVOL
  480.         jne     @F
  481.         mov     eax, [edi+input]
  482.         mov     eax, [eax]
  483.         call    set_master_vol          ;eax= vol
  484.         ret
  485. @@:
  486.         cmp     eax, DEV_GET_MASTERVOL
  487.         jne     @F
  488.         mov     ebx, [edi+output]
  489.         stdcall get_master_vol, ebx
  490.         ret
  491. @@:
  492.         cmp     eax, DEV_GET_INFO
  493.         jne     @F
  494.         mov     ebx, [edi+output]
  495.         stdcall get_dev_info, ebx
  496.         ret
  497. @@:
  498.         cmp     eax, DEV_GET_POS
  499.         jne     @F
  500.         push    ebx  edx
  501.         mov     edx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CURR_COUNT
  502.         call    [ctrl.ctrl_read32]
  503.         and     eax, 0x00FFFFFF
  504.         mov     ebx, 4096
  505.         sub     ebx, eax
  506.         shr     ebx, 2
  507.         mov     edx, [edi+output]
  508.         mov     [edx], ebx
  509.         pop     edx ebx
  510.         ret
  511. @@:
  512. .fail:
  513.         or      eax, -1
  514.         ret
  515. endp
  516.  
  517. restore   handle
  518. restore   io_code
  519. restore   input
  520. restore   inp_size
  521. restore   output
  522. restore   out_size
  523.  
  524.  
  525. align 4
  526. proc ac97_irq_VIA
  527.            locals
  528.              status db 0
  529.            endl
  530.  
  531.         mov     edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS
  532.         call    [ctrl.ctrl_read8]
  533.         test    al, VIA_REG_STAT_ACTIVE
  534.         jz      @f
  535.  
  536.         and     al, VIA_REG_STAT_EOL or VIA_REG_STAT_FLAG or VIA_REG_STAT_STOPPED
  537.         mov     byte [status], al
  538.  
  539.         mov     ebx, dword [buff_list]
  540.         cmp     [ctrl.user_callback], 0
  541.         je      @f
  542.         stdcall [ctrl.user_callback], ebx
  543.        @@:
  544.         mov     al, byte [status]               ;; ack ;;
  545.         mov     edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS
  546.         call    [ctrl.ctrl_write8]
  547.  
  548.         ret
  549. endp
  550.  
  551.  
  552. align 4
  553. proc create_primary_buff
  554.  
  555.         stdcall KernelAlloc, 0x10000
  556.         mov     [ctrl.buffer], eax
  557.  
  558.         mov     edi, eax
  559.         mov     ecx, 0x10000/4
  560.         xor     eax, eax
  561.         cld
  562.         rep stosd
  563.  
  564.         mov     eax, [ctrl.buffer]
  565.         call    GetPgAddr
  566.         mov     edi, pcmout_bdl
  567.         stosd
  568.         mov     eax, 0x80004000
  569.         stosd
  570.  
  571.         mov     edi, buff_list
  572.         mov     eax, [ctrl.buffer]
  573.         mov     ecx, 4
  574. @@:
  575.         mov     [edi], eax
  576.         mov     [edi+16], eax
  577.         mov     [edi+32], eax
  578.         mov     [edi+48], eax
  579.         mov     [edi+64], eax
  580.         mov     [edi+80], eax
  581.         mov     [edi+96], eax
  582.         mov     [edi+112], eax
  583.  
  584.            ;add      eax, 0x4000
  585.         add     edi, 4
  586.         loop    @B
  587.  
  588.         stdcall channel_reset, VIADEV_PLAYBACK
  589.         stdcall codec_check_ready
  590.  
  591.         mov     eax, pcmout_bdl
  592.         mov     ebx, eax
  593.         call    GetPgAddr
  594.         and     ebx, 0xFFF
  595.         add     eax, ebx
  596.  
  597.         mov     edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_TABLE_PTR
  598.         call    [ctrl.ctrl_write32]
  599.  
  600.         stdcall codec_check_ready
  601.  
  602.         mov     edx, VIADEV_PLAYBACK +VIA_REG_OFS_PLAYBACK_VOLUME_L
  603.         mov     eax, 7    ;31
  604.         call    [ctrl.ctrl_write8]
  605.  
  606.         mov     edx, VIADEV_PLAYBACK +VIA_REG_OFS_PLAYBACK_VOLUME_R
  607.         mov     eax, 7    ;31
  608.         call    [ctrl.ctrl_write8]
  609.  
  610.         mov     edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX
  611.         mov     eax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000
  612.         mov     [ctrl.lvi_reg], 16  ;0xF;eax
  613.         call    [ctrl.ctrl_write32]
  614.  
  615.         stdcall codec_check_ready
  616.         ret
  617. endp
  618.  
  619.  
  620. proc channel_reset channel:dword
  621.         mov     esi, dword [channel]
  622.         mov     edx, esi
  623.         add     edx, VIA_REG_OFFSET_CONTROL
  624.         mov     eax, VIA_REG_CTRL_PAUSE or VIA_REG_CTRL_TERMINATE or VIA_REG_CTRL_RESET
  625.         call    [ctrl.ctrl_write8]
  626.  
  627.         mov     edx, esi
  628.         add     edx, VIA_REG_OFFSET_CONTROL
  629.         call    [ctrl.ctrl_read8]
  630.  
  631.         mov     eax, 50000       ; wait 50 ms
  632.         call    StallExec
  633.            ; disable interrupts
  634.         mov     edx, esi
  635.         add     edx, VIA_REG_OFFSET_CONTROL
  636.         xor     eax, eax
  637.         call    [ctrl.ctrl_write8]
  638.  
  639.            ; clear interrupts
  640.         mov     edx, esi
  641.         add     edx, VIA_REG_OFFSET_STATUS
  642.         mov     eax, 0x03
  643.         call    [ctrl.ctrl_write8]
  644.  
  645.         ;outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
  646.           ; mov      edx, esi                  ;; for via686
  647.           ; add      edx, VIA_REG_OFFSET_TYPE
  648.           ; mov      eax, 0x03
  649.           ; call     [ctrl.ctrl_write8]
  650.  
  651.         ;; outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
  652.            ;mov      edx, esi
  653.            ;add      edx, VIA_REG_OFFSET_CURR_PTR
  654.            ;xor      eax, eax
  655.            ;call     [ctrl.ctrl_write8]
  656.  
  657.         ret
  658. endp
  659.  
  660.  
  661. align 4
  662. proc detect_controller
  663.            locals
  664.              last_bus dd ?
  665.              bus      dd ?
  666.              devfn    dd ?
  667.            endl
  668.  
  669.         xor     eax, eax
  670.         mov     [bus], eax
  671.         inc     eax
  672.         call    PciApi
  673.         cmp     eax, -1
  674.         je      .err
  675.  
  676.         mov     [last_bus], eax
  677.  
  678. .next_bus:
  679.         and     [devfn], 0
  680. .next_dev:
  681.         stdcall PciRead32, [bus], [devfn], dword 0
  682.         test    eax, eax
  683.         jz      .next
  684.         cmp     eax, -1
  685.         je      .next
  686.  
  687.         mov     edi, devices
  688. @@:
  689.         mov     ebx, [edi]
  690.         test    ebx, ebx
  691.         jz      .next
  692.  
  693.         cmp     eax, ebx
  694.         je      .found
  695.         add     edi, 12
  696.         jmp     @B
  697. .next:
  698.         inc     [devfn]
  699.         cmp     [devfn], 256
  700.         jb      .next_dev
  701.         mov     eax, [bus]
  702.         inc     eax
  703.         mov     [bus], eax
  704.         cmp     eax, [last_bus]
  705.         jna     .next_bus
  706.         xor     eax, eax
  707.         ret
  708. .found:
  709.         mov     ebx, [bus]
  710.         mov     [ctrl.bus], ebx
  711.  
  712.         mov     ecx, [devfn]
  713.         mov     [ctrl.devfn], ecx
  714.  
  715.         mov     edx, eax
  716.         and     edx, 0xFFFF
  717.         mov     [ctrl.vendor], edx
  718.         shr     eax, 16
  719.         mov     [ctrl.dev_id], eax
  720.  
  721.         mov     ebx, [edi+4]
  722.         mov     [ctrl.ctrl_ids], ebx
  723.         mov     esi, [edi+8]
  724.         mov     [ctrl.ctrl_setup], esi
  725.  
  726.         cmp     edx, VID_VIA
  727.         jne     @F
  728.         mov     [ctrl.vendor_ids], msg_VIA
  729.         ret
  730. @@:
  731.  
  732. .err:
  733.         xor     eax, eax
  734.         mov     [ctrl.vendor_ids], eax    ;something  wrong ?
  735.         ret
  736. endp
  737.  
  738. align 4
  739. proc init_controller
  740.  
  741.         stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
  742.         mov     ebx, eax
  743.         and     eax, 0xFFFF
  744.         mov     [ctrl.pci_cmd], eax
  745.         shr     ebx, 16
  746.         mov     [ctrl.pci_stat], ebx
  747.  
  748.         mov     esi, msgPciCmd
  749.         call    SysMsgBoardStr
  750.         call    dword2str
  751.         call    SysMsgBoardStr
  752.  
  753.         mov     esi, msgPciStat
  754.         call    SysMsgBoardStr
  755.         mov     eax, [ctrl.pci_stat]
  756.         call    dword2str
  757.         call    SysMsgBoardStr
  758.  
  759.         mov     esi, msgCtrlIsaIo
  760.         call    SysMsgBoardStr
  761.         stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
  762.         call    dword2str
  763.         call    SysMsgBoardStr
  764.  
  765.         and     eax, 0xFFC0
  766.         mov     [ctrl.ctrl_io_base], eax
  767.  
  768. .default:
  769.         stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
  770.         and     eax, 0xFF
  771. @@:
  772.         mov     [ctrl.int_line], eax
  773.  
  774.            ;stdcall  PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_FUNC_ENABLE ;0x42
  775.            ;mov      byte [old_legacy], al
  776.  
  777.            ;stdcall  PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_PNP_CONTROL ;0x43
  778.            ;mov      byte [old_legacy_cfg], al
  779.  
  780.            ;mov      al, VIA_FUNC_ENABLE_SB or VIA_FUNC_ENABLE_FM
  781.            ;xor      al, 0xFF
  782.            ;and      al, byte [old_legacy]
  783.            ;and      eax, 0xFF
  784.            ;stdcall  PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_FUNC_ENABLE, eax ;0x42
  785.            ;mov      byte [old_legacy], al
  786.  
  787.         call    [ctrl.ctrl_setup]
  788.         xor     eax, eax
  789.         inc     eax
  790.         ret
  791. endp
  792.  
  793. align 4
  794. proc set_VIA
  795.         mov     [ctrl.codec_read16], codec_io_r16         ;virtual
  796.         mov     [ctrl.codec_write16], codec_io_w16        ;virtual
  797.  
  798.         mov     [ctrl.ctrl_read8 ], ctrl_io_r8            ;virtual
  799.         mov     [ctrl.ctrl_read16], ctrl_io_r16           ;virtual
  800.         mov     [ctrl.ctrl_read32], ctrl_io_r32           ;virtual
  801.  
  802.         mov     [ctrl.ctrl_write8 ], ctrl_io_w8           ;virtual
  803.         mov     [ctrl.ctrl_write16], ctrl_io_w16          ;virtual
  804.         mov     [ctrl.ctrl_write32], ctrl_io_w32          ;virtual
  805.         ret
  806. endp
  807.  
  808.  
  809. align 4
  810. proc init_codec
  811.            locals
  812.              counter dd ?
  813.            endl
  814.  
  815.         mov     esi, msgControl
  816.         call    SysMsgBoardStr
  817.         stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL
  818.         and     eax, 0xFF
  819.         call    dword2str
  820.         call    SysMsgBoardStr
  821.  
  822.         mov     esi, msgStatus
  823.         call    SysMsgBoardStr
  824.         stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT
  825.         and     eax, 0xFF
  826.         push    eax
  827.         call    dword2str
  828.         call    SysMsgBoardStr
  829.         pop     eax
  830.  
  831.         test    eax, VIA_ACLINK_C00_READY
  832.         jnz     .ready
  833.  
  834.         call    reset_codec
  835.         test    eax, eax
  836.         jz      .err
  837.  
  838. .ready:
  839.         xor     edx, edx         ; ac_reg_0
  840.         call    [ctrl.codec_write16]
  841.         jmp     .done
  842.  
  843. .err:
  844.         xor     eax, eax              ; timeout error
  845.         ret
  846.  
  847. .done:
  848.         call    detect_codec
  849.  
  850.         xor     eax, eax
  851.         inc     eax
  852.         ret
  853. endp
  854.  
  855. align 4
  856. proc reset_codec
  857.         stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, \
  858.                 VIA_ACLINK_CTRL_ENABLE or VIA_ACLINK_CTRL_RESET or VIA_ACLINK_CTRL_SYNC
  859.         mov     eax, 100000        ; wait 100 ms
  860.         call    StallExec
  861. .cold:
  862.         call    cold_reset
  863.         jnc     .ok
  864.  
  865.      if DEBUG
  866.         mov     esi, msgCFail
  867.         call    SysMsgBoardStr
  868.      end if
  869.         xor     eax, eax         ; timeout error
  870.         ret
  871. .ok:
  872.      if DEBUG
  873.         mov     esi, msgResetOk
  874.         call    SysMsgBoardStr
  875.      end if
  876.         xor     eax, eax
  877.         inc     eax
  878.         ret
  879. endp
  880.  
  881.  
  882. align 4
  883. proc cold_reset
  884.            locals
  885.              counter dd ?
  886.            endl
  887.  
  888.         stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, dword 0
  889.  
  890.      if DEBUG
  891.         mov     esi, msgCold
  892.         call    SysMsgBoardStr
  893.      end if
  894.  
  895.         mov     eax, 100000         ; wait 100 ms ;400000     ; wait 400 ms
  896.         call    StallExec
  897.  
  898.            ;; ACLink on, deassert ACLink reset, VSR, SGD data out
  899.            ;; note - FM data out has trouble with non VRA codecs !!
  900.         stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, dword VIA_ACLINK_CTRL_INIT
  901.  
  902.         mov     [counter], 16        ; total 20*100 ms = 2s
  903. .wait:
  904.         stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT
  905.         test    eax, VIA_ACLINK_C00_READY
  906.         jnz     .ok
  907.  
  908.         mov     eax, 100000        ; wait 100 ms
  909.         call    StallExec
  910.  
  911.         dec     [counter]
  912.         jnz     .wait
  913.  
  914.      if DEBUG
  915.         mov     esi, msgCRFail
  916.         call    SysMsgBoardStr
  917.      end if
  918.  
  919. .fail:
  920.         stc
  921.         ret
  922. .ok:
  923.         mov     esi, msgControl
  924.         call    SysMsgBoardStr
  925.         stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL
  926.         call    dword2str
  927.         call    SysMsgBoardStr
  928.  
  929.         mov     esi, msgStatus
  930.         call    SysMsgBoardStr
  931.         stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT
  932.         and     eax, 0xFF
  933.         push    eax
  934.         call    dword2str
  935.         call    SysMsgBoardStr
  936.         pop     eax
  937.  
  938.         test    eax, VIA_ACLINK_C00_READY     ;CTRL_ST_CREADY
  939.         jz      .fail
  940.         clc
  941.         ret
  942. endp
  943.  
  944. align 4
  945. play:
  946.         mov     edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX
  947.         mov     eax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000
  948.         mov     [ctrl.lvi_reg], 16
  949.         call    [ctrl.ctrl_write32]
  950.  
  951.         mov     eax, VIA_REG_CTRL_INT
  952.         or      eax, VIA_REG_CTRL_START
  953.         mov     edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL
  954.         call    [ctrl.ctrl_write8]
  955.  
  956.         xor     eax, eax
  957.         ret
  958.  
  959. align 4
  960. stop:
  961.         mov     eax, VIA_REG_CTRL_INT
  962.         or      eax, VIA_REG_CTRL_TERMINATE
  963.         mov     edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL
  964.         call    [ctrl.ctrl_write8]
  965.  
  966.         stdcall channel_reset, VIADEV_PLAYBACK
  967.         xor     eax, eax
  968.         ret
  969.  
  970. align 4
  971. proc get_dev_info stdcall, p_info:dword
  972.            virtual at esi
  973.              CTRL_INFO CTRL_INFO
  974.            end virtual
  975.  
  976.         mov     esi, [p_info]
  977.         mov     eax, [ctrl.int_line]
  978.         mov     ecx, [ctrl.ctrl_io_base]
  979.         mov     [CTRL_INFO.irq], eax
  980.         mov     [CTRL_INFO.ctrl_io_base], ecx
  981.  
  982.         xor     eax, eax
  983.            ;mov      edx, VIADEV_PLAYBACK   +VIA_REG_OFFSET_TABLE_PTR
  984.            ;call     [ctrl.ctrl_read32]
  985.         mov     [CTRL_INFO.codec_io_base], eax
  986.            ;mov      edx, VIADEV_PLAYBACK   +VIA_REG_OFFSET_STOP_IDX
  987.            ;call     [ctrl.ctrl_read32]
  988.         mov     [CTRL_INFO.codec_mem_base], eax
  989.            ;mov      edx, VIADEV_PLAYBACK   +VIA_REG_OFFSET_CURR_COUNT
  990.            ;call     [ctrl.ctrl_read32]
  991.         mov     [CTRL_INFO.ctrl_mem_base], eax
  992.  
  993.         mov     eax, [codec.chip_id]
  994.         mov     [CTRL_INFO.codec_id], eax
  995.  
  996.         mov     edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL
  997.         call    [ctrl.ctrl_read8]
  998.         and     eax, 0xFF
  999.         mov     [CTRL_INFO.glob_cntrl], eax
  1000.  
  1001.         mov     edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS
  1002.         call    [ctrl.ctrl_read8]
  1003.         and     eax, 0xFF
  1004.         mov     [CTRL_INFO.glob_sta], eax
  1005.  
  1006.         mov     ebx, [ctrl.pci_cmd]
  1007.         mov     [CTRL_INFO.pci_cmd], ebx
  1008.         ret
  1009. endp
  1010.  
  1011. align 4
  1012. proc set_callback stdcall, handler:dword
  1013.         mov     eax, [handler]
  1014.         mov     [ctrl.user_callback], eax
  1015.         ret
  1016. endp
  1017.  
  1018.  
  1019. align 4
  1020. proc codec_check_ready stdcall
  1021.            locals
  1022.              counter dd ?
  1023.            endl
  1024.  
  1025.         mov     [counter], 1000         ; total 1000*1 ms = 1s
  1026. .wait:
  1027.         call    [ctrl.codec_read16]
  1028.         test    eax, VIA_REG_AC97_BUSY
  1029.         jz      .ok
  1030.  
  1031.         mov     eax, 1000       ; wait 1 ms
  1032.         call    StallExec
  1033.  
  1034.         sub     [counter] , 1
  1035.         jnz     .wait
  1036. .err:
  1037.         mov     eax, -1
  1038.         ret
  1039. .ok:
  1040.         and     eax, 0xFFFF
  1041.         ret
  1042. endp
  1043.  
  1044.  
  1045. align 4
  1046. proc codec_valid stdcall
  1047.         stdcall codec_check_ready
  1048.         ret
  1049. endp
  1050.  
  1051. align 4
  1052. proc codec_read stdcall, ac_reg:dword      ; reg = edx, reval = eax
  1053.            locals
  1054.              counter dd ?
  1055.            endl
  1056.  
  1057.            ;Use only primary codec.
  1058.         mov     eax, [ac_reg]
  1059.         and     eax, 0x7F
  1060.         shl     eax, VIA_REG_AC97_CMD_SHIFT
  1061.         or      eax, VIA_REG_AC97_PRIMARY_VALID or VIA_REG_AC97_READ
  1062.  
  1063.         mov     [counter], 3         ; total 3*20 ms = 60ms
  1064. .wait:
  1065.         push    eax
  1066.         call    [ctrl.codec_write16]
  1067.  
  1068.         mov     eax, 20000       ; wait 20 ms
  1069.         call    StallExec
  1070.  
  1071.         stdcall codec_valid
  1072.         cmp     eax, 0
  1073.         pop     eax
  1074.         jge     .ok
  1075.  
  1076.         sub     [counter] , 1
  1077.         jnz     .wait
  1078.         jmp     .err
  1079.  
  1080. .ok:
  1081.         mov     eax, 25000       ; wait 25 ms
  1082.         call    StallExec
  1083.  
  1084.         call    [ctrl.codec_read16]      ;change edx !!!
  1085.         and     eax, 0xFFFF
  1086.         ret
  1087. .err:
  1088.      if DEBUG
  1089.         mov     esi, msgCInvalid
  1090.         call    SysMsgBoardStr
  1091.      end if
  1092.         mov     eax, -1            ; invalid codec error
  1093.         ret
  1094. endp
  1095.  
  1096. align 4
  1097. proc codec_write stdcall, ac_reg:dword
  1098.            ;Use only primary codec.
  1099.         mov     esi, [ac_reg]
  1100.         mov     edx, esi
  1101.         shl     edx, VIA_REG_AC97_CMD_SHIFT
  1102.  
  1103.         shl     eax, VIA_REG_AC97_DATA_SHIFT
  1104.         or      edx, eax
  1105.  
  1106.         mov     eax, VIA_REG_AC97_CODEC_ID_PRIMARY     ;not VIA_REG_AC97_CODEC_ID_PRIMARY
  1107.         shl     eax, VIA_REG_AC97_CODEC_ID_SHIFT
  1108.         or      edx, eax
  1109.  
  1110.         mov     eax, edx
  1111.         mov     edx, esi
  1112.         call    [ctrl.codec_write16]
  1113.         mov     [codec.regs+esi], ax
  1114.  
  1115.         stdcall codec_check_ready
  1116.         cmp     eax, 0
  1117.         jl      .err
  1118. .ok:
  1119.         ret
  1120. .err:
  1121.      if DEBUG
  1122.         mov     esi, msgCFail
  1123.         call    SysMsgBoardStr
  1124.      end if
  1125.            ;mov      eax, -1        ; codec not ready error
  1126.         ret
  1127. endp
  1128.  
  1129. align 4
  1130. proc StallExec
  1131.         push    ecx
  1132.         push    edx
  1133.         push    ebx
  1134.         push    eax
  1135.  
  1136.         mov     ecx, CPU_FREQ
  1137.         mul     ecx
  1138.         mov     ebx, eax           ;low
  1139.         mov     ecx, edx           ;high
  1140.         rdtsc
  1141.         add     ebx, eax
  1142.         adc     ecx, edx
  1143. @@:
  1144.         rdtsc
  1145.         sub     eax, ebx
  1146.         sbb     edx, ecx
  1147.         js      @B
  1148.  
  1149.         pop     eax
  1150.         pop     ebx
  1151.         pop     edx
  1152.         pop     ecx
  1153.         ret
  1154. endp
  1155.  
  1156. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1157. ;          CONTROLLER IO functions
  1158. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1159.  
  1160. align 4
  1161. proc codec_io_r16 ;r32
  1162.         mov     edx, [ctrl.ctrl_io_base]
  1163.         add     edx, VIA_REG_AC97
  1164.         in      eax, dx
  1165.         ret
  1166. endp
  1167.  
  1168. align 4
  1169. proc codec_io_w16 ;w32
  1170.         mov     edx, [ctrl.ctrl_io_base]
  1171.         add     edx, VIA_REG_AC97
  1172.         out     dx, eax
  1173.         ret
  1174. endp
  1175.  
  1176. align 4
  1177. proc ctrl_io_r8
  1178.         add     edx, [ctrl.ctrl_io_base]
  1179.         in      al, dx
  1180.         ret
  1181. endp
  1182.  
  1183. align 4
  1184. proc ctrl_io_r16
  1185.         add     edx, [ctrl.ctrl_io_base]
  1186.         in      ax, dx
  1187.         ret
  1188. endp
  1189.  
  1190. align 4
  1191. proc ctrl_io_r32
  1192.         add     edx, [ctrl.ctrl_io_base]
  1193.         in      eax, dx
  1194.         ret
  1195. endp
  1196.  
  1197. align 4
  1198. proc ctrl_io_w8
  1199.         add     edx, [ctrl.ctrl_io_base]
  1200.         out     dx, al
  1201.         ret
  1202. endp
  1203.  
  1204. align 4
  1205. proc ctrl_io_w16
  1206.         add     edx, [ctrl.ctrl_io_base]
  1207.         out     dx, ax
  1208.         ret
  1209. endp
  1210.  
  1211. align 4
  1212. proc ctrl_io_w32
  1213.         add     edx, [ctrl.ctrl_io_base]
  1214.         out     dx, eax
  1215.         ret
  1216. endp
  1217.  
  1218.  
  1219. align 4
  1220. dword2str:
  1221.         push    eax ebx ecx
  1222.         mov     esi, hex_buff
  1223.         mov     ecx, -8
  1224.    @@:
  1225.         rol     eax, 4
  1226.         mov     ebx, eax
  1227.         and     ebx, 0x0F
  1228.         mov     bl, [ebx+hexletters]
  1229.         mov     [8+esi+ecx], bl
  1230.         inc     ecx
  1231.         jnz     @B
  1232.         pop     ecx ebx eax
  1233.         ret
  1234.  
  1235. hexletters   db '0123456789ABCDEF'
  1236. hex_buff     db 8 dup(0),13,10,0
  1237.  
  1238.  
  1239. include "codec.inc"
  1240.  
  1241. align 4
  1242. devices dd (CTRL_VT82C686  shl 16)+VID_VIA,msg_VT82C686,set_VIA
  1243.         dd (CTRL_VT8233_5  shl 16)+VID_VIA,msg_VT8233,set_VIA
  1244.         dd 0    ;terminator
  1245.  
  1246.  
  1247. version      dd (5 shl 16) or (API_VERSION and 0xFFFF)
  1248.  
  1249. msg_VT82C686 db 'VT82C686', 13,10, 0
  1250. msg_VT8233   db 'VT8233',   13,10, 0
  1251. msg_VIA      db 'VIA'   ,   13,10, 0
  1252.  
  1253. szKernel            db 'KERNEL', 0
  1254. sz_sound_srv        db 'SOUND',0
  1255.  
  1256. msgInit      db 'detect hardware...',13,10,0
  1257. msgFail      db 'device not found',13,10,0
  1258. msgAttchIRQ  db 'IRQ line not supported', 13,10, 0
  1259. msgInvIRQ    db 'IRQ line not assigned or invalid', 13,10, 0
  1260. msgPlay      db 'start play', 13,10,0
  1261. msgStop      db 'stop play',  13,10,0
  1262. ;msgIRQ       db 'AC97 IRQ', 13,10,0
  1263. ;msgInitCtrl  db 'init controller',13,10,0
  1264. ;msgInitCodec db 'init codec',13,10,0
  1265. msgPrimBuff  db 'create primary buffer ...',0
  1266. msgDone      db 'done',13,10,0
  1267. msgRemap     db 'Remap IRQ',13,10,0
  1268. ;msgReg       db 'set service handler',13,10,0
  1269. ;msgOk        db 'service installed',13,10,0
  1270. msgCold      db 'cold reset',13,10,0
  1271. ;msgWarm      db 'warm reset',13,10,0
  1272. ;msgWRFail    db 'warm reset failed',13,10,0
  1273. msgCRFail    db 'cold reset failed',13,10,0
  1274. msgCFail     db 'codec not ready',13,10,0
  1275. msgCInvalid  db 'codec is not valid',13,10,0 ;Asper
  1276. msgResetOk   db 'reset complete',13,10,0
  1277. msgStatus    db 'global status   ',0
  1278. msgControl   db 'global control  ',0
  1279. msgPciCmd    db 'PCI command     ',0
  1280. msgPciStat   db 'PCI status      ',0
  1281. msgCtrlIsaIo db 'controller io base   ',0
  1282. ;msgMixIsaIo  db 'codec io base        ',0
  1283. ;msgCtrlMMIo  db 'controller mmio base ',0
  1284. ;msgMixMMIo   db 'codec mmio base      ',0
  1285. ;msgIrqMap    db 'AC97 irq map as      ',0
  1286.  
  1287.  
  1288. section '.data' data readable writable align 16
  1289.  
  1290. pcmout_bdl       rq 32
  1291. buff_list        rd 32
  1292.  
  1293. codec CODEC
  1294. ctrl AC_CNTRL
  1295.  
  1296. chip_type        rb 1
  1297.