Subversion Repositories Kolibri OS

Compare Revisions

Problem with comparison.

Regard whitespace Rev HEAD → Rev 1

/trunk/video/vesa12.inc
0,0 → 1,973
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; VESA12.INC ;;
;; ;;
;; Vesa 1.2 functions for MenuetOS ;;
;; ;;
;; Copyright 2002 Ville Turjanmaa ;;
;; ;;
;; quickcode@mail.ru - bankswitch for S3 cards ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
; A complete video driver should include the following types of function
;
; Putpixel
; Getpixel
;
; Drawimage
; Drawbar
;
; Drawbackground
;
;
; Modifying the set_bank -function is mostly enough
; for different Vesa 1.2 setups.
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!{
 
; set_bank modified by kmeaw
set_bank:
cli
cmp al,[0xfff2]
je retsb
mov [0xfff2],al
push ax
push dx
push cx
mov cl, al
mov dx, 0x3D4
mov al, 0x38
out dx, al ;CR38 Register Lock 1 ;Note: Traditionally 48h is used to
;unlock and 00h to lock
inc dx
mov al, 0x48
out dx, al ;3d5 -?
dec dx
mov al, 0x31
out dx, al ;CR31 Memory Configuration Register
;0 Enable Base Address Offset (CPUA BASE). Enables bank operation if set, ;disables if clear.
;4-5 Bit 16-17 of the Display Start Address. For the 801/5,928 see index 51h,
;for the 864/964 see index 69h.
 
inc dx
in al, dx
dec dx
mov ah, al
mov al, 0x31
out dx, ax
mov al, ah
or al, 9
inc dx
out dx, al
dec dx
mov al, 0x35
out dx, al ;CR35 CRT Register Lock
inc dx
in al, dx
dec dx
and al, 0xF0
mov ch, cl
and ch, 0x0F
or ch, al
mov al, 0x35
out dx, al
inc dx
mov al, ch
out dx, ax
dec dx
mov al, 0x51 ;Extended System Control 2 Register
out dx, al
inc dx
in al, dx
dec dx
and al, 0xF3
shr cl, 2
and cl, 0x0C
or cl, al
mov al, 0x51
out dx, al
inc dx
mov al, cl
out dx, al
dec dx
mov al, 0x38
out dx, al
inc dx
xor al, al
out dx, al
dec dx
pop cx
pop dx
pop ax
retsb:
sti
ret
 
;Set bank function for Intel 810/815 chipsets
; *****Modified by Protopopius, Russia.*****
; ********* http://menuetos.hut.ru **************
; ************************************************
;
;set_bank:
;cli
;cmp al,[0xfff2]
;je retsb
;mov [0xfff2],al
;push ax
;push dx
;mov dx,3CEh
;mov ah,al ; Save value for later use
;mov al,10h ; Index GR10 (Address Mapping)
;out dx,al ; Select GR10
;inc dl
;mov al,3 ; Set bits 0 and 1 (Enable linear page mapping)
;out dx,al ; Write value
;dec dl
;mov al,11h ; Index GR11 (Page Selector)
;out dx,al ; Select GR11
;inc dl
;mov al,ah ; Write address
;out dx,al ; Write the value
;pop dx
;pop ax
;retsb:
;sti
;ret
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
 
;set_bank:
; cli
; cmp al,[0xfff2]
; je retsb
; mov [0xfff2],al
; push ax
; push dx
; mov ah,al
; mov dx,0x03D4
; mov al,0x39
; out dx,al
; inc dl
; mov al,0xA5
; out dx,al
; dec dl
; mov al,6Ah
; out dx,al
; inc dl
; mov al,ah
; out dx,al
; dec dl
; mov al,0x39
; out dx,al
; inc dl
; mov al,0x5A
; out dx,al
; dec dl
; pop dx
; pop ax
;
; retsb:
; ret
 
 
vesa12_drawbackground:
 
call [disable_mouse]
 
push eax
push ebx
push ecx
push edx
 
xor edx,edx
mov eax,dword[WinMapAddress-8]
mov ebx,dword[WinMapAddress-4]
mul ebx
mov ebx,3
mul ebx
mov [imax],eax
mov eax,[draw_data+32+0]
mov ebx,[draw_data+32+4]
mov edi,0 ;no force
 
v12dp3:
 
push eax
push ebx
mov esi,0x300000
 
cmp [WinMapAddress-12],dword 1 ; tiled background
jne no_vesa12_tiled_bgr
 
push edx
 
xor edx,edx
mov ecx,[WinMapAddress-8]
div ecx
mov eax,edx
 
push eax
mov eax,ebx
xor edx,edx
mov ecx,[WinMapAddress-4]
div ecx
mov ebx,edx
pop eax
 
pop edx
 
no_vesa12_tiled_bgr:
 
cmp [WinMapAddress-12],dword 2 ; stretched background
jne no_vesa12_stretched_bgr
 
push edx
 
imul eax,dword [WinMapAddress-8]
xor edx,edx
mov ecx,[0xfe00]
inc ecx
div ecx
 
push eax
mov eax,ebx
imul eax,dword [WinMapAddress-4]
xor edx,edx
mov ecx,[0xfe04]
inc ecx
div ecx
mov ebx,eax
pop eax
 
pop edx
 
no_vesa12_stretched_bgr:
 
 
push eax
mov eax,ebx
xor edx,edx
mov ebx,[WinMapAddress-8]
add ebx,[WinMapAddress-8]
add ebx,[WinMapAddress-8]
mul ebx
mov esi,eax
pop eax
add esi,eax
add esi,eax
add esi,eax
add esi,0x300000
pop ebx
pop eax
 
v12di4:
 
mov ecx,[esi]
pusha
mov esi,eax
mov edi,ebx
mov eax,[0xfe00]
add eax,1
mul ebx
add eax,esi
add eax,WinMapAddress
cmp [eax],byte 1
jnz v12nbgp
mov eax,[0xfe08]
mov ebx,edi
mul ebx
add eax,esi
add eax,esi
add eax,esi
cmp [0xFBF1],byte 24
jz v12bgl3
add eax,esi
 
v12bgl3:
 
push ebx
push eax
 
sub eax,[0xfe80]
 
shr eax,16
call set_bank
pop eax
and eax,65535
add eax,0xa0000
pop ebx
 
mov [eax],cx
add eax,2
shr ecx,16
mov [eax],cl
sti
 
v12nbgp:
 
popa
add esi,3
inc eax
cmp eax,[draw_data+32+8]
jg v12nodp31
jmp v12dp3
 
v12nodp31:
 
mov eax,[draw_data+32+0]
inc ebx
cmp ebx,[draw_data+32+12]
jg v12dp4
jmp v12dp3
 
v12dp4:
 
pop edx
pop ecx
pop ebx
pop eax
ret
 
 
vesa12_drawbar:
 
call [disable_mouse]
 
;; mov [novesachecksum],dword 0
sub edx,ebx
sub ecx,eax
push esi
push edi
push eax
push ebx
push ecx
push edx
mov ecx,[0x3010]
add eax,[ecx-twdw]
add ebx,[ecx-twdw+4]
push eax
mov eax,ebx ; y
mov ebx,[0xfe08]
mul ebx
pop ecx
add eax,ecx ; x
add eax,ecx
add eax,ecx
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x start
jz dbpi2412
add eax,ecx
 
dbpi2412:
 
add eax,[0xfe80]
mov edi,eax
 
; x size
 
mov eax,[esp+4] ; [esp+6]
mov ecx,eax
add ecx,eax
add ecx,eax
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x size
jz dbpi24312
add ecx,eax
 
dbpi24312:
 
mov ebx,[esp+0]
 
; check limits ?
 
push eax
push ecx
mov eax,[0x3010]
mov ecx,[eax+draw_data-0x3000+0]
cmp ecx,0
jnz dbcblimitlset12
mov ecx,[eax+draw_data-0x3000+4]
cmp ecx,0
jnz dbcblimitlset12
mov ecx,[eax+draw_data-0x3000+8]
cmp ecx,[0xfe00]
jnz dbcblimitlset12
mov ecx,[eax+draw_data-0x3000+12]
cmp ecx,[0xfe04]
jnz dbcblimitlset12
pop ecx
pop eax
push dword 0
jmp dbcblimitlno12
 
dbcblimitlset12:
 
pop ecx
pop eax
push dword 1
 
dbcblimitlno12:
 
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ?
jz dbpi24bit12
jmp dbpi32bit12
 
 
; DRAWBAR 24 BBP
 
 
dbpi24bit12:
 
push eax
push ebx
push edx
mov eax,ecx
mov ebx,3
div ebx
mov ecx,eax
pop edx
pop ebx
pop eax
cld
 
dbnewpi12:
 
push ebx
push edi
push ecx
 
xor edx,edx
mov eax,edi
sub eax,[0xfe80]
mov ebx,3
div ebx
add eax,WinMapAddress
mov ebx,[0x3010]
movzx ebx,byte[ebx+0xe]
cld
 
dbnp2412:
 
mov dl,[eax]
push eax
push ecx
cmp dl,bl
jnz dbimp24no12
cmp [esp+5*4],dword 0
jz dbimp24yes12
; call dbcplimit
; jnz dbimp24no12
 
dbimp24yes12:
 
push edi
mov eax,edi
sub eax,[0xfe80]
shr eax,16
call set_bank
and edi,0xffff
add edi,0xa0000
mov eax,[esp+8+3*4+16+4+4]
stosw
shr eax,16
stosb
sti
pop edi
add edi,3
pop ecx
pop eax
inc eax
loop dbnp2412
jmp dbnp24d12
 
dbimp24no12:
 
pop ecx
pop eax
cld
add edi,3
inc eax
loop dbnp2412
 
dbnp24d12:
 
mov eax,[esp+3*4+16+4]
test eax,0x80000000
jz nodbgl2412
cmp al,0
jz nodbgl2412
dec eax
mov [esp+3*4+16+4],eax
 
nodbgl2412:
 
pop ecx
pop edi
pop ebx
add edi,[0xfe08]
dec ebx
jz dbnonewpi12
jmp dbnewpi12
 
dbnonewpi12:
 
add esp,7*4
 
ret
 
 
; DRAWBAR 32 BBP
 
 
dbpi32bit12:
 
cld
shr ecx,2
 
dbnewpi3212:
 
push ebx
push edi
push ecx
 
mov eax,edi
sub eax,[0xfe80]
shr eax,2
add eax,WinMapAddress
mov ebx,[0x3010]
movzx ebx,byte[ebx+0xe]
cld
 
dbnp3212:
 
mov dl,[eax]
push eax
push ecx
cmp dl,bl
jnz dbimp32no12
cmp [esp+5*4],dword 0
jz dbimp32yes12
; call dbcplimit
; jnz dbimp32no12
 
dbimp32yes12:
 
push edi
mov eax,edi
sub eax,[0xfe80]
shr eax,16
call set_bank
and edi,0xffff
add edi,0xa0000
mov eax,[esp+8+3*4+16+4+4]
stosw
shr eax,16
stosb
sti
pop edi
add edi,4
inc ebp
pop ecx
pop eax
inc eax
loop dbnp3212
jmp dbnp32d12
 
dbimp32no12:
 
pop ecx
pop eax
inc eax
add edi,4
inc ebp
loop dbnp3212
 
dbnp32d12:
 
mov eax,[esp+12+16+4]
test eax,0x80000000
jz nodbgl3212
cmp al,0
jz nodbgl3212
dec eax
mov [esp+12+16+4],eax
 
nodbgl3212:
 
pop ecx
pop edi
pop ebx
add edi,[0xfe08]
dec ebx
jz nodbnewpi3212
jmp dbnewpi3212
 
nodbnewpi3212:
 
add esp,7*4
ret
 
 
Vesa12_putpixel24:
 
mov edi,eax ; x
mov eax,ebx ; y
lea edi,[edi+edi*2]
mov ebx,[0xfe08]
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,0xa0000
mov eax,[esp+28]
stosw
shr eax,16
mov [edi],al
sti
ret
 
 
 
Vesa12_putpixel32:
 
mov edi,eax ; x
mov eax,ebx ; y
shl edi,2
mov ebx,[0xfe08]
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,0xa0000
mov ecx,[esp+28]
mov [edi],ecx
sti
ret
 
 
Vesa12_getpixel24:
 
mov edi,eax ; x
mov eax,ebx ; y
lea edi,[edi+edi*2]
mov ebx,[0xfe08]
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,0xa0000
mov ecx,[edi]
and ecx,255*256*256+255*256+255
sti
ret
 
 
Vesa12_getpixel32:
 
mov edi,eax ; x
mov eax,ebx ; y
shl edi,2
mov ebx,[0xfe08]
xor edx,edx
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,0xa0000
mov ecx,[edi]
and ecx,255*256*256+255*256+255
sti
 
ret
 
 
 
vesa12_putimage:
 
; mov ebx,image
; mov ecx,320*65536+240
; mov edx,20*65536+20
 
call [disable_mouse]
 
mov [novesachecksum],dword 0
push esi
push edi
push eax
push ebx
push ecx
push edx
movzx eax,word [esp+2]
movzx ebx,word [esp+0]
mov ecx,[0x3010]
add eax,[ecx-twdw]
add ebx,[ecx-twdw+4]
push eax
mov eax,ebx ; y
mov ebx,[0xfe08]
mul ebx
pop ecx
add eax,ecx ; x
add eax,ecx
add eax,ecx
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x start
jz pi2412
add eax,ecx
 
pi2412:
 
add eax,[0xfe80]
mov edi,eax
 
; x size
 
movzx eax,word [esp+6]
mov ecx,eax
add ecx,eax
add ecx,eax
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x size
jz pi24312
add ecx,eax
 
pi24312:
 
mov esi,[esp+8]
movzx ebx,word [esp+4]
 
; check limits while draw ?
 
push eax
push ecx
mov eax,[0x3010]
mov ecx,[eax+draw_data-0x3000+0]
cmp ecx,0
jnz dbcblimitlset212
mov ecx,[eax+draw_data-0x3000+4]
cmp ecx,0
jnz dbcblimitlset212
mov ecx,[eax+draw_data-0x3000+8]
cmp ecx,[0xfe00]
jnz dbcblimitlset212
mov ecx,[eax+draw_data-0x3000+12]
cmp ecx,[0xfe04]
jnz dbcblimitlset212
pop ecx
pop eax
push dword 0
jmp dbcblimitlno212
 
dbcblimitlset212:
 
pop ecx
pop eax
push dword 1
 
dbcblimitlno212:
 
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ?
jz pi24bit12
jmp pi32bit12
 
pi24bit12:
 
cld
push eax
push ebx
push edx
xor edx,edx
mov eax,ecx
mov ebx,3
div ebx
mov ecx,eax
pop edx
pop ebx
pop eax
 
newpi12:
 
push edi
push esi
push ecx
push ebx
 
xor edx,edx
mov eax,edi
sub eax,[0xfe80]
mov ebx,3
div ebx
add eax,WinMapAddress
mov ebx,[0x3010]
mov bl,[ebx+0xe]
mov bh,[esp+4*4]
 
np2412:
 
cmp bl,[eax]
jnz imp24no12
mov edx,[esi]
cmp bh,0
jz imp24yes12
; call dbcplimit
; jnz imp24no12
 
imp24yes12:
 
push eax
push edi
mov eax,edi
sub eax,[0xfe80]
shr eax,16
call set_bank
and edi,0xffff
add edi,0xa0000
mov [edi],edx
shr edx,2
mov [edi+2],dl
sti
pop edi
pop eax
 
imp24no12:
 
inc eax
add esi,3
add edi,3
dec ecx
jnz np2412
 
np24d12:
 
pop ebx
pop ecx
pop esi
pop edi
 
add edi,[0xfe08]
xor eax,eax
mov ax,[esp+4+2+4]
lea eax,[eax+eax*2]
add esi,eax
dec ebx
jz nonewpi12
jmp newpi12
 
nonewpi12:
 
add esp,7*4
mov eax,0
ret
 
 
pi32bit12:
 
cld
shr ecx,2
 
newpi3212:
 
push edi
push esi
push ecx
push ebx
 
mov eax,edi
sub eax,[0xfe80]
shr eax,2
add eax,WinMapAddress
mov ebx,[0x3010]
mov bl,[ebx+0xe]
mov bh,[esp+4*4]
 
np3212:
 
cmp bl,[eax]
jnz imp32no12
mov edx,[esi]
cmp bh,0
jz imp32yes12
; call dbcplimit
; jnz imp32no12
 
imp32yes12:
 
push eax
push edi
mov eax,edi
sub eax,[0xfe80]
shr eax,16
call set_bank
and edi,0xffff
add edi,0xa0000
mov [edi],edx
sti
pop edi
pop eax
 
imp32no12:
 
inc eax
add esi,3
add edi,4
dec ecx
jnz np3212
 
np32d12:
 
pop ebx
pop ecx
pop esi
pop edi
 
add edi,[0xfe08]
movzx eax,word [esp+4+2+4]
lea eax,[eax+eax*2]
add esi,eax
dec ebx
jz nonewpi3212
jmp newpi3212
 
nonewpi3212:
 
add esp,7*4
mov eax,0
ret
 
 
vesa12_read_screen_pixel:
 
and eax,0x3FFFFF
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ?
jz v12rsp24
mov edi,eax
shl edi,2
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,0xa0000
mov eax,[edi]
and eax,0x00ffffff
ret
v12rsp24:
 
imul eax,3
mov edi,eax
shr eax,16
call set_bank
and edi,65535
add edi,0xa0000
mov eax,[edi]
and eax,0x00ffffff
ret
 
 
/trunk/video/vesa20.inc
0,0 → 1,1107
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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 0x460000
 
 
 
;*************************************************
; getpixel
;
; in:
; eax = x coordinate
; ebx = y coordinate
;
; ret:
; ecx = 00 RR GG BB
 
getpixel:
push eax ebx edx edi
call dword [0xe024]
pop edi edx ebx 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
 
;*************************************************
 
virtual at esp
putimg:
.real_sx dd ?
.real_sy dd ?
.image_sx dd ?
.image_sy dd ?
.image_cx dd ?
.image_cy dd ?
.pti dd ?
.abs_cx dd ?
.abs_cy dd ?
.line_increment dd ?
.source_bpp dd ?
.winmap_newline dd ?
.screen_newline dd ?
.stack_data = 4*13
end virtual
 
align 4
; ebx = pointer
; ecx = size [x|y]
; edx = coordinates [x|y]
vesa20_putimage:
pushad
call [disable_mouse]
 
sub esp, putimg.stack_data
 
mov [putimg.source_bpp], 3
; test ebx, 0x80000000
; jz @f
; inc [putimg.source_bpp]
; @@:
; and ebx, 0x7FFFFFFF
 
; save pointer to image
mov [putimg.pti], ebx
 
; unpack the size
mov eax, ecx
and ecx, 0xFFFF
shr eax, 16
mov [putimg.image_sx], eax
mov [putimg.image_sy], ecx
 
; unpack the coordinates
mov eax, edx
and edx, 0xFFFF
shr eax, 16
mov [putimg.image_cx], eax
mov [putimg.image_cy], edx
 
; calculate absolute (i.e. screen) coordinates
mov eax, [0x3010]
mov ebx, [eax-twdw + 0]
add ebx, [putimg.image_cx]
mov [putimg.abs_cx], ebx
mov ebx, [eax-twdw + 4]
add ebx, [putimg.image_cy]
mov [putimg.abs_cy], ebx
 
; real_sx = MIN(wnd_sx-image_cx, image_sx);
mov ebx, [eax-twdw + 8] ; ebx = wnd_sx
sub ebx, [putimg.image_cx]
ja @f
add esp, putimg.stack_data
popad
xor eax, eax
inc eax
ret
@@:
cmp ebx, [putimg.image_sx]
jbe .end_x
mov ebx, [putimg.image_sx]
dec ebx
.end_x:
inc ebx
mov [putimg.real_sx], ebx
 
; init real_sy
mov ebx, [eax-twdw + 12] ; ebx = wnd_sy
sub ebx, [putimg.image_cy]
ja @f
add esp, putimg.stack_data
popad
xor eax, eax
inc eax
ret
@@:
cmp ebx, [putimg.image_sy]
jbe .end_y
mov ebx, [putimg.image_sy]
dec ebx
.end_y:
inc ebx
mov [putimg.real_sy], ebx
 
; line increment
mov eax, [putimg.image_sx]
sub eax, [putimg.real_sx]
;; imul eax, [putimg.source_bpp]
lea eax, [eax + eax * 2]
mov [putimg.line_increment], eax
 
; winmap new line increment
mov eax, [ScreenWidth]
inc eax
sub eax, [putimg.real_sx]
mov [putimg.winmap_newline], eax
 
; screen new line increment
mov eax, [BytesPerScanLine]
mov ecx, [putimg.real_sx]
movzx ebx, byte [ScreenBPP]
shr ebx, 3
imul ecx, ebx
sub eax, ecx
mov [putimg.screen_newline], eax
 
; pointer to image
mov ecx, [putimg.pti]
 
; pointer to screen
mov edx, [putimg.abs_cy]
imul edx, [BytesPerScanLine]
mov eax, [putimg.abs_cx]
movzx ebx, byte [ScreenBPP]
shr ebx, 3
imul eax, ebx
add edx, eax
add edx, [LFBAddress]
 
; pointer to pixel map
mov eax, [putimg.abs_cy]
imul eax, [ScreenWidth]
add eax, [putimg.abs_cy]
add eax, [putimg.abs_cx]
add eax, WinMapAddress
xchg eax, ebp
 
; get process number
mov eax, [0x3010]
mov bl, [eax+0xE]
 
cmp byte [ScreenBPP], 32
je put_image_end_32
 
;put_image_end_24:
;cli ; !!!!!!!!!!!!!!!!!!!!!!
mov edi, [putimg.real_sy]
align 4
.new_line:
mov esi, [putimg.real_sx]
 
; push ebp edx
align 4
.new_x:
 
cmp [ebp], bl
jne .skip
mov eax, [ecx] ; ecx = RRBBGGRR
mov [edx], ax
shr eax, 16
mov [edx+2], al
.skip:
 
add ecx, 3 ;[putimg.source_bpp]
add edx, 3
inc ebp
 
dec esi
jnz .new_x
; pop edx ebp
 
add ecx, [putimg.line_increment]
add edx, [putimg.screen_newline] ;[BytesPerScanLine]
add ebp, [putimg.winmap_newline] ;[ScreenWidth]
;inc ebp
 
dec edi
jnz .new_line
.finish:
add esp, putimg.stack_data
popad
xor eax, eax
;sti ; !!!!!!!!!!!!!!!!!!!!!
ret
 
put_image_end_32:
mov edi, [putimg.real_sy]
align 4
.new_line:
mov esi, [putimg.real_sx]
 
; push ebp edx
align 4
.new_x:
 
cmp [ebp], bl
jne .skip
mov eax, [ecx] ; ecx = RRBBGGRR
mov [edx], eax
.skip:
 
add ecx, [putimg.source_bpp]
add edx, 4
inc ebp
 
dec esi
jnz .new_x
; pop edx ebp
 
add ecx, [putimg.line_increment]
add edx, [putimg.screen_newline] ;[BytesPerScanLine]
add ebp, [putimg.winmap_newline] ;[ScreenWidth]
;inc ebp
 
dec edi
jnz .new_line
.finish:
add esp, putimg.stack_data
popad
xor eax, eax
ret
 
 
;*************************************************
align 4
__sys_putpixel:
 
; eax = x coordinate
; ebx = y coordinate
; ecx = ?? RR GG BB ; 0x01000000 negation
; edi = 0x00000001 force
 
;;; mov [novesachecksum], dword 0
 
pushad
test edi,1 ; force ?
jnz .forced
; not forced:
call checkpixel
test ecx,ecx
jnz .exit
.forced:
cmp [ScreenWidth], eax
jb .exit
cmp [ScreenHeight], ebx
jb .exit
.ok:
; 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] ; call the real put_pixel function
.exit:
popad
ret
 
align 4
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
 
 
align 4
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
 
 
;*************************************************
 
;align 4
calculate_edi:
mov edi, ebx
imul edi, [ScreenWidth]
add edi, ebx
add edi, eax
ret
 
;*************************************************
 
; DRAWLINE
 
align 4
__sys_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
 
align 4
 
.draw:
push eax ebx
shr eax, 16
shr ebx, 16
call [putpixel]
pop ebx 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 edx
 
cmp edx, eax ; make sure x2 is above x1
jge @f
xchg eax, edx
align 4
@@:
call [putpixel]
inc eax
cmp eax, edx
jle @b
 
pop edx eax
ret
 
 
vline:
; draw a vertical line
; eax = x
; ebx = y1
; edx = y2
; ecx = color
; edi = force ?
push ebx edx
 
cmp edx, ebx ; make sure y2 is above y1
jge @f
xchg ebx, edx
align 4
@@:
call [putpixel]
inc ebx
cmp ebx, edx
jle @b
 
pop edx ebx
ret
 
 
;*************************************************
 
 
virtual at esp
drbar:
.bar_sx dd ?
.bar_sy dd ?
.bar_cx dd ?
.bar_cy dd ?
.abs_cx dd ?
.abs_cy dd ?
.real_sx dd ?
.real_sy dd ?
.color dd ?
.line_inc_scr dd ?
.line_inc_map dd ?
.stack_data = 4*11
end virtual
 
align 4
; eax cx
; ebx cy
; ecx xe
; edx ye
; edi color
vesa20_drawbar:
pushad
call [disable_mouse]
 
sub esp, drbar.stack_data
 
mov [drbar.color], edi
 
sub edx, ebx
sub ecx, eax
mov [drbar.bar_sy], edx
mov [drbar.bar_sx], ecx
 
mov [drbar.bar_cx], eax
mov [drbar.bar_cy], ebx
 
mov edi, [0x3010]
add eax, [edi-twdw + 0] ; win_cx
add ebx, [edi-twdw + 4] ; win_cy
mov [drbar.abs_cx], eax
mov [drbar.abs_cy], ebx
 
; real_sx = MIN(wnd_sx-bar_cx, bar_sx);
mov ebx, [edi-twdw + 8] ; ebx = wnd_sx
sub ebx, [drbar.bar_cx]
ja @f
add esp, drbar.stack_data
popad
xor eax, eax
inc eax
ret
@@:
cmp ebx, [drbar.bar_sx]
jbe .end_x
mov ebx, [drbar.bar_sx]
.end_x:
mov [drbar.real_sx], ebx
 
; real_sy = MIN(wnd_sy-bar_cy, bar_sy);
mov ebx, [edi-twdw + 12] ; ebx = wnd_sy
sub ebx, [drbar.bar_cy]
ja @f
add esp, drbar.stack_data
popad
xor eax, eax
inc eax
ret
@@:
cmp ebx, [drbar.bar_sy]
jbe .end_y
mov ebx, [drbar.bar_sy]
.end_y:
mov [drbar.real_sy], ebx
 
; line_inc_map
mov eax, [ScreenWidth]
sub eax, [drbar.real_sx]
inc eax
mov [drbar.line_inc_map], eax
 
; line_inc_scr
mov eax, [drbar.real_sx]
movzx ebx, byte [ScreenBPP]
shr ebx, 3
imul eax, ebx
neg eax
add eax, [BytesPerScanLine]
mov [drbar.line_inc_scr], eax
 
; pointer to screen
mov edx, [drbar.abs_cy]
imul edx, [BytesPerScanLine]
mov eax, [drbar.abs_cx]
; movzx ebx, byte [ScreenBPP]
; shr ebx, 3
imul eax, ebx
add edx, eax
add edx, [LFBAddress]
 
; pointer to pixel map
mov eax, [drbar.abs_cy]
imul eax, [ScreenWidth]
add eax, [drbar.abs_cy]
add eax, [drbar.abs_cx]
add eax, WinMapAddress
xchg eax, ebp
 
; get process number
mov eax, [0x3010]
mov bl, [eax+0xE]
 
cmp byte [ScreenBPP], 24
jne draw_bar_end_32
draw_bar_end_24:
;cli ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
mov eax, [drbar.color] ;; BBGGRR00
mov bh, al ;; bh = BB
shr eax, 8 ;; eax = RRGG
; eax - color high RRGG
; bl - process num
; bh - color low BB
; ecx - temp
; edx - pointer to screen
; esi - counter
; edi - counter
 
mov esi, [drbar.real_sy]
align 4
.new_y:
mov edi, [drbar.real_sx]
align 4
.new_x:
 
cmp byte [ebp], bl
jne .skip
mov [edx], bh
mov [edx + 1], ax
.skip:
 
; add pixel
add edx, 3
inc ebp
 
dec edi
jnz .new_x
 
; add line
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
 
; <Ivan 15.10.04> drawing gradient bars
test eax, 0x00800000
jz @f
test bh, bh
jz @f
dec bh
@@:
; </Ivan 15.10.04>
 
dec esi
jnz .new_y
 
add esp, drbar.stack_data
popad
xor eax, eax
;sti ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ret
 
draw_bar_end_32:
mov eax, [drbar.color] ;; BBGGRR00
 
mov esi, [drbar.real_sy]
align 4
.new_y:
mov edi, [drbar.real_sx]
align 4
.new_x:
 
cmp byte [ebp], bl
jne .skip
mov [edx], eax
.skip:
 
; add pixel
add edx, 4
inc ebp
 
dec edi
jnz .new_x
 
; add line
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
 
; <Ivan 15.10.04> drawing gradient bars
test eax, 0x80000000
jz @f
test al, al
jz @f
dec al
@@:
; </Ivan 15.10.04>
 
dec esi
jnz .new_y
 
add esp, drbar.stack_data
popad
xor eax, eax
ret
 
 
;voodoodbcplimit:
 
; ebp:=(y+Ywin)*(ScreenXSize+1)+(x+Xwin)+AddrBuffer
 
 
; pusha
 
; xor edx,edx
; mov eax,ebp
; mov ebx,[ScreenWidth] ; Screen_X_size
; inc ebx ; +1
; sub eax,WinMapAddress ; -AddrBuffer
; div ebx ;
; mov ebx,eax ; ebx:=Y
; mov eax,edx ; eax:=X
; call cplimit
 
; test ecx,ecx
; jne dbcpl12
; popa
; clc
; ret
; dbcpl12:
; popa
; stc
; ret
 
 
 
 
;dbcplimit:
 
; pusha
 
; xor edx,edx
; mov ebx,[ScreenWidth]
; inc ebx
; sub eax,WinMapAddress
; div ebx
; mov ebx,eax
; mov eax,edx
; call cplimit
 
; test ecx,ecx
; jne dbcpl1
; popa
; clc
; ret
; dbcpl1:
; popa
; stc
; ret
 
 
 
 
 
 
;--------------vbe voodoo ------------------------------------------------
vesa20_drawbackground_tiled:
 
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 ebp,[draw_data+32+0] ; x start:=(x+Xwin)
mov ebx,[draw_data+32+4] ; y start:=(y+Ywin)
 
mov eax,[BytesPerScanLine]
mul ebx
xchg ebp, eax ; BytesPerScanLine*(Ywin+y)
add ebp, eax ; +X
add ebp, eax ; +X
add ebp, eax ; +X
 
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz @f
add ebp,eax ; +X
@@:
add ebp,[LFBAddress] ; +LFB
 
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
 
call calculate_edi
 
 
dp3: ; MAIN LOOP
 
cmp [edi+WinMapAddress],byte 1 ; ptrBuffer^<>byte(1)
; je ybgp
;
; jmp nbgp
;
; ybgp:
jne nbgp
 
push eax
push ebx
 
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+0] ; eax:=Ystart
xor edx,edx ;
div ecx ; Ystart/H
 
mov eax,edx ; eax:=Rem
xor edx,edx ;
mov ebx,[esp+8] ; ebx:=B*3
mul ebx ;
add esi,eax ;
mov eax,[esi+0x300000]
and eax,0xffffff
 
xchg edi, ebp
stosw
shr eax,16
stosb
xchg ebp, edi ; ebp+=3
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz @f
inc ebp ; +1
@@:
 
pop ebx
pop eax
 
jmp hook1
 
nbgp:
add ebp,3 ; +3
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz @f
inc ebp ; +1
@@:
 
hook1:
 
inc edi ; ptrBuffer++
add esi,3 ; ptrImage+=3
inc eax
cmp eax,[draw_data+32+8] ; X > xend?
; jg nodp3
; jmp dp3
;
; nodp3:
jle dp3
 
mov ebp,[draw_data+32+0]
 
inc ebx
 
mov eax,[BytesPerScanLine]
mul ebx
xchg ebp, eax ; BytesPerScanLine*(Ywin+y)
add ebp, eax ; +X
add ebp, eax ; +X=X*2
add ebp, eax ; +X=X*3
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz @f
add ebp,eax ; +X=X*4
@@:
add ebp,[LFBAddress] ; +LFB
 
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
 
call calculate_edi
 
cmp ebx,[draw_data+32+12]
; jg dp4
;
; jmp dp3
;
; dp4:
jle dp3
 
add esp,4
 
pop edx
pop ecx
pop ebx
pop eax
pop ebp
 
ret
 
; ----------
 
 
vesa20_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 ebp,[draw_data+32+0] ; x start:=(x+Xwin)
mov ebx,[draw_data+32+4] ; y start:=(y+Ywin)
 
mov eax,[BytesPerScanLine]
mul ebx
xchg ebp, eax ; BytesPerScanLine*(Ywin+y)
add ebp, eax ; +X
add ebp, eax ; +X
add ebp, eax ; +X
 
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz @f
add ebp,eax ; +X
@@:
add ebp,[LFBAddress] ; +LFB
 
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
 
call calculate_edi
 
 
sdp3: ; MAIN LOOP
 
cmp [edi+WinMapAddress],byte 1 ; ptrBuffer^<>byte(1)
jne snbgp
 
push eax
push ebx
 
mov eax,dword [WinMapAddress-8]
imul eax, [esp+4] ;4
xor edx,edx
mov ebx,[ScreenWidth]
div ebx
lea esi,[eax+eax*2]
mov eax,dword [WinMapAddress-4]
imul eax, [esp+0] ;0
xor edx,edx
mov ebx,[ScreenHeight]
div ebx
imul eax, [esp+8] ;8
add esi,eax
 
mov eax,[esi+0x300000]
and eax,0xffffff
 
xchg edi, ebp
stosw
shr eax,16
stosb
xchg ebp, edi ; ebp+=3
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz @f
inc ebp ; +1
@@:
 
pop ebx
pop eax
 
jmp shook1
 
snbgp:
add ebp,3 ; +3
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz @f
inc ebp ; +1
@@:
 
shook1:
 
inc edi ; ptrBuffer++
add esi,3 ; ptrImage+=3
inc eax
cmp eax,[draw_data+32+8] ; X > xend?
jle sdp3
 
mov ebp,[draw_data+32+0]
 
inc ebx
 
mov eax,[BytesPerScanLine]
mul ebx
xchg ebp, eax ; BytesPerScanLine*(Ywin+y)
add ebp, eax ; +X
add ebp, eax ; +X=X*2
add ebp, eax ; +X=X*3
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz @f
add ebp,eax ; +X=X*4
@@:
add ebp,[LFBAddress] ; +LFB
 
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
 
call calculate_edi
 
cmp ebx,[draw_data+32+12]
jle sdp3
 
add esp,4
 
pop edx
pop ecx
pop ebx
pop eax
pop ebp
 
ret
/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