Subversion Repositories Kolibri OS

Rev

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

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