kolibrios-gitea/kernel/trunk/drivers/ati2d.asm
Sergey Semyonov (Serge) 5b119159d4 copyrights
git-svn-id: svn://kolibrios.org@431 a494cfbc-eb01-0410-851d-a64ba20cac60
2007-03-26 12:18:08 +00:00

1015 lines
23 KiB
NASM

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
format MS COFF
include 'proc32.inc'
include 'imports.inc'
DEBUG equ 1
VID_ATI equ 0x1002
LOAD_FROM_FILE equ 0
LOAD_FROM_MEM equ 1
LOAD_INDIRECT equ 2
LOAD_SYSTEM equ 3
VIDEO_FREE equ 2
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
R8500 equ 0x514C ;R200
R9000 equ 0x4966 ;RV250
R9200 equ 0x5961 ;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
OS_BASE equ 0
new_app_base equ 0x80000000
SLOT_BASE equ 0x0080000
PG_SW equ 0x003
PG_NOCACHE equ 0x018
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 wrr dest, src
{
mov edi, [ati_io]
mov dword [edi+dest], src
}
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 .exit
if DEBUG
mov esi, msgInit
call SysMsgBoardStr
end if
call detect_ati
test eax, eax
jz .fail
call init_ati
test eax, eax
jz .fail
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 .fail
mov dword [SetHwCursor], drvCursorPos ;enable hardware cursor
mov dword [HwCursorRestore], drv_restore
mov dword [HwCursorCreate], ati_cursor
ret
.fail:
if DEBUG
mov esi, msgFail
call SysMsgBoardStr
end if
.exit:
xor eax, eax
; mov ebx, SetHwCursor
; mov dword [ebx], eax ;force disable hardware cursor
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 ebx, [edi+io_code]
cmp ebx, VIDEO_FREE
jne .fail
mov eax, [edi+input]
call video_free
.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, 4
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
align 4
proc init_ati
stdcall AllocKernelSpace, dword 0x10000
test eax, eax
jz .fail
mov [ati_io], eax
stdcall PciRead32, [bus], [devfn], dword 0x18
and eax, 0xFFFF0000
mov esi, eax
mov edi, [ati_io]
mov edx, 16
@@:
stdcall MapPage,edi,esi,PG_SW+PG_NOCACHE
add edi, 0x1000
add esi, 0x1000
dec edx
jnz @B
mov edi, [ati_io]
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 drvShowCursor
xor eax, eax
inc eax
.fail:
ret
endp
align 4
drv_restore:
ret 8
align 4
drvShowCursor:
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 drvCursorPos 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
engSetupSolidFill:
push ebp
mov ebp, esp
push dword 3
call engWaitForFifo
wrr RD_DP_GUI_MASTER_CNTL, cmdSolidFill
mov eax, [ebp+8]
wrr RD_DP_BRUSH_FRGD_CLR,eax
mov edi, [ati_io]
mov dword [edi+RD_DP_CNTL],(RD_DST_X_LEFT_TO_RIGHT or RD_DST_Y_TOP_TO_BOTTOM)
leave
ret 4
align 4
drvSolidFill:
;x:word,y:word,w:word,h:word,color:dword
push ebp
mov ebp, esp
x equ ebp+8
y equ ebp+12
w equ ebp+16
h equ ebp+20
color equ ebp+24
push dword [ebp+24]
call engSetupSolidFill
push dword 2
call engWaitForFifo
mov edi, [ati_io]
mov eax, [y]
mov ebx, [x]
shl eax,16
or eax, ebx
mov ecx, [w]
mov edx, [h]
shl ecx,16
or ecx, edx
mov [edi+RD_DST_Y_X], eax
mov [edi+RD_DST_WIDTH_HEIGHT], ecx
call engFlush
leave
ret 20
align 4
devices dd (R8500 shl 16)+VID_ATI
dd (R9000 shl 16)+VID_ATI
dd (R9200 shl 16)+VID_ATI
dd (R9500 shl 16)+VID_ATI
dd (R9500P shl 16)+VID_ATI
dd (R9550 shl 16)+VID_ATI
dd (R9600 shl 16)+VID_ATI
dd (R9600XT shl 16)+VID_ATI
dd (R9700P shl 16)+VID_ATI
dd (R9800 shl 16)+VID_ATI
dd (R9800P shl 16)+VID_ATI
dd (R9800XT shl 16)+VID_ATI
dd 0 ;terminator
version dd 0x00040004
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
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
bus dd ?
devfn dd ?
ati_io dd ?