?? vesa20.inc
字號:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; VESA20.INC ;;
;; ;;
;; Vesa 2.0 functions for MenuetOS ;;
;; ;;
;; Copyright 2002 Ville Turjanmaa ;;
;; Alexey, kgaz@crosswindws.net ;;
;; - Voodoo compatible graphics ;;
;; Juan M. Caravaca ;;
;; - Graphics optimimizations eg. drawline ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; If you're planning to write your own video driver I suggest
; you replace the VESA12.INC file and see those instructions.
ScreenWidth equ 0xfe00
ScreenHeight equ 0xfe04
BytesPerScanLine equ 0xfe08
LFBAddress equ 0xfe80
ScreenBPP equ 0xfbf1
WinMapAddress equ 0x400000
vesa20_read_screen_pixel:
and eax, 0x3FFFFF
shl eax, 2
cmp byte [ScreenBPP], 24 ; 24 or 32 bpp ?
jz .no24bpp
shr eax, 2
lea eax, [eax+eax*2]
.no24bpp:
add eax, [LFBAddress]
mov eax, [eax]
and eax, 0x00ffffff
ret
; getpixel
;
; in:
; eax = x coordinate
; ebx = y coordinate
;
; ret:
; ecx = 00 RR GG BB
getpixel:
push eax
push ebx
push edx
push edi
call dword [0xe024]
pop edi
pop edx
pop ebx
pop eax
ret
Vesa20_getpixel24:
; eax = x
; ebx = y
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
lea edi, [eax+eax*2] ; edi = x*3
add edi, ebx ; edi = x*3+(y*y multiplier)
add edi, [LFBAddress] ; ebx = where pixel is in memory
mov ecx, [edi]
and ecx, 0xffffff
ret
Vesa20_getpixel32:
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier)
add edi, [LFBAddress] ; ebx = where pixel is in memory
mov ecx, [edi]
and ecx, 0xffffff
ret
vesa20_putimage:
call disable_mouse
mov [novesachecksum],dword 0
push ebp ;
mov esi, ebx
xor ebx, ebx
mov bx, dx ; ebx := y
shr edx, 16 ; edx := x
mov eax, [0x3010]
add edx, [eax-twdw] ; edx+=Xwin
add ebx, [eax-twdw+4]; ebx+=Ywin
mov edi, ebx ; edi:=(y+Ywin)
imul edi, dword [BytesPerScanLine] ; edi:=BPScanLine*(y+Ywin)
mov ebp, ebx ; ebp:=(y+Ywin)
imul ebp, [ScreenWidth]
add ebp, ebx ; (ScreenXSize+1)*(Y+YWin)
; +(x+Xwin)+AddrBuffer
lea edi, [edi + edx*4] ; edi += (X+XWin)*4
lea ebp, [ebp + edx + WinMapAddress] ; ebp:=(y+Ywin)*(SXSize+
; +(x+Xwin)+AddrBuffer
add edi, [LFBAddress]
xor ebx, ebx ; ebx:=H
mov bx, cx
shr ecx, 16 ; ecx = B
mov eax, ecx
shl ecx, 2 ; ecx *= 4
cmp byte [ScreenBPP], 32
jz .bpp32
; corrections for 24 bpp
sub edi, edx
sub ecx, eax
.bpp32:
; ecx:=B*PytesPerPixel
;mov esi,[esp+8] ; esi:=AddrImg
; check limits while draw ?
push ebx
mov edx, [0x3010]
cmp dword [edx+draw_data-0x3000+0], 0
jnz dbcblimitlset2
cmp dword [edx+draw_data-0x3000+4], 0
jnz dbcblimitlset2
mov ebx, [edx+draw_data-0x3000+8]
cmp ebx, [ScreenWidth] ; ecx <> Screen X size
jnz dbcblimitlset2
mov ebx, [edx+draw_data-0x3000+12]
cmp ebx, [ScreenHeight] ; ecx <> Screen Y size
jnz dbcblimitlset2
mov bh, 0
jmp dbcblimitlno2
dbcblimitlset2:
mov bh, 1
dbcblimitlno2:
mov bl, [edx+0xe]
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ?
jz pi24bit
jmp pi32bit
; eax = B
; ecx = B*PytesPerPixel
; edx = 0x3010
; esi = ptr to image data
; edi = ptr to screen where begining painting
; ds:ebp = ptr to windows map
; bh = 0 force
; 1 not force
; bl = window ID on windows map
pi24bit:
.RenderBlock:
push edi
push esi
push eax
push ebp
.RenderLine:
cmp bl,[ds:ebp]
jnz .imp24no
cmp bh, 0
jz .imp24yes
call voodoodbcplimit
jnz .imp24no
.imp24yes:
mov edx, [esi]
mov [edi], dx
shr edx, 16
mov [edi+2], dl
.imp24no:
add esi, 3 ; esi+=3 ptrImage+=3
add edi, 3 ; edi+=3 ptrScreen+=3
inc ebp
dec eax ; B--
jnz .RenderLine
pop ebp
pop eax
pop esi
pop edi
add edi, [BytesPerScanLine] ; ptrScreen+=BytesPerScanLine
add esi, ecx
add ebp, [ScreenWidth]
inc ebp
dec dword [esp] ; H--
jnz .RenderBlock
pop ebx
pop ebp
xor eax, eax
ret
pi32bit:
sub ecx, eax ; ecx = B*4 - B = B*3
.RenderBlock:
push edi
push esi
push eax
push ebp
.RenderLine:
cmp bl,[ds:ebp]
jnz .imp32no
cmp bh,0
jz .imp32yes
call voodoodbcplimit
jnz .imp32no
.imp32yes:
mov edx, [esi]
mov [edi], edx
.imp32no:
add esi, 3 ; esi+=3 ptrImage+=3
add edi, 4 ; edi+=4 ptrScreen+=4
inc ebp
dec eax ; B--
jnz .RenderLine
pop ebp
pop eax
pop esi
pop edi
add edi, [BytesPerScanLine] ; ptrScreen+=BytesPerScanLine
add esi, ecx
add ebp, [ScreenWidth]
inc ebp
dec dword [esp] ; H--
jnz .RenderBlock
pop ebx
pop ebp
xor eax, eax
ret
putpixel:
; eax = x coordinate
; ebx = y coordinate
; ecx = ?? RR GG BB ; 0x01000000 negation
; edi = 0x00000001 force
mov [novesachecksum], dword 0
pusha
test edi,1 ; force ?
jnz drawok2
noforce:
call checkpixel
cmp ecx, 0
jnz ppr
drawok2:
cmp [ScreenWidth], eax
jb ppr
cmp [ScreenHeight], ebx
jb ppr
ppok:
; check if negation
test ecx,0x01000000
jz noneg
call getpixel
not ecx
mov [esp+32-8],ecx
noneg:
; OK to set pixel
call dword [0xe020]
ppr:
popa
ret
Vesa20_putpixel24:
; eax = x
; ebx = y
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
lea edi, [eax+eax*2] ; edi = x*3
mov eax, [esp+32-8+4]
add edi, [LFBAddress]
add edi, ebx ; ebx = where to put pixel in memory
mov [edi], ax
shr eax, 16
mov [edi+2], al
ret
Vesa20_putpixel32:
; eax = x
; ebx = y
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier)
mov eax, [esp+32-8+4] ; eax = color
add edi, [LFBAddress] ; ebx = where to put pixel in memory
mov [edi], eax
ret
;-------------------------------------------------
calculate_edi:
mov edi, ebx
imul edi, [ScreenWidth]
add edi, ebx
add edi, eax
ret
;-------------------------------------------------
; DRAWLINE
draw_line:
call disable_mouse
; draw a line
; eax = HIWORD = x1
; LOWORD = x2
; ebx = HIWORD = y1
; LOWORD = y2
; ecx = color
; edi = force ?
pusha
dl_x1 equ esp+20
dl_y1 equ esp+16
dl_x2 equ esp+12
dl_y2 equ esp+8
dl_dx equ esp+4
dl_dy equ esp+0
xor edx, edx ; clear edx
xor esi, esi ; unpack arguments
xor ebp, ebp
mov si, ax ; esi = x2
mov bp, bx ; ebp = y2
shr eax, 16 ; eax = x1
shr ebx, 16 ; ebx = y1
push eax ; save x1
push ebx ; save y1
push esi ; save x2
push ebp ; save y2
; checking x-axis...
sub esi, eax ; esi = x2-x1
push esi ; save y2-y1
jl .x2lx1 ; is x2 less than x1 ?
jg .no_vline ; x1 > x2 ?
mov edx, ebp ; else (if x1=x2)
call vline
push edx ; necessary to rightly restore stack frame at .exit
jmp .exit
.x2lx1:
neg esi ; get esi absolute value
.no_vline:
; checking y-axis...
sub ebp, ebx ; ebp = y2-y1
push ebp ; save y2-y1
jl .y2ly1 ; is y2 less than y1 ?
jg .no_hline ; y1 > y2 ?
mov edx, [dl_x2] ; else (if y1=y2)
call hline
jmp .exit
.y2ly1:
neg ebp ; get ebp absolute value
.no_hline:
cmp ebp, esi
jle .x_rules ; |y2-y1| < |x2-x1| ?
cmp [dl_y2], ebx ; make sure y1 is at the begining
jge .no_reverse1
neg dword [dl_dx]
mov edx, [dl_x2]
mov [dl_x2], eax
mov [dl_x1], edx
mov edx, [dl_y2]
mov [dl_y2], ebx
mov [dl_y1], edx
.no_reverse1:
mov eax, [dl_dx]
cdq ; extend eax sing to edx
shl eax, 16 ; using 16bit fix-point maths
idiv ebp ; eax = ((x2-x1)*65536)/(y2-y1)
mov edx, ebp ; edx = counter (number of pixels to draw)
mov ebp, 1 *65536 ; <<16 ; ebp = dy = 1.0
mov esi, eax ; esi = dx
jmp .y_rules
.x_rules:
cmp [dl_x2], eax ; make sure x1 is at the begining
jge .no_reverse2
neg dword [dl_dy]
mov edx, [dl_x2]
mov [dl_x2], eax
mov [dl_x1], edx
mov edx, [dl_y2]
mov [dl_y2], ebx
mov [dl_y1], edx
.no_reverse2:
xor edx, edx
mov eax, [dl_dy]
cdq ; extend eax sing to edx
shl eax, 16 ; using 16bit fix-point maths
idiv esi ; eax = ((y2-y1)*65536)/(x2-x1)
mov edx, esi ; edx = counter (number of pixels to draw)
mov esi, 1 *65536 ;<< 16 ; esi = dx = 1.0
mov ebp, eax ; ebp = dy
.y_rules:
mov eax, [dl_x1]
mov ebx, [dl_y1]
shl eax, 16
shl ebx, 16
.draw:
push eax
push ebx
shr eax, 16
shr ebx, 16
call putpixel
pop ebx
pop eax
add ebx, ebp ; y = y+dy
add eax, esi ; x = x+dx
dec edx
jnz .draw
; force last drawn pixel to be at (x2,y2)
mov eax, [dl_x2]
mov ebx, [dl_y2]
call putpixel
.exit:
add esp, 6*4
popa
ret
hline:
; draw an horizontal line
; eax = x1
; edx = x2
; ebx = y
; ecx = color
; edi = force ?
push eax
push edx
cmp edx, eax ; make sure x2 is above x1
jge .draw_hline
xchg eax, edx
.draw_hline:
call putpixel
inc eax
cmp eax, edx
jle .draw_hline
pop edx
pop eax
ret
vline:
; draw a vertical line
; eax = x
; ebx = y1
; edx = y2
; ecx = color
; edi = force ?
push ebx
push edx
cmp edx, ebx ; make sure y2 is above y1
jge .draw_vline
xchg ebx, edx
.draw_vline:
call putpixel
inc ebx
cmp ebx, edx
jle .draw_vline
pop edx
pop ebx
ret
vesa20_drawbar:
call disable_mouse
mov [novesachecksum],dword 0
sub edx,ebx ; edx:=Yend-Ystart=H
sub ecx,eax ; ecx:=Xend-Xstat=B
push ebp ; +24
push esi ; +20
push edi ; +16
push eax ; +12
push ebx ; +8
push ecx ; +4
push edx ; +0
mov ecx,[0x3010] ;
add eax,[ecx-twdw] ; eax:=Xwin+x
add ebx,[ecx-twdw+4] ; ebx:=Ywin+y
mov ecx, eax ; ecx:=(x+Xwin)
mov eax, [BytesPerScanLine] ; BytesPerScanLine
mul ebx ; *(y+Ywin)
mov edi, eax ; edi:=BytesPerScanLine*(y+Ywin)
mov eax, [ScreenWidth] ; ScreenXSize
inc eax ; +1
mul ebx ; *(y+Ywin)
mov ebp, eax ;
add ebp, ecx ; +(x+Win)
add ebp, WinMapAddress ; ebp:=(y+Ywin)*(ScreenXSize+1)+(x+Xwin)+AdrBf
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -