Subversion Repositories Kolibri OS

Compare Revisions

Problem with comparison.

Regard whitespace Rev HEAD → Rev 1

/trunk/video/vga.inc
0,0 → 1,781
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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:
 
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
 
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:
 
; 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
 
ret
 
 
vga_drawbar:
 
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
 
ret
 
 
vga_drawbackground_tiled:
 
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:
 
 
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