kolibrios-fun/kernel/trunk/video/vga.inc
Marat Zakiyanov (Mario79) 333b0bbae6 1) Parallel processing of mouses: PS2, COM1, COM2
2) Detection PS2 mouse.
3) Switching FPU in PM with reset.
4) Click on the application button - works only if during release of a up-button mouse the cursor is on the button application. Realization Victor Alberto Gil Hanla (vhanla). Version 1.1
5) Return of focus (activated window) on previous application at completion of the active application
6) Change skin of header of windows type 4, at loss and return of focus (activated window).

git-svn-id: svn://kolibrios.org@33 a494cfbc-eb01-0410-851d-a64ba20cac60
2006-01-06 11:46:26 +00:00

788 lines
17 KiB
PHP

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; VGA.INC ;;
;; ;;
;; 640x480 mode 0x12 VGA functions for MenuetOS ;;
;; ;;
;; Paul Butcher, paul.butcher@asa.co.uk ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
paletteVGA:
;16 colour palette
mov dx,0x3c8
mov al,0
out dx,al
mov ecx,16
mov dx,0x3c9
xor eax,eax
palvganew:
mov al,0
test ah,4
jz palvgalbl1
add al,31
test ah,8
jz palvgalbl1
add al,32
palvgalbl1:
out dx,al ; red 0,31 or 63
mov al,0
test ah,2
jz palvgalbl2
add al,31
test ah,8
jz palvgalbl2
add al,32
palvgalbl2:
out dx,al ; blue 0,31 or 63
mov al,0
test ah,1
jz palvgalbl3
add al,31
test ah,8
jz palvgalbl3
add al,32
palvgalbl3:
out dx,al ; green 0,31 or 63
add ah,1
loop palvganew
ret
vga_putimage:
; pushad
call [disable_mouse]
push ebp ;
push esi ;
push edi ;
push eax ;
push ebx ; +8 [ptrImage]
push ecx ; +4 [BH]
push edx ; +0 [xy]
movzx eax,word [esp+2] ; eax:=x
movzx ebx,word [esp+0] ; ebx:=y
mov ecx,[0x3010] ;
add eax,[ecx-twdw] ; eax+=Xwin
add ebx,[ecx-twdw+4] ; ebx+=Ywin
mov ecx,ebx ; ecx = y+Ywin
mov edx,eax ; edx = x+Xwin
imul ebx, 640*4 ; (y+Ywin)*BytesPerScanLine
shl eax,2 ; (x+Xwin)*BytesPerPixel
add eax,ebx ;
mov edi,eax ; store copy
add eax,[0xfe80] ; +AddrLFB
;entry point in LFB >> EAX:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrLFB
shr edi,5 ; change from 4 to 1/8 BytesPerPixel
add edi,0xa0000 ; + VGABasePtr
;VGA start address >> EDI:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrVGA
mov ebx, [0xfe00] ; ScreenXSize
inc ebx ; +1
imul ebx,ecx ; *(y+Ywin)
mov ebp, ebx ;
add ebp, edx ; +(x+Xwin)
add ebp, WinMapAddress ; ebp:=(y+Ywin)*(ScreenXSize+1)+(x+Xwin)+AddrBuffer
mov esi,[esp+8] ; esi:=AddrImg
movzx ecx,word [esp+6] ; ecx:=B
movzx ebx,word [esp+4] ; ebx:=H
; check limits while draw ?
push ecx ; B
push eax ; LFB address
mov eax,[0x3010]
mov ecx,[eax+draw_data-0x3000+0]
cmp ecx,0
jnz dbcblimitlset_vga
mov ecx,[eax+draw_data-0x3000+4]
cmp ecx,0
jnz dbcblimitlset_vga
mov ecx,[eax+draw_data-0x3000+8]
cmp ecx,[0xfe00] ; ecx <> Screen X size
jnz dbcblimitlset_vga
mov ecx,[eax+draw_data-0x3000+12]
cmp ecx,[0xfe04] ; ecx <> Screen Y size
jnz dbcblimitlset_vga
pop eax ; LFB address
pop ecx ; B
push dword 0
jmp pimvga
dbcblimitlset_vga:
pop eax ; LFB address
pop ecx ; B
push dword 1
pimvga:
push edi
push esi
push eax ; LFB address
push ecx ; B
push ebx ; H
push edx ; x+Xwin
mov ebx,[0x3010]
mov bl,[ebx+0xe]
mov bh,[esp+6*4]
cld
npvga:
cmp bl,[ds:ebp]
jnz impvgano
; cmp bh,0
; jz impvgayes
; call voodoodbcplimit
; jnz impvgano
; impvgayes:
push eax ; LFB address
push ebx ; app no.
push ecx ; B
push edx ; x+Xwin
mov edx,[esi] ; color
mov [eax],dx
shr edx,16
mov [eax+2],dl
mov eax,[esi] ; color
mov ecx,[esp] ; x+Xwin
and ecx,0x07 ; modulo 8
call setvgapixel ; eax=color, ecx=x%8, edi=VGA address
pop edx
pop ecx
pop ebx
pop eax
impvgano:
add esi,3 ; esi+=3 ptrImage+=3
add eax,4 ; eax+=4 LFBaddr +=4
inc ebp
inc edx ; x+Xwin+n
test edx,0x07 ; test modulo 8
jnz impvgacont
inc edi
impvgacont:
dec ecx ; B--
jnz npvga
pop edx
pop ebx
pop ecx
pop eax
pop esi
pop edi
add edi,640/8 ; add one VGA line
add eax,640*4 ; add one LFB line
sub ebp, ecx ; -B
add ebp, [0xfe00] ;
inc ebp ; ptrBuffer:=ptrBuffer-B+Screen_Xsize+1
push ecx
lea ecx,[ecx+ecx*2] ;
add esi,ecx ; ptrImage:=ptrImage+B*3
pop ecx
dec ebx ; H--
jnz near pimvga
add esp,4 ; jump saved limit byte
pop edx
pop ecx
pop ebx
pop eax
pop edi
pop esi
pop ebp
; call [draw_pointer]
; call [disable_mouse]
; popad
ret
VGA_putpixel:
; eax = x
; ebx = y
mov ecx,eax
mov eax, [esp+32-8+4] ; color
imul ebx, 640*4 ; y*BytesPerLine (Vesa2.0 32)
lea edx, [ebx+ecx*4] ; + x*BytesPerPixel (Vesa2.0 32)
mov edi,edx
add edi, [0xfe80] ; + LFB address
mov [edi], eax ; write to LFB for Vesa2.0
shr edx,5 ; change BytesPerPixel to 1/8
mov edi,edx
add edi, 0x0a0000 ; address of pixel in VGA area
and ecx,0x07 ; bit no. (modulo 8)
setvgapixel:
cli
; edi = address, eax = 24bit colour, ecx = bit no. (modulo 8)
push eax
mov ebx,eax ; color
;mov al,0x08
;mov dx,0x03ce
;out dx,al ; select GDC bit mask register
inc cl
mov ax, 0x100
shr ax,cl
mov dx,0x03cf
out dx,al ; set bit mask for pixel
mov dl,0
mov eax,ebx
and eax,0x000000ff ; blue
cmp eax,85
jle p13green
or dl,0x01
cmp eax,170
jle p13green
or dl,0x08
p13green:
and ebx,0x0000ff00 ; green
cmp ebx,85*256
jle p13red
or dl,0x02
cmp ebx,170*256
jle p13red
or dl,0x08
p13red:
pop ebx
and ebx,0x00ff0000 ; red
cmp ebx,85*256*256
jle p13cont
or dl,0x04
cmp ebx,170*256*256
jle p13cont
or dl,0x08
p13cont:
mov al,[edi] ; dummy read
mov [edi],dl
sti
ret
vga_drawbar:
; pushad
call [disable_mouse]
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 edx, ebx ; edx:=(y+Ywin)
imul ebx, 640/8 ;
mov edi, ebx ; edi:=BytesPerScanLine*(y+Ywin)
shr eax, 3 ;
add edi, eax ; + (x+Xwin)*BytesPerPixel
add edi,0xa0000 ; + VGAbaseaddress
mov eax, [0xfe00] ; ScreenXSize
inc eax ; +1
imul eax,edx ; *(y+Ywin)
mov ebp, eax ;
add ebp, ecx ; +(x+Win)
add ebp, WinMapAddress ; +AddrBuffer
mov eax, [0xfe08] ; BytesPerScanLine - LFB
mul edx ; *(y+Ywin)
mov esi,eax
add esi,ecx
add esi,ecx
add esi,ecx
add esi,ecx ; + 4*(x+Xwin)
add esi,[0xfe80] ; +AddrLFB
; edi:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel + AddrVGA
; esi:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel + AddrLFB
; ebp:=(y+Ywin)*(ScreenXSize+1)+(x+Xwin)+AddrBuffer
; x size
mov eax,[esp+4] ; B [esp+4]
mov ebx,[esp+0] ; H
mov edx,[esp+16] ; color
test edx,0x80000000
jz nodbglvga
; no color glide for VGA - set to half glide
shr ebx,1 ; H/2
sub edx,ebx
mov [esp+16],edx
mov ebx,[esp+0] ; reset to H
nodbglvga:
; check limits ?
push eax
push ecx
mov eax,[0x3010]
mov ecx,[eax+draw_data-0x3000+0]
cmp ecx,0
jnz dbcblimitlset_vga2
mov ecx,[eax+draw_data-0x3000+4]
cmp ecx,0
jnz dbcblimitlset_vga2
mov ecx,[eax+draw_data-0x3000+8]
cmp ecx,[0xfe00]
jnz dbcblimitlset_vga2
mov ecx,[eax+draw_data-0x3000+12]
cmp ecx,[0xfe04]
jnz dbcblimitlset_vga2
pop ecx
pop eax
push dword 0
jmp dbnewpivga
dbcblimitlset_vga2:
pop ecx ; x+Xwin
pop eax ; B
push dword 1
dbnewpivga:
push eax; B
push ebx ; H
push edi
push esi
push ecx ; x+Xwin
mov ebx,[0x3010]
movzx ebx,byte[ebx+0xe]
cld
dbnpvga:
mov dl,[ds:ebp]
cmp dl,bl
jnz dbimpvgano
; mov edx,[esp+5*4] ; check limit?
; cmp edx,0
; jz dbimpvgayes
; call voodoodbcplimit
; jnz dbimpvgano
; dbimpvgayes:
push eax ; B
push ebx
push ecx ; x+Xwin
mov eax,[esp+12+20+16+4] ; color
mov ebx,eax
mov [esi],bx ; write LFB pixel
shr ebx,16
mov [esi+2],bl
and ecx,0x07 ; modulo 8
call setvgapixel ; eax=color, ecx=x%8, edi=VGA address
pop ecx
pop ebx
pop eax
dbimpvgano:
add esi,4 ; ptrLFB+=4
inc ebp ; address buffer
inc ecx ; x posn++
test ecx,0x07 ; test modulo 8
jnz dbvgacont
inc edi ; VGA screen ptr++
dbvgacont:
dec eax ; B-- NB ecx in Vesa20 fn?
jnz dbnpvga
dbnpvgad:
pop ecx
pop esi
pop edi
pop ebx
pop eax
add esi,[0xfe08] ; ptrLFB+=BytesPerScanLine
add edi,640/8 ; ptrScreen+=BytesPerScanLine
add ebp,[0xfe00] ;
sub ebp, eax ; was ecx in vesa20 fn?
inc ebp ; ptrBuffer:=ptrBuffer-B+BytesPerLine+1
dec ebx ; H--
jz nodbnewpivga ; H<>0
jmp dbnewpivga
nodbnewpivga:
add esp,7*4 ; NB includes limit check flag
;pop ebx
;pop eax
;pop edi
;pop esi
pop ebp
;pop edx
;pop ecx
; popad
ret
vga_drawbackground_tiled:
call [disable_mouse]
push ebp
push eax
push ebx
push ecx
push edx
mov edx,dword [0x400000-8] ; B
add edx,dword [WinMapAddress-8] ; +B
add edx,dword [WinMapAddress-8] ; +B
push edx
mov eax,[draw_data+32+0] ; x start:=(x+Xwin)
mov ebx,[draw_data+32+4] ; y start:=(y+Ywin)
mov ecx,eax
mov edx,ebx
imul edx, 640*4 ; (y+Ywin)*BytesPerScanLine
shl ecx,2 ; (x+Xwin)*BytesPerPixel
add ecx,edx ;
mov ebp,ecx ; store copy
add ecx,[0xfe80] ; +AddrLFB
;entry point in LFB >> ECX:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+Addr
shr ebp,5 ; change from 4 to 1/8 BytesPerPixel
add ebp,0xa0000 ; + VGABasePtr
;VGA start address >> EBP:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrV
call calculate_edi
dp3vga: ; MAIN LOOP
cmp [edi+WinMapAddress],byte 1 ; ptrBuffer^<>byte(1)
je ybgpvga
jmp nbgpvga
ybgpvga:
push eax ; x
push ebx ; y
push ecx ; LFB address
mov ecx,dword [WinMapAddress-8] ; B
xor edx,edx ; edx:=0
div ecx ; Xstart/B
; eax=Int(qn) edx:=Rem
lea esi,[edx+edx*2] ; esi:=edx*3
mov ecx,dword [WinMapAddress-4] ; ecx:=H
mov eax,[esp+4] ; eax:=Ystart
xor edx,edx ;
div ecx ; Ystart/H
mov eax,edx ; eax:=Rem
xor edx,edx ;
mov ebx,[esp+12] ; ebx:=B*3
mul ebx ;
add esi,eax ;
mov eax,[esi+0x300000] ; color
and eax,0xffffff
mov ecx, [esp] ; LFB address
mov ebx,eax ; copy color
mov [ecx],bx
shr ebx,16
mov [ecx+2],bl
xchg edi, ebp
mov ecx,[esp+8] ; x position
and ecx,0x07 ; x modulo 8
call setvgapixel ; eax=color, ecx=x%8, edi=VGA address
xchg ebp, edi
pop ecx
pop ebx
pop eax
nbgpvga:
inc eax ; x++
cmp eax,[draw_data+32+8] ; X > xend?
jg nodp3vga
test eax,0x07 ; x test modulo 8
jnz hook1vga
inc ebp ; VGA address++
hook1vga:
add ecx,4 ; LFB address += 4
inc edi ; ptrBuffer++
add esi,3 ; ptrImage+=3
jmp dp3vga
nodp3vga:
mov eax,[draw_data+32+0] ; x+Xwin
inc ebx ; y position
mov ecx,eax
mov edx,ebx
imul edx, 640*4 ; (y+Ywin)*BytesPerScanLine
shl ecx,2 ; (x+Xwin)*BytesPerPixel
add ecx,edx ;
mov ebp,ecx ; store copy
add ecx,[0xfe80] ; +AddrLFB
;entry point in LFB >> ECX:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+Addr
shr ebp,5 ; change from 4 to 1/8 BytesPerPixel
add ebp,0xa0000 ; + VGABasePtr
;VGA start address >> EBP:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrV
call calculate_edi
cmp ebx,[draw_data+32+12] ; Y > yend
jg dp4vga
jmp dp3vga
dp4vga:
add esp,4
pop edx
pop ecx
pop ebx
pop eax
pop ebp
ret
; ----------
vga_drawbackground_stretch:
call [disable_mouse]
push ebp
push eax
push ebx
push ecx
push edx
mov edx,dword [WinMapAddress-8] ; B
add edx,dword [WinMapAddress-8] ; +B
add edx,dword [WinMapAddress-8] ; +B
push edx
mov eax,[draw_data+32+0] ; x start:=(x+Xwin)
mov ebx,[draw_data+32+4] ; y start:=(y+Ywin)
mov ecx,eax
mov edx,ebx
imul edx, 640*4 ; (y+Ywin)*BytesPerScanLine
shl ecx,2 ; (x+Xwin)*BytesPerPixel
add ecx,edx ;
mov ebp,ecx ; store copy
add ecx,[0xfe80] ; +AddrLFB
;entry point in LFB >> ECX:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+Addr
shr ebp,5 ; change from 4 to 1/8 BytesPerPixel
add ebp,0xa0000 ; + VGABasePtr
;VGA start address >> EBP:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrV
call calculate_edi
sdp3vga: ; MAIN LOOP
cmp [edi+WinMapAddress],byte 1 ; ptrBuffer^<>byte(1)
je sybgpvga
jmp snbgpvga
sybgpvga:
push eax ; x
push ebx ; y
push ecx ; LFB address
mov eax,dword [WinMapAddress-8] ; B
xor edx,edx
mov ebx,[esp+8] ; Xstart
mul ebx ; B*Xstart
xor edx,edx
mov ebx,[0xfe00] ; x screen width
div ebx ; B*Xstart/xwidth
lea esi,[eax+eax*2] ; *3
mov eax,dword [WinMapAddress-4] ; H
xor edx,edx
mov ebx,[esp+4] ; Ystart
mul ebx ; H*Ystart
xor edx,edx
mov ebx,[0xfe04] ; y screen height
div ebx ; H*Ystart/yheight
xor edx,edx
mov ebx,[esp+12] ; B*3
mul ebx ;
add esi,eax
mov eax,[esi+0x300000] ; color
and eax,0xffffff
mov ecx, [esp] ; LFB address
mov ebx,eax ; copy color
mov [ecx],bx
shr ebx,16
mov [ecx+2],bl
xchg edi, ebp
mov ecx,[esp+8] ; x position
and ecx,0x07 ; x modulo 8
call setvgapixel ; eax=color, ecx=x%8, edi=VGA address
xchg ebp, edi ; ebp+=3
pop ecx
pop ebx
pop eax
snbgpvga:
inc eax ; x++
cmp eax,[draw_data+32+8] ; X > xend?
jg snodp3vga
test eax,0x07 ; x test modulo 8
jnz shook1vga
inc ebp ; VGA address++
shook1vga:
add ecx,4 ; LFB address += 4
inc edi ; ptrBuffer++
add esi,3 ; ptrImage+=3
jmp sdp3vga
snodp3vga:
mov eax,[draw_data+32+0] ; x+Xwin
inc ebx ; y position
mov ecx,eax
mov edx,ebx
imul edx, 640*4 ; (y+Ywin)*BytesPerScanLine
shl ecx,2 ; (x+Xwin)*BytesPerPixel
add ecx,edx ;
mov ebp,ecx ; store copy
add ecx,[0xfe80] ; +AddrLFB
;entry point in LFB >> ECX:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+Addr
shr ebp,5 ; change from 4 to 1/8 BytesPerPixel
add ebp,0xa0000 ; + VGABasePtr
;VGA start address >> EBP:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+A
call calculate_edi
cmp ebx,[draw_data+32+12] ; Y > yend
jg sdp4vga
jmp sdp3vga
sdp4vga:
add esp,4
pop edx
pop ecx
pop ebx
pop eax
pop ebp
ret