/kernel/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 |
/kernel/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 |
/kernel/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 |