Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 874 → Rev 1147

/kernel/tags/kolibri0.7.5.0/drivers/ati2d.asm
0,0 → 1,1731
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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'
 
R500_HW2D equ 0
 
API_VERSION equ 0x01000100
 
STRIDE equ 8
 
VID_ATI equ 0x1002
 
LOAD_FROM_FILE equ 0
LOAD_FROM_MEM equ 1
LOAD_INDIRECT equ 2
LOAD_SYSTEM equ 3
 
SRV_GETVERSION equ 0
 
struc BITMAPINFOHEADER {
.biSize dd ? ; DWORD
.biWidth dd ? ; LONG
.biHeight dd ? ; LONG
.biPlanes dw ? ; WORD
.biBitCount dw ? ; WORD
.biCompression dd ? ; DWORD
.biSizeImage dd ? ; DWORD
.biXPelsPerMeter dd ? ; LONG
.biYPelsPerMeter dd ? ; LONG
.biClrUsed dd ? ; DWORD
.biClrImportant dd ? ; DWORD
}
 
virtual at 0
BI BITMAPINFOHEADER
end virtual
 
struc CURSOR
{;common object header
.magic dd ? ;'CURS'
.destroy dd ? ;internal destructor
.fd dd ? ;next object in list
.bk dd ? ;prev object in list
.pid dd ? ;owner id
 
;cursor data
.base dd ? ;allocated memory
.hot_x dd ? ;hotspot coords
.hot_y dd ?
}
virtual at 0
CURSOR CURSOR
end virtual
 
CURSOR_SIZE equ 32
 
OS_BASE equ 0x80000000
SLOT_BASE equ (OS_BASE+0x0080000)
LFB_BASE equ 0xFE000000
 
PG_SW equ 0x003
PG_NOCACHE equ 0x018
 
PCI_MEMORY_MASK equ 0xfffffff0
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
;MMIO equ 0F9000000h
RD_RB3D_CNTL equ 1c3ch
 
RD_MEM_CNTL equ 0140h
RD_CRTC_GEN_CNTL equ 0050h
RD_CRTC_CUR_EN equ 10000h
RD_DISPLAY_BASE_ADDR equ 023ch
RD_DEFAULT_OFFSET equ 16e0h
 
CUR_HORZ_VERT_OFF equ 0268h
CUR_HORZ_VERT_POSN equ 0264h
CUR_OFFSET equ 0260h
 
 
RD_RB3D_CNTL equ 1c3ch
RD_RBBM_STATUS equ 0e40h
RD_RBBM_FIFOCNT_MASK equ 007fh
RD_RBBM_ACTIVE equ 80000000h
RD_TIMEOUT equ 2000000
 
RD_DP_GUI_MASTER_CNTL equ 0146ch
RD_DP_BRUSH_BKGD_CLR equ 01478h
RD_DP_BRUSH_FRGD_CLR equ 0147ch
RD_DP_SRC_BKGD_CLR equ 015dch
RD_DP_SRC_FRGD_CLR equ 015d8h
RD_DP_CNTL equ 016c0h
RD_DP_DATATYPE equ 016c4h
RD_DP_WRITE_MASK equ 016cch
RD_DP_SRC_SOURCE_MEMORY equ (2 shl 24)
RD_DP_SRC_SOURCE_HOST_DATA equ (3 shl 24)
RD_DEFAULT_SC_BOTTOM_RIGHT equ 16e8h
RD_GMC_BRUSH_SOLID_COLOR equ (13 shl 4)
RD_DEFAULT_SC_RIGHT_MAX equ 1fffh
RD_DEFAULT_SC_BOTTOM_MAX equ 1fff0000h
RD_GMC_DST_DATATYPE_SHIFT equ 8
 
RD_ROP3_S equ 00cc0000h
RD_ROP3_P equ 00f00000h
 
RD_RB2D_DSTCACHE_MODE equ 03428h
RD_RB2D_DSTCACHE_CTLSTAT equ 0342ch
RD_RB2D_DC_FLUSH_ALL equ 000fh
RD_RB2D_DC_BUSY equ 80000000h
 
RD_GMC_BRUSH_SOLID_COLOR equ 000000D0h
RD_GMC_SRC_DATATYPE_COLOR equ (3 shl 12)
RD_GMC_CLR_CMP_CNTL_DIS equ (1 shl 28)
RD_GMC_WR_MSK_DIS equ (1 shl 30)
 
cmdSolidFill equ 73f036d0h
 
RD_DST_PITCH_OFFSET equ 142ch
RD_SRC_PITCH_OFFSET equ 1428h
 
RD_DST_X_LEFT_TO_RIGHT equ 1
RD_DST_Y_TOP_TO_BOTTOM equ 2
RD_DST_Y_X equ 1438h
RD_DST_WIDTH_HEIGHT equ 1598h
RD_DST_LINE_START equ 1600h
RD_DST_LINE_END equ 1604h
R300_MEM_NUM_CHANNELS_MASK equ 0003h
 
macro rdr op1, op2
{
mov edi, [ati_io]
mov op1, [edi+op2]
}
 
macro BEGIN_RING
{
mov edi, [rhd.ring_base]
mov edx, [rhd.ring_wp]
}
 
macro COMMIT_RING
{
and edx, 0x1FFF
mov [rhd.ring_wp], edx
 
lock add [esp], dword 0 ; Flush writes to ring
 
wrr RADEON_CP_RB_WPTR, edx
rdr eax, RADEON_CP_RB_RPTR
}
 
macro OUT_PACKET0 reg, count
{
mov eax, (RADEON_CP_PACKET0 + (count shl 16) + (reg shr 2))
mov [edi+edx*4], eax
inc edx
}
 
macro OUT_PACKET3 pkt, count
{
mov eax, (RADEON_CP_PACKET3 or pkt or (count shl 16))
mov [edi+edx*4], eax
inc edx
}
 
macro OUT_RING val
{
mov eax, val
mov [edi+edx*4], eax
inc edx
}
 
macro RADEON_WAIT_UNTIL_IDLE
{
OUT_PACKET0 RADEON_WAIT_UNTIL, 0
OUT_RING RADEON_WAIT_2D_IDLECLEAN + \
RADEON_WAIT_3D_IDLECLEAN + \
RADEON_WAIT_HOST_IDLECLEAN
}
 
macro RADEON_PURGE_CACHE
{
OUT_PACKET0 R5XX_RB3D_DSTCACHE_CTLSTAT, 0
OUT_RING R5XX_RB3D_DC_FLUSH_ALL
}
 
macro RADEON_PURGE_ZCACHE
{
OUT_PACKET0 RADEON_RB3D_ZCACHE_CTLSTAT, 0
OUT_RING RADEON_RB3D_ZC_FLUSH_ALL
}
 
macro wrr dest, src
{
mov edi, [ati_io]
mov dword [edi+dest], src
}
 
macro rmask dest, val, mask
{
mov edi, [ati_io]
mov eax, [edi+dest]
and eax, not mask
or eax, (val and mask)
mov [edi+dest], eax
}
 
public START
public service_proc
public version
 
CURSOR_IMAGE_OFFSET equ 0x00500000
 
DRV_ENTRY equ 1
DRV_EXIT equ -1
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .restore
 
if DEBUG
mov esi, msgInit
call SysMsgBoardStr
end if
 
call detect_ati
test eax, eax
jz .fail
 
mov ebx, [SelectHwCursor]
mov ecx, [SetHwCursor]
mov edx, [HwCursorRestore]
mov esi, [HwCursorCreate]
 
mov [oldSelect], ebx
mov [oldSet], ecx
mov [oldRestore], edx
mov [oldCreate], esi
 
call eax
 
or eax, -1
mov [cursor_map], eax
mov [cursor_map+4], eax
mov edx, cursor_map
mov [cursor_start], edx
add edx, 8
mov [cursor_end], edx
 
stdcall RegService, sz_ati_srv, service_proc
test eax, eax
jz .restore
 
if R500_HW2D
stdcall RegService, sz_HDraw_srv, r500_HDraw
 
mov ebx, START
and ebx, -4096
mov [eax+0x20], ebx
mov [eax+0x24], dword 0 ;hack
end if
mov ebx, [fnSelect]
mov ecx, [fnSet]
 
mov [SelectHwCursor], ebx
mov [SetHwCursor], ecx
mov dword [HwCursorRestore], drv_restore
mov dword [HwCursorCreate], ati_cursor
 
ret
.restore:
mov eax, [oldSelect]
mov ebx, [oldSet]
mov ecx, [oldRestore]
mov edx, [oldCreate]
 
mov [SelectHwCursor], eax
mov [SetHwCursor], ebx
mov [HwCursorRestore], ecx
mov [HwCursorCreate], edx
 
xor eax, eax
ret
 
.fail:
if DEBUG
mov esi, msgFail
call SysMsgBoardStr
end if
 
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 ebx, [ioctl]
cmp [ebx+io_code], SRV_GETVERSION
jne .fail
 
mov eax, [ebx+output]
cmp [ebx+out_size], 4
jne .fail
mov [eax], dword API_VERSION
xor eax, eax
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 detect_ati
locals
last_bus 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, STRIDE
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 eax, [edi+4]
ret
.err:
xor eax, eax
ret
endp
 
align 4
proc init_r200
stdcall PciRead32, [bus], [devfn], dword 0x18
and eax, PCI_MEMORY_MASK
stdcall MapIoMem,eax,0x10000,(PG_SW+PG_NOCACHE)
test eax, eax
jz .fail
 
mov [ati_io], eax
mov edi, eax
 
mov dword [edi+RD_RB3D_CNTL], 0
call engRestore
 
mov edi, [ati_io]
mov eax, [edi+0x50]
mov ebx,3
shl ebx,20
not ebx
and eax,ebx
mov ebx, 2
shl ebx,20
or eax, ebx
mov [edi+0x50], eax
 
call r200_ShowCursor
 
mov [fnSelect], r200_SelectCursor
mov [fnSet], r200_SetCursor
 
xor eax, eax
inc eax
.fail:
ret
endp
 
if R500_HW2D
include 'r500hw.inc'
end if
 
align 4
proc init_r500
 
stdcall PciRead32, [bus], [devfn], dword 0x18
and eax, PCI_MEMORY_MASK
stdcall MapIoMem,eax,0x10000,(PG_SW+PG_NOCACHE)
test eax, eax
jz .fail
 
mov [ati_io], eax
 
mov [fnSelect], r500_SelectCursor
mov [fnSet], r500_SetCursor
 
rdr eax, 0x6110
mov [r500_LFB], eax
 
if R500_HW2D
call R5xx2DInit
end if
wrr 0x6410, 0x001F001F
wrr 0x6400, dword (3 shl 8)
 
xor eax, eax
inc eax
.fail:
ret
endp
 
 
align 4
drv_restore:
ret 8
 
 
align 4
proc r500_SelectCursor stdcall,hcursor:dword
 
mov esi, [hcursor]
 
mov edx, [esi+CURSOR.base]
sub edx, LFB_BASE
add edx, [r500_LFB]
wrr 0x6408, edx
 
mov eax, [esi+CURSOR.hot_x]
shl eax, 16
mov ax, word [esi+CURSOR.hot_y]
wrr 0x6418, eax
ret
endp
 
align 4
proc r500_SetCursor stdcall, hcursor:dword, x:dword, y:dword
pushfd
cli
 
mov esi, [hcursor]
mov edi, [ati_io]
 
mov eax, [x]
shl eax, 16
mov ax, word [y]
 
mov [edi+0x6414], eax
or dword [edi+0x6400], 1
 
popfd
ret
endp
 
align 4
r500_ShowCursor:
 
mov edi, [ati_io]
or dword [edi+0x6400], 1
ret
 
align 4
r200_ShowCursor:
mov edi, [ati_io]
 
mov eax, [edi+RD_CRTC_GEN_CNTL]
bts eax,16
mov [edi+RD_CRTC_GEN_CNTL], eax
ret
 
 
align 4
proc r200_SelectCursor stdcall,hcursor:dword
 
ret
endp
 
align 4
proc r200_SetCursor stdcall, hcursor:dword, x:dword, y:dword
pushfd
cli
 
xor eax, eax
xor edx, edx
mov esi, [hcursor]
mov ebx, [x]
mov ecx, [y]
 
sub ebx, [esi+CURSOR.hot_x]
jnc @F
neg ebx
mov eax, ebx
shl eax, 16
xor ebx, ebx
@@:
sub ecx, [esi+CURSOR.hot_y]
jnc @F
neg ecx
mov ax, cx
mov edx, ecx
xor ecx, ecx
@@:
or eax, 0x80000000
wrr CUR_HORZ_VERT_OFF, eax
 
shl ebx, 16
mov bx, cx
or ebx, 0x80000000
wrr CUR_HORZ_VERT_POSN, ebx
 
shl edx, 8
add edx, [esi+CURSOR.base]
sub edx, LFBAddress
wrr CUR_OFFSET, edx
popfd
ret
endp
 
align 4
proc video_alloc
 
pushfd
cli
mov ebx, [cursor_start]
mov ecx, [cursor_end]
.l1:
bsf eax,[ebx];
jnz .found
add ebx,4
cmp ebx, ecx
jb .l1
popfd
xor eax,eax
ret
.found:
btr [ebx], eax
popfd
 
mov [cursor_start],ebx
sub ebx, cursor_map
lea eax,[eax+ebx*8]
 
shl eax,14
add eax, LFBAddress+CURSOR_IMAGE_OFFSET
ret
endp
 
align 4
video_free:
pushfd
cli
sub eax, LFBAddress+CURSOR_IMAGE_OFFSET
shr eax, 14
mov ebx, cursor_map
bts [ebx], eax
shr eax, 3
and eax, not 3
add eax, ebx
cmp [cursor_start], eax
ja @f
popfd
ret
@@:
mov [cursor_start], eax
popfd
ret
 
; param
; eax= pid
; ebx= src
; ecx= flags
 
align 4
ati_cursor:
.src equ esp
.flags equ esp+4
.hcursor equ esp+8
 
sub esp, 4 ;space for .hcursor
push ecx
push ebx
 
mov ebx, eax
mov eax, CURSOR_SIZE
call CreateObject
test eax, eax
jz .fail
 
mov [.hcursor],eax
 
xor ebx, ebx
mov [eax+CURSOR.magic], 'CURS'
mov [eax+CURSOR.destroy], destroy_cursor
mov [eax+CURSOR.hot_x], ebx
mov [eax+CURSOR.hot_y], ebx
 
call video_alloc
mov edi, [.hcursor]
mov [edi+CURSOR.base], eax
 
mov esi, [.src]
mov ebx, [.flags]
cmp bx, LOAD_INDIRECT
je .indirect
 
movzx ecx, word [esi+10]
movzx edx, word [esi+12]
mov [edi+CURSOR.hot_x], ecx
mov [edi+CURSOR.hot_y], edx
 
stdcall ati_init_cursor, eax, esi
mov eax, [.hcursor]
.fail:
add esp, 12
ret
.indirect:
shr ebx, 16
movzx ecx, bh
movzx edx, bl
mov [edi+CURSOR.hot_x], ecx
mov [edi+CURSOR.hot_y], edx
 
mov edi, eax
mov ebx, eax
mov ecx, 64*64
xor eax,eax
cld
rep stosd
mov edi, ebx
 
mov esi, [.src]
mov ebx, 32
cld
@@:
mov ecx, 32
rep movsd
add edi, 128
dec ebx
jnz @B
mov eax, [.hcursor]
add esp, 12
ret
 
align 4
destroy_cursor:
 
push eax
mov eax, [eax+CURSOR.base]
call video_free
pop eax
 
call DestroyObject
ret
 
align 4
proc ati_init_cursor stdcall, dst:dword, src:dword
locals
rBase dd ?
pQuad dd ?
pBits dd ?
pAnd dd ?
width dd ?
height dd ?
counter dd ?
endl
 
mov esi, [src]
add esi,[esi+18]
mov eax,esi
 
cmp [esi+BI.biBitCount], 24
je .img_24
cmp [esi+BI.biBitCount], 8
je .img_8
cmp [esi+BI.biBitCount], 4
je .img_4
 
.img_2:
add eax, [esi]
mov [pQuad],eax
add eax,8
mov [pBits],eax
add eax, 128
mov [pAnd],eax
mov eax,[esi+4]
mov [width],eax
mov ebx,[esi+8]
shr ebx,1
mov [height],ebx
 
mov edi, pCursor
add edi, 32*31*4
mov [rBase],edi
 
mov esi,[pQuad]
.l21:
mov ebx, [pBits]
mov ebx, [ebx]
bswap ebx
mov eax, [pAnd]
mov eax, [eax]
bswap eax
mov [counter], 32
@@:
xor edx, edx
shl eax,1
setc dl
dec edx
 
xor ecx, ecx
shl ebx,1
setc cl
mov ecx, [esi+ecx*4]
and ecx, edx
and edx, 0xFF000000
or edx, ecx
mov [edi], edx
 
add edi, 4
dec [counter]
jnz @B
 
add [pBits], 4
add [pAnd], 4
mov edi,[rBase]
sub edi,128
mov [rBase],edi
sub [height],1
jnz .l21
jmp .copy
.img_4:
add eax, [esi]
mov [pQuad],eax
add eax,64
mov [pBits],eax
add eax, 0x200
mov [pAnd],eax
mov eax,[esi+4]
mov [width],eax
mov ebx,[esi+8]
shr ebx,1
mov [height],ebx
 
mov edi, pCursor
add edi, 32*31*4
mov [rBase],edi
 
mov esi,[pQuad]
mov ebx, [pBits]
.l4:
mov eax, [pAnd]
mov eax, [eax]
bswap eax
mov [counter], 16
@@:
xor edx, edx
shl eax,1
setc dl
dec edx
 
movzx ecx, byte [ebx]
and cl, 0xF0
shr ecx, 2
mov ecx, [esi+ecx]
and ecx, edx
and edx, 0xFF000000
or edx, ecx
mov [edi], edx
 
xor edx, edx
shl eax,1
setc dl
dec edx
 
movzx ecx, byte [ebx]
and cl, 0x0F
mov ecx, [esi+ecx*4]
and ecx, edx
and edx, 0xFF000000
or edx, ecx
mov [edi+4], edx
 
inc ebx
add edi, 8
dec [counter]
jnz @B
 
add [pAnd], 4
mov edi,[rBase]
sub edi,128
mov [rBase],edi
sub [height],1
jnz .l4
jmp .copy
.img_8:
add eax, [esi]
mov [pQuad],eax
add eax,1024
mov [pBits],eax
add eax, 1024
mov [pAnd],eax
mov eax,[esi+4]
mov [width],eax
mov ebx,[esi+8]
shr ebx,1
mov [height],ebx
 
mov edi, pCursor
add edi, 32*31*4
mov [rBase],edi
 
mov esi,[pQuad]
mov ebx, [pBits]
.l81:
mov eax, [pAnd]
mov eax, [eax]
bswap eax
mov [counter], 32
@@:
xor edx, edx
shl eax,1
setc dl
dec edx
 
movzx ecx, byte [ebx]
mov ecx, [esi+ecx*4]
and ecx, edx
and edx, 0xFF000000
or edx, ecx
mov [edi], edx
 
inc ebx
add edi, 4
dec [counter]
jnz @B
 
add [pAnd], 4
mov edi,[rBase]
sub edi,128
mov [rBase],edi
sub [height],1
jnz .l81
jmp .copy
.img_24:
add eax, [esi]
mov [pQuad],eax
add eax, 0xC00
mov [pAnd],eax
mov eax,[esi+BI.biWidth]
mov [width],eax
mov ebx,[esi+BI.biHeight]
shr ebx,1
mov [height],ebx
 
mov edi, pCursor
add edi, 32*31*4
mov [rBase],edi
 
mov esi,[pAnd]
mov ebx, [pQuad]
.row_24:
mov eax, [esi]
bswap eax
mov [counter], 32
@@:
xor edx, edx
shl eax,1
setc dl
dec edx
 
mov ecx, [ebx]
and ecx, 0x00FFFFFF
and ecx, edx
and edx, 0xFF000000
or edx, ecx
mov [edi], edx
add ebx, 3
add edi, 4
dec [counter]
jnz @B
 
add esi, 4
mov edi,[rBase]
sub edi,128
mov [rBase],edi
sub [height],1
jnz .row_24
.copy:
mov edi, [dst]
mov ecx, 64*64
xor eax,eax
rep stosd
 
mov esi, pCursor
mov edi, [dst]
mov ebx, 32
cld
@@:
mov ecx, 32
rep movsd
add edi, 128
dec ebx
jnz @B
ret
endp
 
align 4
proc engFlush
 
mov edi, [ati_io]
 
mov eax, [edi+RD_RB2D_DSTCACHE_CTLSTAT]
or eax,RD_RB2D_DC_FLUSH_ALL
mov [edi+RD_RB2D_DSTCACHE_CTLSTAT],eax
 
mov ecx, RD_TIMEOUT
@@:
mov eax,[edi+RD_RB2D_DSTCACHE_CTLSTAT]
and eax, RD_RB2D_DC_BUSY
jz .exit
 
sub ecx,1
jnz @B
.exit:
ret
endp
 
 
align 4
engWaitForFifo:
cnt equ bp+8
push ebp
mov ebp, esp
 
mov edi, [ati_io]
 
mov ecx, RD_TIMEOUT
@@:
mov eax, [edi+RD_RBBM_STATUS]
and eax, RD_RBBM_FIFOCNT_MASK
cmp eax, [ebp+8]
jae .exit
 
sub ecx,1
jmp @B
 
.exit:
leave
ret 4
 
align 4
proc engWaitForIdle
 
push dword 64
call engWaitForFifo
 
mov edi, [ati_io]
mov ecx ,RD_TIMEOUT
@@:
mov eax, [edi+RD_RBBM_STATUS]
and eax,RD_RBBM_ACTIVE
jz .exit
 
sub ecx,1
jnz @B
.exit:
call engFlush
ret
endp
 
 
align 4
proc engRestore
 
; push dword 1
; call engWaitForFifo
 
; mov dword [MMIO+RD_RB2D_DSTCACHE_MODE], 0
 
push dword 3
call engWaitForFifo
 
mov edi, [ati_io]
 
mov eax, [edi+RD_DISPLAY_BASE_ADDR]
shr eax, 10d
or eax,(64d shl 22d)
mov [edi+RD_DEFAULT_OFFSET],eax
mov [edi+RD_SRC_PITCH_OFFSET],eax
mov [edi+RD_DST_PITCH_OFFSET],eax
 
push dword 1
call engWaitForFifo
 
mov edi, [ati_io]
mov eax, [edi+RD_DP_DATATYPE]
btr eax, 29d
mov [edi+RD_DP_DATATYPE],eax
 
push dword 1
call engWaitForFifo
 
mov edi, [ati_io]
mov dword [edi+RD_DEFAULT_SC_BOTTOM_RIGHT],\
(RD_DEFAULT_SC_RIGHT_MAX or RD_DEFAULT_SC_BOTTOM_MAX)
 
push dword 1
call engWaitForFifo
 
mov edi, [ati_io]
mov dword [edi+RD_DP_GUI_MASTER_CNTL],\
(RD_GMC_BRUSH_SOLID_COLOR or \
RD_GMC_SRC_DATATYPE_COLOR or \
(6 shl RD_GMC_DST_DATATYPE_SHIFT) or \
RD_GMC_CLR_CMP_CNTL_DIS or \
RD_ROP3_P or \
RD_GMC_WR_MSK_DIS)
 
 
push dword 7
call engWaitForFifo
 
mov edi, [ati_io]
 
mov dword [edi+RD_DST_LINE_START],0
mov dword [edi+RD_DST_LINE_END], 0
mov dword [edi+RD_DP_BRUSH_FRGD_CLR], 808000ffh
mov dword [edi+RD_DP_BRUSH_BKGD_CLR], 002020ffh
mov dword [edi+RD_DP_SRC_FRGD_CLR], 808000ffh
mov dword [edi+RD_DP_SRC_BKGD_CLR], 004000ffh
mov dword [edi+RD_DP_WRITE_MASK],0ffffffffh
 
call engWaitForIdle
 
ret
endp
 
 
 
align 4
dword2str:
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
ret
 
hexletters db '0123456789ABCDEF'
hex_buff db 8 dup(0),13,10,0
 
R200M equ 0x5a62 ;R300
R7000 equ 0x5159 ;R200
R750M equ 0x4c57 ;M7 mobile rv200
R8500 equ 0x514C ;R200
R9000 equ 0x4966 ;RV250
R9200 equ 0x5961 ;RV280
R9200SE equ 0x5964 ;RV280
R9500 equ 0x4144 ;R300
R9500P equ 0x4E45 ;R300
R9550 equ 0x4153 ;RV350
R9600 equ 0x4150 ;RV350
R9600XT equ 0x4152 ;RV360
R9700P equ 0x4E44 ;R300
R9800 equ 0x4E49 ;R350
R9800P equ 0x4E48 ;R350
R9800XT equ 0x4E4A ;R360
 
 
align 4
 
devices:
dd (R200M shl 16)+VID_ATI, init_r200 ;R300
dd (R7000 shl 16)+VID_ATI, init_r200
dd (R750M shl 16)+VID_ATI, init_r200 ;M7
dd (R8500 shl 16)+VID_ATI, init_r200
dd (R9000 shl 16)+VID_ATI, init_r200
dd (0x514D shl 16)+VID_ATI, init_r200 ;R200 9100
 
dd (R9200 shl 16)+VID_ATI, init_r200
dd (R9200SE shl 16)+VID_ATI, init_r200
 
dd (0x5960 shl 16)+VID_ATI, init_r200 ;RV280 9250
 
dd (R9500 shl 16)+VID_ATI, init_r200
dd (R9500P shl 16)+VID_ATI, init_r200
dd (R9550 shl 16)+VID_ATI, init_r200
 
dd (R9600 shl 16)+VID_ATI, init_r200
dd (R9600XT shl 16)+VID_ATI, init_r200
dd (0x4155 shl 16)+VID_ATI, init_r200 ;RV350 9600
dd (0x4151 shl 16)+VID_ATI, init_r200 ;RV350 9600
dd (0x4E51 shl 16)+VID_ATI, init_r200 ;RV350 9600
 
dd (R9700P shl 16)+VID_ATI, init_r200
 
dd (0x4148 shl 16)+VID_ATI, init_r200 ;R350 9800
dd (R9800 shl 16)+VID_ATI, init_r200
dd (R9800P shl 16)+VID_ATI, init_r200
dd (R9800XT shl 16)+VID_ATI, init_r200
 
dd (0x5B60 shl 16)+VID_ATI, init_r200 ;RV370 X300/X550
dd (0x5B63 shl 16)+VID_ATI, init_r200 ;RV370 X550
dd (0x5B62 shl 16)+VID_ATI, init_r200 ;RV380x X600
dd (0x3E50 shl 16)+VID_ATI, init_r200 ;RV380 X600/X550
 
dd (0x5B4F shl 16)+VID_ATI, init_r200 ;RV410 X700
dd (0x5B4D shl 16)+VID_ATI, init_r200 ;RV410 X700
dd (0x5B4B shl 16)+VID_ATI, init_r200 ;RV410 X700
dd (0x5B4C shl 16)+VID_ATI, init_r200 ;RV410 X700
 
dd (0x4a49 shl 16)+VID_ATI, init_r200 ;R420 X800 PRO/GTO
dd (0x4a4B shl 16)+VID_ATI, init_r200 ;R420 X800
dd (0x5549 shl 16)+VID_ATI, init_r200 ;R423 X800
dd (0x4a4A shl 16)+VID_ATI, init_r200 ;R420 X800
dd (0x554F shl 16)+VID_ATI, init_r200 ;R430 X800
dd (0x554D shl 16)+VID_ATI, init_r200 ;R430 X800
dd (0x554E shl 16)+VID_ATI, init_r200 ;R430 X800
dd (0x5D57 shl 16)+VID_ATI, init_r200 ;R423 X800 XT
dd (0x4A50 shl 16)+VID_ATI, init_r200 ;R420 X800 XT
dd (0x554A shl 16)+VID_ATI, init_r200 ;R423 X800 XT
dd (0x5D4F shl 16)+VID_ATI, init_r200 ;R423 X800/X850
dd (0x554B shl 16)+VID_ATI, init_r200 ;R423 X800 GT
 
dd (0x4B4B shl 16)+VID_ATI, init_r200 ;R481 X850
dd (0x4B49 shl 16)+VID_ATI, init_r200 ;R481 X850
dd (0x4B4C shl 16)+VID_ATI, init_r200 ;R481 X850
 
dd (0x5D4D shl 16)+VID_ATI, init_r200 ;R480 X850
dd (0x5D52 shl 16)+VID_ATI, init_r200 ;R480 X850
 
dd (0x7100 shl 16)+VID_ATI, init_r500 ;Radeon X1800
dd (0x7101 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1800 XT
dd (0x7102 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1800
dd (0x7103 shl 16)+VID_ATI, init_r500 ;Mobility FireGL V7200
dd (0x7104 shl 16)+VID_ATI, init_r500 ;FireGL V7200
dd (0x7105 shl 16)+VID_ATI, init_r500 ;FireGL V5300
dd (0x7106 shl 16)+VID_ATI, init_r500 ;Mobility FireGL V7100
dd (0x7108 shl 16)+VID_ATI, init_r500 ;Radeon X1800
dd (0x7109 shl 16)+VID_ATI, init_r500 ;Radeon X1800
dd (0x710A shl 16)+VID_ATI, init_r500 ;Radeon X1800
dd (0x710B shl 16)+VID_ATI, init_r500 ;Radeon X1800
dd (0x710C shl 16)+VID_ATI, init_r500 ;Radeon X1800
dd (0x710E shl 16)+VID_ATI, init_r500 ;FireGL V7300
dd (0x710F shl 16)+VID_ATI, init_r500 ;FireGL V7350
dd (0x7140 shl 16)+VID_ATI, init_r500 ;Radeon X1600/X1550
dd (0x7141 shl 16)+VID_ATI, init_r500 ;RV505
dd (0x7142 shl 16)+VID_ATI, init_r500 ;Radeon X1300/X1550
dd (0x7143 shl 16)+VID_ATI, init_r500 ;Radeon X1550
dd (0x7144 shl 16)+VID_ATI, init_r500 ;M54-GL
dd (0x7145 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1400
dd (0x7146 shl 16)+VID_ATI, init_r500 ;Radeon X1300/X1550
dd (0x7147 shl 16)+VID_ATI, init_r500 ;Radeon X1550 64-bit
dd (0x7149 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1300
dd (0x714A shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1300
dd (0x714B shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1300
dd (0x714C shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1300
dd (0x714D shl 16)+VID_ATI, init_r500 ;Radeon X1300
dd (0x714E shl 16)+VID_ATI, init_r500 ;Radeon X1300
dd (0x714F shl 16)+VID_ATI, init_r500 ;RV505
dd (0x7151 shl 16)+VID_ATI, init_r500 ;RV505
dd (0x7152 shl 16)+VID_ATI, init_r500 ;FireGL V3300
dd (0x7153 shl 16)+VID_ATI, init_r500 ;FireGL V3350
dd (0x715E shl 16)+VID_ATI, init_r500 ;Radeon X1300
dd (0x715F shl 16)+VID_ATI, init_r500 ;Radeon X1550 64-bit
dd (0x7180 shl 16)+VID_ATI, init_r500 ;Radeon X1300/X1550
dd (0x7181 shl 16)+VID_ATI, init_r500 ;Radeon X1600
dd (0x7183 shl 16)+VID_ATI, init_r500 ;Radeon X1300/X1550
dd (0x7186 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1450
dd (0x7187 shl 16)+VID_ATI, init_r500 ;Radeon X1300/X1550
dd (0x7188 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X2300
dd (0x718A shl 16)+VID_ATI, init_r500 ;Mobility Radeon X2300
dd (0x718B shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1350
dd (0x718C shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1350
dd (0x718D shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1450
dd (0x718F shl 16)+VID_ATI, init_r500 ;Radeon X1300
dd (0x7193 shl 16)+VID_ATI, init_r500 ;Radeon X1550
dd (0x7196 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1350
dd (0x719B shl 16)+VID_ATI, init_r500 ;FireMV 2250
dd (0x719F shl 16)+VID_ATI, init_r500 ;Radeon X1550 64-bit
dd (0x71C0 shl 16)+VID_ATI, init_r500 ;Radeon X1600
dd (0x71C1 shl 16)+VID_ATI, init_r500 ;Radeon X1650
dd (0x71C2 shl 16)+VID_ATI, init_r500 ;Radeon X1600
dd (0x71C3 shl 16)+VID_ATI, init_r500 ;Radeon X1600
dd (0x71C4 shl 16)+VID_ATI, init_r500 ;Mobility FireGL V5200
dd (0x71C5 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1600
dd (0x71C6 shl 16)+VID_ATI, init_r500 ;Radeon X1650
dd (0x71C7 shl 16)+VID_ATI, init_r500 ;Radeon X1650
dd (0x71CD shl 16)+VID_ATI, init_r500 ;Radeon X1600
dd (0x71CE shl 16)+VID_ATI, init_r500 ;Radeon X1300 XT/X1600 Pro
dd (0x71D2 shl 16)+VID_ATI, init_r500 ;FireGL V3400
dd (0x71D4 shl 16)+VID_ATI, init_r500 ;Mobility FireGL V5250
dd (0x71D5 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1700
dd (0x71D6 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1700 XT
dd (0x71DA shl 16)+VID_ATI, init_r500 ;FireGL V5200
dd (0x71DE shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1700
dd (0x7200 shl 16)+VID_ATI, init_r500 ;Radeon X2300HD
dd (0x7210 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 2300
dd (0x7211 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 2300
dd (0x7240 shl 16)+VID_ATI, init_r500 ;Radeon X1950
dd (0x7243 shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x7244 shl 16)+VID_ATI, init_r500 ;Radeon X1950
dd (0x7245 shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x7246 shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x7247 shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x7248 shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x7249 shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x724A shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x724B shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x724C shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x724D shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x724E shl 16)+VID_ATI, init_r500 ;AMD Stream Processor
dd (0x724F shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x7280 shl 16)+VID_ATI, init_r500 ;Radeon X1950
dd (0x7281 shl 16)+VID_ATI, init_r500 ;RV560
dd (0x7283 shl 16)+VID_ATI, init_r500 ;RV560
dd (0x7284 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1900
dd (0x7287 shl 16)+VID_ATI, init_r500 ;RV560
dd (0x7288 shl 16)+VID_ATI, init_r500 ;Radeon X1950 GT
dd (0x7289 shl 16)+VID_ATI, init_r500 ;RV570
dd (0x728B shl 16)+VID_ATI, init_r500 ;RV570
dd (0x728C shl 16)+VID_ATI, init_r500 ;ATI FireGL V7400
dd (0x7290 shl 16)+VID_ATI, init_r500 ;RV560
dd (0x7291 shl 16)+VID_ATI, init_r500 ;Radeon X1650
dd (0x7293 shl 16)+VID_ATI, init_r500 ;Radeon X1650
dd (0x7297 shl 16)+VID_ATI, init_r500 ;RV560
dd (0x791E shl 16)+VID_ATI, init_r500 ;Radeon X1200
dd (0x791F shl 16)+VID_ATI, init_r500 ;Radeon X1200
dd (0x793F shl 16)+VID_ATI, init_r500 ;Radeon Xpress 1200
dd (0x7941 shl 16)+VID_ATI, init_r500 ;Radeon Xpress 1200
dd (0x7942 shl 16)+VID_ATI, init_r500 ;Radeon Xpress 1200 (M)
dd (0x796C shl 16)+VID_ATI, init_r500 ;RS740
dd (0x796D shl 16)+VID_ATI, init_r500 ;RS740M
dd (0x796E shl 16)+VID_ATI, init_r500 ;ATI Radeon 2100 RS740
dd (0x796F shl 16)+VID_ATI, init_r500 ;RS740M
dd (0x9400 shl 16)+VID_ATI, init_r500 ;Radeon HD 2900 XT
dd (0x9401 shl 16)+VID_ATI, init_r500 ;Radeon HD 2900 XT
dd (0x9402 shl 16)+VID_ATI, init_r500 ;Radeon HD 2900 XT
dd (0x9403 shl 16)+VID_ATI, init_r500 ;Radeon HD 2900 Pro
dd (0x9405 shl 16)+VID_ATI, init_r500 ;Radeon HD 2900 GT
dd (0x940A shl 16)+VID_ATI, init_r500 ;FireGL V8650
dd (0x940B shl 16)+VID_ATI, init_r500 ;FireGL V8600
dd (0x940F shl 16)+VID_ATI, init_r500 ;FireGL V7600
dd (0x94C0 shl 16)+VID_ATI, init_r500 ;RV610
dd (0x94C1 shl 16)+VID_ATI, init_r500 ;Radeon HD 2400 XT
dd (0x94C3 shl 16)+VID_ATI, init_r500 ;Radeon HD 2400 Pro
dd (0x94C4 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 2400 PRO AGP
dd (0x94C5 shl 16)+VID_ATI, init_r500 ;FireGL V4000
dd (0x94C6 shl 16)+VID_ATI, init_r500 ;RV610
dd (0x94C7 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 2350
dd (0x94C8 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 2400 XT
dd (0x94C9 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 2400
dd (0x94CB shl 16)+VID_ATI, init_r500 ;ATI RADEON E2400
dd (0x94CC shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 2400
dd (0x9500 shl 16)+VID_ATI, init_r500 ;RV670
dd (0x9501 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD3870
dd (0x9504 shl 16)+VID_ATI, init_r500 ;ATI Mobility Radeon HD 3850
dd (0x9505 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD3850
dd (0x9506 shl 16)+VID_ATI, init_r500 ;ATI Mobility Radeon HD 3850 X2
dd (0x9507 shl 16)+VID_ATI, init_r500 ;RV670
dd (0x9508 shl 16)+VID_ATI, init_r500 ;ATI Mobility Radeon HD 3870
dd (0x9509 shl 16)+VID_ATI, init_r500 ;ATI Mobility Radeon HD 3870 X2
dd (0x950F shl 16)+VID_ATI, init_r500 ;ATI Radeon HD3870 X2
dd (0x9511 shl 16)+VID_ATI, init_r500 ;ATI FireGL V7700
dd (0x9515 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3850 AGP
dd (0x9517 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3960
dd (0x9519 shl 16)+VID_ATI, init_r500 ;FireStream 9170
dd (0x9580 shl 16)+VID_ATI, init_r500 ;RV630
dd (0x9581 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 2600
dd (0x9583 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 2600 XT
dd (0x9586 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 2600 XT AGP
dd (0x9587 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 2600 Pro AGP
dd (0x9588 shl 16)+VID_ATI, init_r500 ;Radeon HD 2600 XT
dd (0x9589 shl 16)+VID_ATI, init_r500 ;Radeon HD 2600 Pro
dd (0x958A shl 16)+VID_ATI, init_r500 ;Gemini RV630
dd (0x958B shl 16)+VID_ATI, init_r500 ;Gemini ATI Mobility Radeon HD 2600 XT
dd (0x958C shl 16)+VID_ATI, init_r500 ;FireGL V5600
dd (0x958D shl 16)+VID_ATI, init_r500 ;FireGL V3600
dd (0x958E shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 2600 LE
dd (0x958F shl 16)+VID_ATI, init_r500 ;ATI Mobility FireGL Graphics Processor
dd (0x9590 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3600 Series
dd (0x9591 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 3650
dd (0x9593 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 3670
dd (0x9595 shl 16)+VID_ATI, init_r500 ;Mobility FireGL V5700
dd (0x9596 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3650 AGP
dd (0x9597 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3600 Series
dd (0x9598 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3670
dd (0x9599 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3600 Series
dd (0x959B shl 16)+VID_ATI, init_r500 ;Mobility FireGL Graphics Processor
dd (0x95C0 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3470
dd (0x95C2 shl 16)+VID_ATI, init_r500 ;ATI Mobility Radeon HD 3430 (M82)
dd (0x95C4 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 3400 Series (M82)
dd (0x95C5 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3450
dd (0x95C7 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3430
dd (0x95CC shl 16)+VID_ATI, init_r500 ;Fire PRO Professional Graphics ASIC
dd (0x95CD shl 16)+VID_ATI, init_r500 ;ATI FireMV 2450
dd (0x95CE shl 16)+VID_ATI, init_r500 ;ATI FireMV 2260
dd (0x95CF shl 16)+VID_ATI, init_r500 ;ATI FireMV 2260
dd (0x9610 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3200 Graphics
dd (0x9611 shl 16)+VID_ATI, init_r500 ;ATI Radeon 3100 Graphics
dd (0x9612 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3200 Graphics
dd (0x9613 shl 16)+VID_ATI, init_r500 ;ATI Radeon 3100 Graphics
dd (0x9614 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3300 Graphics
dd (0x9440 shl 16)+VID_ATI, init_r500 ;ATI Radeon 4800 Series
dd (0x9441 shl 16)+VID_ATI, init_r500 ;ATI Radeon 4870 X2
dd (0x9442 shl 16)+VID_ATI, init_r500 ;ATI Radeon 4800 Series
dd (0x9444 shl 16)+VID_ATI, init_r500 ;Everest ATI FirePro Graphics Accelerator
dd (0x9446 shl 16)+VID_ATI, init_r500 ;K2 ATI FirePro Graphics Accelerator
dd (0x944E shl 16)+VID_ATI, init_r500 ;RV770
dd (0x9456 shl 16)+VID_ATI, init_r500 ;Denali ATI FirePro Graphics
 
dd 0 ;terminator
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
if R500_HW2D
 
align 16
R5xxRops dd R5XX_ROP3_ZERO, R5XX_ROP3_ZERO ;GXclear
dd R5XX_ROP3_DSa, R5XX_ROP3_DPa ;Gxand
dd R5XX_ROP3_SDna, R5XX_ROP3_PDna ;GXandReverse
dd R5XX_ROP3_S, R5XX_ROP3_P ;GXcopy
dd R5XX_ROP3_DSna, R5XX_ROP3_DPna ;GXandInverted
dd R5XX_ROP3_D, R5XX_ROP3_D ;GXnoop
dd R5XX_ROP3_DSx, R5XX_ROP3_DPx ;GXxor
dd R5XX_ROP3_DSo, R5XX_ROP3_DPo ;GXor
dd R5XX_ROP3_DSon, R5XX_ROP3_DPon ;GXnor
dd R5XX_ROP3_DSxn, R5XX_ROP3_PDxn ;GXequiv
dd R5XX_ROP3_Dn, R5XX_ROP3_Dn ;GXinvert
dd R5XX_ROP3_SDno, R5XX_ROP3_PDno ;GXorReverse
dd R5XX_ROP3_Sn, R5XX_ROP3_Pn ;GXcopyInverted
dd R5XX_ROP3_DSno, R5XX_ROP3_DPno ;GXorInverted
dd R5XX_ROP3_DSan, R5XX_ROP3_DPan ;GXnand
dd R5XX_ROP3_ONE, R5XX_ROP3_ONE ;GXset
end if
 
 
sz_ati_srv db 'HWCURSOR',0
 
msgInit db 'detect hardware...',13,10,0
msgPCI db 'PCI accsess not supported',13,10,0
msgFail db 'device not found',13,10,0
msg_neg db 'neg ecx',13,10,0
 
if R500_HW2D
 
sz_HDraw_srv db 'HDRAW',0
 
msgR5xx2DFlushtimeout \
db 'R5xx2DFlush timeout error',13,10,0
msgR5xxFIFOWaitLocaltimeout \
db 'R5xxFIFOWaitLocal timeout error', 13, 10,0
msgR5xx2DIdleLocaltimeout \
db 'R5xx2DIdleLocal timeout error', 13,10,0
 
align 4
R520_cp_microcode:
dd 0x4200e000, 0000000000
dd 0x4000e000, 0000000000
dd 0x00000099, 0x00000008
dd 0x0000009d, 0x00000008
dd 0x4a554b4a, 0000000000
dd 0x4a4a4467, 0000000000
dd 0x55526f75, 0000000000
dd 0x4a7e7d65, 0000000000
dd 0xe0dae6f6, 0000000000
dd 0x4ac54a4a, 0000000000
dd 0xc8828282, 0000000000
dd 0xbf4acfc1, 0000000000
dd 0x87b04ad5, 0000000000
dd 0xb5838383, 0000000000
dd 0x4a0f85ba, 0000000000
dd 0x000ca000, 0x00000004
dd 0x000d0012, 0x00000038
dd 0x0000e8b4, 0x00000004
dd 0x000d0014, 0x00000038
dd 0x0000e8b6, 0x00000004
dd 0x000d0016, 0x00000038
dd 0x0000e854, 0x00000004
dd 0x000d0018, 0x00000038
dd 0x0000e855, 0x00000004
dd 0x000d001a, 0x00000038
dd 0x0000e856, 0x00000004
dd 0x000d001c, 0x00000038
dd 0x0000e857, 0x00000004
dd 0x000d001e, 0x00000038
dd 0x0000e824, 0x00000004
dd 0x000d0020, 0x00000038
dd 0x0000e825, 0x00000004
dd 0x000d0022, 0x00000038
dd 0x0000e830, 0x00000004
dd 0x000d0024, 0x00000038
dd 0x0000f0c0, 0x00000004
dd 0x000d0026, 0x00000038
dd 0x0000f0c1, 0x00000004
dd 0x000d0028, 0x00000038
dd 0x0000e000, 0x00000004
dd 0x000d002a, 0x00000038
dd 0x0000e000, 0x00000004
dd 0x000d002c, 0x00000038
dd 0x0000e000, 0x00000004
dd 0x000d002e, 0x00000038
dd 0x0000e000, 0x00000004
dd 0x000d0030, 0x00000038
dd 0x0000e000, 0x00000004
dd 0x000d0032, 0x00000038
dd 0x0000f180, 0x00000004
dd 0x000d0034, 0x00000038
dd 0x0000f393, 0x00000004
dd 0x000d0036, 0x00000038
dd 0x0000f38a, 0x00000004
dd 0x000d0038, 0x00000038
dd 0x0000f38e, 0x00000004
dd 0x0000e821, 0x00000004
dd 0x0140a000, 0x00000004
dd 0x00000043, 0x00000018
dd 0x00cce800, 0x00000004
dd 0x001b0001, 0x00000004
dd 0x08004800, 0x00000004
dd 0x001b0001, 0x00000004
dd 0x08004800, 0x00000004
dd 0x001b0001, 0x00000004
dd 0x08004800, 0x00000004
dd 0x0000003a, 0x00000008
dd 0x0000a000, 0000000000
dd 0x2000451d, 0x00000004
dd 0x0000e580, 0x00000004
dd 0x000ce581, 0x00000004
dd 0x08004580, 0x00000004
dd 0x000ce581, 0x00000004
dd 0x00000047, 0x00000008
dd 0x0000a000, 0000000000
dd 0x000c2000, 0x00000004
dd 0x0000e50e, 0x00000004
dd 0x00032000, 0x00000004
dd 0x00022051, 0x00000028
dd 0x00000051, 0x00000024
dd 0x0800450f, 0x00000004
dd 0x0000a04b, 0x00000008
dd 0x0000e565, 0x00000004
dd 0x0000e566, 0x00000004
dd 0x00000052, 0x00000008
dd 0x03cca5b4, 0x00000004
dd 0x05432000, 0x00000004
dd 0x00022000, 0x00000004
dd 0x4ccce05e, 0x00000030
dd 0x08274565, 0x00000004
dd 0x0000005e, 0x00000030
dd 0x08004564, 0x00000004
dd 0x0000e566, 0x00000004
dd 0x00000055, 0x00000008
dd 0x00802061, 0x00000010
dd 0x00202000, 0x00000004
dd 0x001b00ff, 0x00000004
dd 0x01000064, 0x00000010
dd 0x001f2000, 0x00000004
dd 0x001c00ff, 0x00000004
dd 0000000000, 0x0000000c
dd 0x00000072, 0x00000030
dd 0x00000055, 0x00000008
dd 0x0000e576, 0x00000004
dd 0x0000e577, 0x00000004
dd 0x0000e50e, 0x00000004
dd 0x0000e50f, 0x00000004
dd 0x0140a000, 0x00000004
dd 0x00000069, 0x00000018
dd 0x00c0e5f9, 0x000000c2
dd 0x00000069, 0x00000008
dd 0x0014e50e, 0x00000004
dd 0x0040e50f, 0x00000004
dd 0x00c0006c, 0x00000008
dd 0x0000e570, 0x00000004
dd 0x0000e571, 0x00000004
dd 0x0000e572, 0x0000000c
dd 0x0000a000, 0x00000004
dd 0x0140a000, 0x00000004
dd 0x0000e568, 0x00000004
dd 0x000c2000, 0x00000004
dd 0x00000076, 0x00000018
dd 0x000b0000, 0x00000004
dd 0x18c0e562, 0x00000004
dd 0x00000078, 0x00000008
dd 0x00c00077, 0x00000008
dd 0x000700c7, 0x00000004
dd 0x00000080, 0x00000038
dd 0x0000e5bb, 0x00000004
dd 0x0000e5bc, 0000000000
dd 0x0000a000, 0x00000004
dd 0x0000e821, 0x00000004
dd 0x0000e800, 0000000000
dd 0x0000e821, 0x00000004
dd 0x0000e82e, 0000000000
dd 0x02cca000, 0x00000004
dd 0x00140000, 0x00000004
dd 0x000ce1cc, 0x00000004
dd 0x050de1cd, 0x00000004
dd 0x00400000, 0x00000004
dd 0x0000008f, 0x00000018
dd 0x00c0a000, 0x00000004
dd 0x0000008c, 0x00000008
dd 0x00000091, 0x00000020
dd 0x4200e000, 0000000000
dd 0x00000098, 0x00000038
dd 0x000ca000, 0x00000004
dd 0x00140000, 0x00000004
dd 0x000c2000, 0x00000004
dd 0x00160000, 0x00000004
dd 0x700ce000, 0x00000004
dd 0x00140094, 0x00000008
dd 0x4000e000, 0000000000
dd 0x02400000, 0x00000004
dd 0x400ee000, 0x00000004
dd 0x02400000, 0x00000004
dd 0x4000e000, 0000000000
dd 0x000c2000, 0x00000004
dd 0x0240e51b, 0x00000004
dd 0x0080e50a, 0x00000005
dd 0x0080e50b, 0x00000005
dd 0x00220000, 0x00000004
dd 0x000700c7, 0x00000004
dd 0x000000a4, 0x00000038
dd 0x0080e5bd, 0x00000005
dd 0x0000e5bb, 0x00000005
dd 0x0080e5bc, 0x00000005
dd 0x00210000, 0x00000004
dd 0x02800000, 0x00000004
dd 0x00c000ab, 0x00000018
dd 0x4180e000, 0x00000040
dd 0x000000ad, 0x00000024
dd 0x01000000, 0x0000000c
dd 0x0100e51d, 0x0000000c
dd 0x000045bb, 0x00000004
dd 0x000080a7, 0x00000008
dd 0x0000f3ce, 0x00000004
dd 0x0140a000, 0x00000004
dd 0x00cc2000, 0x00000004
dd 0x08c053cf, 0x00000040
dd 0x00008000, 0000000000
dd 0x0000f3d2, 0x00000004
dd 0x0140a000, 0x00000004
dd 0x00cc2000, 0x00000004
dd 0x08c053d3, 0x00000040
dd 0x00008000, 0000000000
dd 0x0000f39d, 0x00000004
dd 0x0140a000, 0x00000004
dd 0x00cc2000, 0x00000004
dd 0x08c0539e, 0x00000040
dd 0x00008000, 0000000000
dd 0x03c00830, 0x00000004
dd 0x4200e000, 0000000000
dd 0x0000a000, 0x00000004
dd 0x200045e0, 0x00000004
dd 0x0000e5e1, 0000000000
dd 0x00000001, 0000000000
dd 0x000700c4, 0x00000004
dd 0x0800e394, 0000000000
dd 0000000000, 0000000000
dd 0x0000e8c4, 0x00000004
dd 0x0000e8c5, 0x00000004
dd 0x0000e8c6, 0x00000004
dd 0x0000e928, 0x00000004
dd 0x0000e929, 0x00000004
dd 0x0000e92a, 0x00000004
dd 0x000000c8, 0x00000008
dd 0x0000e928, 0x00000004
dd 0x0000e929, 0x00000004
dd 0x0000e92a, 0x00000004
dd 0x000000cf, 0x00000008
dd 0xdeadbeef, 0000000000
dd 0x00000116, 0000000000
dd 0x000700d3, 0x00000004
dd 0x080050e7, 0x00000004
dd 0x000700d4, 0x00000004
dd 0x0800401c, 0x00000004
dd 0x0000e01d, 0000000000
dd 0x02c02000, 0x00000004
dd 0x00060000, 0x00000004
dd 0x000000de, 0x00000034
dd 0x000000db, 0x00000008
dd 0x00008000, 0x00000004
dd 0xc000e000, 0000000000
dd 0x0000e1cc, 0x00000004
dd 0x0500e1cd, 0x00000004
dd 0x000ca000, 0x00000004
dd 0x000000e5, 0x00000034
dd 0x000000e1, 0x00000008
dd 0x0000a000, 0000000000
dd 0x0019e1cc, 0x00000004
dd 0x001b0001, 0x00000004
dd 0x0500a000, 0x00000004
dd 0x080041cd, 0x00000004
dd 0x000ca000, 0x00000004
dd 0x000000fb, 0x00000034
dd 0x0000004a, 0x00000008
dd 0000000000, 0000000000
dd 0000000000, 0000000000
dd 0000000000, 0000000000
dd 0000000000, 0000000000
dd 0000000000, 0000000000
dd 0000000000, 0000000000
dd 0000000000, 0000000000
dd 0000000000, 0000000000
dd 0000000000, 0000000000
dd 0x000c2000, 0x00000004
dd 0x001d0018, 0x00000004
dd 0x001a0001, 0x00000004
dd 0x000000fb, 0x00000034
dd 0x0000004a, 0x00000008
dd 0x0500a04a, 0x00000008
dd 0000000000, 0000000000
dd 0000000000, 0000000000
dd 0000000000, 0000000000
dd 0000000000, 0000000000
 
 
end if
 
if 0
msg6100 db '6100: ',0
msg6104 db '6104: ',0
msg6108 db '6108: ',0
msg6110 db '6110: ',0
msg6120 db '6120: ',0
msg6124 db '6124: ',0
msg6128 db '6128: ',0
msg612C db '612C: ',0
msg6130 db '6130: ',0
msg6134 db '6134: ',0
msg6138 db '6138: ',0
end if
 
buff db 8 dup(0)
db 13,10, 0
 
section '.data' data readable writable align 16
 
pCursor db 4096 dup(?)
 
cursor_map rd 2
cursor_start rd 1
cursor_end rd 1
 
fnSelect rd 1
fnSet rd 1
oldSelect rd 1
oldSet rd 1
oldRestore rd 1
oldCreate rd 1
 
r500_LFB rd 1
 
bus dd ?
devfn dd ?
ati_io dd ?
 
if R500_HW2D
 
__xmin rd 1
__xmax rd 1
__ymin rd 1
__ymax rd 1
 
rhd RHD
 
end if
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/tags/kolibri0.7.5.0/drivers/r500hw.inc
0,0 → 1,1272
if 0
 
Copyright 2008 Serge
 
The below code is a rework from code in
xf86-video-radeonhd/src/r5xx_accel.c, xf86-video-radeonhd/src/r5xx_xaa.c
 
git://anongit.freedesktop.org/git/nouveau/xf86-video-radeonhd
git://anongit.freedesktop.org/git/xorg/driver/xf86-video-ati
 
 
Copyright 2008 Luc Verhaegen <lverhaegen@novell.com>
Copyright 2008 Matthias Hopf <mhopf@novell.com>
Copyright 2008 Egbert Eich <eich@novell.com>
Copyright 2008 Advanced Micro Devices, Inc.
 
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
 
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
 
The below code is a rework from code in xf86-video-ati/src/radeon_accel.c
The original license is included below, it has the messed up disclaimer and
an all rights reserved statement.
 
 
Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
VA Linux Systems Inc., Fremont, California.
 
All Rights Reserved.
 
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation on the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
 
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
 
Authors:
Kevin E. Martin <martin@xfree86.org>
Rickard E. Faith <faith@valinux.com>
Alan Hourihane <alanh@fairlite.demon.co.uk>
 
end if
 
RADEON_CP_ME_RAM_ADDR equ 0x07d4
RADEON_CP_ME_RAM_RADDR equ 0x07d8
RADEON_CP_ME_RAM_DATAH equ 0x07dc
RADEON_CP_ME_RAM_DATAL equ 0x07e0
 
RADEON_CP_RB_BASE equ 0x0700
RADEON_CP_RB_CNTL equ 0x0704
RADEON_RB_NO_UPDATE equ (1 shl 27)
RADEON_CP_RB_RPTR_ADDR equ 0x070c
RADEON_CP_RB_RPTR equ 0x0710
RADEON_CP_RB_WPTR equ 0x0714
 
RADEON_CP_CSQ_CNTL equ 0x0740
RADEON_CSQ_CNT_PRIMARY_MASK equ (0xff shl 0)
RADEON_CSQ_PRIDIS_INDDIS equ (0 shl 28)
RADEON_CSQ_PRIPIO_INDDIS equ (1 shl 28)
RADEON_CSQ_PRIBM_INDDIS equ (2 shl 28)
RADEON_CSQ_PRIPIO_INDBM equ (3 shl 28)
RADEON_CSQ_PRIBM_INDBM equ (4 shl 28)
RADEON_CSQ_PRIPIO_INDPIO equ (15 shl 28)
 
RADEON_CP_RB_WPTR_DELAY equ 0x0718
 
RADEON_SCRATCH_UMSK equ 0x0770
RADEON_SCRATCH_ADDR equ 0x0774
 
RADEON_ISYNC_CNTL equ 0x1724
RADEON_ISYNC_ANY2D_IDLE3D equ (1 shl 0)
RADEON_ISYNC_ANY3D_IDLE2D equ (1 shl 1)
RADEON_ISYNC_TRIG2D_IDLE3D equ (1 shl 2)
RADEON_ISYNC_TRIG3D_IDLE2D equ (1 shl 3)
RADEON_ISYNC_WAIT_IDLEGUI equ (1 shl 4)
RADEON_ISYNC_CPSCRATCH_IDLEGUI equ (1 shl 5)
 
RADEON_AIC_CNTL equ 0x01d0
RADEON_PCIGART_TRANSLATE_EN equ (1 shl 0)
RADEON_AIC_STAT equ 0x01d4
RADEON_AIC_PT_BASE equ 0x01d8
RADEON_AIC_LO_ADDR equ 0x01dc
RADEON_AIC_HI_ADDR equ 0x01e0
RADEON_AIC_TLB_ADDR equ 0x01e4
RADEON_AIC_TLB_DATA equ 0x01e8
 
RADEON_WAIT_UNTIL equ 0x1720
RADEON_WAIT_CRTC_PFLIP equ (1 shl 0)
RADEON_WAIT_2D_IDLE equ (1 shl 14)
RADEON_WAIT_3D_IDLE equ (1 shl 15)
RADEON_WAIT_2D_IDLECLEAN equ (1 shl 16)
RADEON_WAIT_3D_IDLECLEAN equ (1 shl 17)
RADEON_WAIT_HOST_IDLECLEAN equ (1 shl 18)
 
D1GRPH_PITCH equ 0x6120
D1GRPH_X_END equ 0x6134
D1GRPH_Y_END equ 0x6138
 
 
R5XX_DATATYPE_ARGB8888 equ 6
 
R5XX_RB3D_CNTL equ 0x1c3c
 
R5XX_RBBM_STATUS equ 0x0e40
R5XX_RBBM_FIFOCNT_MASK equ 0x007f
R5XX_RBBM_ACTIVE equ (1 shl 31)
 
R5XX_RBBM_SOFT_RESET equ 0x00f0
R5XX_SOFT_RESET_CP equ (1 shl 0)
R5XX_SOFT_RESET_HI equ (1 shl 1)
R5XX_SOFT_RESET_SE equ (1 shl 2)
R5XX_SOFT_RESET_RE equ (1 shl 3)
R5XX_SOFT_RESET_PP equ (1 shl 4)
R5XX_SOFT_RESET_E2 equ (1 shl 5)
R5XX_SOFT_RESET_RB equ (1 shl 6)
R5XX_SOFT_RESET_HDP equ (1 shl 7)
 
R5XX_SRC_PITCH_OFFSET equ 0x1428
R5XX_DST_PITCH_OFFSET equ 0x142c
 
R5XX_DP_DATATYPE equ 0x16c4
R5XX_HOST_BIG_ENDIAN_EN equ (1 shl 29)
 
R5XX_DP_CNTL equ 0x16c0
R5XX_DST_X_LEFT_TO_RIGHT equ (1 shl 0)
R5XX_DST_Y_TOP_TO_BOTTOM equ (1 shl 1)
R5XX_DP_DST_TILE_LINEAR equ (0 shl 3)
R5XX_DP_DST_TILE_MACRO equ (1 shl 3)
R5XX_DP_DST_TILE_MICRO equ (2 shl 3)
R5XX_DP_DST_TILE_BOTH equ (3 shl 3)
 
RADEON_RB3D_ZCACHE_CTLSTAT equ 0x3254
RADEON_RB3D_ZC_FLUSH equ (1 shl 0)
RADEON_RB3D_ZC_FREE equ (1 shl 2)
RADEON_RB3D_ZC_FLUSH_ALL equ 0x5
RADEON_RB3D_ZC_BUSY equ (1 shl 31)
 
R5XX_RB3D_DSTCACHE_CTLSTAT equ 0x325C
R5XX_RB3D_DC_FLUSH equ (3 shl 0)
R5XX_RB3D_DC_FREE equ (3 shl 2)
R5XX_RB3D_DC_FLUSH_ALL equ 0xf
R5XX_RB3D_DC_BUSY equ (1 shl 31)
 
R5XX_SURFACE_CNTL equ 0x0b00
R5XX_SURF_TRANSLATION_DIS equ (1 shl 8)
R5XX_NONSURF_AP0_SWP_16BPP equ (1 shl 20)
R5XX_NONSURF_AP0_SWP_32BPP equ (1 shl 21)
R5XX_NONSURF_AP1_SWP_16BPP equ (1 shl 22)
R5XX_NONSURF_AP1_SWP_32BPP equ (1 shl 23)
 
R5XX_DEFAULT_SC_BOTTOM_RIGHT equ 0x16e8
R5XX_DEFAULT_SC_RIGHT_MAX equ (0x1fff shl 0)
R5XX_DEFAULT_SC_BOTTOM_MAX equ (0x1fff shl 16)
 
R5XX_SC_TOP_LEFT equ 0x16ec
R5XX_SC_BOTTOM_RIGHT equ 0x16f0
R5XX_SC_SIGN_MASK_LO equ 0x8000
R5XX_SC_SIGN_MASK_HI equ 0x80000000
 
R5XX_DP_GUI_MASTER_CNTL equ 0x146c
R5XX_GMC_SRC_PITCH_OFFSET_CNTL equ (1 shl 0)
R5XX_GMC_DST_PITCH_OFFSET_CNTL equ (1 shl 1)
R5XX_GMC_SRC_CLIPPING equ (1 shl 2)
R5XX_GMC_DST_CLIPPING equ (1 shl 3)
R5XX_GMC_BRUSH_DATATYPE_MASK equ (0x0f shl 4)
R5XX_GMC_BRUSH_8X8_MONO_FG_BG equ (0 shl 4)
R5XX_GMC_BRUSH_8X8_MONO_FG_LA equ (1 shl 4)
R5XX_GMC_BRUSH_1X8_MONO_FG_BG equ (4 shl 4)
R5XX_GMC_BRUSH_1X8_MONO_FG_LA equ (5 shl 4)
R5XX_GMC_BRUSH_32x1_MONO_FG_BG equ (6 shl 4)
R5XX_GMC_BRUSH_32x1_MONO_FG_LA equ (7 shl 4)
R5XX_GMC_BRUSH_32x32_MONO_FG_BG equ (8 shl 4)
R5XX_GMC_BRUSH_32x32_MONO_FG_LA equ (9 shl 4)
R5XX_GMC_BRUSH_8x8_COLOR equ (10 shl 4)
R5XX_GMC_BRUSH_1X8_COLOR equ (12 shl 4)
R5XX_GMC_BRUSH_SOLID_COLOR equ (13 shl 4)
R5XX_GMC_BRUSH_NONE equ (15 shl 4)
R5XX_GMC_DST_8BPP_CI equ (2 shl 8)
R5XX_GMC_DST_15BPP equ (3 shl 8)
R5XX_GMC_DST_16BPP equ (4 shl 8)
R5XX_GMC_DST_24BPP equ (5 shl 8)
R5XX_GMC_DST_32BPP equ (6 shl 8)
R5XX_GMC_DST_8BPP_RGB equ (7 shl 8)
R5XX_GMC_DST_Y8 equ (8 shl 8)
R5XX_GMC_DST_RGB8 equ (9 shl 8)
R5XX_GMC_DST_VYUY equ (11 shl 8)
R5XX_GMC_DST_YVYU equ (12 shl 8)
R5XX_GMC_DST_AYUV444 equ (14 shl 8)
R5XX_GMC_DST_ARGB4444 equ (15 shl 8)
R5XX_GMC_DST_DATATYPE_MASK equ (0x0f shl 8)
R5XX_GMC_DST_DATATYPE_SHIFT equ 8
R5XX_GMC_SRC_DATATYPE_MASK equ (3 shl 12)
R5XX_GMC_SRC_DATATYPE_MONO_FG_BG equ (0 shl 12)
R5XX_GMC_SRC_DATATYPE_MONO_FG_LA equ (1 shl 12)
R5XX_GMC_SRC_DATATYPE_COLOR equ (3 shl 12)
R5XX_GMC_BYTE_PIX_ORDER equ (1 shl 14)
R5XX_GMC_BYTE_MSB_TO_LSB equ (0 shl 14)
R5XX_GMC_BYTE_LSB_TO_MSB equ (1 shl 14)
R5XX_GMC_CONVERSION_TEMP equ (1 shl 15)
R5XX_GMC_CONVERSION_TEMP_6500 equ (0 shl 15)
R5XX_GMC_CONVERSION_TEMP_9300 equ (1 shl 15)
R5XX_GMC_ROP3_MASK equ (0xff shl 16)
R5XX_DP_SRC_SOURCE_MASK equ (7 shl 24)
R5XX_DP_SRC_SOURCE_MEMORY equ (2 shl 24)
R5XX_DP_SRC_SOURCE_HOST_DATA equ (3 shl 24)
R5XX_GMC_3D_FCN_EN equ (1 shl 27)
R5XX_GMC_CLR_CMP_CNTL_DIS equ (1 shl 28)
R5XX_GMC_AUX_CLIP_DIS equ (1 shl 29)
R5XX_GMC_WR_MSK_DIS equ (1 shl 30)
R5XX_GMC_LD_BRUSH_Y_X equ (1 shl 31)
R5XX_ROP3_ZERO equ 0x00000000
R5XX_ROP3_DSa equ 0x00880000
R5XX_ROP3_SDna equ 0x00440000
R5XX_ROP3_S equ 0x00cc0000
R5XX_ROP3_DSna equ 0x00220000
R5XX_ROP3_D equ 0x00aa0000
R5XX_ROP3_DSx equ 0x00660000
R5XX_ROP3_DSo equ 0x00ee0000
R5XX_ROP3_DSon equ 0x00110000
R5XX_ROP3_DSxn equ 0x00990000
R5XX_ROP3_Dn equ 0x00550000
R5XX_ROP3_SDno equ 0x00dd0000
R5XX_ROP3_Sn equ 0x00330000
R5XX_ROP3_DSno equ 0x00bb0000
R5XX_ROP3_DSan equ 0x00770000
R5XX_ROP3_ONE equ 0x00ff0000
R5XX_ROP3_DPa equ 0x00a00000
R5XX_ROP3_PDna equ 0x00500000
R5XX_ROP3_P equ 0x00f00000
R5XX_ROP3_DPna equ 0x000a0000
R5XX_ROP3_D equ 0x00aa0000
R5XX_ROP3_DPx equ 0x005a0000
R5XX_ROP3_DPo equ 0x00fa0000
R5XX_ROP3_DPon equ 0x00050000
R5XX_ROP3_PDxn equ 0x00a50000
R5XX_ROP3_PDno equ 0x00f50000
R5XX_ROP3_Pn equ 0x000f0000
R5XX_ROP3_DPno equ 0x00af0000
R5XX_ROP3_DPan equ 0x005f0000
 
R5XX_HOST_PATH_CNTL equ 0x0130
R5XX_HDP_SOFT_RESET equ (1 shl 26)
R5XX_HDP_APER_CNTL equ (1 shl 23)
 
R5XX_RB3D_DSTCACHE_MODE equ 0x3258
R5XX_RB3D_DC_CACHE_ENABLE equ (0)
R5XX_RB3D_DC_2D_CACHE_DISABLE equ (1)
R5XX_RB3D_DC_3D_CACHE_DISABLE equ (2)
R5XX_RB3D_DC_CACHE_DISABLE equ (3)
R5XX_RB3D_DC_2D_CACHE_LINESIZE_128 equ (1 shl 2)
R5XX_RB3D_DC_3D_CACHE_LINESIZE_128 equ (2 shl 2)
R5XX_RB3D_DC_2D_CACHE_AUTOFLUSH equ (1 shl 8)
R5XX_RB3D_DC_3D_CACHE_AUTOFLUSH equ (2 shl 8)
R200_RB3D_DC_2D_CACHE_AUTOFREE equ (1 shl 10)
R200_RB3D_DC_3D_CACHE_AUTOFREE equ (2 shl 10)
R5XX_RB3D_DC_FORCE_RMW equ (1 shl 16)
R5XX_RB3D_DC_DISABLE_RI_FILL equ (1 shl 24)
R5XX_RB3D_DC_DISABLE_RI_READ equ (1 shl 25)
 
R5XX_BRUSH_Y_X equ 0x1474
R5XX_DP_BRUSH_BKGD_CLR equ 0x1478
R5XX_DP_BRUSH_FRGD_CLR equ 0x147c
R5XX_BRUSH_DATA0 equ 0x1480
R5XX_BRUSH_DATA1 equ 0x1484
 
R5XX_SRC_Y_X equ 0x1434
 
R5XX_DST_Y_X equ 0x1438
R5XX_DST_HEIGHT_WIDTH equ 0x143c
R5XX_DST_WIDTH_HEIGHT equ 0x1598
 
R5XX_DST_LINE_START equ 0x1600
R5XX_DST_LINE_END equ 0x1604
R5XX_DST_LINE_PATCOUNT equ 0x1608
R5XX_BRES_CNTL_SHIFT equ 8
 
 
R5XX_DP_SRC_BKGD_CLR equ 0x15dc
R5XX_DP_SRC_FRGD_CLR equ 0x15d8
 
R5XX_DP_WRITE_MASK equ 0x16cc
 
 
RADEON_CP_PACKET0 equ 0x00000000
 
struc RHD
{
.control rd 1
.control_saved rd 1
.datatype rd 1
.surface_cntl rd 1
.dst_pitch_offset rd 1
.ring_base rd 1
.ring_rp rd 1
.ring_wp rd 1
};
 
R5XX_LOOP_COUNT equ 2000000
 
 
 
align 4
R5xxFIFOWaitLocal:
 
mov ecx, R5XX_LOOP_COUNT
@@:
rdr ebx, R5XX_RBBM_STATUS
and ebx, R5XX_RBBM_FIFOCNT_MASK
 
cmp eax, ebx
jbe .done
loop @B
 
mov esi, msgR5xxFIFOWaitLocaltimeout
call SysMsgBoardStr
xor eax, eax
ret
.done:
mov eax, 1
ret
 
align 4
R5xxFIFOWait:
call R5xxFIFOWaitLocal
test eax, eax
jz .reset
 
ret
.reset:
call R5xx2DReset
call R5xx2DSetup
 
ret
 
 
; Wait for the graphics engine to be completely idle: the FIFO has
; drained, the Pixel Cache is flushed, and the engine is idle. This is
; a standard "sync" function that will make the hardware "quiescent".
 
align 4
R5xx2DIdleLocal:
 
mov ecx, R5XX_LOOP_COUNT
@@:
rdr eax, R5XX_RBBM_STATUS
and eax, R5XX_RBBM_FIFOCNT_MASK
cmp eax, 0x40
je @F
loop @B
 
mov esi, msgR5xx2DIdleLocaltimeout
call SysMsgBoardStr
xor eax, eax
ret
@@:
mov ecx, R5XX_LOOP_COUNT
@@:
rdr eax, R5XX_RBBM_STATUS
test eax, R5XX_RBBM_ACTIVE
jz .done
loop @B
 
mov esi, msgR5xx2DIdleLocaltimeout
call SysMsgBoardStr
xor eax, eax
ret
.done:
call R5xx2DFlush
ret
 
align 4
R5xx2DFlush:
rmask R5XX_RB3D_DSTCACHE_CTLSTAT, R5XX_RB3D_DC_FLUSH_ALL, R5XX_RB3D_DC_FLUSH_ALL
 
mov ecx, R5XX_LOOP_COUNT
@@:
rdr eax, R5XX_RB3D_DSTCACHE_CTLSTAT
test eax, R5XX_RB3D_DC_BUSY
jz .done
loop @B
.fail:
mov esi, msgR5xx2DFlushtimeout
call SysMsgBoardStr
xor eax, eax
ret
.done:
mov eax, 1
ret
 
align 4
proc R5xx2DReset
locals
save rd 1
tmp rd 1
endl
 
; The following RBBM_SOFT_RESET sequence can help un-wedge
; an R300 after the command processor got stuck.
 
rdr eax, R5XX_RBBM_SOFT_RESET
mov [save], eax
 
or eax, R5XX_SOFT_RESET_CP or \
R5XX_SOFT_RESET_HI or R5XX_SOFT_RESET_SE or \
R5XX_SOFT_RESET_RE or R5XX_SOFT_RESET_PP or \
R5XX_SOFT_RESET_E2 or R5XX_SOFT_RESET_RB
mov [tmp], eax
 
wrr R5XX_RBBM_SOFT_RESET, eax
 
rdr ebx, R5XX_RBBM_SOFT_RESET
and eax, not (R5XX_SOFT_RESET_CP or R5XX_SOFT_RESET_HI or \
R5XX_SOFT_RESET_SE or R5XX_SOFT_RESET_RE or \
R5XX_SOFT_RESET_PP or R5XX_SOFT_RESET_E2 or \
R5XX_SOFT_RESET_RB)
wrr R5XX_RBBM_SOFT_RESET, eax
rdr ebx, R5XX_RBBM_SOFT_RESET
mov eax, [save]
wrr R5XX_RBBM_SOFT_RESET, eax
rdr ebx, R5XX_RBBM_SOFT_RESET
call R5xx2DFlush
 
; Soft resetting HDP thru RBBM_SOFT_RESET register can cause some
; unexpected behaviour on some machines. Here we use
; R5XX_HOST_PATH_CNTL to reset it.
 
rdr edx, R5XX_HOST_PATH_CNTL
 
rdr ebx, R5XX_RBBM_SOFT_RESET
 
or ebx, R5XX_SOFT_RESET_CP or R5XX_SOFT_RESET_HI or R5XX_SOFT_RESET_E2
 
wrr R5XX_RBBM_SOFT_RESET, ebx
 
rdr eax, R5XX_RBBM_SOFT_RESET
 
wrr R5XX_RBBM_SOFT_RESET, 0
 
rdr ebx, R5XX_RB3D_DSTCACHE_MODE
 
or ebx, (1 shl 17)
wrr R5XX_RB3D_DSTCACHE_MODE, ebx
 
lea eax, [edx+R5XX_HDP_SOFT_RESET]
wrr R5XX_HOST_PATH_CNTL, eax
 
rdr ebx, R5XX_HOST_PATH_CNTL
 
wrr R5XX_HOST_PATH_CNTL, edx
 
ret
endp
 
align 4
R5xx2DSetup:
 
; Setup engine location. This shouldn't be necessary since we
; set them appropriately before any accel ops, but let's avoid
; random bogus DMA in case we inadvertently trigger the engine
; in the wrong place (happened).
 
mov eax, 2
call R5xxFIFOWaitLocal
 
mov eax, [rhd.dst_pitch_offset]
wrr R5XX_DST_PITCH_OFFSET, eax
 
wrr R5XX_SRC_PITCH_OFFSET, eax
 
mov eax, 1
call R5xxFIFOWaitLocal
 
rmask R5XX_DP_DATATYPE, 0, R5XX_HOST_BIG_ENDIAN_EN
 
mov eax, [rhd.surface_cntl]
wrr R5XX_SURFACE_CNTL, eax
 
mov eax, 1
call R5xxFIFOWaitLocal
 
wrr R5XX_DEFAULT_SC_BOTTOM_RIGHT,\
(R5XX_DEFAULT_SC_RIGHT_MAX or R5XX_DEFAULT_SC_BOTTOM_MAX)
 
mov eax, 1
call R5xxFIFOWaitLocal
 
mov eax, [rhd.control]
or eax, (R5XX_GMC_BRUSH_SOLID_COLOR or R5XX_GMC_SRC_DATATYPE_COLOR)
wrr R5XX_DP_GUI_MASTER_CNTL, eax
 
mov eax, 5
call R5xxFIFOWaitLocal
 
wrr R5XX_DP_BRUSH_FRGD_CLR, 0xFFFFFFFF
 
wrr R5XX_DP_BRUSH_BKGD_CLR, 0x00000000
 
wrr R5XX_DP_SRC_FRGD_CLR, 0xFFFFFFFF
wrr R5XX_DP_SRC_BKGD_CLR, 0x00000000
wrr R5XX_DP_WRITE_MASK, 0xFFFFFFFF
 
call R5xx2DIdleLocal
ret
 
align 4
R5xx2DPreInit:
 
mov [rhd.control],\
(R5XX_DATATYPE_ARGB8888 shl R5XX_GMC_DST_DATATYPE_SHIFT) or\
R5XX_GMC_CLR_CMP_CNTL_DIS or R5XX_GMC_DST_PITCH_OFFSET_CNTL
 
mov [rhd.datatype], R5XX_DATATYPE_ARGB8888
mov [rhd.surface_cntl],0
 
rdr eax, D1GRPH_PITCH
shl eax, 18
 
mov ebx, [r500_LFB]
shr ebx, 10
or eax, ebx
 
mov [rhd.dst_pitch_offset], eax
 
ret
 
RADEON_BUS_CNTL equ 0x0030
RADEON_BUS_MASTER_DIS equ (1 shl 6)
 
align 4
R5xxCpInit:
stdcall CreateRingBuffer, 0x8000, PG_SW+PG_NOCACHE
test eax, eax
jz .fail
 
mov [rhd.ring_base], eax
call GetPgAddr
 
wrr RADEON_CP_RB_BASE, eax
 
wrr RADEON_CP_RB_WPTR_DELAY, 0
 
rdr ebx, RADEON_CP_RB_RPTR
wrr RADEON_CP_RB_WPTR, ebx
 
mov [rhd.ring_rp], ebx
mov [rhd.ring_wp], ebx
 
wrr RADEON_CP_RB_RPTR_ADDR, 0 ;ring buffer read pointer
;no update
 
wrr RADEON_CP_RB_CNTL, RADEON_RB_NO_UPDATE + 12
wrr RADEON_SCRATCH_UMSK, 0 ;no scratch update
 
rdr ebx, RADEON_BUS_CNTL
and ebx, not RADEON_BUS_MASTER_DIS
 
wrr RADEON_BUS_CNTL, ebx
 
; wrr RADEON_LAST_FRAME_REG, 0
; wrr RADEON_LAST_DISPATCH_REG, 0
; wrr RADEON_LAST_CLEAR_REG, 0
 
call R5xx2DIdleLocal
 
wrr RADEON_ISYNC_CNTL, RADEON_ISYNC_ANY2D_IDLE3D + \
RADEON_ISYNC_ANY3D_IDLE2D + \
RADEON_ISYNC_WAIT_IDLEGUI + \
RADEON_ISYNC_CPSCRATCH_IDLEGUI
.fail:
ret
 
align 4
load_microcode:
 
pushfd
cli
 
call R5xx2DIdleLocal
 
wrr RADEON_CP_ME_RAM_ADDR, 0
 
lea esi, [R520_cp_microcode]
mov ecx, 256
@@:
mov eax, [esi]
mov ebx, [esi+4]
wrr RADEON_CP_ME_RAM_DATAH, ebx
wrr RADEON_CP_ME_RAM_DATAL, eax
add esi, 8
loop @B
 
popfd
ret
 
 
align 4
R5xx2DInit:
 
call R5xx2DPreInit
wrr R5XX_RB3D_CNTL, 0
 
call R5xx2DReset
call R5xx2DSetup
 
rdr eax, RADEON_AIC_CNTL ;disable GART
and eax, not RADEON_PCIGART_TRANSLATE_EN
wrr RADEON_AIC_CNTL, eax
 
call load_microcode
 
call R5xxCpInit
 
rdr eax, D1GRPH_X_END
rdr ebx, D1GRPH_Y_END
dec eax
dec ebx
 
mov [__xmin], 0 ;set clip
mov [__ymin], 0
mov [__xmax], eax
mov [__ymax], ebx
 
wrr RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM
 
; BEGIN_RING
; RADEON_PURGE_CACHE
; RADEON_PURGE_ZCACHE
; RADEON_WAIT_UNTIL_IDLE
; COMMIT_RING
 
ret
 
proc R5xxSetupForSolidFill stdcall,color:dword, rop:dword, planemask:dword
 
mov edx, [rop]
mov edx, [R5xxRops+4+edx*8]
or edx, [rhd.control]
or edx, (R5XX_GMC_BRUSH_SOLID_COLOR or R5XX_GMC_SRC_DATATYPE_COLOR)
 
; Save for later clipping
mov [rhd.control_saved], edx
 
mov eax, 4
call R5xxFIFOWait
 
wrr R5XX_DP_GUI_MASTER_CNTL, edx
 
mov eax, [color]
wrr R5XX_DP_BRUSH_FRGD_CLR, eax
 
mov ebx, [planemask]
wrr R5XX_DP_WRITE_MASK, ebx
 
wrr R5XX_DP_CNTL, (R5XX_DST_X_LEFT_TO_RIGHT or R5XX_DST_Y_TOP_TO_BOTTOM)
 
ret
endp
 
align 4
proc R5xxSolidFillRect stdcall, x:dword, y:dword, w:dword, h:dword
 
mov eax, 3
call R5xxFIFOWait
 
mov eax, [rhd.dst_pitch_offset]
wrr R5XX_DST_PITCH_OFFSET, eax
 
mov ebx, [y]
shl ebx, 16
mov bx, word [x]
wrr R5XX_DST_Y_X, ebx
 
mov ecx, [w]
shl ecx, 16
mov cx, word [h]
wrr R5XX_DST_WIDTH_HEIGHT, ecx
 
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
 
SRV_GETVERSION equ 0
SOLID_FILL equ 1
LINE_2P equ 2
 
align 4
proc r500_entry stdcall, state:dword
 
.close:
; call r500_close
 
xor eax, eax
ret
endp
 
CURRENT_TASK equ (OS_BASE+0x0003000)
TASK_COUNT equ (OS_BASE+0x0003004)
WIN_STACK equ (OS_BASE+0x000C000)
 
 
align 4
proc r500_HDraw stdcall, ioctl:dword
 
mov ebx, [ioctl]
mov eax, [ebx+io_code]
cmp eax, LINE_2P
ja .fail
 
cmp eax, SRV_GETVERSION
jne @F
 
mov eax, [ebx+output]
cmp [ebx+out_size], 4
jne .fail
mov [eax], dword API_VERSION
xor eax, eax
ret
@@:
mov edx, [CURRENT_TASK]
movzx edx, word [WIN_STACK+edx*2]
cmp edx, [TASK_COUNT]
jne .skip ;skip if window inactive
 
cmp eax, SOLID_FILL
jne @F
 
cmp [ebx+inp_size], 5
jne .fail
 
mov esi, [ebx+input]
call solid_fill
.skip:
xor eax, eax
ret
@@:
cmp eax, LINE_2P
jne @F
 
cmp [ebx+inp_size], 5
jne .fail
 
mov esi, [ebx+input]
call solid_line
xor eax, eax
ret
@@:
 
.fail:
or eax, -1
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
struc FILL
{
.color rd 1
.x rd 1
.y rd 1
.w rd 1
.h rd 1
}
 
virtual at 0
FILL FILL
end virtual
 
struc LINE2P
{
.color rd 1
.x1 rd 1
.y1 rd 1
.x2 rd 1
.y2 rd 1
}
 
virtual at 0
LINE2P LINE2P
end virtual
 
GXcopy equ 3
 
RADEON_CP_PACKET3 equ 0xC0000000
 
PAINT_MULTI equ 0xC0009A00
 
DST_PITCH_OFFSET_CNTL equ ( 1 shl 1)
BRUSH_SOLID_COLOR equ ( 13 shl 4)
COLOR_ARGB equ ( 6 shl 8)
SRC_DATATYPE_COLOR equ ( 3 shl 12)
 
;RADEON_ROP3_P equ
 
; esi= input params
align 4
solid_fill:
 
mov ebx, [esi+FILL.x]
mov ecx, [esi+FILL.y]
mov eax, [esi+FILL.w]
mov edx, [esi+FILL.h]
 
lea eax, [eax+ebx-1] ;x2
lea edx, [edx+ecx-1] ;y2
 
push edx ;y2
push eax ;x2
 
mov eax, esp ;&x2
lea ebx, [esp+4] ;&y2
 
lea ecx, [esi+FILL.x]
lea edx, [esi+FILL.y]
 
push ebx ;&y2
push eax ;&x2
push edx ;&y1
push ecx ;&x1
 
call _BlockClip
add esp, 16
test eax, eax
jnz .exit
 
;mov edx, [R5xxRops+4+GXcopy*8]
;or edx, [rhd.control]
;or edx, (R5XX_GMC_BRUSH_SOLID_COLOR or R5XX_GMC_SRC_DATATYPE_COLOR)
 
pushfd
cli
 
 
BEGIN_RING
OUT_PACKET3 PAINT_MULTI, 4
OUT_RING (DST_PITCH_OFFSET_CNTL + \
BRUSH_SOLID_COLOR + \
COLOR_ARGB + \
SRC_DATATYPE_COLOR + \
(1 shl 28)+(1 shl 30) + \
R5XX_ROP3_P)
 
OUT_RING [rhd.dst_pitch_offset]
OUT_RING [esi+FILL.color]
 
mov ebx, [esi+FILL.y]
shl ebx, 16
mov bx, word [esi+FILL.x]
OUT_RING ebx
 
mov ecx, [esp+4] ;x2
sub ecx, [esi+FILL.x]
inc ecx ;w
 
mov eax, [esp+8] ;y2
sub eax, [esi+FILL.y]
inc eax ;h
 
shl ecx, 16
mov cx, ax ;w|h
 
OUT_RING ecx
COMMIT_RING
 
if 0
; mov eax, 7
; call R5xxFIFOWait
 
; wrr R5XX_DP_GUI_MASTER_CNTL, edx
 
; mov eax, [esi+FILL.color]
; wrr R5XX_DP_BRUSH_FRGD_CLR, eax
 
; wrr R5XX_DP_WRITE_MASK, 0xFFFFFFFF
 
; wrr R5XX_DP_CNTL, (R5XX_DST_X_LEFT_TO_RIGHT or R5XX_DST_Y_TOP_TO_BOTTOM)
 
; mov eax, [rhd.dst_pitch_offset]
; wrr R5XX_DST_PITCH_OFFSET, eax
 
; mov ebx, [esi+FILL.y]
; shl ebx, 16
; mov bx, word [esi+FILL.x]
; wrr R5XX_DST_Y_X, ebx
 
; mov ecx, [esp+4] ;x2
; sub ecx, [esi+FILL.x]
; inc ecx ;w
 
; mov eax, [esp+8] ;y2
; sub eax, [esi+FILL.y]
; inc eax ;h
 
; shl ecx, 16
; mov cx, ax ;w|h
; wrr R5XX_DST_WIDTH_HEIGHT, ecx
end if
popfd
.exit:
add esp, 8
ret
 
align 4
solid_line:
 
lea eax, [esi+LINE2P.y2]
lea ebx, [esi+LINE2P.x2]
lea ecx, [esi+LINE2P.y1]
lea edx, [esi+LINE2P.x1]
 
push eax
push ebx
push ecx
push edx
 
call _LineClip
add esp, 16
test eax, eax
jnz .exit
 
mov edx, [R5xxRops+4+GXcopy*8]
or edx, [rhd.control]
or edx, (R5XX_GMC_BRUSH_SOLID_COLOR or R5XX_GMC_SRC_DATATYPE_COLOR)
 
pushfd
cli
 
mov eax, 7
call R5xxFIFOWait
 
wrr R5XX_DST_LINE_PATCOUNT, (0x55 shl R5XX_BRES_CNTL_SHIFT)
wrr R5XX_DP_GUI_MASTER_CNTL, edx
 
mov eax, [esi+FILL.color]
wrr R5XX_DP_BRUSH_FRGD_CLR, eax
 
wrr R5XX_DP_WRITE_MASK, 0xFFFFFFFF
 
mov eax, [rhd.dst_pitch_offset]
wrr R5XX_DST_PITCH_OFFSET, eax
 
mov ebx, [esi+LINE2P.y1]
shl ebx, 16
mov bx, word [esi+LINE2P.x1]
wrr R5XX_DST_LINE_START, ebx
 
mov ecx, [esi+LINE2P.y2]
shl ecx, 16
mov cx, word [esi+LINE2P.x2]
wrr R5XX_DST_LINE_END, ecx
popfd
.exit:
ret
 
align 4
__L1OutCode:
cmp eax, [__xmin]
mov ecx, edx
setl dl
sal edx, 3
cmp eax, [__xmax]
jle L9
or edx, 4
L9:
cmp ecx, [__ymin]
jge L11
or edx, 1
L11:
cmp ecx, [__ymax]
jle L13
or edx, 2
L13:
movzx eax, dl
ret
 
align 4
_line_inter:
push ebp
mov ebp, edx
push edi
push esi
push ebx
sub esp, 4
mov ebx, [eax]
mov [esp], eax
mov edx, [esp+24]
mov edi, [ebp]
sub ecx, ebx
mov eax, ecx
sar eax, 31
sub edx, edi
mov esi, eax
xor esi, ecx
sub esi, eax
mov eax, [esp+28]
lea ecx, [edx+edx]
sub eax, ebx
cdq
xor eax, edx
sub eax, edx
imul ecx, eax
test ecx, ecx
jle L17
add ecx, esi
jmp L19
L17:
sub ecx, esi
L19:
lea edx, [esi+esi]
mov eax, ecx
mov ebx, edx
cdq
idiv ebx
lea eax, [eax+edi]
mov [ebp], eax
mov eax, [esp]
mov edx, [esp+28]
mov [eax], edx
pop eax
pop ebx
pop esi
pop edi
pop ebp
ret
 
_LineClip:
push ebp
push edi
push esi
push ebx
mov eax, [esp+24]
mov ecx, [esp+20]
mov ebp, [esp+28]
mov edi, [esp+32]
mov edx, [eax]
mov eax, [ecx]
call __L1OutCode
mov edx, [edi]
mov bl, al
mov eax, [ebp]
call __L1OutCode
L48:
mov esi, eax
L47:
mov eax, esi
and al, bl
jne L23
mov edx, esi
cmp bl, dl
je L23
test bl, bl
jne L26
movsx eax, dl
test al, 1
je L28
push [__ymin]
mov ecx, [esp+24]
push dword [ecx]
jmp L51
L28:
test al, 2
je L31
push [__ymax]
mov edx, [esp+24]
push dword [edx]
L51:
mov eax, [esp+32]
mov edx, ebp
mov ecx, [eax]
mov eax, edi
jmp L49
L31:
test al, 4
je L33
push [__xmax]
jmp L52
L33:
test al, 8
je L30
push [__xmin]
L52:
mov edx, [esp+28]
push dword [edx]
mov edx, edi
mov eax, [esp+28]
mov ecx, [eax]
mov eax, ebp
L49:
call _line_inter
pop esi
pop eax
L30:
mov edx, [edi]
mov eax, [ebp]
call __L1OutCode
jmp L48
L26:
movsx eax, bl
test al, 1
je L36
push [__ymin]
jmp L53
L36:
test al, 2
je L39
push [__ymax]
L53:
push dword [ebp]
mov ecx, [edi]
mov edx, [esp+28]
mov eax, [esp+32]
jmp L50
L39:
test al, 4
je L41
push [__xmax]
jmp L54
L41:
test al, 8
je L38
push [__xmin]
L54:
push dword [edi]
mov ecx, [ebp]
mov edx, [esp+32]
mov eax, [esp+28]
L50:
call _line_inter
pop edx
pop ecx
L38:
mov ecx, [esp+24]
mov edx, [ecx]
mov ecx, [esp+20]
mov eax, [ecx]
call __L1OutCode
mov bl, al
jmp L47
L23:
pop ebx
movsx eax, al
pop esi
pop edi
pop ebp
ret
 
align 4
_block_inter:
test cl, 1
push ebx
mov ebx, eax
je L57
mov eax, [__ymin]
jmp L66
L57:
test cl, 2
je L60
mov eax, [__ymax]
L66:
mov [edx], eax
jmp L65
L60:
test cl, 4
je L62
mov eax, [__xmax]
jmp L67
L62:
and cl, 8
je L65
mov eax, [__xmin]
L67:
mov [ebx], eax
L65:
pop ebx
ret
 
align 4
_BlockClip:
push ebp
push edi
push esi
push ebx
mov eax, [esp+24]
mov ecx, [esp+20]
mov ebp, [esp+28]
mov edi, [esp+32]
mov edx, [eax]
mov eax, [ecx]
call __L1OutCode
mov edx, [edi]
mov ebx, eax
mov eax, [ebp]
call __L1OutCode
L80:
mov esi, eax
L79:
test esi, ebx
jne L70
cmp ebx, esi
je L72
test ebx, ebx
jne L74
mov edx, edi
mov eax, ebp
mov ecx, esi
call _block_inter
mov edx, [edi]
mov eax, [ebp]
call __L1OutCode
jmp L80
L74:
mov edx, [esp+24]
mov ecx, ebx
mov eax, [esp+20]
call _block_inter
mov eax, [esp+24]
mov ecx, [esp+20]
mov edx, [eax]
mov eax, [ecx]
call __L1OutCode
mov ebx, eax
jmp L79
L72:
mov esi, ebx
L70:
mov eax, esi
and eax, ebx
pop ebx
cwde
pop esi
pop edi
pop ebp
ret
/kernel/tags/kolibri0.7.5.0/drivers/sb16/README.TXT
0,0 → 1,72
Nable 21.05.2008.
This driver is my contribution (or donation) to KolibriOS. This is provided
AS IS in hope it'll be useful, but WITHOUT ANY WARRANTY! No responcibility
for any hardware damage or data loss. Use at your own risk!
 
;-------------------------------------------------------------------------------
;Changelog:
;-------------------------------------------------------------------------------
v0.2 - DEV_SET(GET)_MASTERVOL functions are unlocked and implemented.
 
v0.1 - first release.
 
;-------------------------------------------------------------------------------
;Tiny FAQ for sound driver by Nable for SB16 sound card.
;-------------------------------------------------------------------------------
 
;What is it?--------------------------------------------------------------------
As you may know there is a sound subsystem ('INFINITY') in KolibriOS.
This subsystem includes mixer and separate interface for soundplayer
program and driver, so player application don't need to know what soundcard
is installed and how to cope with it, all work with card do the driver.
Before this time there were drivers only for AC97 integrated sound, but I
don't have such at home and if I would upgrade my computer with a newest
hardware, with 100% probability integrated sound will be HD Codec, nowadays
AC97 is not actual (2008 year is at calendar). But I'm not planning to upgrade
my computer so much now (and in next 5-6 years), writing the driver for my PCI
ESS Maestro1 card is difficult for me (may be some time later), so I decided
to write a driver for SB16. At first it is easy, there are many working
examples for DOS, there are heaps of good documentation and as an ISA device
SB16 can be programmed through I/O ports (about 5 ports are used), that is
more easy than PCI access. Now, enough lirics, lets go to physics :-)
If you still don't understand what stuff is it, I'll tell this in brief:
with this driver you can play MP3 and WAV music (using AC97SND player) and
sounds (some games and DOSBOX can produce sound output through sound
subsystem) in KolibriOS.
 
;Yeah! I need sound in Kolibri and I have SB16 card. Whats then?----------------
At first copy my SOUND.OBJ to /sys/drivers at your Kolibri system. Note,
that if you have AC97 card and it's driver started - then new driver won't
run until reboot. Then run BOARD and go to 'user' tab. Then try to run
AC97SND player. At BOARD you will see the following (if you had a proper
card):
|----------------------------|
|detecting hardware... | <- detector startup message
|DSP found at port 220h | <- if you have a proper card, it'll be
|DSP version 4.13 - SB16 | autodetected. Numbers may be different.
|failed to attach IRQ5 | <- don't mention. Old kernels reserve IRQ5
|owner's handler: 0x80D74284 | see below how to fix it.
|----------------------------|
At first, note that DSP version must be 4.xx or higher. Older cards are not
supported in this first release, maybe some time later. If nothing detected
but PNP/BIOS or some other OS detects your card - I'm sorry, it's perverted
PNP card like OPTi16, that is like HD Codec - until you init it through
PCI->ISA bridge (HD Codec of course through PCI->PCI bridge), map it, etc,
you can't use it in any way. I'd rather write a PCI device driver, than
for this extreme perversion. If your card detected and has a proper version
but you see 'failed to attach IRQ' - delete stroke 'mov [irq_owner+4*5],1' from the
file kernel.asm of your kernel source, save it, rebuild kernel, copy new
kernel to /sys/ (did you rename 'kernel' to 'kernel.mnt'? You should do it),
restart kernel (Ctrl+Alt+F12, Home). THE EASIER WAY IS TO USE A NEWER KERNEL,
since SVN802 it's fixed.
Now everything should be OK.
 
;It works for a part of the second and then stops, but system doesn't hang------
Go to 'config.inc' of my driver and change 'sb_irq_num' value from 5 to 7.
Then save, rebuild driver (compile 'sound.asm'), put 'sound' to /sys/drivers/
(you need to rename file 'sound' to 'sound.obj'), restart kernel and try again
to produce sound.
 
;-------------------------------------------------------------------------------
Ask your questions at KolibriOS forum: board.kolibrios.org
I'll try to answer you if possible.
/kernel/tags/kolibri0.7.5.0/drivers/sb16/CONFIG.INC
0,0 → 1,50
;flags------------------------------------------------------------
DEBUG equ 1 ;show messages at debug board
use_cli_sti equ 1 ;driver become more stable (theoretically)
 
;constants--------------------------------------------------------
API_VERSION equ 0 ;debug
 
OS_BASE equ 0x80000000
new_app_base equ 0x0
PROC_BASE equ (OS_BASE+0x080000)
SB16Buffer equ (OS_BASE+0x2A0000)
SB16_Status equ (OS_BASE+0x2B0000)
DMAPage equ ((SB16Buffer-OS_BASE) shr 16)
 
SB16Buffer0 equ SB16Buffer
SB16Buffer1 equ (SB16Buffer+16384)
SB16Buffer2 equ (SB16Buffer+(2*16384))
SB16Buffer3 equ (SB16Buffer+(3*16384))
 
sb_irq_num equ 5 ;default values for SB16, may be overrided by autodetect
sb_dma_num equ 5 ;default values for SB16, may be overrided by autodetect
 
small_buffer equ 32768
full_buffer equ 65536
sb_buffer_size equ full_buffer
 
__supported_buffer_sizes fix <small_buffer, full_buffer>
 
if ~(sb_buffer_size in __supported_buffer_sizes)
display 13,10,'unsupported buffer size was selected, check config.inc',13,10
stop
end if
 
sb_out_rate equ 48000
;time constant for cards older than SB16
sb_tc equ (256-(1000000/(sb_out_rate*2)))
 
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
 
DRV_ENTRY equ 1
DRV_EXIT equ -1
 
/kernel/tags/kolibri0.7.5.0/drivers/sb16/SB16.INC
0,0 → 1,297
;--------------------------------
; program dma
;--------------------------------
sb_set_dma:
mov ebx,[sound_dma]
lea eax,[ebx+4] ;mask required channel
cmp bl,4
ja .use_second_dma_controller
jb @f
.dma_setup_error:
if DEBUG
mov esi,msgErrDMAsetup
call SysMsgBoardStr
end if
mov dword[esp],START.stop
ret
@@:
if use_cli_sti
cli ;here to minimize time with disabled ints
end if
out 0xA,al ;mask required channel
 
xor eax,eax
out 0xC,al ;clear byte pointer flip-flop register
 
lea eax,[ebx+0x58] ;auto-init mode for channel (ebx)
out 0xB,al ;DMA channel 0-3 mode register
 
movzx edx,byte[ebx+dma_table] ;page register
mov al,DMAPage
out dx,al
 
lea edx,[ebx*2] ;DMA channel 0-3 base address
 
mov al,0 ;LSB is 0
out dx,al
 
; mov al,0 ;MSB is 0 too
out dx,al
 
inc edx ;DMA channel 0-3 byte count
 
mov al,((sb_buffer_size-1) and 0xff)
out dx,al
 
mov al,((sb_buffer_size-1) shr 8) ;it is the same
out dx,al
 
mov eax,ebx ;unmask DMA channel
out 0xA,al
 
if use_cli_sti
sti
end if
ret
 
.use_second_dma_controller:
cmp bl,7
ja .dma_setup_error
 
sub bl,4
sub al,4
if use_cli_sti
cli ;here to minimize time with disabled ints
end if
out 0xD4,al ;mask required channel
 
xor eax,eax
out 0xD8,al ;clear byte pointer flip-flop register
 
lea eax,[ebx+0x58] ;auto-init mode for channel (ebx+4)
out 0xD6,al ;DMA channel 4-7 mode register
 
movzx edx,byte[ebx+dma_table+4] ;page register
mov al,DMAPage
out dx,al
 
lea edx,[ebx*4+0xC0] ;DMA channel 4-7 base address
 
mov al,0 ;LSB is 0 ;for 16bit DMA this contains
out dx,al ;A1-A8 lines of address bus, A0 is zero
 
; mov al,0 ;MSB is 0 too ;for 16bit DMA this contains
out dx,al ;A9-A16 lines of address bus
 
inc edx
inc edx ;DMA channel 4-7 16bit word count
 
mov al,(((sb_buffer_size/2)-1) and 0xff)
out dx,al
 
mov al,(((sb_buffer_size/2)-1) shr 8)
out dx,al
 
mov eax,ebx ;unmask DMA channel
out 0xD4,al
 
if use_cli_sti
sti
end if
ret
;-------------------------------------------------------------------------------
; out byte to SB DSP's write port
;-------------------------------------------------------------------------------
macro sb_out data_to_out {
@@:
in al,dx
test al,al ;is DSP busy?
js @b ;it's busy
mov al,data_to_out ;it's free
out dx,al
}
;-------------------------------------------------------------------------------
; stop playing
;-------------------------------------------------------------------------------
proc sb_stop
mov edx,[sb_base_port]
add dl,0xC
sb_out 0xD3 ;turn the speaker off
sb_out 0xDA ;exit 8bit DMA
sb_out 0xD9 ;exit 16bit DMA
ret
endp
;-------------------------------------------------------------------------------
; start playing
;-------------------------------------------------------------------------------
proc sb_play
and [int_flip_flop],0
mov edx,[sb_base_port]
add dl,0xC
sb_out 0xD1 ;turn speaker on
; sb_out 0x48 ;set DSP transfer size ;for older cards, not supported
; ;in this version
; mov ax,32767 ;(64k)/2-1
;@@: ;out the low byte...
; in al,dx
; test al,al ;is DSP busy?
; js @b ;it's busy
; out dx,al
 
; mov al,ah ;...then the high byte
;@@:
; in al,dx
; test al,al ;is DSP busy?
; js @b ;it's busy
; out dx,al
 
; sb_out 0x1C ;auto-init 8bit playback
 
; 0xBXh - 16 bit DMA mode
; ||||
sb_out 10110110b ;bCommand
; ||||
; |||+-reserved
; ||+--turn FIFO on (0 for off)
; |+---auto-init mode on (0 for off)
; +----A/D: 0-output, 1-input
; +------stereo on
; |+-----unsigned (1 for signed)
; ||
sb_out 00110000b ;bMode
; || ||||
; ---------reserved
;wSize is a number of 16bit samples less 1. For auto-init mode each half
;buffer is (64k)/2 bytes long and, obviously, contains ((64k)/2)/2 samples
sb_out (((sb_buffer_size/2/2)-1) and 0xFF) ;wSize.LowByte
sb_out (((sb_buffer_size/2/2)-1) shr 8) ;wSize.HighByte
ret
endp
;-------------------------------------------------------------------------------
; reset DSP
;-------------------------------------------------------------------------------
proc sb_reset
and [int_flip_flop],0
mov edx,[sb_base_port]
add dl,6
mov al,1 ;start DSP reset
 
if use_cli_sti
cli ;here to minimize time with disabled ints
end if
out dx,al
mov ecx,40 ;wait at least 3 microsec.
@@:
in al,dx
loop @b
 
xor eax,eax ;stop DSP reset
if use_cli_sti
sti
end if
out dx,al
ret
endp
 
;-------------------------------------------------------------------------------
; set the rate for playing, enable stereo
;-------------------------------------------------------------------------------
proc sb_setup
mov edx,[sb_base_port]
add dl,0xC
sb_out 40h ;set time constant, this is for old cards
sb_out sb_tc
 
sb_out 41h ;set sound rate, this can only SB16
sb_out (sb_out_rate shr 8) ;first high byte (MSB)
sb_out (sb_out_rate and 0xff) ;then low byte (LSB)
 
; mov al,0xE ;for older cards, not supported in this version
; sub dl,(0xC-4) ;talk to SB's mixer
; out dx,al ;select this register of the mixer
; mov ecx,6 ;wait for the chip
;@@:
; in al,dx
; loop @b
 
; inc edx ;now read the data port
; in al,dx
; or al,22h ;turn on stereo
; mov ah,al
 
; mov al,0xE
; dec edx ;talk to SB's mixer
; out dx,al ;select this register of the mixer
 
; mov ecx,6 ;wait for the chip
;@@:
; in al,dx
; loop @b
 
; inc edx ;now send data to the data port
; mov al,ah
; out dx,al
 
; dec edx
; mov ecx,35 ;wait for the chip
;@@:
; in al,dx
; loop @b
ret
endp
 
;-------------------------------------------------------------------------------
; set master volume of SB mixer, note, not only SB16 but SBPro and older
; this is the first step to more full support for hardware
;-------------------------------------------------------------------------------
;in: eax in range [-10000;0] - master volume for _both_ channels
;note that x*3*17/2000 and x*3/2000*17 are not the same numbers,
;because we count in integers
proc sb_set_master_vol
mov [sb_master_vol],eax
add eax,10000 ;SB sound level rise from 0 to MAX_LEVEL
lea eax,[eax+eax*2] ;*3
mov ebx,2000 ;divisor
xor edx,edx
cmp byte[sb_DSP_version_int],4
jae @f ;SBPro's MAX_LEVEL is 15, but we *11 because
;volume byte looks like that: 0xLR, where L - left
;channel volume, R - right, 0<=R,L<=15
div ebx
imul eax,17
mov edx,[sb_base_port]
push eax ;here for optimisation
add dl,4
mov al,0x22 ;write mixer register 0x22
out dx,al
in al,dx ;wait for the chip ;6
in al,dx ;wait for the chip ;5
in al,dx ;wait for the chip ;4
in al,dx ;wait for the chip ;3
in al,dx ;wait for the chip ;2
in al,dx ;wait for the chip ;1
pop eax ;go!
inc edx
out dx,al
ret
@@: ;SB16's MAX_LEVEL is 255
imul eax,17
div ebx
mov edx,[sb_base_port]
push eax ;here for optimisation
add dl,4
mov al,0x30 ;left speaker
out dx,al
pop eax ;<--+
inc edx ; \/
push eax ;here for optimisation
out dx,al ;write
dec edx
mov al,0x31 ;right speaker
out dx,al
pop eax
inc edx
out dx,al ;write
ret
endp
;-------------------------------------------------------------------------------
/kernel/tags/kolibri0.7.5.0/drivers/sb16/sb16.asm
0,0 → 1,389
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
format MS COFF
 
include 'config.inc'
 
;structs----------------------------------------------------------
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
;something--------------------------------------------------------
public START
public service_proc
public version
 
include '..\proc32.inc'
include '..\imports.inc'
 
section '.flat' code readable align 16
 
include 'sb16.inc'
 
;-------------------------------------------------------------------------------
proc START stdcall, state:dword
cmp [state], 1
jne .stop
.entry:
 
if DEBUG
mov esi, msgInit
call SysMsgBoardStr
end if
 
call detect ;returns DSP version or zero if
test eax,eax ;SB card not found
jz .exit
 
if DEBUG
movzx eax,al ;major version
mov esi,sb_DSP_description
dec eax
jz .sb_say_about_found_dsp
mov dword[esi],'2.x '
dec eax
jz .sb_say_about_found_dsp
mov dword[esi],'Pro '
dec eax
jz .sb_say_about_found_dsp
mov dword[esi],'16 '
.sb_say_about_found_dsp:
mov esi,msgDSPFound
call SysMsgBoardStr
end if
xor eax,eax
mov ebx,[sb_base_port]
lea ecx,[ebx+0xF]
call ReservePortArea ;these ports must be my!
if DEBUG
dec eax
jnz @f
mov esi,msgErrRsrvPorts
call SysMsgBoardStr
@@:
end if
 
call sb_setup ;clock it, etc
 
stdcall AttachIntHandler, sb_irq_num, sb_irq, 0
 
if DEBUG
test eax,eax
jnz @f
 
mov esi,msgErrAtchIRQ
call SysMsgBoardStr
 
stdcall GetIntHandler, sb_irq_num
call SysMsgBoardNum
 
jmp .stop
@@:
mov esi,msgSucAtchIRQ
call SysMsgBoardStr
end if
stdcall RegService, my_service, service_proc
ret
.stop:
call sb_reset
.exit:
 
if DEBUG
mov esi,msgExit
call SysMsgBoardStr
end if
 
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 sb_stop ;to play smth new we must stop smth old
 
call pre_fill_data ;fill first and second half of the buffer
call pre_fill_data ;
 
call sb_set_dma ;is it really needed here? Paranoia.
call sb_play
xor eax,eax ;set maximum volume
call sb_set_master_vol
xor eax,eax
ret
;@@: ;all this commented stuff in service proc
; cmp eax,DEV_STOP ;is never used. Mixer do this virtually,
; jne @f ;e.g. instead of stopping driver it
;if DEBUG ;outputs silence
; mov esi,msgStop
; call SysMsgBoardStr
;end if
; call sb_stop
; xor eax,eax
; ret
@@:
cmp eax,DEV_CALLBACK
jne @f
if DEBUG
mov esi,msgCallback
call SysMsgBoardStr
end if
mov edi,[edi+input]
mov eax,[edi]
mov [callback],eax
if DEBUG
call SysMsgBoardNum
end if
xor eax,eax
ret
@@:
cmp eax,DEV_SET_MASTERVOL ;Serge asked me to unlock
jne @F ;DEV_SET(GET)_MASTERVOL, although mixer doesn't use it.
;It doesn't use it _in current version_ - but in the future...
 
if DEBUG
mov esi,msgSetVol
call SysMsgBoardStr
end if
mov eax,[edi+input]
mov eax,[eax]
call sb_set_master_vol
xor eax,eax
ret
@@:
cmp eax,DEV_GET_MASTERVOL
jne @F
if DEBUG
mov esi,msgGetVol
call SysMsgBoardStr
end if
mov eax,[edi+output]
mov edx,[sb_master_vol]
mov [eax],edx
xor eax,eax
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 sb_irq
mov edx,[sb_base_port] ;tell the DSP that we have processed IRQ
add dl,0xF ;0xF for 16 bit sound, 0xE for 8 bit sound
in al,dx ;for non-stop sound
 
pre_fill_data:
mov eax,int_flip_flop
not dword[eax]
mov eax,[eax]
test eax,eax
jns .fill_second_half
 
if sb_buffer_size eq small_buffer
stdcall [callback],SB16Buffer0 ;for 32k buffer
else if sb_buffer_size eq full_buffer
stdcall [callback],SB16Buffer0 ;for 64k buffer
stdcall [callback],SB16Buffer1 ;for 64k buffer
end if
xor eax,eax
ret
 
.fill_second_half:
if sb_buffer_size eq small_buffer
stdcall [callback],SB16Buffer1 ;for 32k buffer
else if sb_buffer_size eq full_buffer
stdcall [callback],SB16Buffer2 ;for 64k buffer
stdcall [callback],SB16Buffer3 ;for 64k buffer
end if
xor eax,eax
ret
endp
;-------------------------------------------------------------------------------
align 4
proc detect
.sb_detect_next_port:
if DEBUG
inc dword[port_second_digit_num]
end if
mov edx,sb_base_port
add byte[edx],10h
cmp byte[edx],80h
jbe .sb_try_to_detect_at_specified_port
;error - no SB card detected
.sb_not_found_err:
xor eax, eax
ret
 
.sb_try_to_detect_at_specified_port:
call sb_reset
add dl,8
mov ecx,100
.sb_check_port:
in al,dx
test al,al ;is DSP port ready to be read?
jns .sb_port_not_ready
 
sub dl,4
in al,dx ;check for AAh response
add dl,4
cmp al,0xAA
jne .sb_port_not_ready
.sb_card_found:
and dl,0xF0
add dl,0xC
sb_out 0xE1 ;get DSP version
add dl,2
@@:
in al,dx
test al,al ;is DSP port ready to be read?
jns @b
sub dl,4
in al,dx ;get major version
ror eax,16
add dl,4
@@:
in al,dx
test al,al ;is DSP port ready to be read?
jns @b
sub dl,4
in al,dx ;get minor version
xor edx,edx
mov dl,10
div dl
ror eax,16
xor ah,ah
mov [sb_DSP_version_int],eax ;for internal usage
if DEBUG
add [sb_DSP_version],eax
end if
ret
 
.sb_port_not_ready:
loop .sb_check_port ;100 retries (~100 microsec.)
jmp .sb_detect_next_port
endp
;-------------------------------------------------------------------------------
if DEBUG
proc SysMsgBoardNum ;warning: destroys eax,ebx,ecx,esi
mov ebx,eax
mov ecx,8
mov esi,(number_to_out+1)
.1:
mov eax,ebx
and eax,0xF
add al,'0'
cmp al,(10+'0')
jb @f
add al,('A'-'0'-10)
@@:
mov [esi+ecx],al
shr ebx,4
loop .1
dec esi
call SysMsgBoardStr
ret
endp
end if
;all initialized data place here
align 4
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
sb_base_port: dd 200h ;don't ask me why - see the code&docs
 
sound_dma dd sb_dma_num
 
;note that 4th DMA channel doesn't exist, it is used for cascade
;plugging the first DMA controler to the second
dma_table db 0x87,0x83,0x81,0x82,0xFF,0x8B,0x89,0x8A
 
my_service db 'SOUND',0 ;max 16 chars include zero
 
if DEBUG
number_to_out db '0x00000000',13,10,0
 
msgInit db 'detecting hardware...',13,10,0
msgExit db 'exiting... May be some problems found?',13,10,0
msgPlay db 'start play',13,10,0
;msgStop db 'stop play',13,10,0
msgCallback db 'set_callback received from the mixer!',13,10
db 'callback handler is: ',0
msgErrAtchIRQ db 'failed to attach IRQ',(sb_irq_num+'0'),13,10
db 'owner',39,'s handler: ',0
msgSucAtchIRQ db 'succesfully attached IRQ',(sb_irq_num+'0')
db ' as hardcoded',13,10,0
msgErrRsrvPorts db 'failed to reserve needed ports.',13,10
db 'Driver may work unstable',13,10,0
msgSetVol db 'DEV_SET_MASTERVOL call came',13,10,0
msgGetVol db 'DEV_GET_MASTERVOL call came',13,10,0
msgErrDMAsetup db 'failed to setup DMA - bad channel',13,10,0
;-------------------------------------------------------------------------------
msgDSPFound db 'DSP found at port 2'
label port_second_digit_num dword at $
db '00h',13,10,'DSP version '
sb_DSP_version: db '0.00 - SB'
sb_DSP_description: db 32,32,32,32,13,10,0
;-------------------------------------------------------------------------------
end if
 
section '.data' data readable writable align 16
;all uninitialized data place here
 
;pTempBuf rd 1
 
callback rd 1
 
int_flip_flop rd 1
 
sb_master_vol rd 1
 
sb_DSP_version_int rd 1
/kernel/tags/kolibri0.7.5.0/drivers/uart.asm
0,0 → 1,976
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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 0
UART_VERSION equ API_VERSION
 
PG_SW equ 0x003
page_tabs equ 0xFDC00000 ;hack
 
OS_BASE equ 0x80000000
SLOT_BASE equ (OS_BASE+0x0080000)
TASK_COUNT equ (OS_BASE+0x0003004)
CURRENT_TASK equ (OS_BASE+0x0003000)
 
 
struc APPOBJ ;common object header
{
.magic dd ? ;
.destroy dd ? ;internal destructor
.fd dd ? ;next object in list
.bk dd ? ;prev object in list
.pid dd ? ;owner id
};
 
virtual at 0
APPOBJ APPOBJ
end virtual
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
DEBUG equ 1
 
DRV_ENTRY equ 1
DRV_EXIT equ -1
 
THR_REG equ 0; x3f8 ;transtitter/reciever
IER_REG equ 1; x3f9 ;interrupt enable
IIR_REG equ 2; x3fA ;interrupt info
LCR_REG equ 3; x3FB ;line control
MCR_REG equ 4; x3FC ;modem control
LSR_REG equ 5; x3FD ;line status
MSR_REG equ 6; x3FE ;modem status
 
LCR_5BIT equ 0x00
LCR_6BIT equ 0x01
LCR_7BIT equ 0x02
LCR_8BIT equ 0x03
LCR_STOP_1 equ 0x00
LCR_STOP_2 equ 0x04
LCR_PARITY equ 0x08
LCR_EVEN equ 0x10
LCR_STICK equ 0x20
LCR_BREAK equ 0x40
LCR_DLAB equ 0x80
 
LSR_DR equ 0x01 ;data ready
LSR_OE equ 0x02 ;overrun error
LSR_PE equ 0x04 ;parity error
LSR_FE equ 0x08 ;framing error
LSR_BI equ 0x10 ;break interrupt
LSR_THRE equ 0x20 ;transmitter holding empty
LSR_TEMT equ 0x40 ;transmitter empty
LSR_FER equ 0x80 ;FIFO error
 
FCR_EFIFO equ 0x01 ;enable FIFO
FCR_CRB equ 0x02 ;clear reciever FIFO
FCR_CXMIT equ 0x04 ;clear transmitter FIFO
FCR_RDY equ 0x08 ;set RXRDY and TXRDY pins
FCR_FIFO_1 equ 0x00 ;1 byte trigger
FCR_FIFO_4 equ 0x40 ;4 bytes trigger
FCR_FIFO_8 equ 0x80 ;8 bytes trigger
FCR_FIFO_14 equ 0xC0 ;14 bytes trigger
 
IIR_INTR equ 0x01 ;1= no interrupts
 
IER_RDAI equ 0x01 ;reciever data interrupt
IER_THRI equ 0x02 ;transmitter empty interrupt
IER_LSI equ 0x04 ;line status interrupt
IER_MSI equ 0x08 ;modem status interrupt
 
MCR_DTR equ 0x01 ;0-> DTR=1, 1-> DTR=0
MCR_RTS equ 0x02 ;0-> RTS=1, 1-> RTS=0
MCR_OUT_1 equ 0x04 ;0-> OUT1=1, 1-> OUT1=0
MCR_OUT_2 equ 0x08 ;0-> OUT2=1, 1-> OUT2=0; enable intr
MCR_LOOP equ 0x10 ;lopback mode
 
MSR_DCTS equ 0x01 ;delta clear to send
MSR_DDSR equ 0x02 ;delta data set redy
MSR_TERI equ 0x04 ;trailinh edge of ring
MSR_DDCD equ 0x08 ;delta carrier detect
 
 
RATE_50 equ 0
RATE_75 equ 1
RATE_110 equ 2
RATE_134 equ 3
RATE_150 equ 4
RATE_300 equ 5
RATE_600 equ 6
RATE_1200 equ 7
RATE_1800 equ 8
RATE_2000 equ 9
RATE_2400 equ 10
RATE_3600 equ 11
RATE_4800 equ 12
RATE_7200 equ 13
RATE_9600 equ 14
RATE_19200 equ 15
RATE_38400 equ 16
RATE_57600 equ 17
RATE_115200 equ 18
 
COM_1 equ 1
COM_2 equ 2
COM_3 equ 3
COM_4 equ 4
COM_MAX equ 2 ;only two port supported
 
COM_1_BASE equ 0x3F8
COM_2_BASE equ 0x2F8
 
COM_1_IRQ equ 4
COM_2_IRQ equ 3
 
UART_CLOSED equ 0
UART_TRANSMIT equ 1
UART_STOP equ 2
 
struc UART
{
.lock dd ?
.base dd ?
.lcr_reg dd ?
.mcr_reg dd ?
.rate dd ?
.mode dd ?
.state dd ?
 
.rcvr_buff dd ?
.rcvr_rp dd ?
.rcvr_wp dd ?
.rcvr_count dd ?
.rcvr_top dd ?
 
.xmit_buff dd ?
.xmit_rp dd ?
.xmit_wp dd ?
.xmit_count dd ?
.xmit_free dd ?
.xmit_top dd ?
}
virtual at 0
UART UART
end virtual
 
UART_SIZE equ 18*4
 
struc CONNECTION
{
.magic dd ? ;'CNCT'
.destroy dd ? ;internal destructor
.fd dd ? ;next object in list
.bk dd ? ;prev object in list
.pid dd ? ;owner id
 
.id dd ? ;reserved
.uart dd ? ;uart pointer
}
 
virtual at 0
CONNECTION CONNECTION
end virtual
 
CONNECTION_SIZE equ 7*4
 
public START
public service_proc
public version
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .stop
 
mov eax, UART_SIZE
call Kmalloc
test eax, eax
jz .fail
 
mov [com1], eax
mov edi, eax
mov ecx, UART_SIZE/4
xor eax, eax
cld
rep stosd
 
mov eax, [com1]
mov [eax+UART.base], COM_1_BASE
 
stdcall AllocKernelSpace, 32768
 
mov edi, [com1]
mov edx, eax
 
mov [edi+UART.rcvr_buff], eax
add eax, 8192
mov [edi+UART.rcvr_top], eax
add eax, 8192
mov [edi+UART.xmit_buff], eax
add eax, 8192
mov [edi+UART.xmit_top], eax
 
call AllocPage
test eax, eax
jz .fail
 
shr edx, 12
or eax, PG_SW
mov [page_tabs+edx*4], eax
mov [page_tabs+edx*4+8], eax
 
call AllocPage
test eax, eax
jz .fail
 
or eax, PG_SW
mov [page_tabs+edx*4+4], eax
mov [page_tabs+edx*4+12], eax
 
call AllocPage
test eax, eax
jz .fail
 
or eax, PG_SW
mov [page_tabs+edx*4+16], eax
mov [page_tabs+edx*4+24], eax
 
call AllocPage
test eax, eax
jz .fail
 
or eax, PG_SW
mov [page_tabs+edx*4+20], eax
mov [page_tabs+edx*4+28], eax
 
mov eax, [edi+UART.rcvr_buff]
invlpg [eax]
invlpg [eax+0x1000]
invlpg [eax+0x2000]
invlpg [eax+0x3000]
invlpg [eax+0x4000]
invlpg [eax+0x5000]
invlpg [eax+0x6000]
invlpg [eax+0x7000]
 
mov eax, edi
call uart_reset.internal ;eax= uart
 
stdcall AttachIntHandler, COM_1_IRQ, com_1_isr, dword 0
stdcall RegService, sz_uart_srv, service_proc
ret
.fail:
.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
 
SRV_GETVERSION equ 0
PORT_OPEN equ 1
PORT_CLOSE equ 2
PORT_RESET equ 3
PORT_SETMODE equ 4
PORT_GETMODE equ 5
PORT_SETMCR equ 6
PORT_GETMCR equ 7
PORT_READ equ 8
PORT_WRITE equ 9
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov ebx, [ioctl]
mov eax, [ebx+io_code]
cmp eax, PORT_WRITE
ja .fail
 
cmp eax, SRV_GETVERSION
jne @F
 
mov eax, [ebx+output]
cmp [ebx+out_size], 4
jne .fail
mov [eax], dword UART_VERSION
xor eax, eax
ret
@@:
cmp eax, PORT_OPEN
jne @F
 
cmp [ebx+out_size], 4
jne .fail
 
mov ebx, [ebx+input]
mov eax, [ebx]
call uart_open
mov ebx, [ioctl]
mov ebx, [ebx+output]
mov [ebx], ecx
ret
@@:
mov esi, [ebx+input] ;input buffer
mov edi, [ebx+output]
call [uart_func+eax*4]
ret
.fail:
or eax, -1
ret
 
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
 
; param
; esi= input buffer
; +0 connection
;
; retval
; eax= error code
 
align 4
uart_reset:
mov eax, [esi]
cmp [eax+APPOBJ.magic], 'CNCT'
jne .fail
 
cmp [eax+APPOBJ.destroy], uart_close.destroy
jne .fail
 
mov eax, [eax+CONNECTION.uart]
test eax, eax
jz .fail
 
; set mode 2400 bod 8-bit
; disable DTR & RTS
; clear FIFO
; clear pending interrupts
;
; param
; eax= uart
 
align 4
.internal:
mov esi, eax
mov [eax+UART.state], UART_CLOSED
mov edx, [eax+UART.base]
add edx, MCR_REG
xor eax, eax
out dx, al ;clear DTR & RTS
 
mov eax, esi
mov ebx, RATE_2400
mov ecx, LCR_8BIT+LCR_STOP_1
call uart_set_mode.internal
 
mov edx, [esi+UART.base]
add edx, IIR_REG
mov eax,FCR_EFIFO+FCR_CRB+FCR_CXMIT+FCR_FIFO_14
out dx, al
.clear_RB:
mov edx, [esi+UART.base]
add edx, LSR_REG
in al, dx
test eax, LSR_DR
jz @F
 
mov edx, [esi+UART.base]
in al, dx
jmp .clear_RB
@@:
mov edx, [esi+UART.base]
add edx, IER_REG
mov eax,IER_RDAI+IER_THRI+IER_LSI
out dx, al
.clear_IIR:
mov edx, [esi+UART.base]
add edx, IIR_REG
in al, dx
test al, IIR_INTR
jnz .done
 
shr eax, 1
and eax, 3
jnz @F
 
mov edx, [esi+UART.base]
add edx, MSR_REG
in al, dx
jmp .clear_IIR
@@:
cmp eax, 1
je .clear_IIR
 
cmp eax, 2
jne @F
 
mov edx, [esi+UART.base]
in al, dx
jmp .clear_IIR
@@:
mov edx, [esi+UART.base]
add edx, LSR_REG
in al, dx
jmp .clear_IIR
.done:
mov edi, [esi+UART.rcvr_buff]
mov ecx, 8192/4
xor eax, eax
 
mov [esi+UART.rcvr_rp], edi
mov [esi+UART.rcvr_wp], edi
mov [esi+UART.rcvr_count], eax
 
cld
rep stosd
 
mov edi, [esi+UART.xmit_buff]
mov ecx, 8192/4
 
mov [esi+UART.xmit_rp], edi
mov [esi+UART.xmit_wp], edi
mov [esi+UART.xmit_count], eax
mov [esi+UART.xmit_free], 8192
 
rep stosd
ret ;eax= 0
.fail:
or eax, -1
ret
 
; param
; esi= input buffer
; +0 connection
; +4 rate
; +8 mode
;
; retval
; eax= error code
 
align 4
uart_set_mode:
mov eax, [esi]
cmp [eax+APPOBJ.magic], 'CNCT'
jne .fail
 
cmp [eax+APPOBJ.destroy], uart_close.destroy
jne .fail
 
mov eax, [eax+CONNECTION.uart]
test eax, eax
jz .fail
 
mov ebx, [esi+4]
mov ecx, [esi+8]
 
; param
; eax= uart
; ebx= baud rate
; ecx= mode
 
align 4
.internal:
cmp ebx, RATE_115200
ja .fail
 
cmp ecx, LCR_BREAK
jae .fail
 
mov [eax+UART.rate], ebx
mov [eax+UART.mode], ecx
 
mov esi, eax
mov bx, [divisor+ebx*2]
 
mov edx, [esi+UART.base]
push edx
add edx, LCR_REG
in al, dx
or al, 0x80
out dx, al
 
pop edx
mov al, bl
out dx, al
 
inc dx
mov al, bh
out dx, al
 
add edx, LCR_REG-1
mov eax, ecx
out dx, al
xor eax, eax
ret
.fail:
or eax, -1
ret
 
; param
; esi= input buffer
; +0 connection
; +4 modem control reg valie
;
; retval
; eax= error code
 
align 4
uart_set_mcr:
 
mov eax, [esi]
cmp [eax+APPOBJ.magic], 'CNCT'
jne .fail
 
cmp [eax+APPOBJ.destroy], uart_close.destroy
jne .fail
 
mov eax, [eax+CONNECTION.uart]
test eax, eax
jz .fail
 
mov ebx, [esi+4]
 
mov [eax+UART.mcr_reg], ebx
mov edx, [eax+UART.base]
add edx, MCR_REG
mov al, bl
out dx, al
xor eax, eax
ret
.fail:
or eax, -1
ret
 
; param
; eax= port
;
; retval
; ecx= connection
; eax= error code
 
align 4
uart_open:
dec eax
cmp eax, COM_MAX
jae .fail
 
mov esi, [com1+eax*4] ;uart
push esi
.do_wait:
cmp dword [esi+UART.lock],0
je .get_lock
; call change_task
jmp .do_wait
.get_lock:
mov eax, 1
xchg eax, [esi+UART.lock]
test eax, eax
jnz .do_wait
 
mov eax, esi ;uart
call uart_reset.internal
 
mov ebx, [CURRENT_TASK]
shl ebx, 5
mov ebx, [CURRENT_TASK+ebx+4]
mov eax, CONNECTION_SIZE
call CreateObject
pop esi ;uart
test eax, eax
jz .fail
 
mov [eax+APPOBJ.magic], 'CNCT'
mov [eax+APPOBJ.destroy], uart_close.destroy
mov [eax+CONNECTION.uart], esi
mov ecx, eax
xor eax, eax
ret
.fail:
or eax, -1
ret
restore .uart
 
; param
; esi= input buffer
 
align 4
uart_close:
mov eax, [esi]
cmp [eax+APPOBJ.magic], 'CNCT'
jne .fail
 
cmp [eax+APPOBJ.destroy], uart_close.destroy
jne .fail
.destroy:
push [eax+CONNECTION.uart]
call DestroyObject ;eax= object
pop eax ;eax= uart
test eax, eax
jz .fail
 
mov [eax+UART.state], UART_CLOSED
mov [eax+UART.lock], 0 ;release port
xor eax, eax
ret
.fail:
or eax, -1
ret
 
 
; param
; eax= uart
; ebx= baud rate
 
align 4
set_rate:
cmp ebx, RATE_115200
ja .fail
 
mov [eax+UART.rate], ebx
mov bx, [divisor+ebx*2]
 
mov edx, [eax+UART.base]
add edx, LCR_REG
in al, dx
push eax
or al, 0x80
out dx, al
 
sub edx, LCR_REG
mov al, bl
out dx, al
 
inc edx
mov al, bh
out dx, al
 
pop eax
add edx, LCR_REG-1
out dx, al
.fail:
ret
 
 
; param
; ebx= uart
 
align 4
transmit:
push esi
push edi
 
mov edx, [ebx+UART.base]
 
pushfd
cli
 
mov esi, [ebx+UART.xmit_rp]
mov ecx, [ebx+UART.xmit_count]
test ecx, ecx
je .stop
 
cmp ecx, 16
jbe @F
mov ecx, 16
@@:
sub [ebx+UART.xmit_count], ecx
add [ebx+UART.xmit_free], ecx
cld
@@:
lodsb
out dx, al
dec ecx
jnz @B
 
cmp esi,[ebx+UART.xmit_top]
jb @F
sub esi, 8192
@@:
mov [ebx+UART.xmit_rp], esi
 
cmp [ebx+UART.xmit_count], 0
je .stop
 
mov [ebx+UART.state], UART_TRANSMIT
jmp @F
.stop:
mov [ebx+UART.state], UART_STOP
@@:
popfd
pop edi
pop esi
ret
 
 
; param
; esi= input buffer
; +0 connection
; +4 dst buffer
; +8 dst size
; edi= output buffer
; +0 bytes read
 
; retval
; eax= error code
 
align 4
uart_read:
mov eax, [esi]
cmp [eax+APPOBJ.magic], 'CNCT'
jne .fail
 
cmp [eax+APPOBJ.destroy], uart_close.destroy
jne .fail
 
mov eax, [eax+CONNECTION.uart]
test eax, eax
jz .fail
 
mov ebx, [esi+8] ;dst size
mov ecx, [eax+UART.rcvr_count]
cmp ecx, ebx
jbe @F
mov ecx, ebx
@@:
mov [edi], ecx ;bytes read
test ecx, ecx
jz .done
 
push ecx
 
mov edi, [esi+4] ;dst
mov esi, [eax+UART.rcvr_rp]
cld
rep movsb
pop ecx
 
cmp esi, [eax+UART.rcvr_top]
jb @F
sub esi, 8192
@@:
mov [eax+UART.rcvr_rp], esi
sub [eax+UART.rcvr_count], ecx
.done:
xor eax, eax
ret
.fail:
or eax, -1
ret
 
; param
; esi= input buffer
; +0 connection
; +4 src buffer
; +8 src size
;
; retval
; eax= error code
 
align 4
uart_write:
mov eax, [esi]
cmp [eax+APPOBJ.magic], 'CNCT'
jne .fail
 
cmp [eax+APPOBJ.destroy], uart_close.destroy
jne .fail
 
mov eax, [eax+CONNECTION.uart]
test eax, eax
jz .fail
 
mov ebx, [esi+4]
mov edx, [esi+8]
 
; param
; eax= uart
; ebx= src
; edx= count
 
align 4
.internal:
mov esi, ebx
mov edi, [eax+UART.xmit_wp]
.write:
test edx, edx
jz .fail
.wait:
cmp [eax+UART.xmit_free], 0
jne .fill
 
cmp [eax+UART.state], UART_TRANSMIT
je .wait
 
mov ebx, eax
push edx
call transmit
pop edx
mov eax, ebx
jmp .write
.fill:
mov ecx, [eax+UART.xmit_free]
cmp ecx, edx
jbe @F
mov ecx, edx
@@:
push ecx
cld
rep movsb
pop ecx
sub [eax+UART.xmit_free], ecx
add [eax+UART.xmit_count], ecx
sub edx, ecx
jnz .wait
.done:
cmp edi, [eax+UART.xmit_top]
jb @F
sub edi, 8192
@@:
mov [eax+UART.xmit_wp], edi
cmp [eax+UART.state], UART_TRANSMIT
je @F
mov ebx, eax
call transmit
@@:
xor eax, eax
ret
.fail:
or eax, -1
ret
 
 
align 4
com_2_isr:
mov ebx, [com2]
jmp com_1_isr.get_info
align 4
com_1_isr:
mov ebx, [com1]
.get_info:
mov edx, [ebx+UART.base]
add edx, IIR_REG
in al, dx
 
test al, IIR_INTR
jnz .done
 
shr eax, 1
and eax, 3
 
call [isr_action+eax*4]
jmp .get_info
.done:
ret
 
align 4
isr_line:
mov edx, [ebx+UART.base]
add edx, LSR_REG
in al, dx
ret
 
align 4
isr_recieve:
mov esi, [ebx+UART.base]
add esi, LSR_REG
mov edi, [ebx+UART.rcvr_wp]
xor ecx, ecx
cld
.read:
mov edx, esi
in al, dx
test eax, LSR_DR
jz .done
 
mov edx, [ebx+UART.base]
in al, dx
stosb
inc ecx
jmp .read
.done:
cmp edi, [ebx+UART.rcvr_top]
jb @F
sub edi, 8192
@@:
mov [ebx+UART.rcvr_wp], edi
add [ebx+UART.rcvr_count], ecx
ret
 
align 4
isr_modem:
mov edx, [ebx+UART.base]
add edx, MSR_REG
in al, dx
ret
 
 
align 4
divisor dw 2304, 1536, 1047, 857, 768, 384
dw 192, 96, 64, 58, 48, 32
dw 24, 16, 12, 6, 3, 2, 1
 
align 4
uart_func dd 0 ;SRV_GETVERSION
dd 0 ;PORT_OPEN
dd uart_close ;PORT_CLOSE
dd uart_reset ;PORT_RESET
dd uart_set_mode ;PORT_SETMODE
dd 0 ;PORT_GETMODE
dd uart_set_mcr ;PORT_SETMODEM
dd 0 ;PORT_GETMODEM
dd uart_read ;PORT_READ
dd uart_write ;PORT_WRITE
 
isr_action dd isr_modem
dd transmit
dd isr_recieve
dd isr_line
 
version dd (5 shl 16) or (UART_VERSION and 0xFFFF)
 
sz_uart_srv db 'UART',0
 
align 4
 
com1 rd 1
com2 rd 1
 
/kernel/tags/kolibri0.7.5.0/drivers/com_mouse.asm
0,0 → 1,374
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Includes source code by Kulakov Vladimir Gennadievich. ;;
;; Modified by Mario79 and Rus. ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;driver sceletone
 
format MS COFF
 
DEBUG equ 0
 
include 'proc32.inc'
include 'imports.inc'
 
API_VERSION equ 5 ;debug
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
public START
public version
 
 
DRV_ENTRY equ 1
DRV_EXIT equ -1
STRIDE equ 4 ;size of row in devices table
 
SRV_GETVERSION equ 0
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .exit
.entry:
;Detect_COM_Mouse:
if DEBUG
mov esi, msgInit
call Boot_Log
end if
mov bx, 0x3f8
call MSMouseSearch
cmp AL,'M'
jne @f
;mov [com1_mouse_detected],1
;mov [irq_owner+4*4], 1 ; IRQ4 owner is System
 
mov dx, bx
inc dx ; 0x3f8 + 1
mov al, 1
out dx, al
 
stdcall AttachIntHandler, 4, irq4_handler, dword 0
if DEBUG
cmp eax, 0
jne .label1
 
mov esi, msg_error_attach_int_handler
call Boot_Log
end if
.label1:
mov eax, 0
mov ebx, 0x3F8
mov ecx, 0x3FF
call ReservePortArea
 
if DEBUG
cmp eax, 1
jne .go
 
mov esi, msg_error_reserve_ports
call Boot_Log
 
.go:
mov esi,boot_setmouse_type
call Boot_Log
end if
@@:
mov bx, 0x2f8
call MSMouseSearch
cmp AL,'M'
jne .resume
;mov [com2_mouse_detected],1
;mov [irq_owner+3*4], 1 ; IRQ3 owner is System
 
stdcall AttachIntHandler, 3, irq3_handler, dword 0
 
mov eax, 0
mov ebx, 0x2F8
mov ecx, 0x3F8
call ReservePortArea
if DEBUG
cmp eax, 1
jne @f
 
mov esi, msg_error_reserve_ports
call Boot_Log
@@:
 
mov esi,boot_setmouse_type + 22
call Boot_Log
end if
.resume:
 
stdcall RegService, my_service, service_proc
if DEBUG
cmp eax, 0
jne @f
 
mov esi, msg_exit
call Boot_Log
end if
@@:
ret
.fail:
.exit:
if DEBUG
mov esi, msg_exit
call Boot_Log
end if
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 ebx, [ioctl]
mov eax, [ebx+io_code]
cmp eax, SRV_GETVERSION
jne @F
 
mov eax, [ebx+output]
cmp [ebx+out_size], 4
jne .fail
mov [eax], dword API_VERSION
xor eax, eax
ret
@@:
.fail:
or eax, -1
ret
endp
 
align 4
MSMouseSearch:
; ÏÎÈÑÊ ÌÛØÈ ×ÅÐÅÇ COM-ÏÎÐÒÛ
MouseSearch:
; Óñòàíàâëèâàåì ñêîðîñòü
; ïðèåìà/ïåðåäà÷è 1200 áîä
; in bx COM Port Base Address
mov DX, bx
add DX,3
in AL,DX
or AL,80h ;óñòàíîâèòü áèò DLAB
out DX,AL
mov DX, bx
mov AL,60h ;1200 áîä
out DX,AL
inc DX
mov AL,0
out DX,AL
; Óñòàíîâèòü äëèíó ñëîâà 7 áèò, 1 ñòîïîâûé áèò,
; ÷åòíîñòü íå êîíòðîëèðîâàòü
mov DX, bx
add DX,3
mov AL,00000010b
out DX,AL
; Çàïðåòèòü âñå ïðåðûâàíè
mov dx, bx
inc dx
mov AL,0
out DX,AL
; Ïðîâåðèòü, ÷òî óñòðîéñòâî ïîäêëþ÷åíî è ÿâëÿåòñ
; ìûøüþ òèïà MSMouse
; Îòêëþ÷èòü ïèòàíèå ìûøè è ïðåðûâàíè
mov DX, bx
add EDX,4 ;ðåãèñòð óïðàâëåíèÿ ìîäåìîì
mov AL,0 ;ñáðîñèòü DTR, RTS è OUT2
out DX,AL
; Îæèäàòü 5 "òèêîâ" (0,2 ñ)
mov ecx, 0xFFFF
loop $
; Âêëþ÷èòü ïèòàíèå ìûøè
mov al, 1
out dx, al
mov ecx, 0xFFFF
loop $
; Î÷èñòèòü ðåãèñòð äàííûõ
mov dx, bx
in AL,DX
add edx, 4
mov AL, 1011b ;óñòàíîâèòü DTR è RTS è OUT2
out DX,AL
mov ecx, 0x1FFFF
; Öèêë îïðîñà ïîðòà
WaitData:
; Îæèäàòü åùå 10 "òèêîâ"
dec ecx
cmp ecx,0
je NoMouse
; Ïðîâåðèòü íàëè÷èå èäåíòèôèêàöèîííîãî áàéòà
mov DX, bx
add DX,5
in AL,DX
test AL,1 ;Äàííûå ãîòîâû?
jz WaitData
; Ââåñòè äàííûå
mov DX, bx
in AL,DX
NoMouse:
ret
 
align 4
irq3_handler:
mov dx, 0x2f8
mov esi, com2_mouse
jmp irq_handler
 
align 4
irq4_handler:
mov dx, 0x3f8
mov esi, com1_mouse
 
irq_handler:
 
; in: esi -> COM_MOUSE_DATA struc, dx = base port (xF8h)
add edx, 5 ; xFDh
in al, dx
test al, 1 ; Äàííûå ãîòîâû?
jz .Error
; Ââåñòè äàííûå
sub edx, 5
in al, dx
; Ñáðîñèòü ñòàðøèé íåçíà÷àùèé áèò
and al, 01111111b
 
; Îïðåäåëèòü ïîðÿäêîâûé íîìåð ïðèíèìàåìîãî áàéòà
cmp [esi+COM_MOUSE_DATA.MouseByteNumber], 2
ja .Error
jz .ThirdByte
jp .SecondByte
; Ñîõðàíèòü ïåðâûé áàéò äàííûõ
.FirstByte:
test al, 1000000b ; Ïåðâûé áàéò ïîñûëêè?
jz .Error
mov [esi+COM_MOUSE_DATA.FirstByte], al
inc [esi+COM_MOUSE_DATA.MouseByteNumber]
jmp .EndMouseInterrupt
; Ñîõðàíèòü âòîðîé áàéò äàííûõ
.SecondByte:
test al, 1000000b
jnz .Error
mov [esi+COM_MOUSE_DATA.SecondByte], al
inc [esi+COM_MOUSE_DATA.MouseByteNumber]
jmp .EndMouseInterrupt
; Ñîõðàíèòü òðåòèé áàéò äàííûõ
.ThirdByte:
test al, 1000000b
jnz .Error
mov [esi+COM_MOUSE_DATA.ThirdByte], al
mov [esi+COM_MOUSE_DATA.MouseByteNumber], 0
; (Ïàêåò äàííûõ îò ìûøè ïðèíÿò ïîëíîñòüþ).
; Çàïèñàòü íîâîå çíà÷åíèå ñîñòîÿíèÿ êíîïîê ìûøè
mov al, [esi+COM_MOUSE_DATA.FirstByte]
mov ah, al
shr al, 3
and al, 2
shr ah, 5
and ah, 1
add al, ah
movzx eax, al
mov [BTN_DOWN], eax
 
; Ïðèáàâèòü ïåðåìåùåíèå ïî X ê êîîðäèíàòå X
mov al, [esi+COM_MOUSE_DATA.FirstByte]
shl al, 6
or al, [esi+COM_MOUSE_DATA.SecondByte]
 
cbw
movzx eax, ax
mov [MOUSE_X], eax
 
; Ïðèáàâèòü ïåðåìåùåíèå ïî Y ê êîîðäèíàòå Y
mov al, [esi+COM_MOUSE_DATA.FirstByte]
and al, 00001100b
shl al, 4
or al, [esi+COM_MOUSE_DATA.ThirdByte]
 
cbw
movzx eax, ax
neg eax
mov [MOUSE_Y], eax
 
stdcall SetMouseData, [BTN_DOWN], [MOUSE_X], [MOUSE_Y], 0, 0
 
jmp .EndMouseInterrupt
 
.Error:
; Ïðîèçîøåë ñáîé â ïîðÿäêå ïåðåäà÷è èíôîðìàöèè îò
; ìûøè, îáíóëèòü ñ÷åò÷èê áàéòîâ ïàêåòà äàííûõ
 
mov [esi+COM_MOUSE_DATA.MouseByteNumber],0
.EndMouseInterrupt:
 
ret
 
;all initialized data place here
 
align 4
 
struc COM_MOUSE_DATA {
; Íîìåð ïðèíèìàåìîãî îò ìûøè áàéòà
.MouseByteNumber db ?
; Òðåõáàéòîâàÿ ñòðóêòóðà äàííûõ, ïåðåäàâàåìàÿ ìûøüþ
.FirstByte db ?
.SecondByte db ?
.ThirdByte db ?
;.timer_ticks_com dd ?
}
virtual at 0
COM_MOUSE_DATA COM_MOUSE_DATA
end virtual
 
com1_mouse COM_MOUSE_DATA
com2_mouse COM_MOUSE_DATA
 
MOUSE_X dd 0
MOUSE_Y dd 0
BTN_DOWN dd 0
 
COMPortBaseAddr dw 3F8h
 
 
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
my_service db 'COM_Mouse',0 ;max 16 chars include zero
 
if DEBUG
msgInit db 'Preved bugoga!',13,10,0
boot_setmouse_type db 'Detected - COM1 mouse',13,10,0
db 'Detected - COM2 mouse',13,10,0
msg_error_reserve_ports db 'Error reserving ports!',13,10,0
msg_error_attach_int_handler db 'Error attach interrupt handler!',13,10,0
msg_exit db 'Exit!',13,10,0
end if
 
section '.data' data readable writable align 16
 
;all uninitialized data place here
 
/kernel/tags/kolibri0.7.5.0/drivers/ensoniq.asm
0,0 → 1,1177
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;alpha version
 
format MS COFF
 
DEBUG equ 1
 
 
include 'proc32.inc'
include 'imports.inc'
 
REMAP_IRQ equ 0
 
;irq 0,1,2,8,12,13 íåäîñòóïíû
; FEDCBA9876543210
VALID_IRQ equ 1100111011111000b
ATTCH_IRQ equ 0000111010101000b
 
IRQ_LINE equ 0
 
CPU_FREQ equ 2600d
 
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
 
 
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 0x16 ; PCM out Status register
PCM_OUT_PIV_REG equ 0x1a
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 ?
.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
 
OS_BASE equ 0x80000000
SLOT_BASE equ OS_BASE+0x0080000
new_app_base equ 0
 
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, msgDetect
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
 
jmp .fail ;force 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
 
mov eax, VALID_IRQ
mov ebx, [ctrl.int_line]
mov esi, msgInvIRQ
bt eax, ebx
jnc .fail
mov eax, ATTCH_IRQ
mov esi, msgAttchIRQ
bt eax, ebx
jnc .fail
 
stdcall AttachIntHandler, ebx, ac97_irq, dword 0
stdcall RegService, sz_sound_srv, service_proc
ret
.fail:
if DEBUG
mov esi, msgFail
call SysMsgBoardStr
end if
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, 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
 
; if DEBUG
; mov esi, msgIRQ
; call SysMsgBoardStr
; end if
 
 
cmp [ctrl.user_callback], 0
je @f
 
stdcall [ctrl.user_callback], ebx
@@:
ret
 
.skip:
mov edx, PCM_OUT_CR_REG
mov ax, 0x11 ;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
cld
rep stosd
 
mov eax, [ctrl.buffer]
call GetPgAddr
 
mov ebx, 0xC0002000
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 eax, pcmout_bdl
mov ebx, eax
call GetPgAddr ;eax
and ebx, 0xFFF
add eax, ebx
 
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]
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 ebx, 0x1274
jne @F
mov [ctrl.vendor_ids], msgEnsoniq
ret
@@:
mov [ctrl.vendor_ids], 0 ;something wrong ?
ret
.err:
xor eax, eax
ret
endp
 
align 4
proc init_controller
 
mov esi, msgPCIcmd
call SysMsgBoardStr
 
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
 
call dword2str
call SysMsgBoardStr
 
mov esi, msgIObase
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
; and eax, -16
mov [ctrl.ctrl_io_base], eax
 
call dword2str
call SysMsgBoardStr
 
mov esi, msgIRQline
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
and eax, 0xFF
mov [ctrl.int_line], eax
 
call dword2str
call SysMsgBoardStr
 
call [ctrl.ctrl_setup]
xor eax, eax
inc eax
ret
endp
 
align 4
proc set_ICH
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
 
mov esi, msgControl
call SysMsgBoardStr
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
call dword2str
call SysMsgBoardStr
 
mov esi, msgStatus
call SysMsgBoardStr
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
 
call dword2str
call SysMsgBoardStr
 
test eax, CTRL_ST_CREADY
jnz .ready
 
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:
if DEBUG
mov esi, msgResetOk
call SysMsgBoardStr
end if
 
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
play:
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]
xor eax, eax
ret
 
align 4
stop:
mov edx, PCM_OUT_CR_REG
mov ax, 0x0
call [ctrl.ctrl_write8]
 
mov ax, 0x1c
mov edx, PCM_OUT_SR_REG
call [ctrl.ctrl_write16]
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 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
.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
js @B
 
pop eax
pop ebx
pop edx
pop ecx
ret
endp
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CONTROLLER IO functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
codec_io_r16:
add edx, [ctrl.codec_io_base]
in ax, dx
ret
 
align 4
codec_io_w16:
add edx, [ctrl.codec_io_base]
out dx, ax
ret
 
align 4
ctrl_io_r8:
add edx, [ctrl.ctrl_io_base]
in al, dx
ret
 
align 4
ctrl_io_r16:
add edx, [ctrl.ctrl_io_base]
in ax, dx
ret
 
align 4
ctrl_io_r32:
add edx, [ctrl.ctrl_io_base]
in eax, dx
ret
 
align 4
ctrl_io_w8:
add edx, [ctrl.ctrl_io_base]
out dx, al
ret
 
align 4
ctrl_io_w16:
add edx, [ctrl.ctrl_io_base]
out dx, ax
ret
 
align 4
ctrl_io_w32:
add edx, [ctrl.ctrl_io_base]
out dx, eax
ret
 
 
align 4
dword2str:
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
ret
 
hexletters db '0123456789ABCDEF'
hex_buff db 8 dup(0),13,10,0
 
 
include "codec.inc"
 
align 4
devices dd (0x5000 shl 16)+0x1274,msgEnsoniq,set_ICH
dd (0x5880 shl 16)+0x1274,msgVibra128,set_ICH
dd 0 ;terminator
 
version dd 0x00040004
 
msgEnsoniq db 'Ensonic 1371',13,10,0
msgVibra128 db 'Sound Blaster AudioPCI Vibra 128',13,10,0
 
sz_sound_srv db 'SOUND',0
 
msgDetect 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
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 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
msgResetOk db 'reset complete',13,10,0
msgStatus db 'global status ',0
msgControl db 'global control ',0
msgPCIcmd db 'PCI command ',0
msgIObase db 'IO base ',0
msgIRQline db 'IRQ line ',0
 
section '.data' data readable writable align 16
 
pcmout_bdl rq 32
buff_list rd 32
 
codec CODEC
ctrl AC_CNTRL
 
lpc_bus rd 1
civ_val rd 1
 
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/tags/kolibri0.7.5.0/drivers/imports.inc
0,0 → 1,89
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
macro kernel_export [name]{
forward
if used name
if DEBUG
display 'uses: ',`name,#13,#10
end if
extrn name
end if
}
; all exported kernel functions and data
 
 
kernel_export \
RegService,\
GetService,\
ServiceHandler,\
AttachIntHandler,\
GetIntHandler,\
FpuSave,\
FpuRestore,\
ReservePortArea,\
Boot_Log,\
\
PciApi,\
PciRead32,\
PciRead16,\
PciRead8,\
PciWrite8,\
PciWrite16,\
PciWrite32,\
\
AllocPage,\
AllocPages,\
FreePage,\
MapPage,\
MapSpace,\
MapIoMem,\
GetPgAddr,\
CommitPages,\
ReleasePages,\
\
AllocKernelSpace,\
FreeKernelSpace,\
KernelAlloc,\
KernelFree,\
UserAlloc,\
UserFree,\
Kmalloc,\
Kfree,\
CreateRingBuffer,\
\
GetPid,\
CreateObject,\
DestroyObject,\
CreateEvent,\
RaiseEvent,\
WaitEvent,\
DestroyEvent,\
ClearEvent,\
\
LoadCursor,\
SelectHwCursor,\
SetHwCursor,\
HwCursorRestore,\
HwCursorCreate,\
\
SysMsgBoardStr,\
SysMsgBoardChar,\
GetCurrentTask,\
LoadFile,\
SendEvent,\
SetMouseData,\
Sleep,\
GetTimerTicks,\
\
strncat,\
strncpy,\
strncmp,\
strnlen,\
strchr,\
strrchr,\
\
LFBAddress
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/tags/kolibri0.7.5.0/drivers/infinity.asm
0,0 → 1,1307
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2006-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; Serge 2006-2008
; email: infinity_sound@mail.ru
 
format MS COFF
 
DEBUG equ 1
 
 
include 'proc32.inc'
include 'main.inc'
include 'imports.inc'
 
 
CURRENT_API equ 0x0101 ;1.01
COMPATIBLE_API equ 0x0100 ;1.00
 
API_VERSION equ (COMPATIBLE_API shl 16) or CURRENT_API
SOUND_VERSION equ CURRENT_API
 
 
FORCE_MMX equ 0 ;set to 1 to force use mmx or
FORCE_MMX_128 equ 0 ;integer sse2 extensions
;and reduce driver size
 
;USE_SSE equ 0
 
USE_SSE2_MIXER equ 0 ;floating point mixer. Disabled by default
 
OS_BASE equ 0x80000000
 
CAPS_SSE2 equ 26
PG_SW equ 0x003
 
public START
public service_proc
public version
 
RT_INP_EMPTY equ 0xFF000001
RT_OUT_EMPTY equ 0xFF000002
RT_INP_FULL equ 0xFF000003
RT_OUT_FULL equ 0xFF000004
 
EVENT_WATCHED equ 0x10000000
EVENT_SIGNALED equ 0x20000000
MANUAL_RESET equ 0x40000000
MANUAL_DESTROY equ 0x80000000
 
DEV_PLAY equ 1
DEV_STOP equ 2
DEV_CALLBACK equ 3
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .exit
 
stdcall GetService, szSound
test eax, eax
jz .fail
mov [hSound], eax
 
stdcall KernelAlloc, 16*512
test eax, eax
jz .out_of_mem
mov [mix_buff], eax
 
mov eax, str.fd-FD_OFFSET
mov [str.fd], eax
mov [str.bk], eax
 
if FORCE_MMX
if FORCE_MMX_128
display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10
stop
end if
mov [mix_2_core], mmx_mix_2
mov [mix_3_core], mmx_mix_3
mov [mix_4_core], mmx_mix_4
end if
 
if FORCE_MMX_128
if FORCE_MMX
display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10
stop
end if
mov [mix_2_core], mmx128_mix_2
mov [mix_3_core], mmx128_mix_3
mov [mix_4_core], mmx128_mix_4
end if
 
if 0
 
if ~(FORCE_MMX or FORCE_MMX_128) ;autodetect
mov eax, 1
cpuid
bt edx, CAPS_SSE2
jc .mmx128
;old 64-bit mmx
mov [mix_2_core], mmx_mix_2
mov [mix_3_core], mmx_mix_3
mov [mix_4_core], mmx_mix_4
jmp @F
.mmx128: ;128-bit integer sse2 extensions
mov [mix_2_core], mmx128_mix_2
mov [mix_3_core], mmx128_mix_3
mov [mix_4_core], mmx128_mix_4
@@:
end if
 
end if
stdcall set_handler, [hSound], new_mix
mov [eng_state], SND_STOP
stdcall RegService, szInfinity, service_proc
ret
.fail:
if DEBUG
mov esi, msgFail
call SysMsgBoardStr
end if
.exit:
xor eax, eax
ret
 
.out_of_mem:
if DEBUG
mov esi, msgMem
call SysMsgBoardStr
end if
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, [eax]
mov [eax], dword API_VERSION
xor eax, eax
ret
@@:
cmp eax, SND_CREATE_BUFF
jne @F
mov ebx, [edi+input]
stdcall CreateBuffer,[ebx],[ebx+4]
mov edi, [ioctl]
mov ecx, [edi+output]
mov ecx, [ecx]
mov [ecx], ebx
ret
@@:
mov ebx, [edi+input]
mov edx, [ebx]
 
cmp [edx+STREAM.magic], 'WAVE'
jne .fail
 
cmp [edx+STREAM.size], STREAM_SIZE
jne .fail
 
cmp eax, SND_DESTROY_BUFF
jne @F
mov eax, edx
call DestroyBuffer ;edx= stream
ret
@@:
cmp eax, SND_SETFORMAT
jne @F
stdcall SetFormat,edx,[ebx+4]
ret
@@:
cmp eax, SND_GETFORMAT
jne @F
 
movzx eax, word [edx+STREAM.format]
mov ecx, [edi+output]
mov ecx, [ecx]
mov [ecx], eax
xor eax, eax
ret
@@:
cmp eax, SND_RESET
jne @F
stdcall ResetBuffer,edx,[ebx+4]
ret
@@:
cmp eax, SND_SETPOS
jne @F
stdcall SetBufferPos,edx,[ebx+4]
ret
@@:
cmp eax, SND_GETPOS
jne @F
stdcall GetBufferPos, edx
mov edi, [ioctl]
mov ecx, [edi+output]
mov ecx, [ecx]
mov [ecx], ebx
ret
@@:
cmp eax, SND_SETBUFF
jne @F
mov eax, [ebx+4]
stdcall set_buffer, edx,eax,[ebx+8],[ebx+12]
ret
@@:
cmp eax, SND_SETVOLUME
jne @F
stdcall SetBufferVol,edx,[ebx+4],[ebx+8]
ret
@@:
cmp eax, SND_GETVOLUME
jne @F
 
mov eax, [edi+output]
mov ecx, [eax]
mov eax, [eax+4]
stdcall GetBufferVol,edx,ecx,eax
ret
@@:
cmp eax, SND_SETPAN
jne @F
stdcall SetBufferPan,edx,[ebx+4]
ret
@@:
cmp eax, SND_GETPAN
jne @F
mov eax, [edx+STREAM.pan]
mov ebx, [edi+output]
mov ebx, [ebx]
mov [ebx], eax
xor eax, eax
ret
@@:
cmp eax, SND_OUT
jne @F
 
mov eax, [ebx+4]
stdcall wave_out, edx,eax,[ebx+8]
ret
@@:
cmp eax, SND_PLAY
jne @F
 
stdcall play_buffer, edx,[ebx+4]
ret
@@:
cmp eax, SND_STOP
jne @F
 
stdcall stop_buffer, edx
ret
@@:
cmp eax, SND_GETBUFFSIZE
jne @F
mov eax, [edx+STREAM.in_size]
mov ecx, [edi+output]
mov ecx, [ecx]
mov [ecx], eax
xor eax, eax
ret
@@:
cmp eax, SND_GETFREESPACE
jne @F
 
test [edx+STREAM.format], PCM_OUT
jz .fail
 
mov ebx, [edx+STREAM.in_free]
mov ecx, [edi+output]
mov [ecx], ebx
xor eax, eax
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 CreateBuffer stdcall, format:dword, size:dword
locals
str dd ?
ring_size dd ?
ring_pages dd ?
endl
 
mov eax, [format]
cmp ax, PCM_1_8_8
ja .fail
 
test eax, PCM_OUT
jnz .test_out
test eax, PCM_RING
jnz .test_ring
;staic
test eax, PCM_STATIC
jz .test_out ;use PCM_OUT as default format
jmp .test_ok
.test_out:
test eax, PCM_RING+PCM_STATIC
jnz .fail
or [format], PCM_OUT ;force set
jmp .test_ok
.test_ring:
test eax, PCM_OUT+PCM_STATIC
jnz .fail
.test_ok:
 
call GetPid
mov ebx, eax
mov eax, STREAM_SIZE
 
call CreateObject
test eax, eax
jz .fail
mov [str], eax
 
mov ebx, [format]
mov [eax+STREAM.format], ebx
 
xor ecx, ecx
movzx ebx, bx
cmp ebx, 19
jb @f
mov ecx, 0x80808080
@@:
mov [eax+STREAM.r_silence], ecx
 
shl ebx, 2
lea ebx, [ebx+ebx*2] ;ebx*=12
 
mov ecx, [resampler_params+ebx]
mov edx, [resampler_params+ebx+4]
mov esi, [resampler_params+ebx+8]
 
mov [eax+STREAM.r_size],ecx
mov [eax+STREAM.r_dt], edx
mov [eax+STREAM.resample], esi
xor ecx, ecx
mov [eax+STREAM.l_vol], ecx
mov [eax+STREAM.r_vol], ecx
mov dword [eax+STREAM.l_amp], 0x7FFF7FFF
mov [eax+STREAM.pan], ecx
 
test [format], PCM_STATIC
jnz .static
 
; ring and waveout
 
mov ebx, 0x10000
test [format], PCM_RING
jz .waveout
 
mov ebx, [eax+STREAM.r_size]
add ebx, 4095
and ebx, -4096
add ebx, ebx
.waveout:
mov [ring_size], ebx
mov eax, ebx
shr ebx, 12
mov [ring_pages], ebx
 
stdcall CreateRingBuffer, eax, PG_SW
 
mov edi, [str]
mov ecx, [ring_size]
mov [edi+STREAM.in_base], eax
mov [edi+STREAM.in_size], ecx
add eax, 128
; sub ecx, 128
mov [edi+STREAM.in_wp], eax
mov [edi+STREAM.in_rp], eax
mov [edi+STREAM.in_count], 0
 
mov [edi+STREAM.in_free], ecx
add eax, ecx
mov [edi+STREAM.in_top], eax
 
jmp .out_buff
.static:
mov ecx, [size]
add ecx, 128 ;resampler required
mov [eax+STREAM.in_size], ecx
stdcall KernelAlloc, ecx
 
mov edi, [str]
mov [edi+STREAM.in_base], eax
add eax, 128
mov [edi+STREAM.in_wp], eax
mov [edi+STREAM.in_rp], eax
mov ebx, [size]
mov [edi+STREAM.in_count], ebx
mov [edi+STREAM.in_free], ebx
add eax, ebx
mov [edi+STREAM.in_top], eax
 
.out_buff:
stdcall AllocKernelSpace, dword 128*1024
 
mov edi, [str]
mov [edi+STREAM.out_base], eax
mov [edi+STREAM.out_wp], eax
mov [edi+STREAM.out_rp], eax
mov [edi+STREAM.out_count], 0
add eax, 64*1024
mov [edi+STREAM.out_top], eax
 
stdcall AllocPages, dword 64/4
mov edi, [str]
mov ebx, [edi+STREAM.out_base]
mov ecx, 16
or eax, PG_SW
push eax
push ebx
call CommitPages ;eax, ebx, ecx
mov ecx, 16
pop ebx
pop eax
add ebx, 64*1024
call CommitPages ;double mapped
 
mov edi, [str]
mov ecx, [edi+STREAM.in_top]
mov edi, [edi+STREAM.in_base]
sub ecx, edi
xor eax, eax
shr ecx, 2
cld
rep stosd
 
mov edi, [str]
mov edi, [edi+STREAM.out_base]
mov ecx, (64*1024)/4
rep stosd
 
xor edx, edx
mov ebx, MANUAL_DESTROY
call CreateEvent
 
mov ebx, [str]
mov [ebx+STREAM.notify_event], eax
mov [ebx+STREAM.notify_id], edx
 
mov [ebx+STREAM.magic], 'WAVE'
mov [ebx+STREAM.destroy], DestroyBuffer.destroy
mov [ebx+STREAM.size], STREAM_SIZE
mov [ebx+STREAM.flags], SND_STOP
 
pushf
cli
mov eax, str.fd-FD_OFFSET
mov edx, [eax+STREAM.str_fd]
mov [ebx+STREAM.str_fd], edx
mov [ebx+STREAM.str_bk], eax
mov [eax+STREAM.str_fd], ebx
mov [edx+STREAM.str_bk], ebx
popf
 
xor eax, eax
ret
.fail:
xor ebx, ebx
or eax, -1
ret
endp
 
;param
; eax= buffer handle
 
align 4
DestroyBuffer:
.handle equ esp ;local
 
mov [eax+STREAM.flags], SND_STOP
.destroy:
push eax
 
pushfd
cli
mov ebx, [eax+STREAM.str_fd]
mov ecx, [eax+STREAM.str_bk]
mov [ebx+STREAM.str_bk], ecx
mov [ecx+STREAM.str_fd], ebx
popf
 
stdcall KernelFree, [eax+STREAM.in_base]
mov eax, [.handle]
stdcall KernelFree, [eax+STREAM.out_base]
 
pop eax ;restore stack
call DestroyObject ;eax= stream
xor eax, eax
ret
.fail:
or eax, -1
ret
restore .handle
 
align 4
proc SetFormat stdcall, str:dword, format:dword
 
cmp word [format], PCM_1_8_8
ja .fail
 
mov edx, [str]
mov [edx+STREAM.flags], SND_STOP
 
test [edx+STREAM.format], PCM_RING
jnz .fail
 
; mov eax,[edx+STREAM.out_base]
; mov [edx+STREAM.out_wp], eax
; mov [edx+STREAM.out_rp], eax
; mov [edx+STREAM.out_count], 0
 
movzx eax, word [format]
mov word [edx+STREAM.format], ax
 
xor ebx, ebx
cmp eax, 19
jb @f
mov ebx, 0x80808080
@@:
mov [edx+STREAM.r_silence], ebx
 
shl eax, 2
lea eax, [eax+eax*2] ;eax*=12
 
mov edi, [resampler_params+eax]
mov ecx, [resampler_params+eax+4]
mov ebx, [resampler_params+eax+8]
 
mov [edx+STREAM.r_size],edi
mov [edx+STREAM.r_dt], ecx
mov [edx+STREAM.resample], ebx
 
mov edi, [edx+STREAM.in_base]
mov ecx, 128/4
mov eax, [edx+STREAM.r_silence]
cld
rep stosd
xor eax, eax
ret
.fail:
or eax, -1
ret
endp
 
; for static buffers only
; use waveout for streams
 
align 4
proc set_buffer stdcall, str:dword,src:dword,offs:dword,size:dword
 
mov edx, [str]
test [edx+STREAM.format], PCM_OUT
jnz .fail
 
mov esi, [src]
mov edi, [offs]
add edi, [edx+STREAM.in_base]
add edi, 128
 
cmp edi, [edx+STREAM.in_top]
jae .fail
 
mov ecx, [size]
lea ebx, [ecx+edi]
sub ebx, [edx+STREAM.in_top]
jb @F
sub ecx, ebx
@@:
shr ecx, 2
cld
rep movsd
xor eax,eax
ret
.fail:
or eax, -1
ret
endp
 
; for stream buffers only
 
align 4
proc wave_out stdcall, str:dword,src:dword,size:dword
locals
state_saved dd ?
fpu_state rb 528
endl
 
mov edx, [str]
mov eax, [edx+STREAM.format]
test eax, PCM_OUT
jz .fail
 
cmp ax, PCM_ALL
je .fail
 
mov esi,[src]
test esi, esi
jz .fail
 
cmp esi, OS_BASE
jae .fail
 
mov [state_saved], 0
 
.main_loop:
mov edx, [str]
 
mov ebx, [size]
test ebx, ebx
jz .done
 
cmp [edx+STREAM.flags], SND_STOP
jne .fill
 
mov edi, [edx+STREAM.in_base]
mov ecx, 128/4
mov eax, [edx+STREAM.r_silence]
cld
rep stosd
 
mov ecx, [edx+STREAM.in_size]
sub ecx, 128
mov [edx+STREAM.in_wp], edi
mov [edx+STREAM.in_rp], edi
mov [edx+STREAM.in_count], 0
mov [edx+STREAM.in_free], ecx
 
mov eax,[edx+STREAM.out_base]
mov [edx+STREAM.out_wp], eax
mov [edx+STREAM.out_rp], eax
mov [edx+STREAM.out_count], 0
.fill:
mov ecx, [edx+STREAM.in_free]
test ecx, ecx
jz .wait
 
cmp ecx, ebx
jbe @F
 
mov ecx, ebx
@@:
sub [size], ecx
add [edx+STREAM.in_count], ecx
sub [edx+STREAM.in_free], ecx
 
shr ecx, 2
mov edi, [edx+STREAM.in_wp]
mov esi, [src]
cld
rep movsd
 
mov [src], esi
cmp edi, [edx+STREAM.in_top]
jb @F
sub edi, [edx+STREAM.in_size]
@@:
mov [edx+STREAM.in_wp], edi
 
cmp [edx+STREAM.out_count], 32768
jae .skip
 
cmp [state_saved], 0
jne @F
lea eax, [fpu_state+15]
and eax, -16
call FpuSave
mov [state_saved], 1
@@:
stdcall refill, edx
.skip:
mov edx, [str]
mov [edx+STREAM.flags], SND_PLAY
cmp [eng_state], SND_PLAY
je .main_loop
 
stdcall dev_play, [hSound]
mov [eng_state], SND_PLAY
jmp .main_loop
.wait:
mov edx, [str]
mov eax, [edx+STREAM.notify_event]
mov ebx, [edx+STREAM.notify_id]
call WaitEvent ;eax ebx
jmp .main_loop
.done:
cmp [state_saved], 1
jne @F
 
lea eax, [fpu_state+15]
and eax, -16
call FpuRestore
@@:
xor eax, eax
ret
.fail:
or eax, -1
ret
endp
 
; both static and stream
; reset all but not clear buffers
 
 
; flags reserved
; RESET_INPUT equ 1 ;reserved reset and clear input buffer
; RESET_OUTPUT equ 2 ;reserved reset and clear output buffer
; RESET_ALL equ 3
 
 
align 4
proc ResetBuffer stdcall, str:dword, flags:dword
 
mov edx, [str]
mov [edx+STREAM.flags], SND_STOP
 
mov edi, [edx+STREAM.in_base]
mov ecx, 128/4
mov eax, [edx+STREAM.r_silence]
cld
rep stosd
 
mov [edx+STREAM.in_wp], edi
mov [edx+STREAM.in_rp], edi
 
test [edx+STREAM.flags], PCM_STATIC
jnz .static
mov [edx+STREAM.in_count], 0
jmp @F
.static:
mov eax, [edx+STREAM.in_size]
mov [edx+STREAM.in_count], eax
@@:
 
mov eax, [edx+STREAM.in_size]
sub eax, 128
mov [edx+STREAM.in_free], eax
 
xor eax, eax
mov ebx,[edx+STREAM.out_base]
mov [edx+STREAM.out_wp], ebx
mov [edx+STREAM.out_rp], ebx
mov [edx+STREAM.out_count], eax
ret
.fail:
or eax, -1
ret
endp
 
; for static buffers only
 
align 4
proc SetBufferPos stdcall, str:dword, pos:dword
 
mov edx, [str]
test [edx+STREAM.format], PCM_STATIC
jz .fail
 
mov [edx+STREAM.flags], SND_STOP
 
mov eax, [pos]
add eax, [edx+STREAM.in_base]
mov ebx, [edx+STREAM.in_top]
add eax, 128
 
cmp eax, ebx
jae .fail
 
mov [edx+STREAM.in_rp], eax
sub ebx, eax
mov [edx+STREAM.in_count], ebx
xor eax, eax
ret
.fail:
or eax, -1
ret
endp
 
align 4
proc GetBufferPos stdcall, str:dword
 
mov edx, [str]
test [edx+STREAM.format], PCM_STATIC
jz .fail
 
mov ebx, [edx+STREAM.in_rp]
sub ebx, [edx+STREAM.in_base]
sub ebx, 128
xor eax, eax
ret
.fail:
xor ebx,ebx
or eax, -1
ret
endp
 
; both
 
align 4
proc SetBufferVol stdcall, str:dword,l_vol:dword,r_vol:dword
 
mov edx, [str]
stdcall set_vol_param,[l_vol],[r_vol],[edx+STREAM.pan]
ret
endp
 
proc set_vol_param stdcall, l_vol:dword,r_vol:dword,pan:dword
locals
_600 dd ?
_32767 dd ?
state rb 108
endl
 
mov [_600], 0x44160000 ;600.0
mov [_32767], 32767
 
lea ebx, [state]
fnsave [ebx]
 
movq mm0, qword [l_vol]
pminsw mm0, qword [vol_max]
pmaxsw mm0, qword [vol_min]
movq qword [l_vol], mm0
movq qword [edx+STREAM.l_vol], mm0
 
movd mm1,[pan]
pminsw mm1, qword [pan_max]
pmaxsw mm1, qword [vol_min]
movd [edx+STREAM.pan], mm1
 
cmp word [edx+STREAM.pan], 0
jl @F
 
psubsw mm0,mm1
pminsw mm0, qword [vol_max]
pmaxsw mm0, qword [vol_min]
movd [l_vol],mm0
jmp .calc_amp
@@:
punpckhdq mm0,mm0
paddsw mm0,mm1
pminsw mm0, qword [vol_max]
pmaxsw mm0, qword [vol_min]
movd [r_vol], mm0
.calc_amp:
emms
fild word [l_vol]
 
call .calc
 
fistp word [edx+STREAM.l_amp]
fstp dword [edx+STREAM.l_amp_f]
fstp st0
 
fild word [r_vol]
 
call .calc
 
fistp word [edx+STREAM.r_amp]
fstp dword [edx+STREAM.r_amp_f]
fstp st0
 
fnclex
lea ebx, [state]
frstor [ebx]
 
xor eax, eax
inc eax
ret
.calc:
fdiv dword [_600]
fld st0
frndint
fxch st1
fsub st, st1
f2xm1
fld1
faddp st1, st0
fscale
fld st0
fimul dword [_32767]
ret 0
endp
 
align 4
proc GetBufferVol stdcall, str:dword,p_lvol:dword,p_rvol:dword
 
mov edx, [str]
mov eax, [p_lvol]
movsx ecx, word [edx+STREAM.l_vol]
mov [eax], ecx
 
mov eax, [p_rvol]
movsx ecx, word [edx+STREAM.r_vol]
mov [eax], ecx
xor eax, eax
ret
endp
 
align 4
proc SetBufferPan stdcall, str:dword,pan:dword
 
mov edx, [str]
stdcall set_vol_param,[edx+STREAM.l_vol],\
[edx+STREAM.r_vol],[pan]
ret
endp
 
; for static and ring buffers only
 
align 4
proc play_buffer stdcall, str:dword, flags:dword
 
mov ebx, [str]
mov eax, [ebx+STREAM.format]
test eax, PCM_OUT
jnz .fail
 
cmp ax, PCM_ALL
je .fail
 
mov [ebx+STREAM.flags], SND_PLAY
cmp [eng_state], SND_PLAY
je .done
 
stdcall dev_play, [hSound]
mov [eng_state], SND_PLAY
.done:
test [flags], PLAY_SYNC
jz @F
 
mov edx, [str]
.wait:
mov eax, [edx+STREAM.notify_event]
mov ebx, [edx+STREAM.notify_id]
call WaitEvent ;eax ebx
 
mov edx, [str]
cmp [edx+STREAM.flags], SND_STOP
jne .wait
@@:
xor eax, eax
ret
.fail:
or eax, -1
ret
endp
 
; for static and ring buffers only
 
align 4
proc stop_buffer stdcall, str:dword
 
mov edx, [str]
test [edx+STREAM.format], PCM_STATIC+PCM_RING
jz .fail
 
mov [edx+STREAM.flags], SND_STOP
 
; stdcall [ServiceHandler], [hSound], dword DEV_STOP, 0
 
mov eax, [edx+STREAM.notify_event]
mov ebx, [edx+STREAM.notify_id]
call ClearEvent ;eax ebx
 
xor eax, eax
ret
.fail:
or eax, -1
ret
endp
 
; param
; eax= mix_list
 
align 4
do_mix_list:
 
xor edx, edx
mov esi, str.fd-FD_OFFSET
mov ebx, [esi+STREAM.str_fd]
@@:
cmp ebx, esi
je .done
 
cmp [ebx+STREAM.magic], 'WAVE'
jne .next
 
cmp [ebx+STREAM.size], STREAM_SIZE
jne .next
 
cmp [ebx+STREAM.flags], SND_PLAY;
jne .next
 
mov ecx, [ebx+STREAM.out_count]
test ecx, ecx
jnz .l1
 
test [ebx+STREAM.format], PCM_RING
jnz .next
mov [ebx+STREAM.flags], SND_STOP
jmp .next
.l1:
cmp ecx, 512
jae .add_buff
 
mov edi, [ebx+STREAM.out_rp]
add edi, ecx
sub ecx, 512
neg ecx
push eax
xor eax, eax
cld
rep stosb
pop eax
 
mov [ebx+STREAM.out_count], 512
 
.add_buff:
mov ecx, [ebx+STREAM.out_rp]
mov [eax],ecx
 
if USE_SSE2_MIXER
mov edi, dword [ebx+STREAM.l_amp_f]
mov [eax+4], edi
mov edi, dword [ebx+STREAM.r_amp_f]
mov [eax+8], edi
else
mov edi, dword [ebx+STREAM.l_amp]
mov [eax+4], edi
end if
add [ebx+STREAM.out_rp], 512
sub [ebx+STREAM.out_count], 512
 
add eax, 12
inc edx
.next:
mov ebx, [ebx+STREAM.str_fd]
jmp @B
.done:
mov eax, edx
ret
 
align 4
prepare_playlist:
 
xor edx, edx
mov [play_count], edx
mov esi, str.fd-FD_OFFSET
mov edi, [esi+STREAM.str_fd]
@@:
cmp edi, esi
je .done
 
cmp [edi+STREAM.magic], 'WAVE'
jne .next
 
cmp [edi+STREAM.size], STREAM_SIZE
jne .next
 
cmp [edi+STREAM.flags], SND_PLAY;
jne .next
 
mov [play_list+edx], edi
inc [play_count]
add edx, 4
.next:
mov edi, [edi+STREAM.str_fd]
jmp @B
.done:
ret
 
align 4
proc set_handler stdcall, hsrv:dword, handler_proc:dword
locals
handler dd ?
io_code dd ?
input dd ?
inp_size dd ?
output dd ?
out_size dd ?
val dd ?
endl
 
mov eax, [hsrv]
lea ecx, [handler_proc]
xor ebx, ebx
 
mov [handler], eax
mov [io_code], DEV_CALLBACK
mov [input], ecx
mov [inp_size], 4
mov [output], ebx
mov [out_size], 0
 
lea eax, [handler]
stdcall ServiceHandler, eax
ret
endp
 
align 4
proc dev_play stdcall, hsrv:dword
locals
handle dd ?
io_code dd ?
input dd ?
inp_size dd ?
output dd ?
out_size dd ?
val dd ?
endl
 
mov eax, [hsrv]
xor ebx, ebx
 
mov [handle], eax
mov [io_code], DEV_PLAY
mov [input], ebx
mov [inp_size], ebx
mov [output], ebx
mov [out_size], ebx
 
lea eax, [handle]
stdcall ServiceHandler, eax
ret
endp
 
if 0
align 4
dword2str:
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
ret
 
hexletters db '0123456789ABCDEF'
hex_buff db 8 dup(0),13,10,0
 
end if
 
include 'mixer.asm'
include 'mix_mmx.inc'
include 'mix_sse2.inc'
 
;if USE_SSE
; include 'mix_sse.inc'
;end if
 
align 16
resampler_params:
;r_size r_dt resampler_func
dd 0,0,0 ; 0 PCM_ALL
dd 16384, 0, copy_stream ; 1 PCM_2_16_48
dd 8192, 0, m16_stereo ; 2 PCM_1_16_48
 
dd 16384, 30109, resample_2 ; 3 PCM_2_16_44
dd 8192, 30109, resample_1 ; 4 PCM_1_16_44
 
dd 16384, 21846, resample_2 ; 5 PCM_2_16_32
dd 8192, 21846, resample_1 ; 6 PCM_1_16_32
 
dd 16384, 16384, resample_2 ; 7 PCM_2_16_24
dd 8192, 16384, resample_1 ; 8 PCM_1_16_24
 
dd 8192, 15052, resample_2 ; 9 PCM_2_16_22
dd 4096, 15052, resample_1 ;10 PCM_1_16_22
 
dd 8192, 10923, resample_2 ;11 PCM_2_16_16
dd 4096, 10923, resample_1 ;12 PCM_1_16_16
 
dd 8192, 8192, resample_2 ;13 PCM_2_16_12
dd 4096, 8192, resample_1 ;14 PCM_1_16_12
 
dd 4096, 7527, resample_2 ;15 PCM_2_16_11
dd 2048, 7527, resample_1 ;16 PCM_1_16_11
 
dd 4096, 5462, resample_2 ;17 PCM_2_16_8
dd 2048, 5462, resample_1 ;18 PCM_1_16_8
 
dd 16384, 0, s8_stereo ;19 PCM_2_8_48
dd 8192, 0, m8_stereo ;20 PCM_1_8_48
 
dd 8192, 30109, resample_28 ;21 PCM_2_8_44
dd 4096, 30109, resample_18 ;22 PCM_1_8_44
 
dd 8192, 21846, resample_28 ;23 PCM_2_8_32
dd 4096, 21846, resample_18 ;24 PCM_1_8_32
 
dd 8192, 16384, resample_28 ;25 PCM_2_8_24
dd 4096, 16384, resample_18 ;26 PCM_1_8_24
 
dd 4096, 15052, resample_28 ;27 PCM_2_8_22
dd 2048, 15052, resample_18 ;28 PCM_1_8_22
 
dd 4096, 10923, resample_28 ;29 PCM_2_8_16
dd 2048, 10923, resample_18 ;30 PCM_1_8_16
 
dd 4096, 8192, resample_28 ;31 PCM_2_8_12
dd 2048, 8192, resample_18 ;32 PCM_1_8_12
 
dd 2048, 7527, resample_28 ;33 PCM_2_8_11
dd 1024, 7527, resample_18 ;34 PCM_1_8_11
 
dd 2048, 5462, resample_28 ;35 PCM_2_8_8
dd 1024, 5462, resample_18 ;36 PCM_1_8_8
 
m7 dw 0x8000,0x8000,0x8000,0x8000
mm80 dq 0x8080808080808080
mm_mask dq 0xFF00FF00FF00FF00
 
vol_max dd 0x00000000,0x00000000
vol_min dd 0x0000D8F0,0x0000D8F0
pan_max dd 0x00002710,0x00002710
 
;stream_map dd 0xFFFF ; 16
version dd (5 shl 16) or SOUND_VERSION
 
szInfinity db 'INFINITY',0
szSound db 'SOUND',0
 
if DEBUG
msgFail db 'Sound service not loaded',13,10,0
msgPlay db 'Play buffer',13,10,0
msgStop db 'Stop',13,10,0
msgUser db 'User callback',13,10,0
msgMem db 'Not enough memory',13,10,0
msgDestroy db 'Destroy sound buffer', 13,10,0
msgWaveout db 'Play waveout', 13,10,0
msgSetVolume db 'Set volume',13,10,0
end if
 
section '.data' data readable writable align 16
 
play_list rd 16
mix_input rd 16
play_count rd 1
hSound rd 1
eng_state rd 1
mix_buff rd 1
mix_buff_map rd 1
str.fd rd 1
str.bk rd 1
 
mix_2_core rd 1
mix_3_core rd 1
mix_4_core rd 1
 
 
 
 
 
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/tags/kolibri0.7.5.0/drivers/proc32.inc
0,0 → 1,268
 
; Macroinstructions for defining and calling procedures
 
macro stdcall proc,[arg] ; directly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call proc }
 
macro invoke proc,[arg] ; indirectly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call [proc] }
 
macro ccall proc,[arg] ; directly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
end if
call proc
if size@ccall
add esp,size@ccall
end if }
 
macro cinvoke proc,[arg] ; indirectly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
end if
call [proc]
if size@ccall
add esp,size@ccall
end if }
 
macro proc [args] ; define procedure
{ common
match name params, args>
\{ define@proc name,<params \} }
 
prologue@proc equ prologuedef
 
macro prologuedef procname,flag,parmbytes,localbytes,reglist
{ if parmbytes | localbytes
push ebp
mov ebp,esp
if localbytes
sub esp,localbytes
end if
end if
irps reg, reglist \{ push reg \} }
 
epilogue@proc equ epiloguedef
 
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
{ irps reg, reglist \{ reverse pop reg \}
if parmbytes | localbytes
leave
end if
if flag and 10000b
retn
else
retn parmbytes
end if }
 
macro define@proc name,statement
{ local params,flag,regs,parmbytes,localbytes,current
if used name
name:
match =stdcall args, statement \{ params equ args
flag = 11b \}
match =stdcall, statement \{ params equ
flag = 11b \}
match =c args, statement \{ params equ args
flag = 10001b \}
match =c, statement \{ params equ
flag = 10001b \}
match =params, params \{ params equ statement
flag = 0 \}
virtual at ebp+8
match =uses reglist=,args, params \{ regs equ reglist
params equ args \}
match =regs =uses reglist, regs params \{ regs equ reglist
params equ \}
match =regs, regs \{ regs equ \}
match =,args, params \{ defargs@proc args \}
match =args@proc args, args@proc params \{ defargs@proc args \}
parmbytes = $ - (ebp+8)
end virtual
name # % = parmbytes/4
all@vars equ
current = 0
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
macro locals
\{ virtual at ebp-localbytes+current
macro label . \\{ deflocal@proc .,:, \\}
struc db [val] \\{ \common deflocal@proc .,db,val \\}
struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
macro endl
\{ purge label
restruc db,dw,dp,dd,dt,dq
restruc rb,rw,rp,rd,rt,rq
restruc byte,word,dword,pword,tword,qword
current = $-(ebp-localbytes)
end virtual \}
macro ret operand
\{ match any, operand \\{ retn operand \\}
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs>
\\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2
end if \} }
 
macro defargs@proc [arg]
{ common
if ~ arg eq
forward
local ..arg,current@arg
match argname:type, arg
\{ current@arg equ argname
label ..arg type
argname equ ..arg
if dqword eq type
dd ?,?,?,?
else if tbyte eq type
dd ?,?,?
else if qword eq type | pword eq type
dd ?,?
else
dd ?
end if \}
match =current@arg,current@arg
\{ current@arg equ arg
arg equ ..arg
..arg dd ? \}
common
args@proc equ current@arg
forward
restore current@arg
common
end if }
 
macro deflocal@proc name,def,[val]
{ common
match vars, all@vars \{ all@vars equ all@vars, \}
all@vars equ all@vars name
forward
local ..var,..tmp
..var def val
match =?, val \{ ..tmp equ \}
match any =dup (=?), val \{ ..tmp equ \}
match tmp : value, ..tmp : val
\{ tmp: end virtual
initlocal@proc ..var,def value
virtual at tmp\}
common
match first rest, ..var, \{ name equ first \} }
 
macro initlocal@proc name,def
{ virtual at name
def
size@initlocal = $ - name
end virtual
position@initlocal = 0
while size@initlocal > position@initlocal
virtual at name
def
if size@initlocal - position@initlocal < 2
current@initlocal = 1
load byte@initlocal byte from name+position@initlocal
else if size@initlocal - position@initlocal < 4
current@initlocal = 2
load word@initlocal word from name+position@initlocal
else
current@initlocal = 4
load dword@initlocal dword from name+position@initlocal
end if
end virtual
if current@initlocal = 1
mov byte [name+position@initlocal],byte@initlocal
else if current@initlocal = 2
mov word [name+position@initlocal],word@initlocal
else
mov dword [name+position@initlocal],dword@initlocal
end if
position@initlocal = position@initlocal + current@initlocal
end while }
 
macro endp
{ purge ret,locals,endl
finish@proc
purge finish@proc
restore regs@proc
match all,args@proc \{ restore all \}
restore args@proc
match all,all@vars \{ restore all \} }
 
macro local [var]
{ common
locals
forward done@local equ
match varname[count]:vartype, var
\{ match =BYTE, vartype \\{ varname rb count
restore done@local \\}
match =WORD, vartype \\{ varname rw count
restore done@local \\}
match =DWORD, vartype \\{ varname rd count
restore done@local \\}
match =PWORD, vartype \\{ varname rp count
restore done@local \\}
match =QWORD, vartype \\{ varname rq count
restore done@local \\}
match =TBYTE, vartype \\{ varname rt count
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
rq count+count
restore done@local \\}
match , done@local \\{ virtual
varname vartype
end virtual
rb count*sizeof.\#vartype
restore done@local \\} \}
match :varname:vartype, done@local:var
\{ match =BYTE, vartype \\{ varname db ?
restore done@local \\}
match =WORD, vartype \\{ varname dw ?
restore done@local \\}
match =DWORD, vartype \\{ varname dd ?
restore done@local \\}
match =PWORD, vartype \\{ varname dp ?
restore done@local \\}
match =QWORD, vartype \\{ varname dq ?
restore done@local \\}
match =TBYTE, vartype \\{ varname dt ?
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
dq ?,?
restore done@local \\}
match , done@local \\{ varname vartype
restore done@local \\} \}
match ,done@local
\{ var
restore done@local \}
common
endl }
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/tags/kolibri0.7.5.0/drivers/ps2mouse.asm
0,0 → 1,270
format MS COFF
 
DEBUG equ 0
 
include 'proc32.inc'
include 'imports.inc'
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
public START
public version
 
DRV_ENTRY equ 1
DRV_EXIT equ -1
 
MT_3B equ 0
MT_3BScroll equ 1
MT_5BScroll equ 2
 
PS2_DRV_VER equ 1
 
section '.flat' code readable align 16
 
 
proc START stdcall, state:dword
 
cmp [state], DRV_ENTRY
jne .fin
.init:
 
call detect_mouse
test eax,eax
jnz .exit
 
mov [MouseType],MT_3B
 
call try_mode_ID3
test eax,eax
jnz .stop_try
mov [MouseType],MT_3BScroll
 
call try_mode_ID4
test eax,eax
jnz .stop_try
mov [MouseType],MT_5BScroll
 
.stop_try:
 
mov bl, 0x20 ; read command byte
call kbd_cmd
cmp ah,1
je .exit
 
call kbd_read
cmp ah,1
je .exit
 
or al, 10b
push eax
mov bl, 0x60 ; write command byte
call kbd_cmd
cmp ah,1
je .exit
 
pop eax
call kbd_write
cmp ah,1
je .exit
 
mov al, 0xF4 ; enable data reporting
call mouse_cmd
 
mov bl, 0xAE ; enable keyboard interface
call kbd_cmd
 
stdcall AttachIntHandler, 12, irq_handler, dword 0
stdcall RegService, my_service, service_proc
ret
 
.fin:
;stdcall DetachIntHandler, 12, irq_handler
mov bl, 0xA7 ; disable mouse interface
call kbd_cmd
xor eax, eax
ret
 
.exit:
mov bl, 0xA7 ; disable mouse interface
call kbd_cmd
mov bl, 0xAE ; enable keyboard interface
call kbd_cmd
xor eax, eax
ret
endp
 
proc service_proc stdcall, ioctl:dword
mov edi, [ioctl]
mov eax, [edi+IOCTL.io_code]
test eax, eax
jz .getversion
cmp eax,1
jz .gettype
 
.err:
or eax, -1
ret
 
.ok:
xor eax, eax
ret
 
.getversion:
cmp [edi+IOCTL.out_size], 4
jb .err
mov edi, [edi+IOCTL.output]
mov dword [edi], PS2_DRV_VER ; version of driver
jmp .ok
.gettype:
cmp [edi+IOCTL.out_size], 4
jb .err
mov edi, [edi+IOCTL.output]
mov eax,[MouseType]
mov dword [edi], eax ; mouse type
jmp .ok
endp
 
detect_mouse:
 
mov bl, 0xAD ; disable keyboard interface
call kbd_cmd
cmp ah,1
je .fail
 
mov bl, 0xA8 ; enable mouse interface
call kbd_cmd
cmp ah,1
je .fail
 
mov al, 0xFF ; reset
call mouse_cmd
jc .fail
 
call mouse_read
jc .fail
cmp al, 0xAA
jne .fail ; dead mouse
 
; get device ID
call mouse_read
jc .fail
cmp al, 0x00
jne .fail ; unknown device
xor eax,eax
ret
 
.fail:
or eax,-1
ret
 
try_mode_ID3:
mov al, 0xF3 ;Set Sample Rate
call mouse_cmd
jc .fail
mov al, 0xC8 ;200d
call mouse_cmd
jc .fail
mov al, 0xF3 ;Set Sample Rate
call mouse_cmd
jc .fail
mov al, 0x64 ;100d
call mouse_cmd
jc .fail
mov al, 0xF3 ;Set Sample Rate
call mouse_cmd
jc .fail
mov al, 0x50 ;80d
call mouse_cmd
jc .fail
 
mov al, 0xF2 ;Get device id
call mouse_cmd
jc .fail
 
call mouse_read
jc .fail
cmp al, 0x03
jne .fail
 
xor eax,eax
ret
.fail:
or eax,-1
ret
 
try_mode_ID4:
mov al, 0xF3 ;Set Sample Rate
call mouse_cmd
jc .fail
mov al, 0xC8 ;200d
call mouse_cmd
jc .fail
mov al, 0xF3 ;Set Sample Rate
call mouse_cmd
jc .fail
mov al, 0xC8 ;100d
call mouse_cmd
jc .fail
mov al, 0xF3 ;Set Sample Rate
call mouse_cmd
jc .fail
mov al, 0x50 ;80d
call mouse_cmd
jc .fail
 
mov al, 0xF2 ;Get device id
call mouse_cmd
jc .fail
 
call mouse_read
jc .fail
cmp al, 0x04
jne .fail
 
xor eax,eax
ret
 
.fail:
or eax,-1
ret
include 'ps2m_iofuncs.inc'
include 'ps2m_irqh.inc'
 
section '.data' data readable writable align 16
 
version dd 0x00050005
my_service db 'ps2mouse',0
 
;iofuncs data
mouse_cmd_byte db 0
mouse_nr_tries db 0
mouse_nr_resends db 0
 
;hid data
mouse_byte dd 0
 
first_byte db 0
second_byte db 0
third_byte db 0
fourth_byte db 0
 
;main data
MouseType dd 0
 
XMoving dd 0
YMoving dd 0
ZMoving dd 0
ButtonState dd 0
;timerTicks dd 0
/kernel/tags/kolibri0.7.5.0/drivers/sceletone.asm
0,0 → 1,177
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;driver sceletone
 
format MS COFF
 
DEBUG equ 1
 
API_VERSION equ 0 ;debug
 
include 'proc32.inc'
include 'imports.inc'
 
OS_BASE equ 0;
new_app_base equ 0x60400000
PROC_BASE equ OS_BASE+0x0080000
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
public START
public service_proc
public version
 
DRV_ENTRY equ 1
DRV_EXIT equ -1
STRIDE equ 4 ;size of row in devices table
 
SRV_GETVERSION equ 0
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .exit
.entry:
 
if DEBUG
mov esi, msgInit
call SysMsgBoardStr
end if
 
stdcall RegService, my_service, service_proc
ret
.fail:
.exit:
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 ebx, [ioctl]
mov eax, [ebx+io_code]
cmp eax, SRV_GETVERSION
jne @F
 
mov eax, [ebx+output]
cmp [ebx+out_size], 4
jne .fail
mov [eax], dword API_VERSION
xor eax, eax
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 detect
locals
last_bus 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, STRIDE
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:
xor eax, eax
inc eax
ret
.err:
xor eax, eax
ret
endp
 
DEVICE_ID equ 1234; pci device id
VENDOR_ID equ 5678; device vendor id
 
 
;all initialized data place here
 
align 4
devices dd (DEVICE_ID shl 16)+VENDOR_ID
dd 0 ;terminator
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
my_service db 'MY_SERVICE',0 ;max 16 chars include zero
 
msgInit db 'detect hardware...',13,10,0
msgPCI db 'PCI accsess not supported',13,10,0
msgFail db 'device not found',13,10,0
 
section '.data' data readable writable align 16
 
;all uninitialized data place here
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/tags/kolibri0.7.5.0/drivers/sis.asm
0,0 → 1,1307
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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
DEBUG_IRQ equ 0
 
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
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 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
 
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
 
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 reset_controller
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
;remap IRQ
stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE
 
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, 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
 
if DEBUG_IRQ
mov esi, msgIRQ
call SysMsgBoardStr
end if
 
mov edx, PCM_OUT_CR_REG
mov al, 0x10
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, 0x11
call [ctrl.ctrl_write8]
 
mov eax, [civ_val]
add eax, 1
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, 0x11
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 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 eax, pcmout_bdl
mov ebx, eax
call GetPgAddr ;eax
and ebx, 0xFFF
add eax, ebx
 
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
 
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, msgMixIsaIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
 
call dword2str
call SysMsgBoardStr
 
and eax,0xFFFE
mov [ctrl.codec_io_base], eax
 
mov esi, msgCtrlIsaIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14
 
call dword2str
call SysMsgBoardStr
 
and eax, 0xFFC0
mov [ctrl.ctrl_io_base], eax
 
mov esi, msgMixMMIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18
mov [ctrl.codec_mem_base], eax
 
call dword2str
call SysMsgBoardStr
 
mov esi, msgCtrlMMIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C
mov [ctrl.ctrl_mem_base], eax
 
call dword2str
call SysMsgBoardStr
.default:
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
 
mov esi, msgControl
call SysMsgBoardStr
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
call dword2str
call SysMsgBoardStr
 
mov esi, msgStatus
call SysMsgBoardStr
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
push eax
call dword2str
call SysMsgBoardStr
pop eax
cmp eax, 0xFFFFFFFF
je .err
 
test eax, CTRL_ST_CREADY
jnz .done ;;;;;.ready
 
call reset_codec
test eax, eax
jz .err
 
.ready:
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 eax, 5000 ; wait 5 ms
call StallExec
 
mov edx, CODEC_REG_POWERDOWN
call [ctrl.codec_read16]
and eax, 0x0F
cmp eax, 0x0F
je .done
 
sub [counter] , 1
jnz .wait
.err:
xor eax, eax ; timeout error
ret
.done:
mov eax, 2 ;force set 16-bit 2-channel PCM
mov edx, GLOB_CTRL
call [ctrl.ctrl_write32]
mov eax, 5000 ; wait 5 ms
call StallExec
 
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, CTRL_STAT
call [ctrl.ctrl_read32]
test eax, CTRL_ST_CREADY
jnz .ok
 
dec [counter]
jnz .wait
 
if DEBUG
mov esi, msgWRFail
call SysMsgBoardStr
end if
.fail:
stc
ret
.ok:
clc
ret
endp
 
align 4
proc cold_reset
locals
counter dd ?
endl
 
mov eax, 0x02
mov edx, GLOB_CTRL
call [ctrl.ctrl_write32]
 
if DEBUG
mov esi, msgCold
call SysMsgBoardStr
end if
 
mov eax, 400000 ; wait 400 ms
call StallExec
 
mov [counter], 16 ; total 20*100 ms = 2s
.wait:
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
test eax, CTRL_ST_CREADY
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
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
call dword2str
call SysMsgBoardStr
 
mov esi, msgStatus
call SysMsgBoardStr
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
push eax
call dword2str
call SysMsgBoardStr
pop eax
 
test eax, CTRL_ST_CREADY
jz .fail
clc
ret
endp
 
align 4
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]
xor eax, eax
ret
 
align 4
stop:
mov edx, PCM_OUT_CR_REG
mov ax, 0x0
call [ctrl.ctrl_write8]
 
mov ax, 0x1c
mov edx, PCM_OUT_SR_REG
call [ctrl.ctrl_write16]
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 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
.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
js @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
 
align 4
dword2str:
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
ret
 
hexletters db '0123456789ABCDEF'
hex_buff db 8 dup(0),13,10,0
 
include "codec.inc"
 
align 4
devices dd (CTRL_SIS shl 16)+VID_SIS,msg_AC, set_SIS
dd 0
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
msg_AC db '7012 AC97 controller',13,10, 0
msg_SIS db 'Silicon Integrated Systems',13,10, 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
;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 ...',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
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
 
lpc_bus rd 1
civ_val rd 1
/kernel/tags/kolibri0.7.5.0/drivers/sound.asm
0,0 → 1,1473
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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
 
DEBUG_IRQ equ 0
 
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
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
 
PCM_4 equ BIT20
PCM_6 equ BIT21
 
VID_INTEL equ 0x8086
VID_NVIDIA equ 0x10DE
 
CTRL_ICH equ 0x2415
CTRL_ICH0 equ 0x2425
CTRL_ICH2 equ 0x2435
CTRL_ICH3 equ 0x2445
CTRL_ICH4 equ 0x24C5
CTRL_ICH5 equ 0x24D5
CTRL_ICH6 equ 0x266E
CTRL_ICH7 equ 0x27DE
 
CTRL_NFORCE equ 0x01B1
CTRL_NFORCE2 equ 0x006A
CTRL_NFORCE3 equ 0x00DA
CTRL_MCP04 equ 0x003A
CTRL_CK804 equ 0x0059
CTRL_CK8 equ 0x008A
CTRL_CK8S equ 0x00EA
CTRL_MCP51 equ 0x026B
 
 
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 0x16 ; PCM out Status register
PCM_OUT_PIV_REG equ 0x1a
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 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
 
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
 
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 reset_controller
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
;remap IRQ
stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE
 
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, 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
 
if DEBUG_IRQ
mov esi, msgIRQ
call SysMsgBoardStr
end if
 
mov edx, PCM_OUT_CR_REG
mov al, 0x10; 0x10
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, 0x11 ;0x1D
call [ctrl.ctrl_write8]
 
mov eax, [civ_val]
add eax, 1
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, 0x11 ;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
cld
rep stosd
 
mov eax, [ctrl.buffer]
call GetPgAddr
 
mov ebx, 0xC0002000
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 eax, pcmout_bdl
mov ebx, eax
call GetPgAddr ;eax
and ebx, 0xFFF
add eax, ebx
 
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]
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_INTEL
jne @F
mov [ctrl.vendor_ids], msg_Intel
ret
@@:
cmp edx, VID_NVIDIA
jne @F
mov [ctrl.vendor_ids], msg_NVidia
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, msgMixIsaIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
 
call dword2str
call SysMsgBoardStr
 
and eax,0xFFFE
mov [ctrl.codec_io_base], eax
 
mov esi, msgCtrlIsaIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14
 
call dword2str
call SysMsgBoardStr
 
and eax, 0xFFC0
mov [ctrl.ctrl_io_base], eax
 
mov esi, msgMixMMIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18
mov [ctrl.codec_mem_base], eax
 
call dword2str
call SysMsgBoardStr
 
mov esi, msgCtrlMMIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C
mov [ctrl.ctrl_mem_base], eax
 
call dword2str
call SysMsgBoardStr
 
if 0
 
;;patch for some ugly BIOS ICH-ICH5 compatible
cmp [ctrl.vendor], VID_INTEL
jne .default
 
mov esi, msgIrqMap
call SysMsgBoardStr
stdcall PciRead8, 0, 0xF8, 0x61
and eax, 0xFF
call dword2str
call SysMsgBoardStr
btr eax, 7 ;when bit 7 set remap disabled
jnc @F
xor eax, eax
jmp @F
end if
 
.default:
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_ICH
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
 
PG_SW equ 0x003
PG_NOCACHE equ 0x018
 
align 4
proc set_ICH4
 
stdcall MapIoMem,[ctrl.codec_mem_base],0x1000,PG_SW+PG_NOCACHE
mov [ctrl.codec_mem_base], eax
 
stdcall MapIoMem,[ctrl.ctrl_mem_base],0x1000,PG_SW+PG_NOCACHE
mov [ctrl.ctrl_mem_base], eax
 
mov [ctrl.codec_read16], codec_mem_r16 ;virtual
mov [ctrl.codec_write16], codec_mem_w16 ;virtual
 
mov [ctrl.ctrl_read8 ], ctrl_mem_r8 ;virtual
mov [ctrl.ctrl_read16], ctrl_mem_r16 ;virtual
mov [ctrl.ctrl_read32], ctrl_mem_r32 ;virtual
 
mov [ctrl.ctrl_write8 ], ctrl_mem_w8 ;virtual
mov [ctrl.ctrl_write16], ctrl_mem_w16 ;virtual
mov [ctrl.ctrl_write32], ctrl_mem_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
 
mov esi, msgControl
call SysMsgBoardStr
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
call dword2str
call SysMsgBoardStr
 
mov esi, msgStatus
call SysMsgBoardStr
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
push eax
call dword2str
call SysMsgBoardStr
pop eax
cmp eax, 0xFFFFFFFF
je .err
 
test eax, CTRL_ST_CREADY
jnz .ready
 
call reset_codec
test eax, eax
jz .err
 
.ready:
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 eax, 5000 ; wait 5 ms
call StallExec
 
mov edx, CODEC_REG_POWERDOWN
call [ctrl.codec_read16]
and eax, 0x0F
cmp eax, 0x0F
jz .done
 
sub [counter] , 1
jnz .wait
.err:
xor eax, eax ; timeout error
ret
.done:
mov eax, 2 ;force set 16-bit 2-channel PCM
mov edx, GLOB_CTRL
call [ctrl.ctrl_write32]
mov eax, 5000 ; wait 5 ms
call StallExec
 
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:
if DEBUG
mov esi, msgResetOk
call SysMsgBoardStr
end if
 
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, CTRL_STAT
call [ctrl.ctrl_read32]
test eax, CTRL_ST_CREADY
jnz .ok
 
dec [counter]
jnz .wait
 
if DEBUG
mov esi, msgWRFail
call SysMsgBoardStr
end if
.fail:
stc
ret
.ok:
clc
ret
endp
 
align 4
proc cold_reset
locals
counter dd ?
endl
 
mov eax, 0x02
mov edx, GLOB_CTRL
call [ctrl.ctrl_write32]
 
if DEBUG
mov esi, msgCold
call SysMsgBoardStr
end if
 
mov eax, 400000 ; wait 400 ms
call StallExec
 
mov [counter], 16 ; total 20*100 ms = 2s
.wait:
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
test eax, CTRL_ST_CREADY
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
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
call dword2str
call SysMsgBoardStr
 
mov esi, msgStatus
call SysMsgBoardStr
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
push eax
call dword2str
call SysMsgBoardStr
pop eax
 
test eax, CTRL_ST_CREADY
jz .fail
clc
ret
endp
 
align 4
play:
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]
xor eax, eax
ret
 
align 4
stop:
mov edx, PCM_OUT_CR_REG
mov ax, 0x0
call [ctrl.ctrl_write8]
 
mov ax, 0x1c
mov edx, PCM_OUT_SR_REG
call [ctrl.ctrl_write16]
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 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
.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
js @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
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; MEMORY MAPPED IO (os depended)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
proc codec_mem_r16
add edx, [ctrl.codec_mem_base]
mov ax, word [edx]
ret
endp
 
align 4
proc codec_mem_w16
add edx, [ctrl.codec_mem_base]
mov word [edx], ax
ret
endp
 
align 4
proc ctrl_mem_r8
add edx, [ctrl.ctrl_mem_base]
mov al, [edx]
ret
endp
 
align 4
proc ctrl_mem_r16
add edx, [ctrl.ctrl_mem_base]
mov ax, [edx]
ret
endp
 
align 4
proc ctrl_mem_r32
add edx, [ctrl.ctrl_mem_base]
mov eax, [edx]
ret
endp
 
align 4
proc ctrl_mem_w8
add edx, [ctrl.ctrl_mem_base]
mov [edx], al
ret
endp
 
align 4
proc ctrl_mem_w16
add edx, [ctrl.ctrl_mem_base]
mov [edx], ax
ret
endp
 
align 4
proc ctrl_mem_w32
add edx, [ctrl.ctrl_mem_base]
mov [edx], eax
ret
endp
 
align 4
dword2str:
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
ret
 
hexletters db '0123456789ABCDEF'
hex_buff db 8 dup(0),13,10,0
 
 
include "codec.inc"
 
align 4
devices dd (CTRL_ICH shl 16)+VID_INTEL,msg_ICH, set_ICH
dd (CTRL_ICH0 shl 16)+VID_INTEL,msg_ICH0,set_ICH
dd (CTRL_ICH2 shl 16)+VID_INTEL,msg_ICH2,set_ICH
dd (CTRL_ICH3 shl 16)+VID_INTEL,msg_ICH3,set_ICH
dd (CTRL_ICH4 shl 16)+VID_INTEL,msg_ICH4,set_ICH4
dd (CTRL_ICH5 shl 16)+VID_INTEL,msg_ICH5,set_ICH4
dd (CTRL_ICH6 shl 16)+VID_INTEL,msg_ICH6,set_ICH4
dd (CTRL_ICH7 shl 16)+VID_INTEL,msg_ICH7,set_ICH4
 
dd (CTRL_NFORCE shl 16)+VID_NVIDIA,msg_NForce, set_ICH
dd (CTRL_NFORCE2 shl 16)+VID_NVIDIA,msg_NForce2,set_ICH
dd (CTRL_NFORCE3 shl 16)+VID_NVIDIA,msg_NForce3,set_ICH
dd (CTRL_MCP04 shl 16)+VID_NVIDIA,msg_MCP04,set_ICH
dd (CTRL_CK804 shl 16)+VID_NVIDIA,msg_CK804,set_ICH
dd (CTRL_CK8 shl 16)+VID_NVIDIA,msg_CK8,set_ICH
dd (CTRL_CK8S shl 16)+VID_NVIDIA,msg_CK8S,set_ICH
dd (CTRL_MCP51 shl 16)+VID_NVIDIA,msg_MCP51,set_ICH
 
dd 0 ;terminator
 
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
msg_ICH db '802801AA (ICH)', 13,10, 0
msg_ICH0 db '802801AB (ICH0)', 13,10, 0
msg_ICH2 db '802801BA (ICH2)', 13,10, 0
msg_ICH3 db '802801CA (ICH3)', 13,10, 0
msg_ICH4 db '802801DB (ICH4)', 13,10, 0
msg_ICH5 db '802801EB (ICH5)', 13,10, 0
msg_ICH6 db '802801FB (ICH6)', 13,10, 0
msg_ICH7 db '802801GB (ICH7)', 13,10, 0
msg_Intel db 'Intel ', 0
 
msg_NForce db 'NForce', 13,10, 0
msg_NForce2 db 'NForce 2', 13,10, 0
msg_NForce3 db 'NForce 3', 13,10, 0
msg_MCP04 db 'NForce MCP04',13,10, 0
msg_CK804 db 'NForce CK804',13,10, 0
msg_CK8 db 'NForce CK8', 13,10, 0
msg_CK8S db 'NForce CK8S', 13,10, 0
msg_MCP51 db 'NForce MCP51',13,10, 0
 
msg_NVidia db 'NVidia', 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
;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 ...',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
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
 
lpc_bus rd 1
civ_val rd 1
/kernel/tags/kolibri0.7.5.0/drivers/mixer.asm
0,0 → 1,1263
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2006-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; (C) copyright Serge 2006
; email: infinity_sound@mail.ru
 
 
align 4
 
mix_list rd 32*3
 
align 4
proc new_mix stdcall, output:dword
locals
main_count rd 1
fpu_state rb 528 ;512+16
endl
 
mov [main_count], 32
call prepare_playlist
cmp [play_count], 0
je .clear
 
lea eax, [fpu_state+16]
and eax, -16 ;must be 16b aligned
call FpuSave
 
call update_stream
.mix:
lea eax, [mix_list]
call do_mix_list
test eax, eax
je .done
 
if USE_SSE2_MIXER
 
cmp eax, 1
ja @F
;use fast path
mov edi, [output]
lea edx, [mix_list]
call mix_fast
jmp .next
@@:
cmp eax, 2
ja @F
 
mov edi, [output]
lea edx, [mix_list]
call mix_fast_2_stream
jmp .next
@@:
 
end if
 
lea ebx, [mix_list]
stdcall mix_all, [output], ebx, eax
.next:
add [output], 512
dec [main_count]
jnz .mix
.exit:
lea eax, [fpu_state+16]
and eax, -16
call FpuRestore
ret
.done:
mov ecx, [main_count]
shl ecx, 7 ;ecx*= 512/4
 
mov edi, [output]
xor eax, eax
cld
rep stosd
jmp .exit
.clear:
mov edi, [output]
mov ecx, 4096
xor eax, eax
cld
rep stosd
ret
endp
 
align 4
proc update_stream
locals
stream_index dd ?
event rd 6
endl
 
mov [stream_index], 0
.l1:
mov edx, [stream_index]
mov esi, [play_list+edx*4]
 
mov eax, [esi+STREAM.out_rp]
cmp eax, [esi+STREAM.out_top]
jb @f
sub eax, 64*1024
@@:
mov [esi+STREAM.out_rp], eax
 
cmp [esi+STREAM.out_count], 16384
ja .skip
 
test [esi+STREAM.format], PCM_RING
jnz .ring
 
stdcall refill, esi
.skip:
inc [stream_index]
dec [play_count]
jnz .l1
ret
.ring:
stdcall refill_ring, esi
jmp .skip
endp
 
align 4
proc refill stdcall, str:dword
locals
r_size rd 1
endl
 
mov ebx, [str]
mov edi, [ebx+STREAM.out_wp]
cmp edi, [ebx+STREAM.out_top]
jb @F
sub edi, 0x10000
mov [ebx+STREAM.out_wp], edi
@@:
mov eax, [ebx+STREAM.in_count]
test eax, eax
jz .done
 
mov ecx, [ebx+STREAM.r_size]
cmp eax, ecx
jle @F
 
mov eax, ecx
@@:
mov ecx, eax
cmp word [ebx+STREAM.format], PCM_1_16_8
ja @F
 
shr eax, 1 ;two channles
@@:
test [ebx+STREAM.format], 1 ;even formats mono
jz @F
 
shr eax, 1 ;eax= samples
@@:
shl eax, 15 ;eax*=32768 =r_end
 
mov [r_size], ecx
 
mov esi, [ebx+STREAM.in_rp]
mov edi, [ebx+STREAM.out_wp]
 
stdcall [ebx+STREAM.resample], edi, esi, \
[ebx+STREAM.r_dt], ecx, eax
 
mov ebx, [str]
 
add [ebx+STREAM.out_count], eax;
add [ebx+STREAM.out_wp], eax;
 
mov eax, [ebx+STREAM.in_rp]
mov ecx, [r_size]
add eax, ecx
add [ebx+STREAM.in_free], ecx
sub [ebx+STREAM.in_count], ecx
 
cmp eax, [ebx+STREAM.in_top]
jb @f
 
sub eax, [ebx+STREAM.in_size]
@@:
mov [ebx+STREAM.in_rp], eax
 
.done:
mov eax, [ebx+STREAM.notify_event]
test eax, eax
jz .exit
 
mov ebx, [ebx+STREAM.notify_id]
mov ecx, EVENT_WATCHED
xor edx, edx
call RaiseEvent ;eax, ebx, ecx, edx
.exit:
ret
endp
 
align 4
proc refill_ring stdcall, str:dword
locals
event rd 6
endl
 
mov ebx, [str]
mov edi, [ebx+STREAM.out_wp]
cmp edi, [ebx+STREAM.out_top]
jb @F
sub edi, 0x10000
mov [ebx+STREAM.out_wp], edi
@@:
mov ecx, [ebx+STREAM.r_size]
mov eax, ecx
cmp word [ebx+STREAM.format], PCM_1_16_8
ja @F
 
shr eax, 1 ;two channles
@@:
test [ebx+STREAM.format], 1 ;even formats mono
jz @F
 
shr eax, 1 ;eax= samples
@@:
shl eax, 15 ;eax*=32768 =r_end
 
mov esi, [ebx+STREAM.in_rp]
mov edi, [ebx+STREAM.out_wp]
 
stdcall [ebx+STREAM.resample], edi, esi, \
[ebx+STREAM.r_dt], ecx, eax
 
mov ebx, [str]
 
add [ebx+STREAM.out_count], eax;
add [ebx+STREAM.out_wp], eax;
 
mov eax, [ebx+STREAM.in_rp]
mov ecx, [ebx+STREAM.r_size]
add eax, ecx
add [ebx+STREAM.in_free], ecx
sub [ebx+STREAM.in_count], ecx
 
cmp eax, [ebx+STREAM.in_top]
jb @f
 
sub eax, [ebx+STREAM.in_size]
@@:
mov [ebx+STREAM.in_rp], eax
 
sub eax, [ebx+STREAM.in_base]
sub eax, 128
lea edx, [event]
 
mov dword [edx], RT_INP_EMPTY
mov dword [edx+4], 0
mov dword [edx+8], ebx
mov dword [edx+12], eax
 
mov eax, [ebx+STREAM.notify_event]
test eax, eax
jz .exit
 
mov ebx, [ebx+STREAM.notify_id]
xor ecx, ecx
call RaiseEvent ;eax, ebx, ecx, edx
.exit:
ret
endp
 
if USE_SSE2_MIXER
 
align 4
proc mix_all stdcall, dest:dword, list:dword, count:dword
 
mov edi, [dest]
mov ebx, 32
.mix:
mov edx, [list]
mov ecx, [count]
 
mov eax, [edx]
 
movdqa xmm1, [eax]
movss xmm2, [edx+4]
movss xmm3, [edx+8]
 
punpcklwd xmm0, xmm1
punpckhwd xmm1, xmm1
 
shufps xmm2, xmm3, 0
shufps xmm2, xmm2, 0x88
 
psrad xmm0, 16
psrad xmm1, 16
cvtdq2ps xmm0, xmm0
cvtdq2ps xmm1, xmm1
mulps xmm0, xmm2
mulps xmm1, xmm2
 
.mix_loop:
add dword [edx], 16
add edx, 12
dec ecx
jz @F
 
mov eax, [edx]
 
movdqa xmm3, [eax]
movss xmm4, [edx+4]
movss xmm5, [edx+8]
 
punpcklwd xmm2, xmm3
punpckhwd xmm3, xmm3
 
shufps xmm4, xmm5, 0
shufps xmm4, xmm4, 0x88
 
psrad xmm2, 16
psrad xmm3, 16
 
cvtdq2ps xmm2, xmm2
cvtdq2ps xmm3, xmm3
 
mulps xmm2, xmm4
mulps xmm3, xmm4
addps xmm0, xmm2
addps xmm1, xmm3
 
jmp .mix_loop
@@:
cvtps2dq xmm0, xmm0
cvtps2dq xmm1, xmm1
packssdw xmm0, xmm0
packssdw xmm1, xmm1
punpcklqdq xmm0, xmm1
movntdq [edi], xmm0
 
add edi, 16
dec ebx
jnz .mix
 
ret
endp
 
; param
; edi = dest
; edx = mix_list
 
align 4
mix_fast:
 
mov ebx, 32
mov eax, [edx]
 
movss xmm2, [edx+4] ; vol Lf
movss xmm3, [edx+8] ; vol Rf
shufps xmm2, xmm3, 0 ; Rf Rf Lf Lf
shufps xmm2, xmm2, 0x88 ; volume level Rf Lf Rf Lf
.mix:
movdqa xmm1, [eax] ; R3w L3w R2w L2w R1w L1w R0w L0w
add eax, 16
punpcklwd xmm0, xmm1 ; R1w R1w L1w L1W R0w R0w L0w L0w
punpckhwd xmm1, xmm1 ; R3w R3w L3w L3w R2w R2w L2w L2w
 
psrad xmm0, 16 ; R1d L1d R0d L0d
psrad xmm1, 16 ; R3d L3d R2d L2d
 
cvtdq2ps xmm0, xmm0 ; time to use all power
cvtdq2ps xmm1, xmm1 ; of the dark side
 
mulps xmm0, xmm2 ; R1f' L1f' R0f' L0f'
mulps xmm1, xmm2 ; R3f' L3f' R2f' L2f'
 
cvtps2dq xmm0, xmm0 ; R1d' L1d' R0d' L0d'
cvtps2dq xmm1, xmm1 ; R3d' L3d' R2d' L2d'
packssdw xmm0, xmm0 ; R1w' L1w' R0w' L0w' R1w' L1w' R0w' L0w'
packssdw xmm1, xmm1 ; R3w' L3w' R2w' L2w' R3w' L3w' R2w' L2w'
punpcklqdq xmm0, xmm1 ; R3w' L3w' R2w' L2w' R1w' L1w' R0w' L0w'
movntdq [edi], xmm0
 
add edi, 16
dec ebx
jnz .mix
 
ret
 
align 4
mix_fast_2_stream:
 
mov ebx, 32
mov eax, [edx]
 
movss xmm4, [edx+4] ; vol Lf
movss xmm5, [edx+8] ; vol Rf
mov ecx, [edx+12]
 
movss xmm6, [edx+16] ; vol Lf
movss xmm7, [edx+20] ; vol Rf
 
shufps xmm4, xmm5, 0 ; Rf Rf Lf Lf
shufps xmm4, xmm4, 0x88 ; volume level Rf Lf Rf Lf
 
shufps xmm6, xmm7, 0 ; Rf Rf Lf Lf
shufps xmm6, xmm6, 0x88 ; volume level Rf Lf Rf Lf
 
.mix:
movdqa xmm1, [eax] ; R3w L3w R2w L2w R1w L1w R0w L0w
movdqa xmm3, [ecx] ; R3w L3w R2w L2w R1w L1w R0w L0w
 
add eax, 16
add ecx, 16
 
punpcklwd xmm0, xmm1 ; R1w R1w L1w L1W R0w R0w L0w L0w
punpckhwd xmm1, xmm1 ; R3w R3w L3w L3w R2w R2w L2w L2w
 
psrad xmm0, 16 ; R1d L1d R0d L0d
psrad xmm1, 16 ; R3d L3d R2d L2d
 
cvtdq2ps xmm0, xmm0 ; time to use all power
cvtdq2ps xmm1, xmm1 ; of the dark side
 
mulps xmm0, xmm4 ; R1f' L1f' R0f' L0f'
mulps xmm1, xmm4 ; R3f' L3f' R2f' L2f'
 
punpcklwd xmm2, xmm3 ; R1w R1w L1w L1W R0w R0w L0w L0w
punpckhwd xmm3, xmm3 ; R3w R3w L3w L3w R2w R2w L2w L2w
 
psrad xmm2, 16 ; R1d L1d R0d L0d
psrad xmm3, 16 ; R3d L3d R2d L2d
 
cvtdq2ps xmm2, xmm2 ; time to use all power
cvtdq2ps xmm3, xmm3 ; of the dark side
 
mulps xmm2, xmm6 ; R1f' L1f' R0f' L0f'
mulps xmm3, xmm6 ; R3f' L3f' R2f' L2f'
 
addps xmm0, xmm2
addps xmm1, xmm3
 
cvtps2dq xmm0, xmm0 ; R1d' L1d' R0d' L0d'
cvtps2dq xmm1, xmm1 ; R3d' L3d' R2d' L2d'
packssdw xmm0, xmm0 ; R1w' L1w' R0w' L0w' R1w' L1w' R0w' L0w'
packssdw xmm1, xmm1 ; R3w' L3w' R2w' L2w' R3w' L3w' R2w' L2w'
punpcklqdq xmm0, xmm1 ; R3w' L3w' R2w' L2w' R1w' L1w' R0w' L0w'
movntdq [edi], xmm0
 
add edi, 16
dec ebx
jnz .mix
 
ret
 
else ; fixed point mmx version
 
align 4
proc mix_all stdcall, dest:dword, list:dword, count:dword
 
mov edi, [dest]
mov ebx, 64
.mix:
mov edx, [list]
mov ecx, [count]
 
mov eax, [edx]
 
movq mm0, [eax]
 
movd mm1, [edx+4]
punpckldq mm1,mm1
pmulhw mm0, mm1
psllw mm0, 1
 
.mix_loop:
add dword [edx], 8
add edx, 12
dec ecx
jz @F
 
mov eax, [edx]
movq mm1, [eax]
movd mm2, [edx+4]
punpckldq mm2,mm2
pmulhw mm1, mm2
psllw mm1, 1
paddsw mm0, mm1
jmp .mix_loop
@@:
movq [edi], mm0
add edi, 8
dec ebx
jnz .mix
 
ret
endp
 
end if
 
 
align 4
proc resample_1 stdcall, dest:dword,src:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
; dest equ esp+8
; src equ esp+12
; r_dt equ esp+16
; r_size equ esp+20
; r_end equ esp+24
 
mov edi, [dest]
mov edx, [src]
sub edx, 32*2
mov eax, 16
 
align 4
.l1:
mov ecx, eax
mov esi, eax
and ecx, 0x7FFF
shr esi, 15
lea esi, [edx+esi*2]
 
movsx ebp, word [esi]
movsx esi, word [esi+2]
mov ebx, 32768
imul esi, ecx
sub ebx, ecx
imul ebx, ebp
lea ecx, [ebx+esi+16384]
sar ecx, 15
cmp ecx, 32767 ; 00007fffH
jle @f
mov ecx, 32767 ; 00007fffH
jmp .write
@@:
cmp ecx, -32768 ; ffff8000H
jge .write
mov ecx, -32768 ; ffff8000H
.write:
mov ebx, ecx
shl ebx, 16
mov bx, cx
mov [edi], ebx
add edi, 4
 
add eax, [esp+16]
cmp eax, [esp+24]
jb .l1
 
mov ebp, esp
 
sub edi, [dest]
mov eax, edi
ret
endp
 
align 4
proc resample_18 stdcall, dest:dword,src:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
 
mov edi, [dest]
mov edx, [src]
sub edx, 32
 
mov esi, 16
 
align 4
.l1:
mov ecx, esi
mov eax, esi
and ecx, 0x7FFF
shr eax, 15
lea eax, [edx+eax]
 
mov bx, word [eax]
sub bh, 0x80
sub bl, 0x80
movsx eax, bh
shl eax,8
movsx ebp, bl
shl ebp,8
mov ebx, 32768
imul eax, ecx
sub ebx, ecx
imul ebx, ebp
lea ecx, [ebx+eax+16384]
sar ecx, 15
cmp ecx, 32767 ; 00007fffH
jle @f
mov ecx, 32767 ; 00007fffH
jmp .write
@@:
cmp ecx, -32768 ; ffff8000H
jge .write
mov ecx, -32768 ; ffff8000H
.write:
mov ebx, ecx
shl ebx, 16
mov bx, cx
mov [edi], ebx
add edi, 4
 
add esi, [esp+16]
cmp esi, [esp+24]
jb .l1
 
mov ebp, esp
sub edi, [dest]
mov eax, edi
ret
endp
 
align 4
proc copy_stream stdcall, dest:dword,src:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
mov ecx, [r_size]
mov eax, ecx
shr ecx, 2
mov esi, [src]
mov edi, [dest]
cld
rep movsd
ret
endp
 
align 4
proc resample_2 stdcall, dest:dword,src:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
mov edx, [src]
sub edx, 32*4
mov edi, [dest]
mov ebx, [r_dt]
mov eax, 16
emms
 
align 4
.l1:
mov ecx, eax
mov esi, eax
and ecx, 0x7FFF
shr esi, 15
lea esi, [edx+esi*4]
 
movq mm0, [esi]
movq mm1, mm0
 
movd mm2, ecx
punpcklwd mm2, mm2
movq mm3, qword [m7] ;0x8000
 
psubw mm3, mm2 ; ;0x8000 - iconst
punpckldq mm3, mm2
 
pmulhw mm0, mm3
pmullw mm1, mm3
 
movq mm4, mm1
punpcklwd mm1, mm0
punpckhwd mm4, mm0
paddd mm1, mm4
psrad mm1, 15
packssdw mm1, mm1
movd [edi], mm1
add edi, 4
 
add eax, ebx
cmp eax, [r_end]
jb .l1
emms
 
sub edi, [dest]
mov eax, edi
ret
endp
 
align 4
proc resample_28 stdcall, dest:dword,src:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
mov edx, [src]
sub edx, 32*2
mov edi, [dest]
mov ebx, [r_dt]
mov eax, 16
emms
movq mm7,[mm80]
movq mm6,[mm_mask]
 
align 4
.l1:
mov ecx, eax
mov esi, eax
and ecx, 0x7FFF
shr esi, 15
lea esi, [edx+esi*2]
 
movq mm0, [esi]
psubb mm0,mm7
punpcklbw mm0,mm0
pand mm0,mm6
 
movq mm1, mm0
 
movd mm2, ecx
punpcklwd mm2, mm2
movq mm3, qword [m7] ; // 0x8000
 
psubw mm3, mm2 ; // 0x8000 - iconst
punpckldq mm3, mm2
 
pmulhw mm0, mm3
pmullw mm1, mm3
 
movq mm4, mm1
punpcklwd mm1, mm0
punpckhwd mm4, mm0
paddd mm1, mm4
psrad mm1, 15
packssdw mm1, mm1
movd [edi], mm1
add edi, 4
 
add eax, ebx
cmp eax, [r_end]
jb .l1
emms
 
 
sub edi, [dest]
mov eax, edi
ret
endp
 
 
proc m16_stereo stdcall, dest:dword,src:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
mov esi, [src]
mov edi, [dest]
mov ecx, [r_size]
shr ecx,8
@@:
call m16_s_mmx
add edi, 128
add esi, 64
call m16_s_mmx
add edi, 128
add esi, 64
call m16_s_mmx
add edi, 128
add esi, 64
call m16_s_mmx
add edi, 128
add esi, 64
dec ecx
jnz @b
 
mov eax, [r_size]
add eax, eax
ret
endp
 
align 4
proc s8_stereo stdcall, dest:dword,src:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
mov esi, [src]
mov edi, [dest]
mov ecx, [r_size]
shr ecx, 7
 
movq mm7, [mm80]
movq mm6, [mm_mask]
@@:
call s8_s_mmx
add edi, 64
add esi, 32
call s8_s_mmx
add edi, 64
add esi, 32
call s8_s_mmx
add edi, 64
add esi, 32
call s8_s_mmx
add edi, 64
add esi, 32
dec ecx
jnz @b
 
mov eax, [r_size]
add eax, eax
ret
endp
 
proc m8_stereo stdcall, dest:dword,src:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
mov esi, [src]
mov edi, [dest]
mov ecx, [r_size]
shr ecx, 6
 
movq mm7, [mm80]
movq mm6, [mm_mask]
@@:
call m8_s_mmx
add edi, 64
add esi, 16
call m8_s_mmx
add edi, 64
add esi, 16
call m8_s_mmx
add edi, 64
add esi, 16
call m8_s_mmx
add edi, 64
add esi, 16
dec ecx
jnz @b
 
mov eax, [r_size]
add eax, eax
add eax, eax
ret
endp
 
align 4
proc alloc_mix_buff
 
bsf eax, [mix_buff_map]
jnz .find
xor eax, eax
ret
.find:
btr [mix_buff_map], eax
shl eax, 9
add eax, [mix_buff]
ret
endp
 
align 4
proc m16_s_mmx
 
movq mm0, [esi]
movq mm1, mm0
punpcklwd mm0, mm0
punpckhwd mm1, mm1
movq [edi], mm0
movq [edi+8], mm1
 
movq mm0, [esi+8]
movq mm1, mm0
punpcklwd mm0, mm0
punpckhwd mm1, mm1
movq [edi+16], mm0
movq [edi+24], mm1
 
movq mm0, [esi+16]
movq mm1, mm0
punpcklwd mm0, mm0
punpckhwd mm1, mm1
movq [edi+32], mm0
movq [edi+40], mm1
 
movq mm0, [esi+24]
movq mm1, mm0
punpcklwd mm0, mm0
punpckhwd mm1, mm1
movq [edi+48], mm0
movq [edi+56], mm1
 
movq mm0, [esi+32]
movq mm1, mm0
punpcklwd mm0, mm0
punpckhwd mm1, mm1
movq [edi+64], mm0
movq [edi+72], mm1
 
movq mm0, [esi+40]
movq mm1, mm0
punpcklwd mm0, mm0
punpckhwd mm1, mm1
movq [edi+80], mm0
movq [edi+88], mm1
 
 
movq mm0, [esi+48]
movq mm1, mm0
punpcklwd mm0, mm0
punpckhwd mm1, mm1
movq [edi+96], mm0
movq [edi+104], mm1
 
movq mm0, [esi+56]
movq mm1, mm0
punpcklwd mm0, mm0
punpckhwd mm1, mm1
movq [edi+112], mm0
movq [edi+120], mm1
 
ret
endp
 
align 4
proc s8_s_mmx
 
movq mm0, [esi]
psubb mm0, mm7
movq mm1, mm0
punpcklbw mm0, mm0
pand mm0, mm6
punpckhbw mm1, mm1
pand mm1, mm6
movq [edi], mm0
movq [edi+8], mm1
 
movq mm0, [esi+8]
psubb mm0, mm7
movq mm1, mm0
punpcklbw mm0, mm0
pand mm0, mm6
punpckhbw mm1, mm1
pand mm1, mm6
movq [edi+16], mm0
movq [edi+24], mm1
 
movq mm0, [esi+16]
psubb mm0, mm7
movq mm1, mm0
punpcklbw mm0, mm0
pand mm0, mm6
punpckhbw mm1, mm1
pand mm1, mm6
movq [edi+32], mm0
movq [edi+40], mm1
 
movq mm0, [esi+24]
psubb mm0, mm7
movq mm1, mm0
punpcklbw mm0, mm0
pand mm0, mm6
punpckhbw mm1, mm1
pand mm1, mm6
movq [edi+48], mm0
movq [edi+56], mm1
 
ret
 
endp
 
align 4
proc m8_s_mmx
 
movq mm0, [esi]
psubb mm0, mm7
movq mm1, mm0
punpcklbw mm0, mm0
pand mm0, mm6
punpckhbw mm1, mm1
pand mm1, mm6
movq mm2, mm0
punpcklwd mm0, mm0
punpckhwd mm2, mm2
 
movq mm3, mm1
punpcklwd mm1, mm1
punpckhwd mm3, mm3
 
movq [edi], mm0
movq [edi+8], mm2
movq [edi+16], mm1
movq [edi+24], mm3
 
movq mm0, [esi+8]
psubb mm0, mm7
movq mm1, mm0
punpcklbw mm0, mm0
pand mm0, mm6
punpckhbw mm1, mm1
pand mm1, mm6
movq mm2, mm0
punpcklwd mm0, mm0
punpckhwd mm2, mm2
 
movq mm3, mm1
punpcklwd mm1, mm1
punpckhwd mm3, mm3
 
movq [edi+32], mm0
movq [edi+40], mm2
movq [edi+48], mm1
movq [edi+56], mm3
 
ret
endp
 
align 4
proc mix_2_1 stdcall, output:dword, str0:dword, str1:dword
 
mov edi, [output]
mov eax, [str0]
mov ebx, [str1]
mov esi, 128
call [mix_2_core] ;edi, eax, ebx
 
add edi, esi
add eax, esi
add ebx, esi
call [mix_2_core] ;edi, eax, ebx
 
add edi, esi
add eax, esi
add ebx, esi
call [mix_2_core] ;edi, eax, ebx
 
add edi, esi
add eax, esi
add ebx, esi
call [mix_2_core] ;edi, eax, ebx
ret
endp
 
align 4
proc mix_3_1 stdcall, output:dword, str0:dword, str1:dword, str2:dword
 
mov edi, [output]
mov eax, [str0]
mov ebx, [str1]
mov ecx, [str2]
mov esi, 128
call [mix_3_core]
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
call [mix_3_core]
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
call [mix_3_core]
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
call [mix_3_core]
ret
endp
 
align 4
proc mix_4_1 stdcall, str0:dword, str1:dword,\
str2:dword, str3:dword
 
local output:DWORD
 
call alloc_mix_buff
and eax, eax
jz .err
 
mov [output], eax
 
mov edi, eax
mov eax, [str0]
mov ebx, [str1]
mov ecx, [str2]
mov edx, [str3]
mov esi, 128
call [mix_4_core] ;edi, eax, ebx, ecx, edx
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
add edx, esi
call [mix_4_core] ;edi, eax, ebx, ecx, edx
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
add edx, esi
call [mix_4_core] ;edi, eax, ebx, ecx, edx
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
add edx, esi
call [mix_4_core] ;edi, eax, ebx, ecx, edx
mov eax, [output]
ret
.err:
xor eax, eax
ret
endp
 
 
align 4
proc final_mix stdcall, output:dword, str0:dword, str1:dword,\
str2:dword, str3:dword
 
mov edi, [output]
 
mov eax, [str0]
mov ebx, [str1]
mov ecx, [str2]
mov edx, [str3]
mov esi, 128
call [mix_4_core] ;edi, eax, ebx, ecx, edx
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
add edx, esi
call [mix_4_core] ;edi, eax, ebx, ecx, edx
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
add edx, esi
call [mix_4_core] ;edi, eax, ebx, ecx, edx
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
add edx, esi
call [mix_4_core] ;edi, eax, ebx, ecx, edx
ret
endp
 
align 4
proc copy_mem stdcall, output:dword, input:dword
 
mov edi, [output]
mov esi, [input]
mov ecx, 0x80
.l1:
mov eax, [esi]
mov [edi], eax
add esi, 4
add edi, 4
loop .l1
 
ret
endp
 
proc memcpy
@@:
mov eax, [esi]
mov [edi], eax
add esi, 4
add edi, 4
dec ecx
jnz @B
ret
endp
 
if 0
 
align 4
proc new_mix stdcall, output:dword
locals
mixCounter dd ?
mixIndex dd ?
streamIndex dd ?
inputCount dd ?
main_count dd ?
blockCount dd ?
mix_out dd ?
endl
 
call prepare_playlist
 
cmp [play_count], 0
je .exit
call FpuSave
mov [main_count], 32;
.l00:
mov [mix_buff_map], 0x0000FFFF;
xor eax, eax
mov [mixCounter], eax
mov [mixIndex],eax
mov [streamIndex], eax;
mov ebx, [play_count]
mov [inputCount], ebx
.l0:
mov ecx, 4
.l1:
mov ebx, [streamIndex]
mov esi, [play_list+ebx*4]
mov eax, [esi+STREAM.work_read]
add [esi+STREAM.work_read], 512
 
mov ebx, [mixIndex]
mov [mix_input+ebx*4], eax
inc [mixCounter]
inc [mixIndex]
inc [streamIndex]
dec [inputCount]
jz .m2
 
dec ecx
jnz .l1
 
cmp [mixCounter], 4
jnz .m2
 
stdcall mix_4_1, [mix_input],[mix_input+4],[mix_input+8],[mix_input+12]
sub [mixIndex],4
mov ebx, [mixIndex]
mov [mix_input+ebx*4], eax
inc [mixIndex]
mov [mixCounter], 0
 
cmp [inputCount], 0
jnz .l0
.m2:
cmp [mixIndex], 1
jne @f
stdcall copy_mem, [output], [mix_input]
jmp .m3
@@:
cmp [mixIndex], 2
jne @f
stdcall mix_2_1, [output], [mix_input], [mix_input+4]
jmp .m3
@@:
cmp [mixIndex], 3
jne @f
stdcall mix_3_1, [output],[mix_input],[mix_input+4],[mix_input+8]
jmp .m3
@@:
stdcall final_mix, [output],[mix_input],[mix_input+4],[mix_input+8], [mix_input+12]
.m3:
add [output],512
 
dec [main_count]
jnz .l00
 
call update_stream
emms
call FpuRestore
ret
.exit:
mov edi, [output]
mov ecx, 0x1000
xor eax, eax
cld
rep stosd
ret
endp
 
end if
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/tags/kolibri0.7.5.0/drivers/main.inc
0,0 → 1,164
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2006-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; Serge 2006-2008
; email: infinity_sound@mail.ru
 
 
PLAY_SYNC equ 0x80000000
 
PCM_ALL equ 0
 
PCM_OUT equ 0x08000000
PCM_RING equ 0x10000000
PCM_STATIC equ 0x20000000
PCM_FLOAT equ 0x40000000 ;reserved
PCM_FILTER equ 0x80000000 ;reserved
 
PCM_2_16_48 equ 1
PCM_1_16_48 equ 2
 
PCM_2_16_44 equ 3
PCM_1_16_44 equ 4
 
PCM_2_16_32 equ 5
PCM_1_16_32 equ 6
 
PCM_2_16_24 equ 7
PCM_1_16_24 equ 8
 
PCM_2_16_22 equ 9
PCM_1_16_22 equ 10
 
PCM_2_16_16 equ 11
PCM_1_16_16 equ 12
 
PCM_2_16_12 equ 13
PCM_1_16_12 equ 14
 
PCM_2_16_11 equ 15
PCM_1_16_11 equ 16
 
PCM_2_16_8 equ 17
PCM_1_16_8 equ 18
 
PCM_2_8_48 equ 19
PCM_1_8_48 equ 20
 
PCM_2_8_44 equ 21
PCM_1_8_44 equ 22
 
PCM_2_8_32 equ 23
PCM_1_8_32 equ 24
 
PCM_2_8_24 equ 25
PCM_1_8_24 equ 26
 
PCM_2_8_22 equ 27
PCM_1_8_22 equ 28
 
PCM_2_8_16 equ 29
PCM_1_8_16 equ 30
 
PCM_2_8_12 equ 31
PCM_1_8_12 equ 32
 
PCM_2_8_11 equ 33
PCM_1_8_11 equ 34
 
PCM_2_8_8 equ 35
PCM_1_8_8 equ 36
 
SRV_GETVERSION equ 0
SND_CREATE_BUFF equ 1
SND_DESTROY_BUFF equ 2
SND_SETFORMAT equ 3
SND_GETFORMAT equ 4
SND_RESET equ 5
SND_SETPOS equ 6
SND_GETPOS equ 7
SND_SETBUFF equ 8
SND_OUT equ 9
SND_PLAY equ 10
SND_STOP equ 11
SND_SETVOLUME equ 12
SND_GETVOLUME equ 13
SND_SETPAN equ 14
SND_GETPAN equ 15
SND_GETBUFFSIZE equ 16
SND_GETFREESPACE equ 17
 
struc STREAM
{
.magic dd ? ;'WAVE'
.destroy dd ? ;internal destructor
.fd dd ? ;next object in list
.bk dd ? ;prev object in list
.pid dd ? ;owner id
 
.size dd ?
.str_fd dd ?
.str_bk dd ?
.device dd ?
.format dd ?
.flags dd ?
 
.out_base dd ?
.out_wp dd ?
.out_rp dd ?
.out_count dd ?
.out_top dd ? ;16*4
 
.r_size dd ?
.r_dt dd ?
.r_silence dd ?
.resample dd ?
.l_vol dd ?
.r_vol dd ?
.l_amp dw ?
.r_amp dw ?
.pan dd ?
.l_amp_f dd ? ;float point left
.r_amp_f dd ? ;float point right
 
.in_base dd ?
.in_size dd ?
.in_wp dd ?
.in_rp dd ?
.in_count dd ?
.in_free dd ?
.in_top dd ?
 
.notify_event dd ?
.notify_id dd ?
}
 
STREAM_SIZE equ 36*4
FD_OFFSET equ 24
 
virtual at 0
STREAM STREAM
end virtual
 
struc WAVE_HEADER
{ .riff_id dd ?
.riff_size dd ?
.riff_format dd ?
 
.fmt_id dd ?
.fmt_size dd ?
.format_tag dw ?
.channels dw ?
.freq dd ?
.bytes_sec dd ?
.block_align dw ?
.bits_sample dw ?
 
.data_id dd ?
.data_size dd ?
}
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/tags/kolibri0.7.5.0/drivers/vmode.asm
0,0 → 1,736
;
; MenuetOS Driver (vmode.mdr)
; Target: Vertical Refresh Rate programming and videomode changing
;
; Author: Trans <<<<<13>>>>>
; Date: 20.07.2003
;
; Version: 1.0
; OS: MenuetOS
; Compiler: FASM
;
 
OS_BASE equ 0x80000000
 
use32
 
macro align value { rb (value-1) - ($ + value-1) mod value }
 
org OS_BASE+0x0328000
 
headerstart=$
 
mdid db 'MDAZ' ; 4 byte id
mdhver dd 0x00 ; header version
mdcode dd MDSTART ; start of code
mdver dd 0x00000001 ; driver version (subversion*65536+version)
mdname db 'Trans VideoDriver' ; 32 bytes of full driver name
times (32-($-mdname)) db ' ' ;
 
headerlen=$-headerstart
times (256-headerlen) db 0 ; reserved area for future
 
MDSTART: ; start of driver code ( base_adr+256 bytes)
; ebx(=ecx in program):
; 1 - Get DriverInfo and Driver Initial Set
; 2 - Get Current Video Mode With Vertical Refresh Rate
; 3 - Change Video Mode
; 4 - Return at Start System Video Mode
; 5 - Change vertical and horizontal size of visible screen area
; 6 - Change Vert/Hor position visible area on screen (not complete yet)
;
; MAXF - ...
MAXF=5
 
;-------Main Manager-------------
pushad
cmp ebx,1
jb mdvm_00
cmp ebx,MAXF
ja mdvm_00
shl ebx,2
add ebx,mdvm_func_table
call dword [ebx]
mov [esp+28],eax
mov [esp+24],ecx
mov [esp+20],edx
mov [esp+16],ebx
popad
retn
mdvm_00:
popad
xor eax,eax
dec eax
retn
 
; ------Drivers Functions----------
 
align 4
 
; EBX=1 (in applications ECX=1)- Get DriverInfo and Driver Initial Set
;
; IN: ecx (in app. edx) - pointer to 512-bytes info area in application
; OUT:
;
vm_info_init:
push ecx
cmp [mdrvm],dword 0
jnz .vmii_00
call vm_safe_reg
call vm_get_initial_videomode
mov eax,[initvm]
mov [currvm],eax
call vm_search_sys_func_table
call vm_get_cur_vert_rate
mov [initrr],eax
call vm_calc_pixelclock
call vm_calc_refrate
inc [mdrvm]
.vmii_00:
pop ecx
call vm_transfer_drv_info
mov ebx,dword [refrate]
mov eax,dword [mdid] ;dword [systlb]
retn
 
 
align 4
 
; EBX=2 (in applications ECX=2)- Get Current Video Mode
;
; OUT: eax = X_screen*65536+Y_screen
; ebx = current vertical rate
; ecx = current video mode (number)
vm_get_cur_mode:
cmp [mdrvm],dword 0
jz .vmgcm_00
call vm_get_cur_vert_rate
mov eax,[OS_BASE+0FE00h]
mov ebx,[OS_BASE+0FE04h]
shl eax,16
add eax,ebx
add eax,00010001h
mov ebx,[refrate]
mov ecx,[currvm]
retn
.vmgcm_00:
xor eax,eax
dec eax
retn
 
 
align 4
 
; EBX=3 (in applications ECX=3)- Change Video Mode
;
; IN: ecx = VertRate*65536+VideoMode
; OUT: eax = 0 if no error
;
vm_set_video_mode:
cmp [mdrvm],dword 0
jz .vmsvm_00
call vm_set_selected_mode
; xor eax,eax
retn
.vmsvm_00:
xor eax,eax
dec eax
retn
 
 
align 4
 
; EBX=4 (in applications ECX=4)- Return at Start System Video Mode
;
; IN:
; OUT: eax = = 0 if no error
;
vm_restore_init_video_mode:
cmp [mdrvm],dword 0
jz .vmrivm_00
call vm_restore_reg
xor eax,eax
retn
.vmrivm_00:
xor eax,eax
dec eax
retn
 
 
align 4
 
; EBX=5 (in applications ECX=5)- Change vertical and horizontal size
; of visible screen area
; IN: ecx (in app. edx) = 0/1 - -/+ horizontal size on 1 position
; = 2/3 - -/+ vertical size on 1 position (8 pixels)
; ^-^----- not complete yet
; OUT: eax = = 0 if no error
;
vm_change_screen_size:
cmp [mdrvm],dword 0
jz .vmcss_00
cmp cl,1
ja .vmcss_01
mov eax,ecx
call vm_inc_dec_width
xor eax,eax
retn
.vmcss_01:
and ecx,01h
mov eax,ecx
; call vm_inc_dec_high ; not complete yet
xor eax,eax
retn
.vmcss_00:
xor eax,eax
dec eax
retn
 
 
align 4
 
; EBX=6 (in applications ECX=6)- Change Vert/Hor position visible area on screen
;
; IN: ecx (in app. edx) = 0/1 - -/+ horizontal position on 1 point
; = 2/3 - -/+ vertical position on 1 pixel
; ^-^----- not complete yet
; OUT: eax = 0 if no error
;
vm_change_position_screen:
cmp [mdrvm],dword 0
jz .vmcps_00
; ...
xor eax,eax
retn
.vmcps_00:
xor eax,eax
dec eax
retn
 
 
;-----Drivers Subfunctions---------
 
;
; Searching i40 system functions pointer table in kernel area location
;
vm_search_sys_func_table:
push eax ; eax - current value
push ecx ; ecx - will be counter of equevalent value
push edx ; edx - last value
push esi ; esi - current address
xor ecx,ecx
mov esi,OS_BASE+010000h ; Start address of kernel location
lodsd
mov edx,eax
cld
.vmssft_00:
cmp esi,OS_BASE+30000h
ja .vmssft_03
inc ecx
lodsd
cmp edx,eax
mov edx,eax
je .vmssft_00
cmp ecx,128
ja .vmssft_02
.vmssft_01:
xor ecx,ecx
jmp .vmssft_00
.vmssft_02:
cmp edx,0
je .vmssft_01
sub esi,256*4-1
mov [systlb],esi
xor ecx,ecx
.vmssft_03_0:
inc ecx
lodsd
cmp edx,eax
mov edx,eax
jne .vmssft_03_0
mov esi,dword [systlb]
cmp cx,60
jae .vmssft_03
add esi,256*4-4
lodsb
mov edx,eax
jmp .vmssft_01
.vmssft_03:
mov [systlb],esi
pop esi
pop edx
pop ecx
pop eax
retn
 
; IN:
; OUT: eax= vertical rate in Hz
vm_get_cur_vert_rate:
push edx
push ebx
xor eax,eax
mov edx,eax
mov ebx,eax
mov dx,03DAh
.vmgcvt_00:
in al,dx
test al,8
jz .vmgcvt_00
.vmgcvt_01:
in al,dx
test al,8
jnz .vmgcvt_01
mov ebx,edx
rdtsc
mov edx,ebx
mov ebx,eax
.vmgcvt_02:
in al,dx
test al,8
jz .vmgcvt_02
.vmgcvt_03:
in al,dx
test al,8
jnz .vmgcvt_03
rdtsc
sub eax,ebx
mov ebx,eax
mov eax,[OS_BASE+0F600h]
xor edx,edx
div ebx
inc eax
mov [refrate],eax
pop ebx
pop edx
retn
 
vm_calc_pixelclock:
push ebx
push edx
xor eax,eax
mov al,[_00]
add ax,5
shl eax,3
xor ebx,ebx
mov bl,[_06]
mov bh,[_07]
and bh,00100001b
btr bx,13
jnc .vmcpc_00
or bh,2
.vmcpc_00:
xor edx,edx
mul ebx
xor edx,edx
mul [initrr]
mov [pclock],eax
pop edx
pop ebx
retn
 
;
; Safe of initial CRTC state
;
vm_safe_reg:
push edx
push ebx
push ecx
push edi
cli
mov dx,3d4h ; CRTC
mov al,11h
out dx,al
inc dx
in al,dx
and al,7fh
out dx,al ; Clear protection bit
dec dx
xor ecx,ecx
mov cl,19h
xor bl,bl
mov edi,CRTCreg
.vmsr_00:
mov al,bl
out dx,al
inc dx
in al,dx
dec dx
stosb
inc bl
loop .vmsr_00
sti
pop edi
pop ecx
pop ebx
pop edx
retn
 
;
; Restore of initial CRTC state
;
vm_restore_reg:
push eax
push ebx
push edx
push esi
mov eax,[oldX]
mov [OS_BASE+0FE00h],eax
mov eax,[oldY]
mov [OS_BASE+0FE04h],eax
mov dx,03dah
.vmrr_00:
in al,dx
test al,8
jnz .vmrr_00
.vmrr_01:
in al,dx
test al,8
jnz .vmrr_01
cli
mov dx,03c4h
mov ax,0101h
out dx,ax
mov dx,3d4h ; CRTC
mov al,11h
out dx,al
inc dx
in al,dx
and al,7fh ; Clear Protection bit
out dx,al
dec dx
xor ecx,ecx
mov cl,19h
mov esi,CRTCreg
xor bl,bl
.vmrr_02:
lodsb
mov ah,al
mov al,bl
out dx,ax
inc bl
loop .vmrr_02
sti
; call ref_screen
pop esi
pop edx
pop ecx
pop eax
retn
 
; Calculate of possible vertical refrash rate
; (light version of function)
vm_calc_refrate:
push ebx
push ecx
push edx
push edi
push esi
mov eax,[pclock]
xor edx,edx
mov edi,_m1
mov ebx,eax
mov ecx,(1696*1065)
div ecx
xor edx,edx
stosw
add edi,8
mov eax,ebx
mov ecx,(1344*804)
div ecx
xor edx,edx
stosw
add edi,8
mov eax,ebx
mov ecx,(1056*636)
div ecx
xor edx,edx
stosw
add edi,8
mov eax,ebx
mov ecx,(800*524)
div ecx
xor edx,edx
stosw
mov edi,_m1
mov esi,edi
mov ecx,5*4
.vmcrr_00:
lodsw
cmp ax,55
jb .vmcrr_01
stosw
loop .vmcrr_00
pop esi
pop edi
pop edx
pop ecx
pop ebx
retn
.vmcrr_01:
xor ax,ax
stosw
loop .vmcrr_00
pop esi
pop edi
pop edx
pop ecx
pop ebx
retn
 
vm_get_initial_videomode:
push eax
mov eax,dword [OS_BASE+0FE00h]
mov [oldX],eax
mov eax,dword [OS_BASE+0FE04h]
mov [oldY],eax
mov eax,dword [OS_BASE+0FE0Ch] ; initial video mode
and ax,01FFh
mov dword [initvm],eax
pop eax
retn
 
 
; IN: eax = 0/1 - -/+ 1 position of width
vm_inc_dec_width:
push ebx
push edx
mov ebx,eax
mov dx,3d4h ; CRTC
mov al,11h
out dx,al
inc dx
in al,dx
and al,7fh ; Clear Protection bit
out dx,al
dec dx
xor al,al
out dx,al
inc dx
in al,dx
dec al
cmp bl,0
jnz .vmidr_00
inc al
inc al
.vmidr_00:
out dx,al
pop edx
pop ebx
retn
 
;
; Copy driver info to application area
;
; IN: ecx (in app. edx) - pointer to 512-bytes info area in application
; OUT:
vm_transfer_drv_info:
push ecx
push edi
push esi
mov eax,ecx
xor ecx,ecx
mov cl,32/4
mov esi,mdname
mov edi,drvname
rep movsd
mov ecx,eax
mov eax,[mdver]
mov [drvver],eax
mov edi,[OS_BASE+3010h]
mov edi,[edi+10h]
add edi,ecx
mov esi,drvinfo
xor ecx,ecx
mov cx,512
rep movsb
pop esi
pop edi
pop ecx
retn
 
 
;
; Set selected video mode
; (light version)
;
; IN: ecx = VertRate*65536+VideoMode
;
vm_set_selected_mode:
push edx
push ecx
push esi
ror ecx,16
cmp cx,00h
je .vmssm_03
rol ecx,16
mov eax,ecx
shl eax,16
shr eax,16
mov [currvm],eax
cmp cx,112h
jne .vmssm_00
mov esi,mode0
mov ecx,639
mov edx,479
jmp .vmssm_st00
.vmssm_00:
cmp cx,115h
jne .vmssm_01
mov esi,mode1
mov ecx,799
mov edx,599
jmp .vmssm_st00
.vmssm_01:
cmp cx,118h
jne .vmssm_02
mov esi,mode2
mov ecx,1023
mov edx,767
jmp .vmssm_st00
.vmssm_02:
cmp cx,11Bh
jne .vmssm_03
mov esi,mode2
mov ecx,1279
mov edx,1023
jmp .vmssm_st00
.vmssm_03:
xor eax,eax
dec eax
pop esi
pop ecx
pop edx
retn
.vmssm_st00:
mov [OS_BASE+0FE00h],ecx
mov [OS_BASE+0FE04h],edx
cli
mov dx,03c4h
lodsw
out dx,ax
mov dx,03d4h
mov al,11h
out dx,al
inc dx
in al,dx
and al,7fh
out dx,al
dec dx
mov ecx,13
.vmssm_st01:
lodsw
out dx,ax
loop .vmssm_st01
sti
xor eax,eax
pop esi
pop ecx
pop edx
retn
 
 
;------------DATA AREA---------------
align 4
 
mdvm_func_table:
dd MDSTART
dd vm_info_init, vm_get_cur_mode
dd vm_set_video_mode, vm_restore_init_video_mode
dd vm_change_screen_size, vm_change_position_screen
 
 
CRTCreg:
_00 db ?
_01 db ?
_02 db ?
_03 db ?
_04 db ?
_05 db ?
_06 db ?
_07 db ?
_08 db ?
_09 db ?
_0a db ?
_0b db ?
_0c db ?
_0d db ?
_0e db ?
_0f db ?
_10 db ?
_11 db ?
_12 db ?
_13 db ?
_14 db ?
_15 db ?
_16 db ?
_17 db ?
_18 db ?
_19 db ?
 
align 4
 
oldX dd ?
oldY dd ?
initvm dd ?
currvm dd 0
refrate dd 0
initrr dd 0
systlb dd 0
pclock dd ?
mdrvm dd 0 ; 0 - not drv init yet, 1 - already drv init
 
 
drvinfo:
drvname: times 32 db ' '
drvver dd 0
times (32-($-drvver))/4 dd 0
drvmode dw 011Bh,0118h,0115h,0112h
times (64-($-drvmode))/2 dw 00h
_m1 dw 0,0,0,0,0
_m2 dw 0,0,0,0,0
_m3 dw 0,0,0,0,0
_m4 dw 0,0,0,0,0
_m5 dw 0,0,0,0,0
times (512-($-drvinfo)) db 0
drvinfoend:
 
 
;1280x1024 - 11Bh
mode3:
dw 0101h
dw 0d000h,9f01h,9f02h,9303h,0a904h,1905h,2806h,5a07h
dw 0110h,8411h,0ff12h,0ff15h,2916h
 
;1024x768 - 118h
mode2:
dw 0101h
dw 0a400h,7f01h,7f02h,8703h,8404h,9505h,2406h,0f507h
dw 0310h,8911h,0ff12h,0ff15h,2516h
 
;800x600 - 115h
mode1:
dw 0101h
dw 8000h,6301h,6302h,8303h,6a04h,1a05h,7206h,0f007h
dw 5910h,8d11h,5712h,5715h,7316h
 
;640x480 - 112h, 12h
mode0:
dw 0101h
dw 6000h,4f01h,4f02h,8303h,5304h,9f05h,00b06h,3e07h
dw 0ea10h,8c11h,0df12h,0df15h,0c16h
 
; 640x400
;mymode0:
; dw 0101h
;_0_7 dw 5f00h,4f01h,4f02h,8303h,5304h,9f05h,0BF06h,1f07h
; dw 9c10h,8e11h,8f12h,9615h,0B916h ;,4013h
 
; 640x800
;mymode1:
; dw 0101h
; dw 5f00h,4f01h,4f02h,8003h,5004h,9f05h,06006h,0FF07h
; dw 2d10h,8f11h,2012h,2615h,05716h ;,4013h
 
 
DRVM_END:
 
/kernel/tags/kolibri0.7.5.0/drivers/codec.inc
0,0 → 1,283
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
AD_LOSEL equ BIT5
AD_HPSEL equ BIT10
 
align 4
proc detect_codec
locals
codec_id dd ?
endl
 
stdcall codec_read, dword 0x7C
shl eax, 16
mov [codec_id], eax
 
stdcall codec_read, dword 0x7E
or eax, [codec_id]
 
mov [codec.chip_id], eax
and eax, 0xFFFFFF00
 
mov edi, codecs
@@:
mov ebx, [edi]
test ebx, ebx
jz .unknown
 
cmp eax, ebx
jne .next
mov eax, [edi+4]
mov [codec.ac_vendor_ids], eax
mov esi, eax
call SysMsgBoardStr
stdcall detect_chip, [edi+8]
 
ret
.next:
add edi, 12
jmp @B
.unknown:
mov [codec.ac_vendor_ids], ac_unknown
mov [codec.chip_ids], chip_unknown
 
mov esi, chip_unknown
call SysMsgBoardStr
mov eax, [codec.chip_id]
call dword2str
call SysMsgBoardStr
ret
endp
 
align 4
proc detect_chip stdcall, chip_tab:dword
 
mov eax, [codec.chip_id]
and eax, 0xFF
 
mov edi, [chip_tab]
@@:
mov ebx, [edi]
cmp ebx, 0xFF
je .unknown
 
cmp eax,ebx
jne .next
mov eax, [edi+4]
mov [codec.chip_ids], eax
mov esi, eax
call SysMsgBoardStr
ret
.next:
add edi, 8
jmp @b
.unknown:
mov [codec.chip_ids], chip_unknown
mov esi, chip_unknown
call SysMsgBoardStr
mov eax, [codec.chip_id]
call dword2str
call SysMsgBoardStr
ret
endp
 
align 4
proc setup_codec
 
xor eax, eax
stdcall codec_write, dword CODEC_AUX_VOL
 
mov eax, 0x0B0B
stdcall codec_write, dword CODEC_MASTER_VOL_REG
 
mov ax, 0x08
stdcall codec_write, dword 0x0C
 
mov ax, 0x0808
stdcall codec_write, dword CODEC_PCM_OUT_REG
 
mov ax, 0x0808
stdcall codec_write, dword 0x10
 
mov ax, 0x0808
stdcall codec_write, dword 0x12
 
mov ax, 0x0808
stdcall codec_write, dword 0x16
 
 
stdcall codec_read, dword CODEC_EXT_AUDIO_CTRL_REG
and eax, 0FFFFh - BIT1 ; clear DRA (BIT1)
or eax, BIT0 ; set VRA (BIT0)
stdcall codec_write, dword CODEC_EXT_AUDIO_CTRL_REG
 
stdcall set_sample_rate, dword 48000
 
.init_error:
xor eax, eax ; exit with error
ret
endp
 
 
; param
; eax= volume -10000 - 0 for both channels
 
align 4
set_master_vol:
cmp eax, 0
jl @F
xor eax, eax
jmp .set
@@:
cmp eax, -9450
jg .set
mov eax, -9450 ;clamp into 6 bits
.set:
cdq
mov ebx, -150
idiv ebx
mov ah, al
stdcall codec_write, dword CODEC_MASTER_VOL_REG
xor eax, eax
ret
 
align 4
proc get_master_vol stdcall, pvol:dword
 
stdcall codec_read, dword CODEC_MASTER_VOL_REG
and eax, 0x3F
imul eax, -150
mov ebx, [pvol]
mov [ebx], eax
xor eax, eax
ret
endp
 
align 4
proc set_sample_rate stdcall, rate:dword
mov eax, [rate]
stdcall codec_write, dword CODEC_PCM_FRONT_DACRATE_REG
ret
endp
 
patch_AD:
stdcall codec_read, 0x76
or ax, BIT5+BIT10
stdcall codec_write, 0x76
ret
 
 
 
align 16
ac_unknown db 'unknown manufacturer',13,10,0
ac_Realtek db 'Realtek Semiconductor',13,10,0
ac_Analog db 'Analog Devices',13,10,0
ac_CMedia db 'C-Media Electronics',13,10,0
ac_Cirrus db 'Cirrus Logic',13,10,0
 
chip_unknown db 'unknown codec id ', 0
 
CHIP_ANALOG equ 0x41445300
CHIP_REALTEK equ 0x414C4700
CHIP_CMEDIA equ 0x434D4900
CHIP_CIRRUS equ 0x43525900
 
align 16
codecs dd CHIP_ANALOG, ac_Analog, chips_Analog
dd CHIP_CMEDIA, ac_CMedia, chips_CMedia
dd CHIP_REALTEK,ac_Realtek, chips_Realtek
dd CHIP_CIRRUS, ac_Cirrus, chips_Cirrus
dd 0
 
align 16
chips_Analog dd 0x03, chip_AD1819
dd 0x40, chip_AD1881
dd 0x48, chip_AD1881A
dd 0x60, chip_AD1884
dd 0x61, chip_AD1886
dd 0x62, chip_AD1887
dd 0x63, chip_AD1886A
dd 0x70, chip_AD1980
dd 0x75, chip_AD1985
dd 0xFF
 
chips_Realtek:
dd 0x20, chip_ALC650
dd 0x21, chip_ALC650D
dd 0x22, chip_ALC650E
dd 0x23, chip_ALC650F
dd 0x60, chip_ALC655
dd 0x80, chip_ALC658
dd 0x81, chip_ALC658D
dd 0x90, chip_ALC850
dd 0xFF
 
chips_CMedia dd 0x41, chip_CM9738
dd 0x61, chip_CM9739
dd 0x69, chip_CM9780
dd 0x78, chip_CM9761
dd 0x82, chip_CM9761
dd 0x83, chip_CM9761
dd 0xFF
 
chips_Cirrus dd 0x00, chip_CS4297
dd 0x10, chip_CS4297A
dd 0x20, chip_CS4298
dd 0x28, chip_CS4294
dd 0x30, chip_CS4299
dd 0x34, chip_CS4299D
dd 0x48, chip_CS4201
dd 0x58, chip_CS4205
dd 0x60, chip_CS4291
dd 0x70, chip_CS4202
dd 0xFF
 
 
align 16
;Analog Devices
chip_AD1819 db 'AD1819 ',0dh,0ah,00h
chip_AD1881 db 'AD1881 ',0dh,0ah,00h
chip_AD1881A db 'AD1881A',0dh,0ah,00h
chip_AD1884 db 'AD1885 ',0dh,0ah,00h
chip_AD1885 db 'AD1885 ',0dh,0ah,00h
chip_AD1886 db 'AD1886 ',0dh,0ah,00h
chip_AD1886A db 'AD1886A',0dh,0ah,00h
chip_AD1887 db 'AD1887 ',0dh,0ah,00h
chip_AD1980 db 'AD1980 ',0dh,0ah,00h
chip_AD1985 db 'AD1985 ',0dh,0ah,00h
 
;Realtek
chip_ALC650 db 'ALC650 ',0dh,0ah,00h
chip_ALC650D db 'ALC650D',0dh,0ah,00h
chip_ALC650E db 'ALC650E',0dh,0ah,00h
chip_ALC650F db 'ALC650F',0dh,0ah,00h
chip_ALC655 db 'ALC655 ',0dh,0ah,00h
chip_ALC658 db 'ALC658 ',0dh,0ah,00h
chip_ALC658D db 'ALC658D',0dh,0ah,00h
chip_ALC850 db 'ALC850 ',0dh,0ah,00h
 
;CMedia
chip_CM9738 db 'CMI9738', 0dh,0ah,0
chip_CM9739 db 'CMI9739', 0dh,0ah,0
chip_CM9780 db 'CMI9780', 0dh,0ah,0
chip_CM9761 db 'CMI9761', 0dh,0ah,0
 
;Cirrus
chip_CS4297 db 'CS4297',13,10,0
chip_CS4297A db 'CS4297A',13,10,0
chip_CS4298 db 'CS4298',13,10,0
chip_CS4294 db 'CS4294',13,10,0
chip_CS4299 db 'CS4299',13,10,0
chip_CS4299D db 'CS4299D',13,10,0
chip_CS4201 db 'CS4201',13,10,0
chip_CS4205 db 'CS4205',13,10,0
chip_CS4291 db 'CS4291',13,10,0
chip_CS4202 db 'CS4202',13,10,0
 
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/tags/kolibri0.7.5.0/drivers/usb/urb.inc
0,0 → 1,115
 
struc URB
{
.fd dd ?
.bk dd ?
.dev dd ? ; pointer to associated device
.pipe dd ? ; pipe information
.status dd ? ; non-ISO status
.transfer_flags dd ? ; URB_SHORT_NOT_OK | ...
.transfer_buffer dd ? ; associated data buffer
.transfer_dma dd ? ; dma addr for transfer_buffer
.transfer_buffer_length dd ? ; data buffer length
.actual_length dd ? ; actual transfer length
.setup_packet dd ? ; setup packet (control only)
.setup_dma dd ? ; dma addr for setup_packet
.start_frame dd ? ; start frame (ISO)
.number_of_packets dd ? ; number of ISO packets
.interval dd ? ; transfer interval
 
.error_count dd ? ; number of ISO errors
.context dd ? ; context for completion
.complete dd ? ; (in) completion routine
.iso_frame_desc:
}
 
virtual at 0
URB URB
end virtual
 
 
struc REQ ;usb request
{
.request_type db ?
.request db ?
.value dw ?
.index dw ?
.length dw ?
}
 
virtual at 0
REQ REQ
end virtual
 
align 4
proc usb_control_msg stdcall, dev:dword, pipe:dword, request:dword,\
requesttype:dword, value:dword, index:dword,\
data:dword, size:dword, timeout:dword
 
locals
req REQ
endl
 
lea eax, [req]
mov ecx, [request]
mov ebx, [requesttupe]
mov edx, [value]
mov esi, [index]
mov edi, [size]
 
mov [eax+REQ.request_type], bl
mov [eax+REQ.request], cl
mov [eax+REQ.value], dx
mov [eax+REQ.index], si
mov [eax+REQ.length], di
 
stdcall usb_internal_control_msg, [dev], [pipe],\
eax, [data], [size], [timeout]
 
ret
endp
 
 
; returns status (negative) or length (positive)
static int usb_internal_control_msg(struct usb_device *usb_dev,
unsigned int pipe,
struct usb_ctrlrequest *cmd,
void *data, int len, int timeout)
{
struct urb *urb;
int retv;
int length;
 
urb = usb_alloc_urb(0, GFP_NOIO);
if (!urb)
return -ENOMEM;
usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data,
len, usb_api_blocking_completion, NULL);
 
retv = usb_start_wait_urb(urb, timeout, &length);
if (retv < 0)
return retv;
else
return length;
}
 
 
void usb_fill_control_urb (struct urb *urb,
struct usb_device *dev,
unsigned int pipe,
unsigned char *setup_packet,
void *transfer_buffer,
int buffer_length,
usb_complete_t complete_fn,
void *context)
{
 
urb->dev = dev;
urb->pipe = pipe;
urb->setup_packet = setup_packet;
urb->transfer_buffer = transfer_buffer;
urb->transfer_buffer_length = buffer_length;
urb->complete = complete_fn;
urb->context = context;
}
 
/kernel/tags/kolibri0.7.5.0/drivers/usb/usb.asm
0,0 → 1,435
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;driver sceletone
 
format MS COFF
 
API_VERSION equ 0 ;debug
 
include '../proc32.inc'
include '../imports.inc'
include 'urb.inc'
 
struc UHCI
{
.bus dd ?
.devfn dd ?
.io_base dd ?
.mm_base dd ?
.irq dd ?
.flags dd ?
.reset dd ?
.start dd ?
.stop dd ?
 
.port_c_suspend dd ?
.resuming_ports dd ?
.rh_state dd ?
.rh_numports dd ?
.is_stopped dd ?
.dead dd ?
 
.sizeof:
}
 
virtual at 0
UHCI UHCI
end virtual
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
struc TD ;transfer descriptor
{
.link dd ?
.status dd ?
.token dd ?
.buffer dd ?
 
.addr dd ?
.frame dd ?
.fd dd ?
.bk dd ?
.sizeof:
}
 
virtual at 0
TD TD
end virtual
 
public START
public service_proc
public version
 
DEBUG equ 1
 
DRV_ENTRY equ 1
DRV_EXIT equ -1
STRIDE equ 4 ;size of row in devices table
 
SRV_GETVERSION equ 0
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .exit
.entry:
 
if DEBUG
mov esi, msgInit
call SysMsgBoardStr
end if
 
call init
 
stdcall RegService, my_service, service_proc
ret
.fail:
.exit:
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 ebx, [ioctl]
mov eax, [ebx+io_code]
cmp eax, SRV_GETVERSION
jne @F
 
mov eax, [ebx+output]
cmp [ebx+out_size], 4
jne .fail
mov [eax], dword API_VERSION
xor eax, eax
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 detect
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, STRIDE
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 eax, UHCI.sizeof
call Kmalloc
test eax, eax
jz .mem_fail
 
mov ebx, [bus]
mov [eax+UHCI.bus], ebx
 
mov ecx, [devfn]
mov [eax+UHCI.devfn], ecx
ret
.mem_fail:
if DEBUG
mov esi, msgMemFail
call SysMsgBoardStr
end if
.err:
xor eax, eax
ret
endp
 
PCI_BASE equ 0x20
USB_LEGKEY equ 0xC0
 
align 4
proc init
locals
uhci dd ?
endl
 
call detect
test eax, eax
jz .fail
 
mov [uhci], eax
 
stdcall PciRead32, [eax+UHCI.bus], [eax+UHCI.devfn], PCI_BASE
and eax, 0xFFC0
mov esi, [uhci]
mov [esi+UHCI.io_base], eax
 
stdcall uhci_reset, esi
 
stdcall finish_reset, [uhci]
 
.fail:
if DEBUG
mov esi, msgDevNotFound
call SysMsgBoardStr
end if
ret
endp
 
UHCI_USBINTR equ 4 ; interrupt register
 
UHCI_USBLEGSUP_RWC equ 0x8f00 ; the R/WC bits
UHCI_USBLEGSUP_RO equ 0x5040 ; R/O and reserved bits
 
UHCI_USBCMD_RUN equ 0x0001 ; RUN/STOP bit
UHCI_USBCMD_HCRESET equ 0x0002 ; Host Controller reset
UHCI_USBCMD_EGSM equ 0x0008 ; Global Suspend Mode
UHCI_USBCMD_CONFIGURE equ 0x0040 ; Config Flag
UHCI_USBINTR_RESUME equ 0x0002 ; Resume interrupt enable
 
PORTSC0 equ 0x10
PORTSC1 equ 0x12
 
 
UHCI_RH_RESET equ 0
UHCI_RH_SUSPENDED equ 1
UHCI_RH_AUTO_STOPPED equ 2
UHCI_RH_RESUMING equ 3
 
; In this state the HC changes from running to halted
; so it can legally appear either way.
UHCI_RH_SUSPENDING equ 4
 
; In the following states it's an error if the HC is halted.
; These two must come last.
UHCI_RH_RUNNING equ 5 ; The normal state
UHCI_RH_RUNNING_NODEVS equ 6 ; Running with no devices
 
UHCI_IS_STOPPED equ 9999
 
align 4
proc uhci_reset stdcall, uhci:dword
mov esi, [uhci]
stdcall PciRead16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY
test eax, not (UHCI_USBLEGSUP_RO or UHCI_USBLEGSUP_RWC)
jnz .reset
 
mov edx, [esi+UHCI.io_base]
in ax, dx
test ax, UHCI_USBCMD_RUN
jnz .reset
 
test ax, UHCI_USBCMD_CONFIGURE
jz .reset
 
test ax, UHCI_USBCMD_EGSM
jz .reset
 
add edx, UHCI_USBINTR
in ax, dx
test ax, not UHCI_USBINTR_RESUME
jnz .reset
ret
.reset:
stdcall PciWrite16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY, UHCI_USBLEGSUP_RWC
 
mov edx, [esi+UHCI.io_base]
mov ax, UHCI_USBCMD_HCRESET
out dx, ax
 
xor eax, eax
out dx, ax
add edx, UHCI_USBINTR
out dx, ax
ret
endp
 
proc finish_reset stdcall, uhci:dword
 
mov esi, [uhci]
mov edx, [esi+UHCI.io_base]
add edx, PORTSC0
xor eax, eax
out dx, ax
add edx, (PORTSC1-PORTSC0)
out dx, ax
 
mov [esi+UHCI.port_c_suspend], eax
mov [esi+UHCI.resuming_ports], eax
mov [esi+UHCI.rh_state], UHCI_RH_RESET
mov [esi+UHCI.rh_numports], 2
 
mov [esi+UHCI.is_stopped], UHCI_IS_STOPPED
; mov [ uhci_to_hcd(uhci)->state = HC_STATE_HALT;
; uhci_to_hcd(uhci)->poll_rh = 0;
 
mov [esi+UHCI.dead], eax ; Full reset resurrects the controller
 
ret
endp
 
proc insert_td stdcall, td:dword, frame:dword
 
mov edi, [td]
mov eax, [frame]
and eax, -1024
mov [edi+TD.frame], eax
 
mov ebx, [framelist]
mov edx, [dma_framelist]
shl eax, 5
 
mov ecx, [eax+ebx]
test ecx, ecx
jz .empty
 
mov ecx, [ecx+TD.bk] ;last TD
 
mov edx, [ecx+TD.fd]
mov [edi+TD.fd], edx
mov [edi+TD.bk], ecx
mov [ecx+TD.fd], edi
mov [edx+TD.bk], edi
 
mov eax, [ecx+TD.link]
mov [edi+TD.link], eax
mov ebx, [edi+TD.addr]
mov [ecx+TD.link], ebx
ret
.empty:
mov ecx, [eax+edx]
mov [edi+TD.link], ecx
mov [ebx+eax], edi
mov ecx, [edi+TD.addr]
mov [eax+edx], ecx
ret
endp
 
 
align 4
proc usb_get_descriptor stdcall, dev:dword, type:dword, index:dword,\
buf:dword, size:dword
 
locals
count dd ?
endl
 
mov esi, [buf]
mov ecx, [size]
xor eax, eax
cld
rep stosb
 
mov [count], 3
@@:
mov eax, [type]
shl eax, 8
add eax, [index]
stdcall usb_control_msg, [dev],pipe,USB_REQ_GET_DESCRIPTOR,\
USB_DIR_IN, eax,0,[buf], [size],\
USB_CTRL_GET_TIMEOUT
test eax, eax
jz .next
cmp eax, -1
je .next
jmp. ok
.next:
dec [count]
jnz @B
mov eax, -1
.ok:
ret
endp
 
DEVICE_ID equ 0x24D2 ; pci device id
VENDOR_ID equ 0x8086 ; device vendor id
QEMU_USB equ 0x7020
 
;all initialized data place here
 
align 4
devices dd (DEVICE_ID shl 16)+VENDOR_ID
dd (QEMU_USB shl 16)+VENDOR_ID
dd 0 ;terminator
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
my_service db 'UHCI',0 ;max 16 chars include zero
 
msgInit db 'detect hardware...',13,10,0
msgPCI db 'PCI accsess not supported',13,10,0
msgDevNotFound db 'device not found',13,10,0
msgMemFail db 'Kmalloc failed', 10,10,0
;msgFail db 'device not found',13,10,0
 
section '.data' data readable writable align 16
 
;all uninitialized data place here
 
/kernel/tags/kolibri0.7.5.0/drivers/usb
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/tags/kolibri0.7.5.0/drivers/ps2m_irqh.inc
0,0 → 1,120
;**************************************
;* IRQ HANDLER FOR PS/2 MOUSE *
;**************************************
 
proc irq_handler
 
call Wait8042BufferEmpty ;clear buffer
in al,0x60 ;get scan-code
 
cmp [mouse_byte],0
je .byte1
cmp [mouse_byte],1
je .byte2
cmp [mouse_byte],2
je .byte3
cmp [mouse_byte],3
je .byte4
jmp .error
 
.byte1:
test al,1000b ;first byte?
jz .error
mov [first_byte],al
inc [mouse_byte]
jmp .exit
 
.byte2:
mov [second_byte],al
inc [mouse_byte]
jmp .exit
 
.byte3:
mov [third_byte],al
cmp [MouseType],MT_3B
je .full_packet
inc [mouse_byte]
jmp .exit
.byte4:
mov [fourth_byte],al
 
.full_packet:
mov [mouse_byte],0
mov al,byte [first_byte]
and eax,7
mov byte [ButtonState],al
cmp [MouseType],MT_3B
je .xy_moving
mov al,[fourth_byte]
cmp [MouseType],MT_3BScroll
je .z_moving
mov ah,al
and ah,00110000b
shr ah,1
or byte [ButtonState],ah
and al,00001111b
bt eax,3
jnc .z_moving
or al,11110000b
 
.z_moving:
movsx eax,al
mov [ZMoving],eax
 
.xy_moving:
mov ah,0
mov al,[first_byte]
test al,10000b
jz @f
mov ah,0FFh
 
@@:
mov al,[second_byte]
cwd
mov [XMoving],eax
 
mov ah,0
mov al,[first_byte]
test al,100000b
jz @f
mov ah,0FFh
 
@@:
mov al,[third_byte]
cwd
 
@@:
mov [YMoving],eax
stdcall SetMouseData, [ButtonState], [XMoving], [YMoving], [ZMoving], 0
 
jmp .exit
 
.error:
mov [mouse_byte],0
 
.exit:
ret
endp
 
 
;***********************************************
;* Waiting for clearing I8042 buffer *
;* Retutned state: *
;* ZF is set - good ending, *
;* ZF is cleared - time-out error. *
;***********************************************
Wait8042BufferEmpty:
push ecx
xor ecx,ecx
@@:
in al,64h
test al,00000010b
loopnz @b
pop ecx
 
ret
/kernel/tags/kolibri0.7.5.0/drivers/ps2m_iofuncs.inc
0,0 → 1,141
kbd_read:
push ecx edx
 
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
kr_loop:
in al,0x64
test al,1
jnz kr_ready
loop kr_loop
mov ah,1
jmp kr_exit
kr_ready:
push ecx
mov ecx,32
kr_delay:
loop kr_delay
pop ecx
in al,0x60
xor ah,ah
kr_exit:
pop edx ecx
ret
 
 
kbd_write:
 
push ecx edx
 
mov dl,al
in al,0x60
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
kw_loop:
in al,0x64
test al,2
jz kw_ok
loop kw_loop
mov ah,1
jmp kw_exit
kw_ok:
mov al,dl
out 0x60,al
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
kw_loop3:
in al,0x64
test al,2
jz kw_ok3
loop kw_loop3
mov ah,1
jmp kw_exit
kw_ok3:
mov ah,8
kw_loop4:
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
kw_loop5:
in al,0x64
test al,1
jnz kw_ok4
loop kw_loop5
dec ah
jnz kw_loop4
kw_ok4:
xor ah,ah
kw_exit:
pop edx ecx
ret
 
 
kbd_cmd:
 
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
c_wait:
in al,0x64
test al,2
jz c_send
loop c_wait
jmp c_error
c_send:
mov al,bl
out 0x64,al
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
c_accept:
in al,0x64
test al,2
jz c_ok
loop c_accept
c_error:
mov ah,1
jmp c_exit
c_ok:
xor ah,ah
c_exit:
ret
 
mouse_cmd:
mov [mouse_cmd_byte], al
mov [mouse_nr_resends], 5
.resend:
mov bl, 0xd4
call kbd_cmd
cmp ah,1
je .fail
 
mov al, [mouse_cmd_byte]
call kbd_write
cmp ah, 1
je .fail
call mouse_read
cmp al, 0xFA
jne .noack
clc
ret
.noack:
cmp al, 0xFE ; resend
jne .noresend
dec [mouse_nr_resends]
jnz .resend
.noresend:
.fail:
stc
ret
mouse_read:
mov [mouse_nr_tries], 100
.repeat:
call kbd_read
cmp ah, 1
jne .fin
mov esi, 10
call Sleep
dec [mouse_nr_tries]
jnz .repeat
 
stc
ret
 
.fin:
clc
ret
/kernel/tags/kolibri0.7.5.0/drivers/mix_mmx.inc
0,0 → 1,247
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; params
; edi= output
; eax= input stream 1
; ebx= input stream 2
 
if used mmx_mix_2
 
align 4
mmx_mix_2:
movq mm0, [eax]
movq mm1, [eax+8]
movq mm2, [eax+16]
movq mm3, [eax+24]
movq mm4, [eax+32]
movq mm5, [eax+40]
movq mm6, [eax+48]
movq mm7, [eax+56]
 
paddsw mm0, [ebx]
movq [edi], mm0
paddsw mm1,[ebx+8]
movq [edi+8], mm1
paddsw mm2, [ebx+16]
movq [edi+16], mm2
paddsw mm3, [ebx+24]
movq [edi+24], mm3
paddsw mm4, [ebx+32]
movq [edi+32], mm4
paddsw mm5, [ebx+40]
movq [edi+40], mm5
paddsw mm6, [ebx+48]
movq [edi+48], mm6
paddsw mm7, [ebx+56]
movq [edi+56], mm7
 
movq mm0, [eax+64]
movq mm1, [eax+72]
movq mm2, [eax+80]
movq mm3, [eax+88]
movq mm4, [eax+96]
movq mm5, [eax+104]
movq mm6, [eax+112]
movq mm7, [eax+120]
 
paddsw mm0, [ebx+64]
movq [edi+64], mm0
paddsw mm1, [ebx+72]
movq [edi+72], mm1
paddsw mm2, [ebx+80]
movq [edi+80], mm2
paddsw mm3, [ebx+88]
movq [edi+88], mm3
paddsw mm4, [ebx+96]
movq [edi+96], mm4
paddsw mm5, [ecx+104]
movq [edx+104], mm5
paddsw mm6, [ebx+112]
movq [edi+112], mm6
paddsw mm7, [ebx+120]
movq [edi+120], mm7
ret
 
align 4
mmx_mix_3:
movq mm0, [eax]
movq mm1, [eax+8]
movq mm2, [eax+16]
movq mm3, [eax+24]
movq mm4, [eax+32]
movq mm5, [eax+40]
movq mm6, [eax+48]
movq mm7, [eax+56]
 
paddsw mm0, [ebx]
paddsw mm1, [ebx+8]
paddsw mm2, [ebx+16]
paddsw mm3, [ebx+24]
paddsw mm4, [ebx+32]
paddsw mm5, [ebx+40]
paddsw mm6, [ebx+48]
paddsw mm7, [ebx+56]
paddsw mm0, [ecx]
movq [edi], mm0
paddsw mm1,[ecx+8]
movq [edi+8], mm1
paddsw mm2, [ecx+16]
movq [edi+16], mm2
paddsw mm3, [ecx+24]
movq [edi+24], mm3
paddsw mm4, [ecx+32]
movq [edi+32], mm4
paddsw mm5, [ecx+40]
movq [edi+40], mm5
paddsw mm6, [ecx+48]
movq [edi+48], mm6
paddsw mm7, [ecx+56]
movq [edi+56], mm7
 
movq mm0, [eax+64]
movq mm1, [eax+72]
movq mm2, [eax+80]
movq mm3, [eax+88]
movq mm4, [eax+96]
movq mm5, [eax+104]
movq mm6, [eax+112]
movq mm7, [eax+120]
paddsw mm0, [ebx+64]
paddsw mm1, [ebx+72]
paddsw mm2, [ebx+80]
paddsw mm3, [ebx+88]
paddsw mm4, [ebx+96]
paddsw mm5, [ebx+104]
paddsw mm6, [ebx+112]
paddsw mm7, [ebx+120]
paddsw mm0, [ecx+64]
movq [edi+64], mm0
paddsw mm1, [ecx+72]
movq [edi+72], mm1
paddsw mm2, [ecx+80]
movq [edi+80], mm2
paddsw mm3, [ecx+88]
movq [edi+88], mm3
paddsw mm4, [ecx+96]
movq [edi+96], mm4
paddsw mm5, [ecx+104]
movq [edi+104], mm5
paddsw mm6, [ecx+112]
movq [edi+112], mm6
paddsw mm7, [ecx+120]
movq [edi+120], mm7
ret
 
align 4
mmx_mix_4:
 
movq mm0, [eax]
movq mm2, [eax+8]
movq mm4, [eax+16]
movq mm6, [eax+24]
movq mm1, [ebx]
movq mm3, [ebx+8]
movq mm5, [ebx+16]
movq mm7, [ebx+24]
paddsw mm0, [ecx]
paddsw mm2, [ecx+8]
paddsw mm4, [ecx+16]
paddsw mm6, [ecx+24]
paddsw mm1, [edx]
paddsw mm3, [edx+8]
paddsw mm5, [edx+16]
paddsw mm7, [edx+24]
 
paddsw mm0, mm1
movq [edi], mm0
paddsw mm2, mm3
movq [edi+8], mm2
paddsw mm4, mm5
movq [edi+16], mm4
paddsw mm5, mm6
movq [edi+24], mm6
 
movq mm0, [eax+32]
movq mm2, [eax+40]
movq mm4, [eax+48]
movq mm6, [eax+56]
movq mm1, [ebx+32]
movq mm3, [ebx+40]
movq mm5, [ebx+48]
movq mm7, [ebx+56]
paddsw mm0, [ecx+32]
paddsw mm2, [ecx+40]
paddsw mm4, [ecx+48]
paddsw mm6, [ecx+56]
paddsw mm1, [edx+32]
paddsw mm3, [edx+40]
paddsw mm5, [edx+48]
paddsw mm7, [edx+56]
 
paddsw mm0, mm1
movq [edi+32], mm0
paddsw mm2, mm2
movq [edi+40], mm2
paddsw mm4, mm5
movq [edi+48], mm4
paddsw mm6, mm7
movq [edi+56], mm6
 
movq mm0, [eax+64]
movq mm2, [eax+72]
movq mm4, [eax+80]
movq mm6, [eax+88]
movq mm1, [ebx+64]
movq mm3, [ebx+72]
movq mm5, [ebx+80]
movq mm7, [ebx+88]
paddsw mm0, [ecx+64]
paddsw mm2, [ecx+72]
paddsw mm4, [ecx+80]
paddsw mm6, [ecx+88]
paddsw mm1, [edx+64]
paddsw mm3, [edx+72]
paddsw mm5, [edx+80]
paddsw mm7, [edx+88]
 
paddsw mm0, mm1
movq [edi+64], mm0
paddsw mm2, mm3
movq [edi+72], mm2
paddsw mm4, mm5
movq [edi+80], mm4
paddsw mm6, mm5
movq [edi+88], mm7
 
movq mm0, [eax+96]
movq mm2, [eax+104]
movq mm4, [eax+112]
movq mm6, [eax+120]
movq mm1, [ebx+96]
movq mm3, [ebx+104]
movq mm5, [ebx+112]
movq mm7, [ebx+120]
paddsw mm0, [ecx+96]
paddsw mm2, [ecx+104]
paddsw mm4, [ecx+112]
paddsw mm6, [ecx+120]
paddsw mm1, [edx+96]
paddsw mm3, [edx+104]
paddsw mm5, [edx+112]
paddsw mm7, [edx+120]
paddsw mm0, mm1
movq [eax+96], mm0
paddsw mm2, mm3
movq [edi+104], mm2
paddsw mm4, mm5
movq [edi+112], mm4
paddsw mm6, mm7
movq [edi+120], mm6
ret
 
end if
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/tags/kolibri0.7.5.0/drivers/mix_sse2.inc
0,0 → 1,145
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
if used mmx128_mix_2
 
align 4
mmx128_mix_2:
prefetcht1 [eax+128]
prefetcht1 [ebx+128]
 
movaps xmm0, [eax]
movaps xmm1, [eax+16]
movaps xmm2, [eax+32]
movaps xmm3, [eax+48]
movaps xmm4, [eax+64]
movaps xmm5, [eax+80]
movaps xmm6, [eax+96]
movaps xmm7, [eax+112]
 
paddsw xmm0, [ebx]
movaps [edi], xmm0
paddsw xmm1,[ebx+16]
movaps [edi+16], xmm1
paddsw xmm2, [ebx+32]
movaps [edi+32], xmm2
paddsw xmm3, [ebx+48]
movaps [edi+48], xmm3
paddsw xmm4, [ebx+64]
movaps [edi+64], xmm4
paddsw xmm5, [ebx+80]
movaps [edi+80], xmm5
paddsw xmm6, [ebx+96]
movaps [edi+96], xmm6
paddsw xmm7, [ebx+112]
movaps [edi+112], xmm7
ret
 
align 4
mmx128_mix_3:
prefetcht1 [eax+128]
prefetcht1 [ebx+128]
prefetcht1 [ecx+128]
 
movaps xmm0, [eax]
movaps xmm1, [eax+16]
movaps xmm2, [eax+32]
movaps xmm3, [eax+48]
movaps xmm4, [eax+64]
movaps xmm5, [eax+80]
movaps xmm6, [eax+96]
movaps xmm7, [eax+112]
 
paddsw xmm0, [ebx]
paddsw xmm1, [ebx+16]
paddsw xmm2, [ebx+32]
paddsw xmm3, [ebx+48]
paddsw xmm4, [ebx+64]
paddsw xmm5, [ebx+80]
paddsw xmm6, [ebx+96]
paddsw xmm7, [ebx+112]
 
paddsw xmm0, [ecx]
movaps [edi], xmm0
paddsw xmm1, [ecx+16]
movaps [edi+16], xmm1
paddsw xmm2, [ecx+32]
movaps [edi+32], xmm2
paddsw xmm3, [ecx+48]
movaps [edi+48], xmm3
paddsw xmm4, [ecx+64]
movaps [edi+64], xmm4
paddsw xmm5, [ecx+80]
movaps [edi+80], xmm5
paddsw xmm6, [ecx+96]
movaps [edi+96], xmm6
paddsw xmm7, [ecx+112]
movaps [edi+112], xmm7
ret
 
align 4
mmx128_mix_4:
prefetcht1 [eax+128]
prefetcht1 [ebx+128]
prefetcht1 [ecx+128]
prefetcht1 [edx+128]
 
movaps xmm0, [eax]
movaps xmm2, [eax+16]
movaps xmm4, [eax+32]
movaps xmm6, [eax+48]
movaps xmm1, [ebx]
movaps xmm3, [ebx+16]
movaps xmm5, [ebx+32]
movaps xmm7, [ebx+48]
 
paddsw xmm0, [ecx]
paddsw xmm2, [ecx+16]
paddsw xmm4, [ecx+32]
paddsw xmm6, [ecx+48]
paddsw xmm1, [edx]
paddsw xmm3, [edx+16]
paddsw xmm5, [edx+32]
paddsw xmm7, [edx+48]
 
paddsw xmm0, xmm1
movaps [edi], xmm0
paddsw xmm2, xmm3
movaps [edi+16], xmm2
paddsw xmm4, xmm5
movaps [edi+32], xmm4
paddsw xmm6, xmm7
movaps [edi+48], xmm6
 
movaps xmm0, [eax+64]
movaps xmm2, [eax+80]
movaps xmm4, [eax+96]
movaps xmm6, [eax+112]
 
movaps xmm1, [ebx+64]
movaps xmm3, [ebx+80]
movaps xmm5, [ebx+96]
movaps xmm7, [ebx+112]
paddsw xmm0, [ecx+64]
paddsw xmm2, [ecx+80]
paddsw xmm4, [ecx+96]
paddsw xmm6, [ecx+112]
 
paddsw xmm1, [edx+64]
paddsw xmm3, [edx+80]
paddsw xmm5, [edx+96]
paddsw xmm7, [edx+112]
paddsw xmm0, xmm1
movaps [edi+64], xmm0
paddsw xmm2, xmm3
movaps [edi+80], xmm2
paddsw xmm4, xmm5
movaps [edi+96], xmm4
paddsw xmm6, xmm7
movaps [edi+112], xmm6
ret
end if
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/tags/kolibri0.7.5.0/drivers/.
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj