1178 lines
23 KiB
NASM
1178 lines
23 KiB
NASM
|
|
||
|
format MS COFF
|
||
|
|
||
|
|
||
|
include 'proc32.inc'
|
||
|
|
||
|
DEBUG equ 1
|
||
|
|
||
|
CPU_FREQ equ 2000d ;cpu freq in MHz
|
||
|
|
||
|
BIT0 EQU 0x00000001
|
||
|
BIT1 EQU 0x00000002
|
||
|
BIT2 EQU 0x00000004
|
||
|
BIT3 EQU 0x00000008
|
||
|
BIT4 EQU 0x00000010
|
||
|
BIT5 EQU 0x00000020
|
||
|
BIT6 EQU 0x00000040
|
||
|
BIT7 EQU 0x00000080
|
||
|
BIT8 EQU 0x00000100
|
||
|
BIT9 EQU 0x00000200
|
||
|
BIT10 EQU 0x00000400
|
||
|
BIT11 EQU 0x00000800
|
||
|
BIT12 EQU 0x00001000
|
||
|
BIT13 EQU 0x00002000
|
||
|
BIT14 EQU 0x00004000
|
||
|
BIT15 EQU 0x00008000
|
||
|
BIT16 EQU 0x00010000
|
||
|
BIT17 EQU 0x00020000
|
||
|
BIT18 EQU 0x00040000
|
||
|
BIT19 EQU 0x00080000
|
||
|
BIT20 EQU 0x00100000
|
||
|
BIT21 EQU 0x00200000
|
||
|
BIT22 EQU 0x00400000
|
||
|
BIT23 EQU 0x00800000
|
||
|
BIT24 EQU 0x00100000
|
||
|
BIT25 EQU 0x02000000
|
||
|
BIT26 EQU 0x04000000
|
||
|
BIT27 EQU 0x08000000
|
||
|
BIT28 EQU 0x10000000
|
||
|
BIT29 EQU 0x20000000
|
||
|
BIT30 EQU 0x40000000
|
||
|
BIT31 EQU 0x80000000
|
||
|
|
||
|
VID_SIS equ 0x1039
|
||
|
CTRL_SIS equ 0x7012
|
||
|
|
||
|
PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list
|
||
|
PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register
|
||
|
PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index
|
||
|
PCM_OUT_SR_REG equ 0x18 ; PCM out Status register
|
||
|
PCM_OUT_PIV_REG equ 0x1a ; PCM out prefetched index
|
||
|
PCM_OUT_CIV_REG equ 0x14 ; PCM out current index
|
||
|
|
||
|
PCM_IN_CR_REG equ 0x0b ; PCM in Control Register
|
||
|
MC_IN_CR_REG equ 0x2b ; MIC in Control Register
|
||
|
RR equ BIT1 ; reset registers. Nukes all regs
|
||
|
|
||
|
CODEC_MASTER_VOL_REG equ 0x02
|
||
|
CODEC_AUX_VOL equ 0x04 ;
|
||
|
CODEC_PCM_OUT_REG equ 18h ; PCM output volume
|
||
|
CODEC_EXT_AUDIO_REG equ 28h ; extended audio
|
||
|
CODEC_EXT_AUDIO_CTRL_REG equ 2ah ; extended audio control
|
||
|
CODEC_PCM_FRONT_DACRATE_REG equ 2ch ; PCM out sample rate
|
||
|
CODEC_PCM_SURND_DACRATE_REG equ 2eh ; surround sound sample rate
|
||
|
CODEC_PCM_LFE_DACRATE_REG equ 30h ; LFE sample rate
|
||
|
|
||
|
|
||
|
GLOB_CTRL equ 0x2C ; Global Control
|
||
|
CTRL_STAT equ 0x30 ; Global Status
|
||
|
CTRL_CAS equ 0x34 ; Codec Access Semiphore
|
||
|
|
||
|
CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit
|
||
|
|
||
|
CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready
|
||
|
|
||
|
CTRL_ST_RCS equ 0x00008000 ; Read Completion Status
|
||
|
|
||
|
CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable
|
||
|
CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off
|
||
|
CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset
|
||
|
CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset
|
||
|
CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable
|
||
|
|
||
|
CODEC_REG_POWERDOWN equ 0x26
|
||
|
CODEC_REG_ST equ 0x26
|
||
|
|
||
|
|
||
|
DEV_PLAY equ 1
|
||
|
DEV_STOP equ 2
|
||
|
DEV_CALLBACK equ 3
|
||
|
DEV_SET_BUFF equ 4
|
||
|
DEV_NOTIFY equ 5
|
||
|
DEV_SET_MASTERVOL equ 6
|
||
|
DEV_GET_MASTERVOL equ 7
|
||
|
DEV_GET_INFO equ 8
|
||
|
|
||
|
struc AC_CNTRL ;AC controller base class
|
||
|
{ .bus dd 0
|
||
|
.devfn dd 0
|
||
|
|
||
|
.vendor dd 0
|
||
|
.dev_id dd 0
|
||
|
.pci_cmd dd 0
|
||
|
.pci_stat dd 0
|
||
|
|
||
|
.codec_io_base dd 0
|
||
|
.codec_mem_base dd 0
|
||
|
|
||
|
.ctrl_io_base dd 0
|
||
|
.ctrl_mem_base dd 0
|
||
|
.cfg_reg dd 0
|
||
|
.int_line dd 0
|
||
|
|
||
|
.vendor_ids dd 0 ;vendor id string
|
||
|
.ctrl_ids dd 0 ;hub id string
|
||
|
|
||
|
.buffer dd 0
|
||
|
|
||
|
.notify_pos dd 0
|
||
|
.notify_task dd 0
|
||
|
|
||
|
.lvi_reg dd 0
|
||
|
.ctrl_setup dd 0
|
||
|
.user_callback dd 0
|
||
|
.codec_read16 dd 0
|
||
|
.codec_write16 dd 0
|
||
|
|
||
|
.ctrl_read8 dd 0
|
||
|
.ctrl_read16 dd 0
|
||
|
.ctrl_read32 dd 0
|
||
|
|
||
|
.ctrl_write8 dd 0
|
||
|
.ctrl_write16 dd 0
|
||
|
.ctrl_write32 dd 0
|
||
|
}
|
||
|
|
||
|
struc CODEC ;Audio Chip base class
|
||
|
{
|
||
|
.chip_id dd 0
|
||
|
.flags dd 0
|
||
|
.status dd 0
|
||
|
|
||
|
.ac_vendor_ids dd 0 ;ac vendor id string
|
||
|
.chip_ids dd 0 ;chip model string
|
||
|
|
||
|
.shadow_flag dd 0
|
||
|
dd 0
|
||
|
|
||
|
.regs dw 0 ; codec registers
|
||
|
.reg_master_vol dw 0 ;0x02
|
||
|
.reg_aux_out_vol dw 0 ;0x04
|
||
|
.reg_mone_vol dw 0 ;0x06
|
||
|
.reg_master_tone dw 0 ;0x08
|
||
|
.reg_beep_vol dw 0 ;0x0A
|
||
|
.reg_phone_vol dw 0 ;0x0C
|
||
|
.reg_mic_vol dw 0 ;0x0E
|
||
|
.reg_line_in_vol dw 0 ;0x10
|
||
|
.reg_cd_vol dw 0 ;0x12
|
||
|
.reg_video_vol dw 0 ;0x14
|
||
|
.reg_aux_in_vol dw 0 ;0x16
|
||
|
.reg_pcm_out_vol dw 0 ;0x18
|
||
|
.reg_rec_select dw 0 ;0x1A
|
||
|
.reg_rec_gain dw 0 ;0x1C
|
||
|
.reg_rec_gain_mic dw 0 ;0x1E
|
||
|
.reg_gen dw 0 ;0x20
|
||
|
.reg_3d_ctrl dw 0 ;0X22
|
||
|
.reg_page dw 0 ;0X24
|
||
|
.reg_powerdown dw 0 ;0x26
|
||
|
.reg_ext_audio dw 0 ;0x28
|
||
|
.reg_ext_st dw 0 ;0x2a
|
||
|
.reg_pcm_front_rate dw 0 ;0x2c
|
||
|
.reg_pcm_surr_rate dw 0 ;0x2e
|
||
|
.reg_lfe_rate dw 0 ;0x30
|
||
|
.reg_pcm_in_rate dw 0 ;0x32
|
||
|
dw 0 ;0x34
|
||
|
.reg_cent_lfe_vol dw 0 ;0x36
|
||
|
.reg_surr_vol dw 0 ;0x38
|
||
|
.reg_spdif_ctrl dw 0 ;0x3A
|
||
|
dw 0 ;0x3C
|
||
|
dw 0 ;0x3E
|
||
|
dw 0 ;0x40
|
||
|
dw 0 ;0x42
|
||
|
dw 0 ;0x44
|
||
|
dw 0 ;0x46
|
||
|
dw 0 ;0x48
|
||
|
dw 0 ;0x4A
|
||
|
dw 0 ;0x4C
|
||
|
dw 0 ;0x4E
|
||
|
dw 0 ;0x50
|
||
|
dw 0 ;0x52
|
||
|
dw 0 ;0x54
|
||
|
dw 0 ;0x56
|
||
|
dw 0 ;0x58
|
||
|
dw 0 ;0x5A
|
||
|
dw 0 ;0x5C
|
||
|
dw 0 ;0x5E
|
||
|
.reg_page_0 dw 0 ;0x60
|
||
|
.reg_page_1 dw 0 ;0x62
|
||
|
.reg_page_2 dw 0 ;0x64
|
||
|
.reg_page_3 dw 0 ;0x66
|
||
|
.reg_page_4 dw 0 ;0x68
|
||
|
.reg_page_5 dw 0 ;0x6A
|
||
|
.reg_page_6 dw 0 ;0x6C
|
||
|
.reg_page_7 dw 0 ;0x6E
|
||
|
dw 0 ;0x70
|
||
|
dw 0 ;0x72
|
||
|
dw 0 ;0x74
|
||
|
dw 0 ;0x76
|
||
|
dw 0 ;0x78
|
||
|
dw 0 ;0x7A
|
||
|
.reg_vendor_id_1 dw 0 ;0x7C
|
||
|
.reg_vendor_id_2 dw 0 ;0x7E
|
||
|
|
||
|
|
||
|
.reset dd 0 ;virual
|
||
|
.set_master_vol dd 0
|
||
|
}
|
||
|
|
||
|
struc CTRL_INFO
|
||
|
{ .pci_cmd dd ?
|
||
|
.irq dd ?
|
||
|
.glob_cntrl dd ?
|
||
|
.glob_sta dd ?
|
||
|
.codec_io_base dd ?
|
||
|
.ctrl_io_base dd ?
|
||
|
.codec_mem_base dd ?
|
||
|
.ctrl_mem_base dd ?
|
||
|
.codec_id dd ?
|
||
|
}
|
||
|
|
||
|
struc IOCTL
|
||
|
{ .handle dd ?
|
||
|
.io_code dd ?
|
||
|
.input dd ?
|
||
|
.inp_size dd ?
|
||
|
.output dd ?
|
||
|
.out_size dd ?
|
||
|
}
|
||
|
|
||
|
virtual at 0
|
||
|
IOCTL IOCTL
|
||
|
end virtual
|
||
|
|
||
|
EVENT_NOTIFY equ 0x00000200
|
||
|
|
||
|
OS_BASE equ 0; 0x80400000
|
||
|
new_app_base equ 0x60400000; 0x01000000
|
||
|
PROC_BASE equ OS_BASE+0x0080000
|
||
|
|
||
|
|
||
|
public service_proc
|
||
|
public START
|
||
|
public IMPORTS
|
||
|
|
||
|
section '.flat' align 16
|
||
|
|
||
|
START:
|
||
|
if DEBUG
|
||
|
mov esi, msgInit
|
||
|
call [SysMsgBoardStr]
|
||
|
end if
|
||
|
|
||
|
call detect_controller
|
||
|
test eax, eax
|
||
|
jz .fail
|
||
|
|
||
|
if DEBUG
|
||
|
mov esi,[ctrl.vendor_ids]
|
||
|
call [SysMsgBoardStr]
|
||
|
mov esi, [ctrl.ctrl_ids]
|
||
|
call [SysMsgBoardStr]
|
||
|
end if
|
||
|
|
||
|
call init_controller
|
||
|
test eax, eax
|
||
|
jz .fail
|
||
|
|
||
|
if DEBUG
|
||
|
mov esi, msgInitCodec
|
||
|
call [SysMsgBoardStr]
|
||
|
end if
|
||
|
|
||
|
call init_codec
|
||
|
test eax, eax
|
||
|
jz .fail
|
||
|
|
||
|
if DEBUG
|
||
|
mov esi, [codec.ac_vendor_ids]
|
||
|
call [SysMsgBoardStr]
|
||
|
|
||
|
mov esi, [codec.chip_ids]
|
||
|
call [SysMsgBoardStr]
|
||
|
end if
|
||
|
|
||
|
call reset_controller
|
||
|
call setup_codec
|
||
|
|
||
|
mov esi, msgPrimBuff
|
||
|
call [SysMsgBoardStr]
|
||
|
|
||
|
call create_primary_buff
|
||
|
|
||
|
stdcall [AttachIntHandler], [ctrl.int_line], ac97_irq
|
||
|
|
||
|
stdcall [RegService], sz_sound_srv, service_proc
|
||
|
|
||
|
mov esi, msgOk
|
||
|
call [SysMsgBoardStr]
|
||
|
|
||
|
ret
|
||
|
|
||
|
.fail:
|
||
|
if DEBUG
|
||
|
mov esi, msgFail
|
||
|
call [SysMsgBoardStr]
|
||
|
end if
|
||
|
|
||
|
xor eax, eax
|
||
|
ret
|
||
|
|
||
|
handle equ IOCTL.handle
|
||
|
io_code equ IOCTL.io_code
|
||
|
input equ IOCTL.input
|
||
|
inp_size equ IOCTL.inp_size
|
||
|
output equ IOCTL.output
|
||
|
out_size equ IOCTL.out_size
|
||
|
|
||
|
align 4
|
||
|
proc service_proc stdcall, ioctl:dword
|
||
|
|
||
|
mov edi, [ioctl]
|
||
|
mov eax, [edi+io_code]
|
||
|
cmp eax, DEV_PLAY
|
||
|
jne @F
|
||
|
if DEBUG
|
||
|
mov esi, msgPlay
|
||
|
call [SysMsgBoardStr]
|
||
|
end if
|
||
|
call play
|
||
|
ret
|
||
|
@@:
|
||
|
cmp eax, DEV_STOP
|
||
|
jne @F
|
||
|
if DEBUG
|
||
|
mov esi, msgStop
|
||
|
call [SysMsgBoardStr]
|
||
|
end if
|
||
|
call stop
|
||
|
ret
|
||
|
@@:
|
||
|
cmp eax, DEV_CALLBACK
|
||
|
jne @F
|
||
|
mov ebx, [edi+input]
|
||
|
stdcall set_callback, [ebx]
|
||
|
ret
|
||
|
@@:
|
||
|
cmp eax, DEV_SET_MASTERVOL
|
||
|
jne @F
|
||
|
mov ebx, [edi+input]
|
||
|
stdcall set_master_vol, [ebx]
|
||
|
ret
|
||
|
@@:
|
||
|
cmp eax, DEV_GET_MASTERVOL
|
||
|
jne @F
|
||
|
mov ebx, [edi+output]
|
||
|
test ebx, ebx
|
||
|
jz .fail
|
||
|
|
||
|
stdcall get_master_vol, ebx
|
||
|
ret
|
||
|
@@:
|
||
|
cmp eax, DEV_GET_INFO
|
||
|
jne @F
|
||
|
mov ebx, [edi+output]
|
||
|
stdcall get_dev_info, ebx
|
||
|
ret
|
||
|
@@:
|
||
|
.fail:
|
||
|
xor eax, eax
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
restore handle
|
||
|
restore io_code
|
||
|
restore input
|
||
|
restore inp_size
|
||
|
restore output
|
||
|
restore out_size
|
||
|
|
||
|
align 4
|
||
|
proc ac97_irq
|
||
|
|
||
|
; if DEBUG
|
||
|
; mov esi, msgIRQ
|
||
|
; call [SysMsgBoardStr]
|
||
|
; end if
|
||
|
|
||
|
mov edx, PCM_OUT_CR_REG
|
||
|
mov al, 0x14
|
||
|
call [ctrl.ctrl_write8]
|
||
|
|
||
|
mov ax, 0x1c
|
||
|
mov edx, PCM_OUT_SR_REG
|
||
|
call [ctrl.ctrl_write16]
|
||
|
|
||
|
mov edx, PCM_OUT_CIV_REG
|
||
|
call [ctrl.ctrl_read8]
|
||
|
|
||
|
and eax, 0x1F
|
||
|
cmp eax, [civ_val]
|
||
|
je .skip
|
||
|
|
||
|
mov [civ_val], eax
|
||
|
dec eax
|
||
|
and eax, 0x1F
|
||
|
mov [ctrl.lvi_reg], eax
|
||
|
|
||
|
mov edx, PCM_OUT_LVI_REG
|
||
|
call [ctrl.ctrl_write8]
|
||
|
|
||
|
mov edx, PCM_OUT_CR_REG
|
||
|
mov ax, 0x1D
|
||
|
call [ctrl.ctrl_write8]
|
||
|
|
||
|
mov eax, [civ_val]
|
||
|
add eax, 2
|
||
|
and eax, 31
|
||
|
mov ebx, dword [buff_list+eax*4]
|
||
|
|
||
|
cmp [ctrl.user_callback], 0
|
||
|
je @f
|
||
|
|
||
|
stdcall [ctrl.user_callback], ebx
|
||
|
@@:
|
||
|
ret
|
||
|
|
||
|
.skip:
|
||
|
mov edx, PCM_OUT_CR_REG
|
||
|
mov ax, 0x1D
|
||
|
call [ctrl.ctrl_write8]
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc create_primary_buff
|
||
|
|
||
|
stdcall [KernelAlloc], 0x10000
|
||
|
mov [ctrl.buffer], eax
|
||
|
|
||
|
mov edi, eax
|
||
|
mov ecx, 0x10000/4
|
||
|
xor eax, eax
|
||
|
rep stosd
|
||
|
|
||
|
stdcall [GetPgAddr], [ctrl.buffer]
|
||
|
|
||
|
mov ebx, 0xC0004000
|
||
|
mov ecx, 4
|
||
|
mov edi, pcmout_bdl
|
||
|
@@:
|
||
|
mov [edi], eax
|
||
|
mov [edi+4], ebx
|
||
|
|
||
|
mov [edi+32], eax
|
||
|
mov [edi+4+32], ebx
|
||
|
|
||
|
mov [edi+64], eax
|
||
|
mov [edi+4+64], ebx
|
||
|
|
||
|
mov [edi+96], eax
|
||
|
mov [edi+4+96], ebx
|
||
|
|
||
|
mov [edi+128], eax
|
||
|
mov [edi+4+128], ebx
|
||
|
|
||
|
mov [edi+160], eax
|
||
|
mov [edi+4+160], ebx
|
||
|
|
||
|
mov [edi+192], eax
|
||
|
mov [edi+4+192], ebx
|
||
|
|
||
|
mov [edi+224], eax
|
||
|
mov [edi+4+224], ebx
|
||
|
|
||
|
add eax, 0x4000
|
||
|
add edi, 8
|
||
|
loop @B
|
||
|
|
||
|
mov edi, buff_list
|
||
|
mov eax, [ctrl.buffer]
|
||
|
mov ecx, 4
|
||
|
@@:
|
||
|
mov [edi], eax
|
||
|
mov [edi+16], eax
|
||
|
mov [edi+32], eax
|
||
|
mov [edi+48], eax
|
||
|
mov [edi+64], eax
|
||
|
mov [edi+80], eax
|
||
|
mov [edi+96], eax
|
||
|
mov [edi+112], eax
|
||
|
|
||
|
add eax, 0x4000
|
||
|
add edi, 4
|
||
|
loop @B
|
||
|
|
||
|
mov ecx, pcmout_bdl
|
||
|
stdcall [GetPgAddr], ecx
|
||
|
and ecx, 0xFFF
|
||
|
add eax, ecx
|
||
|
|
||
|
mov edx, PCM_OUT_BDL
|
||
|
call [ctrl.ctrl_write32]
|
||
|
|
||
|
mov eax, 16
|
||
|
mov [ctrl.lvi_reg], eax
|
||
|
mov edx, PCM_OUT_LVI_REG
|
||
|
call [ctrl.ctrl_write8]
|
||
|
|
||
|
mov edx, GLOB_CTRL
|
||
|
call [ctrl.ctrl_read32]
|
||
|
and eax, not 0x000000C0
|
||
|
mov edx, GLOB_CTRL
|
||
|
call [ctrl.ctrl_write32]
|
||
|
|
||
|
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc detect_controller
|
||
|
locals
|
||
|
last_bus dd ?
|
||
|
bus dd ?
|
||
|
devfn dd ?
|
||
|
endl
|
||
|
|
||
|
xor eax, eax
|
||
|
mov [bus], eax
|
||
|
inc eax
|
||
|
call [PciApi]
|
||
|
cmp eax, -1
|
||
|
je .err
|
||
|
|
||
|
mov [last_bus], eax
|
||
|
|
||
|
.next_bus:
|
||
|
and [devfn], 0
|
||
|
.next_dev:
|
||
|
stdcall [PciRead32], [bus], [devfn], dword 0
|
||
|
test eax, eax
|
||
|
jz .next
|
||
|
cmp eax, -1
|
||
|
je .next
|
||
|
|
||
|
mov edi, devices
|
||
|
@@:
|
||
|
mov ebx, [edi]
|
||
|
test ebx, ebx
|
||
|
jz .next
|
||
|
|
||
|
cmp eax, ebx
|
||
|
je .found
|
||
|
add edi, 12
|
||
|
jmp @B
|
||
|
|
||
|
.next: inc [devfn]
|
||
|
cmp [devfn], 256
|
||
|
jb .next_dev
|
||
|
mov eax, [bus]
|
||
|
inc eax
|
||
|
mov [bus], eax
|
||
|
cmp eax, [last_bus]
|
||
|
jna .next_bus
|
||
|
xor eax, eax
|
||
|
ret
|
||
|
.found:
|
||
|
mov ebx, [bus]
|
||
|
mov [ctrl.bus], ebx
|
||
|
|
||
|
mov ecx, [devfn]
|
||
|
mov [ctrl.devfn], ecx
|
||
|
|
||
|
mov edx, eax
|
||
|
and edx, 0xFFFF
|
||
|
mov [ctrl.vendor], edx
|
||
|
shr eax, 16
|
||
|
mov [ctrl.dev_id], eax
|
||
|
|
||
|
mov ebx, [edi+4]
|
||
|
mov [ctrl.ctrl_ids], ebx
|
||
|
mov [ctrl.vendor_ids], msg_SIS
|
||
|
|
||
|
mov esi, [edi+8]
|
||
|
mov [ctrl.ctrl_setup], esi
|
||
|
|
||
|
ret
|
||
|
.err:
|
||
|
xor eax, eax
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc init_controller
|
||
|
|
||
|
stdcall [PciRead32], [ctrl.bus], [ctrl.devfn], dword 4
|
||
|
mov ebx, eax
|
||
|
and eax, 0xFFFF
|
||
|
mov [ctrl.pci_cmd], eax
|
||
|
shr ebx, 16
|
||
|
mov [ctrl.pci_stat], ebx
|
||
|
|
||
|
stdcall [PciRead32], [ctrl.bus], [ctrl.devfn], dword 0x10
|
||
|
and eax,0xFFFE
|
||
|
mov [ctrl.codec_io_base], eax
|
||
|
|
||
|
stdcall [PciRead32], [ctrl.bus], [ctrl.devfn], dword 0x14
|
||
|
and eax, 0xFFC0
|
||
|
mov [ctrl.ctrl_io_base], eax
|
||
|
|
||
|
stdcall [PciRead32], [ctrl.bus], [ctrl.devfn], dword 0x18
|
||
|
mov [ctrl.codec_mem_base], eax
|
||
|
|
||
|
stdcall [PciRead32], [ctrl.bus], [ctrl.devfn], dword 0x1C
|
||
|
mov [ctrl.ctrl_mem_base], eax
|
||
|
|
||
|
stdcall [PciRead32], [ctrl.bus], [ctrl.devfn], dword 0x3C
|
||
|
and eax, 0xFF
|
||
|
mov [ctrl.int_line], eax
|
||
|
|
||
|
stdcall [PciRead8], [ctrl.bus], [ctrl.devfn], dword 0x41
|
||
|
and eax, 0xFF
|
||
|
mov [ctrl.cfg_reg], eax
|
||
|
|
||
|
call [ctrl.ctrl_setup]
|
||
|
xor eax, eax
|
||
|
inc eax
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc set_SIS
|
||
|
mov [ctrl.codec_read16], codec_io_r16 ;virtual
|
||
|
mov [ctrl.codec_write16], codec_io_w16 ;virtual
|
||
|
|
||
|
mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual
|
||
|
mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual
|
||
|
mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual
|
||
|
|
||
|
mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual
|
||
|
mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual
|
||
|
mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc reset_controller
|
||
|
|
||
|
xor eax, eax
|
||
|
mov edx, PCM_IN_CR_REG
|
||
|
call [ctrl.ctrl_write8]
|
||
|
|
||
|
mov edx, PCM_OUT_CR_REG
|
||
|
call [ctrl.ctrl_write8]
|
||
|
|
||
|
mov edx, MC_IN_CR_REG
|
||
|
call [ctrl.ctrl_write8]
|
||
|
|
||
|
mov eax, RR
|
||
|
mov edx, PCM_IN_CR_REG
|
||
|
call [ctrl.ctrl_write8]
|
||
|
|
||
|
mov edx, PCM_OUT_CR_REG
|
||
|
call [ctrl.ctrl_write8]
|
||
|
|
||
|
mov edx, MC_IN_CR_REG
|
||
|
call [ctrl.ctrl_write8]
|
||
|
|
||
|
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc init_codec
|
||
|
locals
|
||
|
counter dd ?
|
||
|
endl
|
||
|
|
||
|
call reset_codec
|
||
|
and eax, eax
|
||
|
jz .err
|
||
|
|
||
|
xor edx, edx ;ac_reg_0
|
||
|
call [ctrl.codec_write16]
|
||
|
|
||
|
xor eax, eax
|
||
|
mov edx, CODEC_REG_POWERDOWN
|
||
|
call [ctrl.codec_write16]
|
||
|
|
||
|
mov [counter], 200 ; total 200*5 ms = 1s
|
||
|
.wait:
|
||
|
mov edx, CODEC_REG_POWERDOWN
|
||
|
call [ctrl.codec_read16]
|
||
|
and eax, 0x0F
|
||
|
cmp eax, 0x0F
|
||
|
jz .ready
|
||
|
|
||
|
mov eax, 5000 ; wait 5 ms
|
||
|
call StallExec
|
||
|
sub [counter] , 1
|
||
|
jnz .wait
|
||
|
.err:
|
||
|
xor eax, eax ; timeout error
|
||
|
ret
|
||
|
.ready:
|
||
|
call detect_codec
|
||
|
|
||
|
xor eax, eax
|
||
|
inc eax
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc reset_codec
|
||
|
mov edx, GLOB_CTRL
|
||
|
call [ctrl.ctrl_read32]
|
||
|
|
||
|
test eax, 0x02
|
||
|
jz .cold
|
||
|
|
||
|
call warm_reset
|
||
|
jnc .ok
|
||
|
.cold:
|
||
|
call cold_reset
|
||
|
jnc .ok
|
||
|
|
||
|
if DEBUG
|
||
|
mov esi, msgCFail
|
||
|
call [SysMsgBoardStr]
|
||
|
end if
|
||
|
xor eax, eax ; timeout error
|
||
|
ret
|
||
|
.ok:
|
||
|
xor eax, eax
|
||
|
inc eax
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc warm_reset
|
||
|
locals
|
||
|
counter dd ?
|
||
|
endl
|
||
|
|
||
|
mov eax, 0x06
|
||
|
mov edx, GLOB_CTRL
|
||
|
call [ctrl.ctrl_write32]
|
||
|
|
||
|
if DEBUG
|
||
|
mov esi, msgWarm
|
||
|
call [SysMsgBoardStr]
|
||
|
end if
|
||
|
|
||
|
mov [counter], 10 ; total 10*100 ms = 1s
|
||
|
.wait:
|
||
|
mov eax, 100000 ; wait 100 ms
|
||
|
call StallExec
|
||
|
|
||
|
mov edx, GLOB_CTRL
|
||
|
call [ctrl.ctrl_read32]
|
||
|
test eax, 4
|
||
|
jz .ok
|
||
|
sub [counter], 1
|
||
|
jnz .wait
|
||
|
|
||
|
if DEBUG
|
||
|
mov esi, msgWRFail
|
||
|
call [SysMsgBoardStr]
|
||
|
end if
|
||
|
|
||
|
stc
|
||
|
ret
|
||
|
.ok:
|
||
|
mov edx, CTRL_STAT
|
||
|
call [ctrl.ctrl_read32]
|
||
|
and eax, CTRL_ST_CREADY
|
||
|
jz .fail
|
||
|
clc
|
||
|
ret
|
||
|
.fail:
|
||
|
stc
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc cold_reset
|
||
|
locals
|
||
|
counter dd ?
|
||
|
endl
|
||
|
|
||
|
xor eax, eax
|
||
|
mov edx, GLOB_CTRL
|
||
|
call [ctrl.ctrl_write32]
|
||
|
|
||
|
if DEBUG
|
||
|
mov esi, msgCold
|
||
|
call [SysMsgBoardStr]
|
||
|
end if
|
||
|
|
||
|
mov eax, 1000000 ; wait 1 s
|
||
|
call StallExec
|
||
|
|
||
|
mov eax, 2
|
||
|
mov edx, GLOB_CTRL
|
||
|
call [ctrl.ctrl_write32]
|
||
|
|
||
|
mov [counter], 10 ; total 10*100 ms = 1s
|
||
|
.wait:
|
||
|
mov eax, 100000 ; wait 100 ms
|
||
|
call StallExec
|
||
|
|
||
|
mov edx, GLOB_CTRL
|
||
|
call [ctrl.ctrl_read32]
|
||
|
test eax, 4
|
||
|
jz .ok
|
||
|
sub [counter], 1
|
||
|
jnz .wait
|
||
|
|
||
|
if DEBUG
|
||
|
mov esi, msgCRFail
|
||
|
call [SysMsgBoardStr]
|
||
|
end if
|
||
|
stc
|
||
|
ret
|
||
|
.ok:
|
||
|
mov edx, CTRL_STAT
|
||
|
call [ctrl.ctrl_read32]
|
||
|
and eax, CTRL_ST_CREADY
|
||
|
jz .fail
|
||
|
clc
|
||
|
ret
|
||
|
.fail:
|
||
|
stc
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc play
|
||
|
xor eax, eax
|
||
|
mov [civ_val], eax
|
||
|
mov edx, PCM_OUT_CIV_REG
|
||
|
call [ctrl.ctrl_write8]
|
||
|
|
||
|
mov eax, 16
|
||
|
mov [ctrl.lvi_reg], eax
|
||
|
mov edx, PCM_OUT_LVI_REG
|
||
|
call [ctrl.ctrl_write8]
|
||
|
|
||
|
mov edx, PCM_OUT_CR_REG
|
||
|
mov ax, 0x1D
|
||
|
call [ctrl.ctrl_write8]
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc stop
|
||
|
mov edx, PCM_OUT_CR_REG
|
||
|
mov ax, 0x14
|
||
|
call [ctrl.ctrl_write8]
|
||
|
|
||
|
mov eax, 16
|
||
|
mov [ctrl.lvi_reg], eax
|
||
|
mov edx, PCM_OUT_LVI_REG
|
||
|
call [ctrl.ctrl_write8]
|
||
|
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc get_dev_info stdcall, p_info:dword
|
||
|
virtual at esi
|
||
|
CTRL_INFO CTRL_INFO
|
||
|
end virtual
|
||
|
|
||
|
mov esi, [p_info]
|
||
|
mov eax, [ctrl.int_line]
|
||
|
mov ebx, [ctrl.codec_io_base]
|
||
|
mov ecx, [ctrl.ctrl_io_base]
|
||
|
mov edx, [ctrl.codec_mem_base]
|
||
|
mov edi, [ctrl.ctrl_mem_base]
|
||
|
|
||
|
mov [CTRL_INFO.irq], eax
|
||
|
mov [CTRL_INFO.codec_io_base], ebx
|
||
|
mov [CTRL_INFO.ctrl_io_base], ecx
|
||
|
mov [CTRL_INFO.codec_mem_base], edx
|
||
|
mov [CTRL_INFO.ctrl_mem_base], edi
|
||
|
|
||
|
mov eax, [codec.chip_id]
|
||
|
mov [CTRL_INFO.codec_id], eax
|
||
|
|
||
|
mov edx, GLOB_CTRL
|
||
|
call [ctrl.ctrl_read32]
|
||
|
mov [CTRL_INFO.glob_cntrl], eax
|
||
|
|
||
|
mov edx, CTRL_STAT
|
||
|
call [ctrl.ctrl_read32]
|
||
|
mov [CTRL_INFO.glob_sta], eax
|
||
|
|
||
|
mov ebx, [ctrl.pci_cmd]
|
||
|
mov [CTRL_INFO.pci_cmd], ebx
|
||
|
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc set_callback stdcall, handler:dword
|
||
|
mov eax, [handler]
|
||
|
mov [ctrl.user_callback], eax
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax
|
||
|
|
||
|
mov edx, [ac_reg]
|
||
|
|
||
|
mov ebx, edx
|
||
|
shr ebx, 1
|
||
|
bt [codec.shadow_flag], ebx
|
||
|
jc .use_shadow
|
||
|
|
||
|
call [ctrl.codec_read16] ;change edx !!!
|
||
|
mov ecx, eax
|
||
|
|
||
|
mov edx, CTRL_STAT
|
||
|
call [ctrl.ctrl_read32]
|
||
|
test eax, CTRL_ST_RCS
|
||
|
jz .read_ok
|
||
|
|
||
|
mov edx, CTRL_STAT
|
||
|
call [ctrl.ctrl_write32]
|
||
|
xor eax,eax
|
||
|
not eax ;timeout
|
||
|
ret
|
||
|
.read_ok:
|
||
|
mov edx, [ac_reg]
|
||
|
mov [codec.regs+edx], cx
|
||
|
bts [codec.shadow_flag], ebx
|
||
|
mov eax, ecx
|
||
|
ret
|
||
|
.use_shadow:
|
||
|
movzx eax, word [codec.regs+edx]
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc codec_write stdcall, ac_reg:dword
|
||
|
push eax
|
||
|
call check_semafore
|
||
|
and eax, eax
|
||
|
jz .err
|
||
|
pop eax
|
||
|
|
||
|
mov esi, [ac_reg]
|
||
|
mov edx, esi
|
||
|
call [ctrl.codec_write16]
|
||
|
mov [codec.regs+esi], ax
|
||
|
shr esi, 1
|
||
|
bts [codec.shadow_flag], esi
|
||
|
ret
|
||
|
.err:
|
||
|
pop eax
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
|
||
|
align 4
|
||
|
proc codec_check_ready
|
||
|
|
||
|
mov edx, CTRL_ST
|
||
|
call [ctrl.ctrl_read32]
|
||
|
and eax, CTRL_ST_CREADY
|
||
|
jz .not_ready
|
||
|
|
||
|
xor eax, wax
|
||
|
inc eax
|
||
|
ret
|
||
|
|
||
|
align 4
|
||
|
.not_ready:
|
||
|
xor eax, eax
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
|
||
|
align 4
|
||
|
proc check_semafore
|
||
|
local counter:DWORD
|
||
|
|
||
|
mov [counter], 100
|
||
|
.l1:
|
||
|
mov edx, CTRL_CAS
|
||
|
call [ctrl.ctrl_read8]
|
||
|
and eax, CAS_FLAG
|
||
|
jz .ok
|
||
|
|
||
|
mov eax, 1
|
||
|
call StallExec
|
||
|
sub [counter], 1
|
||
|
jnz .l1
|
||
|
xor eax, eax
|
||
|
ret
|
||
|
align 4
|
||
|
.ok:
|
||
|
xor eax,eax
|
||
|
inc eax
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc StallExec
|
||
|
push ecx
|
||
|
push edx
|
||
|
push ebx
|
||
|
push eax
|
||
|
|
||
|
mov ecx, CPU_FREQ
|
||
|
mul ecx
|
||
|
mov ebx, eax ;low
|
||
|
mov ecx, edx ;high
|
||
|
rdtsc
|
||
|
add ebx, eax
|
||
|
adc ecx,edx
|
||
|
@@:
|
||
|
rdtsc
|
||
|
sub eax, ebx
|
||
|
sbb edx, ecx
|
||
|
jb @B
|
||
|
|
||
|
pop eax
|
||
|
pop ebx
|
||
|
pop edx
|
||
|
pop ecx
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
; CONTROLLER IO functions
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
|
||
|
align 4
|
||
|
proc codec_io_r16
|
||
|
add edx, [ctrl.codec_io_base]
|
||
|
in ax, dx
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc codec_io_w16
|
||
|
add edx, [ctrl.codec_io_base]
|
||
|
out dx, ax
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc ctrl_io_r8
|
||
|
add edx, [ctrl.ctrl_io_base]
|
||
|
in al, dx
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc ctrl_io_r16
|
||
|
add edx, [ctrl.ctrl_io_base]
|
||
|
in ax, dx
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc ctrl_io_r32
|
||
|
add edx, [ctrl.ctrl_io_base]
|
||
|
in eax, dx
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc ctrl_io_w8
|
||
|
add edx, [ctrl.ctrl_io_base]
|
||
|
out dx, al
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc ctrl_io_w16
|
||
|
add edx, [ctrl.ctrl_io_base]
|
||
|
out dx, ax
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
align 4
|
||
|
proc ctrl_io_w32
|
||
|
add edx, [ctrl.ctrl_io_base]
|
||
|
out dx, eax
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
include "codec.inc"
|
||
|
|
||
|
|
||
|
align 16
|
||
|
pcmout_bdl dq 32 dup(0)
|
||
|
buff_list dd 32 dup(0)
|
||
|
|
||
|
align 16
|
||
|
ctrl AC_CNTRL
|
||
|
|
||
|
align 16
|
||
|
codec CODEC
|
||
|
|
||
|
civ_val dd 0
|
||
|
|
||
|
align 16
|
||
|
devices dd (CTRL_SIS shl 16)+VID_SIS,msg_AC, set_SIS
|
||
|
dd 0
|
||
|
|
||
|
align 16
|
||
|
imp_table:
|
||
|
IMPORTS:
|
||
|
|
||
|
AttachIntHandler dd szAttachIntHandler
|
||
|
SysMsgBoardStr dd szSysMsgBoardStr
|
||
|
PciApi dd szPciApi
|
||
|
PciRead32 dd szPciRead32
|
||
|
PciRead8 dd szPciRead8
|
||
|
PciWrite8 dd szPciWrite8
|
||
|
AllocKernelSpace dd szAllocKernelSpace
|
||
|
MapPage dd szMapPage
|
||
|
KernelAlloc dd szKernelAlloc
|
||
|
GetPgAddr dd szGetPgAddr
|
||
|
RegService dd szRegService
|
||
|
GetCurrentTask dd szGetCurrentTask
|
||
|
dd 0
|
||
|
|
||
|
msg_AC db '7012 AC97 controller',13,10, 0
|
||
|
msg_SIS db 'Silicon Integrated Systems',13,10, 0
|
||
|
|
||
|
szKernel db 'KERNEL', 0
|
||
|
szAttachIntHandler db 'AttachIntHandler',0
|
||
|
szSysMsgBoardStr db 'SysMsgBoardStr', 0
|
||
|
szPciApi db 'PciApi', 0
|
||
|
szPciRead32 db 'PciRead32', 0
|
||
|
szPciRead8 db 'PciRead8', 0
|
||
|
szPciWrite8 db 'PciWrite8',0
|
||
|
szAllocKernelSpace db 'AllocKernelSpace',0
|
||
|
szMapPage db 'MapPage',0
|
||
|
szRegService db 'RegService',0
|
||
|
szKernelAlloc db 'KernelAlloc',0
|
||
|
szGetPgAddr db 'GetPgAddr',0
|
||
|
szGetCurrentTask db 'GetCurrentTask ',0
|
||
|
|
||
|
sz_sound_srv db 'SOUND',0
|
||
|
|
||
|
msgInit db 'detect hardware...',13,10,0
|
||
|
msgFail db 'device not found',13,10,0
|
||
|
msgPlay db 'start play', 13,10,0
|
||
|
msgStop db 'stop play', 13,10,0
|
||
|
msgNotify db 'call notify',13,10,0
|
||
|
msgIRQ db 'AC97 IRQ', 13,10,0
|
||
|
msgInitCtrl db 'init controller',13,10,0
|
||
|
msgInitCodec db 'init codec',13,10,0
|
||
|
msgPrimBuff db 'create primary buffer',13,10,0
|
||
|
msgReg db 'set service handler',13,10,0
|
||
|
msgOk db 'service installed',13,10,0
|
||
|
msgCold db 'cold resret',13,10,0
|
||
|
msgWarm db 'warm reset',13,10,0
|
||
|
msgWRFail db 'warm reset failed',13,10,0
|
||
|
msgCRFail db 'cold reset failed',13,10,0
|
||
|
msgCFail db 'codec not ready',13,10,0
|