Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 2129 → Rev 2130

/kernel/branches/Kolibri-acpi/drivers/com_mouse.asm
332,7 → 332,7
 
mov [esi+COM_MOUSE_DATA.MouseByteNumber],0
.EndMouseInterrupt:
 
mov al, 1
ret
 
;all initialized data place here
/kernel/branches/Kolibri-acpi/drivers/sb16/sb16.asm
240,6 → 240,7
stdcall [callback],SB16Buffer1 ;for 64k buffer
end if
xor eax,eax
not eax
ret
 
.fill_second_half:
250,6 → 251,7
stdcall [callback],SB16Buffer3 ;for 64k buffer
end if
xor eax,eax
not eax
ret
endp
;-------------------------------------------------------------------------------
/kernel/branches/Kolibri-acpi/drivers/vidintel.asm
0,0 → 1,465
; Stub of videodriver for Intel videocards.
; (c) CleverMouse
 
; When the start procedure gots control,
; it tries to detect preferred resolution,
; sets the detected resolution assuming 32-bpp VESA mode and exits
; (without registering a service).
; Detection can be overloaded with compile-time settings
; use_predefined_mode/predefined_width/predefined_height.
 
; set predefined resolution here
use_predefined_mode = 0;1
predefined_width = 0;1366
predefined_height = 0;768
 
; standard driver stuff
format MS COFF
 
DEBUG = 1
 
include 'proc32.inc'
include 'imports.inc'
 
public START
public version
 
section '.flat' code readable align 16
; the start procedure (see the description above)
START:
; 1. Detect device. Abort if not found.
push esi
call DetectDevice
test esi, esi
jz .return0
; 2. Detect optimal mode unless the mode is given explicitly. Abort if failed.
if use_predefined_mode = 0
call DetectMode
end if
cmp [width], 0
jz .return0_cleanup
; 3. Set the detected mode.
call SetMode
; 4. Cleanup and return.
.return0_cleanup:
stdcall FreeKernelSpace, esi
.return0:
pop esi
xor eax, eax
ret 4
 
; check that there is Intel videocard
; if so, map MMIO registers and set internal variables
; esi points to MMIO block; NULL means no device
DetectDevice:
; 1. Sanity check: check that we are dealing with Intel videocard.
; Integrated video device for Intel is always at PCI:0:2:0.
xor esi, esi ; initialize return value to NULL
; 1a. Get PCI VendorID and DeviceID.
push esi
push 10h
push esi
call PciRead32
; 1b. loword(eax) = ax = VendorID, hiword(eax) = DeviceID.
; Test whether we have Intel chipset.
cmp ax, 8086h
jnz .return
; 1c. Say hi including DeviceID.
shr eax, 10h
push edi
pusha
mov edi, pciid_text
call WriteWord
mov esi, hellomsg
call SysMsgBoardStr
popa
; 1d. Test whether we know this DeviceID.
; If this is the case, remember the position of the device in line of Intel cards;
; this knowledge will be useful later.
; Tested on devices with id: 8086:0046, partially 8086:2A02.
mov ecx, pciids_num
mov edi, pciids
repnz scasw
pop edi
jnz .return_unknown_pciid
sub ecx, pciids_num - 1
neg ecx
mov [deviceType], ecx
; 1e. Continue saying hi with positive intonation.
pusha
mov esi, knownmsg
call SysMsgBoardStr
popa
; 2. Prepare MMIO region to control the card.
; 2a. Read MMIO physical address from PCI config space.
push 10h
cmp ecx, i9xx_start
jae @f
mov byte [esp], 14h
@@:
push 10h
push esi
call PciRead32
; 2b. Mask out PCI region type, lower 4 bits.
and al, not 0xF
; 2c. Create virtual mapping of the physical memory.
push 1Bh
push 100000h
push eax
call MapIoMem
; 3. Return.
xchg esi, eax
.return:
ret
; 1f. If we do not know DeviceID, continue saying hi with negative intonation.
.return_unknown_pciid:
pusha
mov esi, unknownmsg
call SysMsgBoardStr
popa
ret
 
; Convert word in ax to hexadecimal text in edi, advance edi.
WriteWord:
; 1. Convert high byte.
push eax
mov al, ah
call WriteByte
pop eax
; 2. Convert low byte.
; Fall through to WriteByte; ret from WriteByte is ret from WriteWord too.
 
; Convert byte in al to hexadecimal text in edi, advance edi.
WriteByte:
; 1. Convert high nibble.
push eax
shr al, 4
call WriteNibble
pop eax
; 2. Convert low nibble.
and al, 0xF
; Fall through to WriteNibble; ret from WriteNibble is ret from WriteByte too.
 
; Convert nibble in al to hexadecimal text in edi, advance edi.
WriteNibble:
; Obvious, isn't it?
cmp al, 10
sbb al, 69h
das
stosb
ret
 
if use_predefined_mode = 0
; detect resolution of the flat panel
DetectMode:
push esi edi
; 1. Get the location of block of GMBUS* registers.
; Starting with Ironlake, GMBUS* registers were moved.
add esi, 5100h
cmp [deviceType], ironlake_start
jb @f
add esi, 0xC0000
@@:
; 2. Initialize GMBUS engine.
mov edi, edid
mov ecx, 0x10000
@@:
test byte [esi+8+1], 80h
loopnz @b
jnz .fail
mov dword [esi], 3
test byte [esi+8+1], 4
jz .noreset
call ResetGMBus
jnz .fail
.noreset:
; 3. Send read command.
and dword [esi+20h], 0
mov dword [esi+4], 4E8000A1h
; 4. Wait for data, writing to the buffer as data arrive.
.getdata:
mov ecx, 0x10000
@@:
test byte [esi+8+1], 8
loopz @b
test byte [esi+8+1], 4
jz .dataok
call ResetGMBus
jmp .fail
.dataok:
mov eax, [esi+0Ch]
stosd
cmp edi, edid+80h
jb .getdata
; 5. Wait for bus idle.
mov ecx, 0x10000
@@:
test byte [esi+8+1], 2
loopnz @b
; 6. We got EDID; dump it if DEBUG.
if DEBUG
pusha
xor ecx, ecx
mov esi, edid
mov edi, edid_text
.dumploop:
lodsb
call WriteByte
mov al, ' '
stosb
inc cl
test cl, 15
jnz @f
mov byte [edi-1], 13
mov al, 10
stosb
@@:
test cl, cl
jns .dumploop
mov esi, edidmsg
call SysMsgBoardStr
popa
end if
; 7. Test whether EDID is good.
; 7a. Signature: 00 FF FF FF FF FF FF 00.
mov esi, edid
cmp dword [esi], 0xFFFFFF00
jnz .fail
cmp dword [esi+4], 0x00FFFFFF
jnz .fail
; 7b. Checksum must be zero.
xor edx, edx
mov ecx, 80h
@@:
lodsb
add dl, al
loop @b
jnz .fail
; 8. Get width and height from EDID.
xor eax, eax
mov ah, [esi-80h+3Ah]
shr ah, 4
mov al, [esi-80h+38h]
mov [width], eax
mov ah, [esi-80h+3Dh]
shr ah, 4
mov al, [esi-80h+3Bh]
mov [height], eax
; 9. Return.
.fail:
pop edi esi
ret
 
; reset bus, clear all errors
ResetGMBus:
; look into the PRM
mov dword [esi+4], 80000000h
mov dword [esi+4], 0
mov ecx, 0x10000
@@:
test byte [esi+8+1], 2
loopnz @b
ret
end if
 
; set resolution [width]*[height]
SetMode:
; 1. Program the registers of videocard.
; look into the PRM
cli
; or byte [esi+7000Ah], 0Ch ; PIPEACONF: disable Display+Cursor Planes
; or byte [esi+7100Ah], 0Ch ; PIPEBCONF: disable Display+Cursor Planes
xor eax, eax
xor edx, edx
cmp [deviceType], i965_start
jb @f
mov dl, 9Ch - 84h
@@:
; or byte [esi+71403h], 80h ; VGACNTRL: VGA Display Disable
and byte [esi+70080h], not 27h ; CURACNTR: disable cursor A
mov dword [esi+70084h], eax ; CURABASE: force write to CURA* regs
and byte [esi+700C0h], not 27h ; CURBCNTR: disable cursor B
mov dword [esi+700C4h], eax ; CURBBASE: force write to CURB* regs
and byte [esi+70183h], not 80h ; DSPACNTR: disable Primary A Plane
mov dword [esi+edx+70184h], eax ; DSPALINOFF/DSPASURF: force write to DSPA* regs
and byte [esi+71183h], not 80h ; DSPBCNTR: disable Primary B Plane
mov dword [esi+edx+71184h], eax ; DSPBLINOFF/DSPBSURF: force write to DSPB* regs
if 1
cmp [deviceType], ironlake_start
jae .disable_pipes
mov edx, 10000h
or byte [esi+70024h], 2 ; PIPEASTAT: clear VBLANK status
or byte [esi+71024h], 2 ; PIPEBSTAT: clear VBLANK status
.wait_vblank_preironlake1:
mov ecx, 1000h
loop $
test byte [esi+7000Bh], 80h ; PIPEACONF: pipe A active?
jz @f
test byte [esi+70024h], 2 ; PIPEASTAT: got VBLANK?
jz .wait_vblank_preironlake2
@@:
test byte [esi+7100Bh], 80h ; PIPEBCONF: pipe B active?
jz .disable_pipes
test byte [esi+71024h], 2 ; PIPEBSTAT: got VBLANK?
jnz .disable_pipes
.wait_vblank_preironlake2:
dec edx
jnz .wait_vblank_preironlake1
jmp .not_disabled
.disable_pipes:
end if
and byte [esi+7000Bh], not 80h ; PIPEACONF: disable pipe
and byte [esi+7100Bh], not 80h ; PIPEBCONF: disable pipe
if 1
mov edx, 10000h
@@:
mov ecx, 1000h
loop $
test byte [esi+7000Bh], 40h ; PIPEACONF: wait until pipe disabled
jz @f
dec edx
jnz @b
.not_disabled:
sti
jmp .return
@@:
test byte [esi+7100Bh], 40h ; PIPEBCONF: wait until pipe disabled
jz @f
mov ecx, 1000h
loop $
dec edx
jnz @b
jmp .not_disabled
@@:
else
; alternative way of waiting for pipe stop, works too
mov edx, 1000h
.dis1:
push dword [esi+71000h]
push dword [esi+70000h]
mov ecx, 10000h
loop $
pop eax
xor eax, [esi+70000h]
and eax, 1FFFh
pop eax
jnz .notdis1
xor eax, [esi+71000h]
and eax, 1FFFh
jz .disabled
.notdis1:
dec edx
jnz .dis1
.not_disabled:
sti
jmp .return
.disabled:
end if
lea eax, [esi+61183h]
cmp [deviceType], ironlake_start
jb @f
add eax, 0xE0000 - 0x60000
@@:
lea edx, [esi+60000h]
test byte [eax], 40h
jz @f
add edx, 1000h
@@:
mov eax, [width]
dec eax
shl eax, 16
mov ax, word [height]
dec eax
mov dword [edx+1Ch], eax ; PIPEASRC: set source image size
ror eax, 16
mov dword [edx+10190h], eax ; for old cards
mov ecx, [width]
add ecx, 15
and ecx, not 15
shl ecx, 2
mov dword [edx+10188h], ecx ; DSPASTRIDE: set scanline length
and byte [esi+61233h], not 80h ; PFIT_CONTROL: disable panel fitting
or byte [edx+1000Bh], 80h ; PIPEACONF: enable pipe
; and byte [edx+1000Ah], not 0Ch ; PIPEACONF: enable Display+Cursor Planes
or byte [edx+10183h], 80h ; DSPACNTR: enable Display Plane A
sti
; 2. Notify the kernel that resolution has changed.
call GetDisplay
mov edx, [width]
mov dword [eax+8], edx
mov edx, [height]
mov dword [eax+0Ch], edx
mov [eax+18h], ecx
mov eax, [width]
dec eax
dec edx
call SetScreen
.return:
ret
 
align 4
hellomsg db 'Intel videocard detected, PciId=8086:'
pciid_text db '0000'
db ', which is ', 0
knownmsg db 'known',13,10,0
unknownmsg db 'unknown',13,10,0
 
if DEBUG
edidmsg db 'EDID successfully read:',13,10
edid_text rb 8*(16*3+1)
db 0
end if
 
version:
dd 0x50005
 
width dd predefined_width
height dd predefined_height
 
pciids:
dw 0x3577 ; i830m
dw 0x2562 ; 845g
dw 0x3582 ; i855gm
i865_start = ($ - pciids) / 2
dw 0x2572 ; i865g
i9xx_start = ($ - pciids) / 2
dw 0x2582 ; i915g
dw 0x258a ; e7221g (i915g)
dw 0x2592 ; i915gm
dw 0x2772 ; i945g
dw 0x27a2 ; i945gm
dw 0x27ae ; i945gme
i965_start = ($ - pciids) / 2
dw 0x2972 ; i946qz (i965g)
dw 0x2982 ; g35g (i965g)
dw 0x2992 ; i965q (i965g)
dw 0x29a2 ; i965g
dw 0x29b2 ; q35g
dw 0x29c2 ; g33g
dw 0x29d2 ; q33g
dw 0x2a02 ; i965gm
dw 0x2a12 ; i965gm
dw 0x2a42 ; gm45
dw 0x2e02 ; g45
dw 0x2e12 ; g45
dw 0x2e22 ; g45
dw 0x2e32 ; g45
dw 0x2e42 ; g45
dw 0x2e92 ; g45
dw 0xa001 ; pineview
dw 0xa011 ; pineview
ironlake_start = ($ - pciids) / 2
dw 0x0042 ; ironlake_d
dw 0x0046 ; ironlake_m
dw 0x0102 ; sandybridge_d
dw 0x0112 ; sandybridge_d
dw 0x0122 ; sandybridge_d
dw 0x0106 ; sandybridge_m
dw 0x0116 ; sandybridge_m
dw 0x0126 ; sandybridge_m
dw 0x010A ; sandybridge_d
pciids_num = ($ - pciids) / 2
 
align 4
deviceType dd ?
edid rb 0x80
/kernel/branches/Kolibri-acpi/drivers/vt823x.asm
0,0 → 1,1281
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
format MS COFF
 
DEBUG equ 1
 
include 'proc32.inc'
include 'imports.inc'
 
API_VERSION equ 0x01000100
 
USE_COM_IRQ equ 0 ;make irq 3 and irq 4 available for PCI devices
IRQ_REMAP equ 0
IRQ_LINE equ 0
 
 
;irq 0,1,2,8,12,13 ­¥¤®áâ㯭ë
; FEDCBA9876543210
VALID_IRQ equ 1100111011111000b
ATTCH_IRQ equ 0000111010100000b
 
if USE_COM_IRQ
ATTCH_IRQ equ 0000111010111000b
end if
 
CPU_FREQ equ 2600d
 
BIT0 EQU 0x00000001
BIT1 EQU 0x00000002
BIT5 EQU 0x00000020
BIT10 EQU 0x00000400
 
VID_VIA equ 0x1106
 
CTRL_VT82C686 equ 0x3058
CTRL_VT8233_5 equ 0x3059
 
 
CODEC_MASTER_VOL_REG equ 0x02
CODEC_AUX_VOL equ 0x04 ;
CODEC_PCM_OUT_REG equ 0x18 ; PCM output volume
CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio
CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control
CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate
CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate
CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate
 
 
;VIA host controller registers set
;; common offsets
VIA_REG_OFFSET_STATUS equ 0x00 ;; byte - channel status
VIA_REG_STAT_ACTIVE equ 0x80 ;; RO
VIA_REG_STAT_PAUSED equ 0x40 ;; RO
VIA_REG_STAT_TRIGGER_QUEUED equ 0x08 ;; RO
VIA_REG_STAT_STOPPED equ 0x04 ;; RWC
VIA_REG_STAT_EOL equ 0x02 ;; RWC
VIA_REG_STAT_FLAG equ 0x01 ;; RWC
VIA_REG_OFFSET_CONTROL equ 0x01 ;; byte - channel control
VIA_REG_CTRL_START equ 0x80 ;; WO
VIA_REG_CTRL_TERMINATE equ 0x40 ;; WO
VIA_REG_CTRL_AUTOSTART equ 0x20
VIA_REG_CTRL_PAUSE equ 0x08 ;; RW
VIA_REG_CTRL_INT_STOP equ 0x04
VIA_REG_CTRL_INT_EOL equ 0x02
VIA_REG_CTRL_INT_FLAG equ 0x01
VIA_REG_CTRL_RESET equ 0x01 ;; RW - probably reset? undocumented
VIA_REG_CTRL_INT equ (VIA_REG_CTRL_INT_FLAG or \
VIA_REG_CTRL_INT_EOL or \
VIA_REG_CTRL_AUTOSTART)
VIA_REG_OFFSET_TYPE equ 0x02 ;; byte - channel type (686 only)
VIA_REG_TYPE_AUTOSTART equ 0x80 ;; RW - autostart at EOL
VIA_REG_TYPE_16BIT equ 0x20 ;; RW
VIA_REG_TYPE_STEREO equ 0x10 ;; RW
VIA_REG_TYPE_INT_LLINE equ 0x00
VIA_REG_TYPE_INT_LSAMPLE equ 0x04
VIA_REG_TYPE_INT_LESSONE equ 0x08
VIA_REG_TYPE_INT_MASK equ 0x0c
VIA_REG_TYPE_INT_EOL equ 0x02
VIA_REG_TYPE_INT_FLAG equ 0x01
VIA_REG_OFFSET_TABLE_PTR equ 0x04 ;; dword - channel table pointer
VIA_REG_OFFSET_CURR_PTR equ 0x04 ;; dword - channel current pointer
VIA_REG_OFFSET_STOP_IDX equ 0x08 ;; dword - stop index, channel type, sample rate
VIA8233_REG_TYPE_16BIT equ 0x00200000 ;; RW
VIA8233_REG_TYPE_STEREO equ 0x00100000 ;; RW
VIA_REG_OFFSET_CURR_COUNT equ 0x0c ;; dword - channel current count (24 bit)
VIA_REG_OFFSET_CURR_INDEX equ 0x0f ;; byte - channel current index (for via8233 only)
 
 
VIADEV_PLAYBACK equ 0x00
VIADEV_CAPTURE equ 0x10
VIADEV_FM equ 0x20
 
;; AC'97 ;;
VIA_REG_AC97 equ 0x80 ; dword
VIA_REG_AC97_CODEC_ID_MASK equ 0xC0000000 ;(3<<30)
VIA_REG_AC97_CODEC_ID_SHIFT equ 30
VIA_REG_AC97_CODEC_ID_PRIMARY equ 0x00
VIA_REG_AC97_CODEC_ID_SECONDARY equ 0x01
VIA_REG_AC97_SECONDARY_VALID equ 0x08000000 ;(1<<27)
VIA_REG_AC97_PRIMARY_VALID equ 0x02000000 ;(1<<25)
VIA_REG_AC97_BUSY equ 0x01000000 ;(1<<24)
VIA_REG_AC97_READ equ 0x00800000 ;(1<<23)
VIA_REG_AC97_CMD_SHIFT equ 16
VIA_REG_AC97_CMD_MASK equ 0x7E
VIA_REG_AC97_DATA_SHIFT equ 0
VIA_REG_AC97_DATA_MASK equ 0xFFFF
 
VIA_REG_SGD_SHADOW equ 0x84 ; dword
 
;; via8233-specific registers ;;
VIA_REG_OFS_PLAYBACK_VOLUME_L equ 0x02 ;; byte
VIA_REG_OFS_PLAYBACK_VOLUME_R equ 0x03 ;; byte
VIA_REG_OFS_MULTPLAY_FORMAT equ 0x02 ;; byte - format and channels
VIA_REG_MULTPLAY_FMT_8BIT equ 0x00
VIA_REG_MULTPLAY_FMT_16BIT equ 0x80
VIA_REG_MULTPLAY_FMT_CH_MASK equ 0x70 ;; # channels << 4 (valid = 1,2,4,6)
VIA_REG_OFS_CAPTURE_FIFO equ 0x02 ;; byte - bit 6 = fifo enable
VIA_REG_CAPTURE_FIFO_ENABLE equ 0x40
 
VIA_DXS_MAX_VOLUME equ 31 ;; max. volume (attenuation) of reg 0x32/33
 
VIA_TBL_BIT_FLAG equ 0x40000000
VIA_TBL_BIT_EOL equ 0x80000000
 
;; pci space ;;
VIA_ACLINK_STAT equ 0x40
;...
VIA_ACLINK_C00_READY equ 0x01 ; primary codec ready
VIA_ACLINK_CTRL equ 0x41
VIA_ACLINK_CTRL_ENABLE equ 0x80 ; 0: disable, 1: enable
VIA_ACLINK_CTRL_RESET equ 0x40 ; 0: assert, 1: de-assert
VIA_ACLINK_CTRL_SYNC equ 0x20 ; 0: release SYNC, 1: force SYNC hi
VIA_ACLINK_CTRL_SDO equ 0x10 ; 0: release SDO, 1: force SDO hi
VIA_ACLINK_CTRL_VRA equ 0x08 ; 0: disable VRA, 1: enable VRA
VIA_ACLINK_CTRL_PCM equ 0x04 ; 0: disable PCM, 1: enable PCM
VIA_ACLINK_CTRL_FM equ 0x02 ; via686 only
VIA_ACLINK_CTRL_SB equ 0x01 ; via686 only
VIA_ACLINK_CTRL_INIT equ (VIA_ACLINK_CTRL_ENABLE or \
VIA_ACLINK_CTRL_RESET or \
VIA_ACLINK_CTRL_PCM or \
VIA_ACLINK_CTRL_VRA)
VIA_FUNC_ENABLE equ 0x42
VIA_FUNC_MIDI_PNP equ 0x80 ; FIXME: it's 0x40 in the datasheet!
VIA_FUNC_MIDI_IRQMASK equ 0x40 ; FIXME: not documented!
VIA_FUNC_RX2C_WRITE equ 0x20
VIA_FUNC_SB_FIFO_EMPTY equ 0x10
VIA_FUNC_ENABLE_GAME equ 0x08
VIA_FUNC_ENABLE_FM equ 0x04
VIA_FUNC_ENABLE_MIDI equ 0x02
VIA_FUNC_ENABLE_SB equ 0x01
VIA_PNP_CONTROL equ 0x43
VIA_FM_NMI_CTRL equ 0x48
VIA8233_VOLCHG_CTRL equ 0x48
VIA8233_SPDIF_CTRL equ 0x49
VIA8233_SPDIF_DX3 equ 0x08
VIA8233_SPDIF_SLOT_MASK equ 0x03
VIA8233_SPDIF_SLOT_1011 equ 0x00
VIA8233_SPDIF_SLOT_34 equ 0x01
VIA8233_SPDIF_SLOT_78 equ 0x02
VIA8233_SPDIF_SLOT_69 equ 0x03
;] Asper
 
 
SRV_GETVERSION equ 0
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 ?
.devfn dd ?
 
.vendor dd ?
.dev_id dd ?
.pci_cmd dd ?
.pci_stat dd ?
 
.codec_io_base dd ?
.codec_mem_base dd ?
 
.ctrl_io_base dd ?
.ctrl_mem_base dd ?
.cfg_reg dd ?
.int_line dd ?
 
.vendor_ids dd ? ;vendor id string
.ctrl_ids dd ? ;hub id string
 
.buffer dd ?
 
.notify_pos dd ?
.notify_task dd ?
 
.lvi_reg dd ?
.ctrl_setup dd ?
.user_callback dd ?
.codec_read16 dd ?
.codec_write16 dd ?
 
.ctrl_read8 dd ?
.ctrl_read16 dd ?
.ctrl_read32 dd ?
 
.ctrl_write8 dd ?
.ctrl_write16 dd ?
.ctrl_write32 dd ?
}
 
struc CODEC ;Audio Chip base class
{
.chip_id dd ?
.flags dd ?
.status dd ?
 
.ac_vendor_ids dd ? ;ac vendor id string
.chip_ids dd ? ;chip model string
 
.shadow_flag dd ?
dd ?
 
.regs dw ? ; codec registers
.reg_master_vol dw ? ;0x02
.reg_aux_out_vol dw ? ;0x04
.reg_mone_vol dw ? ;0x06
.reg_master_tone dw ? ;0x08
.reg_beep_vol dw ? ;0x0A
.reg_phone_vol dw ? ;0x0C
.reg_mic_vol dw ? ;0x0E
.reg_line_in_vol dw ? ;0x10
.reg_cd_vol dw ? ;0x12
.reg_video_vol dw ? ;0x14
.reg_aux_in_vol dw ? ;0x16
.reg_pcm_out_vol dw ? ;0x18
.reg_rec_select dw ? ;0x1A
.reg_rec_gain dw ? ;0x1C
.reg_rec_gain_mic dw ? ;0x1E
.reg_gen dw ? ;0x20
.reg_3d_ctrl dw ? ;0X22
.reg_page dw ? ;0X24
.reg_powerdown dw ? ;0x26
.reg_ext_audio dw ? ;0x28
.reg_ext_st dw ? ;0x2a
.reg_pcm_front_rate dw ? ;0x2c
.reg_pcm_surr_rate dw ? ;0x2e
.reg_lfe_rate dw ? ;0x30
.reg_pcm_in_rate dw ? ;0x32
dw ? ;0x34
.reg_cent_lfe_vol dw ? ;0x36
.reg_surr_vol dw ? ;0x38
.reg_spdif_ctrl dw ? ;0x3A
dw ? ;0x3C
dw ? ;0x3E
dw ? ;0x40
dw ? ;0x42
dw ? ;0x44
dw ? ;0x46
dw ? ;0x48
dw ? ;0x4A
dw ? ;0x4C
dw ? ;0x4E
dw ? ;0x50
dw ? ;0x52
dw ? ;0x54
dw ? ;0x56
dw ? ;0x58
dw ? ;0x5A
dw ? ;0x5C
dw ? ;0x5E
.reg_page_0 dw ? ;0x60
.reg_page_1 dw ? ;0x62
.reg_page_2 dw ? ;0x64
.reg_page_3 dw ? ;0x66
.reg_page_4 dw ? ;0x68
.reg_page_5 dw ? ;0x6A
.reg_page_6 dw ? ;0x6C
.reg_page_7 dw ? ;0x6E
dw ? ;0x70
dw ? ;0x72
dw ? ;0x74
dw ? ;0x76
dw ? ;0x78
dw ? ;0x7A
.reg_vendor_id_1 dw ? ;0x7C
.reg_vendor_id_2 dw ? ;0x7E
 
 
.reset dd ? ;virual
.set_master_vol dd ?
}
 
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
 
public START
public service_proc
public version
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .stop
 
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
 
call init_codec
test eax, eax
jz .fail
 
call setup_codec
 
mov esi, msgPrimBuff
call SysMsgBoardStr
call create_primary_buff
mov esi, msgDone
call SysMsgBoardStr
 
if IRQ_REMAP
pushf
cli
 
mov ebx, [ctrl.int_line]
in al, 0xA1
mov ah, al
in al, 0x21
test ebx, ebx
jz .skip
bts ax, bx ;mask old line
.skip:
bts ax, IRQ_LINE ;mask new ine
out 0x21, al
mov al, ah
out 0xA1, al
 
stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE ;remap IRQ
 
mov dx, 0x4d0 ;8259 ELCR1
in al, dx
bts ax, IRQ_LINE
out dx, al ;set level-triggered mode
mov [ctrl.int_line], IRQ_LINE
popf
mov esi, msgRemap
call SysMsgBoardStr
end if
 
mov eax, VALID_IRQ
mov ebx, [ctrl.int_line]
mov esi, msgInvIRQ
bt eax, ebx
jnc .fail_msg
mov eax, ATTCH_IRQ
mov esi, msgAttchIRQ
bt eax, ebx
jnc .fail_msg
 
stdcall AttachIntHandler, ebx, ac97_irq_VIA, dword 0
.reg:
stdcall RegService, sz_sound_srv, service_proc
ret
.fail:
if DEBUG
mov esi, msgFail
call SysMsgBoardStr
end if
xor eax, eax
ret
.fail_msg:
call SysMsgBoardStr
xor eax, eax
ret
.stop:
call stop
xor eax, eax
ret
endp
 
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, SRV_GETVERSION
jne @F
mov eax, [edi+output]
cmp [edi+out_size], 4
jne .fail
 
mov [eax], dword API_VERSION
xor eax, eax
ret
@@:
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 eax, [edi+input]
mov eax, [eax]
call set_master_vol ;eax= vol
ret
@@:
cmp eax, DEV_GET_MASTERVOL
jne @F
mov ebx, [edi+output]
stdcall get_master_vol, ebx
ret
@@:
cmp eax, DEV_GET_INFO
jne @F
mov ebx, [edi+output]
stdcall get_dev_info, ebx
ret
@@:
.fail:
or eax, -1
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
 
align 4
proc ac97_irq_VIA
locals
status db 0
endl
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS
call [ctrl.ctrl_read8]
test al, VIA_REG_STAT_ACTIVE
jz @f
 
and al, VIA_REG_STAT_EOL or VIA_REG_STAT_FLAG or VIA_REG_STAT_STOPPED
mov byte [status], al
 
mov ebx, dword [buff_list]
cmp [ctrl.user_callback], 0
je @f
stdcall [ctrl.user_callback], ebx
@@:
mov al, byte [status] ;; ack ;;
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS
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
cld
rep stosd
 
mov eax, [ctrl.buffer]
call GetPgAddr
mov edi, pcmout_bdl
stosd
mov eax, 0x80004000
stosd
 
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
 
stdcall channel_reset, VIADEV_PLAYBACK
stdcall codec_check_ready
 
mov eax, pcmout_bdl
mov ebx, eax
call GetPgAddr
and ebx, 0xFFF
add eax, ebx
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_TABLE_PTR
call [ctrl.ctrl_write32]
 
stdcall codec_check_ready
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFS_PLAYBACK_VOLUME_L
mov eax, 7;31
call [ctrl.ctrl_write8]
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFS_PLAYBACK_VOLUME_R
mov eax, 7;31
call [ctrl.ctrl_write8]
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX
mov eax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000
mov [ctrl.lvi_reg], 16;0xF;eax
call [ctrl.ctrl_write32]
 
stdcall codec_check_ready
ret
endp
 
 
proc channel_reset channel:dword
mov esi, dword [channel]
mov edx, esi
add edx, VIA_REG_OFFSET_CONTROL
mov eax, VIA_REG_CTRL_PAUSE or VIA_REG_CTRL_TERMINATE or VIA_REG_CTRL_RESET
call [ctrl.ctrl_write8]
 
mov edx, esi
add edx, VIA_REG_OFFSET_CONTROL
call [ctrl.ctrl_read8]
 
mov eax, 50000 ; wait 50 ms
call StallExec
; disable interrupts
mov edx, esi
add edx, VIA_REG_OFFSET_CONTROL
xor eax, eax
call [ctrl.ctrl_write8]
 
; clear interrupts
mov edx, esi
add edx, VIA_REG_OFFSET_STATUS
mov eax, 0x03
call [ctrl.ctrl_write8]
 
;outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
; mov edx, esi ;; for via686
; add edx, VIA_REG_OFFSET_TYPE
; mov eax, 0x03
; call [ctrl.ctrl_write8]
 
;; outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
;mov edx, esi
;add edx, VIA_REG_OFFSET_CURR_PTR
;xor eax, eax
;call [ctrl.ctrl_write8]
 
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 esi, [edi+8]
mov [ctrl.ctrl_setup], esi
 
cmp edx, VID_VIA
jne @F
mov [ctrl.vendor_ids], msg_VIA
ret
@@:
 
.err:
xor eax, eax
mov [ctrl.vendor_ids], eax ;something wrong ?
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
 
mov esi, msgPciCmd
call SysMsgBoardStr
call dword2str
call SysMsgBoardStr
 
mov esi, msgPciStat
call SysMsgBoardStr
mov eax, [ctrl.pci_stat]
call dword2str
call SysMsgBoardStr
 
mov esi, msgCtrlIsaIo
call SysMsgBoardStr
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
call dword2str
call SysMsgBoardStr
 
and eax, 0xFFC0
mov [ctrl.ctrl_io_base], eax
 
.default:
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
and eax, 0xFF
@@:
mov [ctrl.int_line], eax
 
;stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_FUNC_ENABLE ;0x42
;mov byte [old_legacy], al
 
;stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_PNP_CONTROL ;0x43
;mov byte [old_legacy_cfg], al
 
;mov al, VIA_FUNC_ENABLE_SB or VIA_FUNC_ENABLE_FM
;xor al, 0xFF
;and al, byte [old_legacy]
;and eax, 0xFF
;stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_FUNC_ENABLE, eax ;0x42
;mov byte [old_legacy], al
 
call [ctrl.ctrl_setup]
xor eax, eax
inc eax
ret
endp
 
align 4
proc set_VIA
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 init_codec
locals
counter dd ?
endl
 
mov esi, msgControl
call SysMsgBoardStr
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL
and eax, 0xFF
call dword2str
call SysMsgBoardStr
 
mov esi, msgStatus
call SysMsgBoardStr
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT
and eax, 0xFF
push eax
call dword2str
call SysMsgBoardStr
pop eax
 
test eax, VIA_ACLINK_C00_READY
jz .ready
 
call reset_codec
test eax, eax
jz .err
 
.ready:
xor edx, edx ; ac_reg_0
call [ctrl.codec_write16]
jmp .done
 
.err:
xor eax, eax ; timeout error
ret
 
.done:
call detect_codec
 
xor eax, eax
inc eax
ret
endp
 
align 4
proc reset_codec
stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, \
VIA_ACLINK_CTRL_ENABLE or VIA_ACLINK_CTRL_RESET or VIA_ACLINK_CTRL_SYNC
mov eax, 100000 ; wait 100 ms
call StallExec
.cold:
call cold_reset
jnc .ok
 
if DEBUG
mov esi, msgCFail
call SysMsgBoardStr
end if
xor eax, eax ; timeout error
ret
.ok:
if DEBUG
mov esi, msgResetOk
call SysMsgBoardStr
end if
xor eax, eax
inc eax
ret
endp
 
 
align 4
proc cold_reset
locals
counter dd ?
endl
 
stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, dword 0
 
if DEBUG
mov esi, msgCold
call SysMsgBoardStr
end if
 
mov eax, 100000 ; wait 100 ms ;400000 ; wait 400 ms
call StallExec
 
;; ACLink on, deassert ACLink reset, VSR, SGD data out
;; note - FM data out has trouble with non VRA codecs !!
stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, dword VIA_ACLINK_CTRL_INIT
 
mov [counter], 16 ; total 20*100 ms = 2s
.wait:
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT
test eax, VIA_ACLINK_C00_READY
jnz .ok
 
mov eax, 100000 ; wait 100 ms
call StallExec
 
dec [counter]
jnz .wait
 
if DEBUG
mov esi, msgCRFail
call SysMsgBoardStr
end if
 
.fail:
stc
ret
.ok:
mov esi, msgControl
call SysMsgBoardStr
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL
call dword2str
call SysMsgBoardStr
 
mov esi, msgStatus
call SysMsgBoardStr
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT
and eax, 0xFF
push eax
call dword2str
call SysMsgBoardStr
pop eax
 
test eax, VIA_ACLINK_C00_READY ;CTRL_ST_CREADY
jz .fail
clc
ret
endp
 
align 4
play:
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX
mov eax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000
mov [ctrl.lvi_reg], 16
call [ctrl.ctrl_write32]
 
mov eax, VIA_REG_CTRL_INT
or eax, VIA_REG_CTRL_START
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL
call [ctrl.ctrl_write8]
 
xor eax, eax
ret
 
align 4
stop:
mov eax, VIA_REG_CTRL_INT
or eax, VIA_REG_CTRL_TERMINATE
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL
call [ctrl.ctrl_write8]
 
stdcall channel_reset, VIADEV_PLAYBACK
xor eax, eax
ret
 
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 ecx, [ctrl.ctrl_io_base]
mov [CTRL_INFO.irq], eax
mov [CTRL_INFO.ctrl_io_base], ecx
 
xor eax, eax
;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_TABLE_PTR
;call [ctrl.ctrl_read32]
mov [CTRL_INFO.codec_io_base], eax
;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX
;call [ctrl.ctrl_read32]
mov [CTRL_INFO.codec_mem_base], eax
;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CURR_COUNT
;call [ctrl.ctrl_read32]
mov [CTRL_INFO.ctrl_mem_base], eax
 
mov eax, [codec.chip_id]
mov [CTRL_INFO.codec_id], eax
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL
call [ctrl.ctrl_read8]
and eax, 0xFF
mov [CTRL_INFO.glob_cntrl], eax
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS
call [ctrl.ctrl_read8]
and eax, 0xFF
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_check_ready stdcall
locals
counter dd ?
endl
 
mov [counter], 1000 ; total 1000*1 ms = 1s
.wait:
call [ctrl.codec_read16]
test eax, VIA_REG_AC97_BUSY
jz .ok
 
mov eax, 1000 ; wait 1 ms
call StallExec
 
sub [counter] , 1
jnz .wait
.err:
mov eax, -1
ret
.ok:
and eax, 0xFFFF
ret
endp
 
 
align 4
proc codec_valid stdcall
stdcall codec_check_ready
ret
endp
 
align 4
proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax
locals
counter dd ?
endl
 
;Use only primary codec.
mov eax, [ac_reg]
and eax, 0x7F
shl eax, VIA_REG_AC97_CMD_SHIFT
or eax, VIA_REG_AC97_PRIMARY_VALID or VIA_REG_AC97_READ
 
mov [counter], 3 ; total 3*20 ms = 60ms
.wait:
push eax
call [ctrl.codec_write16]
 
mov eax, 20000 ; wait 20 ms
call StallExec
 
stdcall codec_valid,
cmp eax, 0
pop eax
jge .ok
 
sub [counter] , 1
jnz .wait
jmp .err
 
.ok:
mov eax, 25000 ; wait 25 ms
call StallExec
 
call [ctrl.codec_read16] ;change edx !!!
and eax, 0xFFFF
ret
.err:
if DEBUG
mov esi, msgCInvalid
call SysMsgBoardStr
end if
mov eax, -1 ; invalid codec error
ret
endp
 
align 4
proc codec_write stdcall, ac_reg:dword
;Use only primary codec.
mov esi, [ac_reg]
mov edx, esi
shl edx, VIA_REG_AC97_CMD_SHIFT
 
shl eax, VIA_REG_AC97_DATA_SHIFT
or edx, eax
 
mov eax, VIA_REG_AC97_CODEC_ID_PRIMARY ;not VIA_REG_AC97_CODEC_ID_PRIMARY
shl eax, VIA_REG_AC97_CODEC_ID_SHIFT
or edx, eax
 
mov eax, edx
mov edx, esi
call [ctrl.codec_write16]
mov [codec.regs+esi], ax
 
stdcall codec_check_ready
cmp eax, 0
jl .err
.ok:
ret
.err:
if DEBUG
mov esi, msgCFail
call SysMsgBoardStr
end if
;mov eax, -1 ; codec not ready error
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
js @B
 
pop eax
pop ebx
pop edx
pop ecx
ret
endp
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CONTROLLER IO functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
proc codec_io_r16 ;r32
mov edx, [ctrl.ctrl_io_base]
add edx, VIA_REG_AC97
in eax, dx
ret
endp
 
align 4
proc codec_io_w16 ;w32
mov edx, [ctrl.ctrl_io_base]
add edx, VIA_REG_AC97
out dx, eax
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
 
 
align 4
dword2str:
push eax ebx ecx
mov esi, hex_buff
mov ecx, -8
@@:
rol eax, 4
mov ebx, eax
and ebx, 0x0F
mov bl, [ebx+hexletters]
mov [8+esi+ecx], bl
inc ecx
jnz @B
pop ecx ebx eax
ret
 
hexletters db '0123456789ABCDEF'
hex_buff db 8 dup(0),13,10,0
 
 
include "codec.inc"
 
align 4
devices dd (CTRL_VT82C686 shl 16)+VID_VIA,msg_VT82C686,set_VIA
dd (CTRL_VT8233_5 shl 16)+VID_VIA,msg_VT8233,set_VIA
dd 0 ;terminator
 
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
msg_VT82C686 db 'VT82C686', 13,10, 0
msg_VT8233 db 'VT8233', 13,10, 0
msg_VIA db 'VIA' , 13,10, 0
 
szKernel db 'KERNEL', 0
sz_sound_srv db 'SOUND',0
 
msgInit db 'detect hardware...',13,10,0
msgFail db 'device not found',13,10,0
msgAttchIRQ db 'IRQ line not supported', 13,10, 0
msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0
msgPlay db 'start play', 13,10,0
msgStop db 'stop play', 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 ...',0
msgDone db 'done',13,10,0
msgRemap db 'Remap IRQ',13,10,0
;msgReg db 'set service handler',13,10,0
;msgOk db 'service installed',13,10,0
msgCold db 'cold reset',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
msgCInvalid db 'codec is not valid',13,10,0 ;Asper
msgResetOk db 'reset complete',13,10,0
msgStatus db 'global status ',0
msgControl db 'global control ',0
msgPciCmd db 'PCI command ',0
msgPciStat db 'PCI status ',0
msgCtrlIsaIo db 'controller io base ',0
;msgMixIsaIo db 'codec io base ',0
;msgCtrlMMIo db 'controller mmio base ',0
;msgMixMMIo db 'codec mmio base ',0
;msgIrqMap db 'AC97 irq map as ',0
 
 
section '.data' data readable writable align 16
 
pcmout_bdl rq 32
buff_list rd 32
 
codec CODEC
ctrl AC_CNTRL
 
chip_type rb 1