/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 |