kolibrios/kernel/trunk/video/vesa20.inc

2519 lines
63 KiB
PHP
Raw Normal View History

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; 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 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
uglobal
align 4
bgr_cur_line rd 1920 ; maximum width of screen
bgr_next_line rd 1920
endg
iglobal
align 4
overlapping_of_points_ptr dd overlapping_of_points
endg
;-----------------------------------------------------------------------------
; eax = x
; ebx = y
align 4
Vesa20_getpixel16:
; check for hardware cursor
cmp [_display.select_cursor], select_cursor
je @f
cmp [_display.select_cursor], 0
jne .no_mouseunder
@@:
; check mouse area for putpixel
test ecx, 0x04000000 ; don't load to mouseunder area
jnz .no_mouseunder
call [_display.check_m_pixel]
test ecx, ecx ; 0xff000000
jnz @f
.no_mouseunder:
; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [eax*2] ; edi = x*2
add edi, ebx ; edi = x*2+(y*y multiplier)
movzx ecx, word[LFB_BASE+edi]
shl ecx, 3
ror ecx, 8
shl cx, 2
ror ecx, 8
shl cl, 3
rol ecx, 16
@@:
and ecx, 0x00ffffff
ret
;-----------------------------------------------------------------------------
; eax = x
; ebx = y
align 4
Vesa20_getpixel24:
; check for hardware cursor
cmp [_display.select_cursor], select_cursor
je @f
cmp [_display.select_cursor], 0
jne .no_mouseunder
@@:
; check mouse area for putpixel
test ecx, 0x04000000 ; don't load to mouseunder area
jnz .no_mouseunder
call [_display.check_m_pixel]
test ecx, ecx ; 0xff000000
jnz @f
.no_mouseunder:
; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [eax+eax*2] ; edi = x*3
add edi, ebx ; edi = x*3+(y*y multiplier)
mov ecx, [LFB_BASE+edi]
@@:
and ecx, 0x00ffffff
ret
;-----------------------------------------------------------------------------
; eax = x
; ebx = y
align 4
Vesa20_getpixel32:
; check for hardware cursor
cmp [_display.select_cursor], select_cursor
je @f
cmp [_display.select_cursor], 0
jne .no_mouseunder
@@:
; check mouse area for putpixel
test ecx, 0x04000000 ; don't load to mouseunder area
jnz .no_mouseunder
call [_display.check_m_pixel]
test ecx, ecx ; 0xff000000
jnz @f
.no_mouseunder:
; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier)
mov ecx, [LFB_BASE+edi]
@@:
and ecx, 0x00ffffff
ret
;-----------------------------------------------------------------------------
; ebx = pointer
; ecx = size [x|y]
; edx = coordinates [x|y]
; ebp = pointer to 'get' function
; esi = pointer to 'init' function
; edi = parameter for 'get' function
align 16
vesa20_putimage:
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 ?
.winmap_newline dd ?
.screen_newline dd ?
.real_sx_and_abs_cx dd ?
.real_sy_and_abs_cy dd ?
.stack_data = 4*14
.edi dd ?
.esi dd ?
.ebp dd ?
.esp dd ?
.ebx dd ?
.edx dd ?
.ecx dd ?
.eax dd ?
.ret_addr dd ?
.arg_0 dd ?
end virtual
pushad
sub esp, putimg.stack_data
; 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, [TASK_BASE]
mov ebx, [eax-twdw + WDATA.box.left]
add ebx, [putimg.image_cx]
mov [putimg.abs_cx], ebx
mov ebx, [eax-twdw + WDATA.box.top]
add ebx, [putimg.image_cy]
mov [putimg.abs_cy], ebx
; real_sx = MIN(wnd_sx-image_cx, image_sx);
mov ebx, [eax-twdw + WDATA.box.width] ; ebx = wnd_sx
inc ebx ; WDATA.box.width is one pixel less than real window x-size
sub ebx, [putimg.image_cx]
ja @f
add esp, putimg.stack_data
popad
ret
@@:
cmp ebx, [putimg.image_sx]
jbe .end_x
mov ebx, [putimg.image_sx]
.end_x:
mov [putimg.real_sx], ebx
; init real_sy
mov ebx, [eax-twdw + WDATA.box.height] ; ebx = wnd_sy
inc ebx
sub ebx, [putimg.image_cy]
ja @f
add esp, putimg.stack_data
popad
ret
@@:
cmp ebx, [putimg.image_sy]
jbe .end_y
mov ebx, [putimg.image_sy]
.end_y:
mov [putimg.real_sy], ebx
; line increment
mov eax, [putimg.image_sx]
mov ecx, [putimg.real_sx]
sub eax, ecx
;; imul eax, [putimg.source_bpp]
; lea eax, [eax + eax * 2]
call esi
add eax, [putimg.arg_0]
mov [putimg.line_increment], eax
; winmap new line increment
mov eax, [_display.width]
sub eax, [putimg.real_sx]
mov [putimg.winmap_newline], eax
; screen new line increment
mov eax, [_display.pitch]
mov ebx, [_display.bytes_per_pixel]
imul ecx, ebx
sub eax, ecx
mov [putimg.screen_newline], eax
; pointer to image
mov esi, [putimg.pti]
; pointer to screen
mov edx, [putimg.abs_cy]
; imul edx, [BytesPerScanLine]
mov edx, [BPSLine_calc_area+edx*4]
mov eax, [putimg.abs_cx]
imul eax, ebx
add edx, eax
; pointer to pixel map
mov eax, [putimg.abs_cy]
; imul eax, [Screen_Max_X]
; add eax, [putimg.abs_cy]
mov eax, [d_width_calc_area + eax*4]
add eax, [putimg.abs_cx]
add eax, [_WinMapAddress]
xchg eax, ebp
mov ecx, [putimg.real_sx]
add ecx, [putimg.abs_cx]
mov [putimg.real_sx_and_abs_cx], ecx
mov ecx, [putimg.real_sy]
add ecx, [putimg.abs_cy]
mov [putimg.real_sy_and_abs_cy], ecx
; get process number
mov ebx, [CURRENT_TASK]
cmp byte [_display.bits_per_pixel], 16
je put_image_end_16
cmp byte [_display.bits_per_pixel], 24
je put_image_end_24
cmp byte [_display.bits_per_pixel], 32
je put_image_end_32
;------------------------------------------------------------------------------
put_image_end_16:
mov edi, [putimg.real_sy]
; check for hardware cursor
mov ecx, [_display.select_cursor]
cmp ecx, select_cursor
je put_image_end_16_new
cmp ecx, 0
je put_image_end_16_old
.new_line:
mov ecx, [putimg.real_sx]
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
; convert to 16 bpp and store to LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [LFB_BASE+edx], ax
.skip:
add edx, 2
inc ebp
dec ecx
jnz .new_x
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
.finish:
add esp, putimg.stack_data
popad
ret
;------------------------------------------------------------------------------
align 4
put_image_end_16_old:
.new_line:
mov ecx, [putimg.real_sx]
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
push ecx
neg ecx
add ecx, [putimg.real_sx_and_abs_cx + 4]
shl ecx, 16
add ecx, [putimg.real_sy_and_abs_cy + 4]
sub ecx, edi
; check mouse area for putpixel
call check_mouse_area_for_putpixel
pop ecx
; convert to 16 bpp and store to LFB
;; and eax, 00000000111110001111110011111000b
;; shr ah, 2
;; shr ax, 3
;; ror eax, 8
;; add al, ah
;; rol eax, 8
mov [LFB_BASE+edx], ax
.skip:
inc edx
inc edx
inc ebp
dec ecx
jnz .new_x
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
jmp put_image_end_16.finish
;------------------------------------------------------------------------------
align 4
put_image_end_16_new:
.new_line:
mov ecx, [putimg.real_sx]
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
push ecx
.sh:
neg ecx
add ecx, [putimg.real_sx_and_abs_cx + 4]
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
shl ecx, 16
add ecx, [putimg.real_sy_and_abs_cy + 4]
sub ecx, edi
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
; check mouse area for putpixel
call check_mouse_area_for_putpixel_new.1
cmp ecx, -1 ; SHIT HAPPENS?
jne .no_mouse_area
mov ecx, [esp]
jmp .sh
.no_mouse_area:
pop ecx
; convert to 16 bpp and store to LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [LFB_BASE+edx], ax
.skip:
add edx, 2
inc ebp
dec ecx
jnz .new_x
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
jmp put_image_end_16.finish
;------------------------------------------------------------------------------
align 4
put_image_end_24:
mov edi, [putimg.real_sy]
; check for hardware cursor
mov ecx, [_display.select_cursor]
cmp ecx, select_cursor
je put_image_end_24_new
cmp ecx, 0
je put_image_end_24_old
.new_line:
mov ecx, [putimg.real_sx]
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
; store to LFB
mov [LFB_BASE+edx], ax
shr eax, 16
mov [LFB_BASE+edx+2], al
.skip:
add edx, 3
inc ebp
dec ecx
jnz .new_x
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
.finish:
add esp, putimg.stack_data
popad
ret
;------------------------------------------------------------------------------
align 4
put_image_end_24_old:
.new_line:
mov ecx, [putimg.real_sx]
;--------------------------------------
align 4
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
push ecx
neg ecx
add ecx, [putimg.real_sx_and_abs_cx + 4]
shl ecx, 16
add ecx, [putimg.real_sy_and_abs_cy + 4]
sub ecx, edi
; check mouse area for putpixel
call check_mouse_area_for_putpixel
pop ecx
; store to LFB
mov [LFB_BASE+edx], ax
shr eax, 16
mov [LFB_BASE+edx+2], al
.skip:
add edx, 3
inc ebp
dec ecx
jnz .new_x
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
jmp put_image_end_24.finish
;------------------------------------------------------------------------------
align 4
put_image_end_24_new:
.new_line:
mov ecx, [putimg.real_sx]
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
push ecx
.sh:
neg ecx
add ecx, [putimg.real_sx_and_abs_cx + 4]
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
shl ecx, 16
add ecx, [putimg.real_sy_and_abs_cy + 4]
sub ecx, edi
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
; check mouse area for putpixel
call check_mouse_area_for_putpixel_new.1
cmp ecx, -1 ; SHIT HAPPENS?
jne .no_mouse_area
mov ecx, [esp]
jmp .sh
.no_mouse_area:
pop ecx
; store to LFB
mov [LFB_BASE+edx], ax
shr eax, 16
mov [LFB_BASE+edx+2], al
.skip:
add edx, 3
inc ebp
dec ecx
jnz .new_x
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
jmp put_image_end_24.finish
;------------------------------------------------------------------------------
align 4
put_image_end_32:
mov edi, [putimg.real_sy]
; check for hardware cursor
mov ecx, [_display.select_cursor]
cmp ecx, select_cursor
je put_image_end_32_new
cmp ecx, 0
je put_image_end_32_old
.new_line:
mov ecx, [putimg.real_sx]
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
; store to LFB
mov [LFB_BASE+edx], eax
.skip:
add edx, 4
inc ebp
dec ecx
jnz .new_x
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
.finish:
add esp, putimg.stack_data
popad
cmp [SCR_MODE], 0x12
jne @f
call VGA__putimage
@@:
mov [EGA_counter], 1
ret
;------------------------------------------------------------------------------
align 4
put_image_end_32_old:
.new_line:
mov ecx, [putimg.real_sx]
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
push ecx
neg ecx
add ecx, [putimg.real_sx_and_abs_cx + 4]
shl ecx, 16
add ecx, [putimg.real_sy_and_abs_cy + 4]
sub ecx, edi
; check mouse area for putpixel
call check_mouse_area_for_putpixel
pop ecx
; store to LFB
mov [LFB_BASE+edx], eax
.skip:
add edx, 4
inc ebp
dec ecx
jnz .new_x
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
jmp put_image_end_32.finish
;------------------------------------------------------------------------------
align 4
put_image_end_32_new:
.new_line:
mov ecx, [putimg.real_sx]
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
push ecx
.sh:
neg ecx
add ecx, [putimg.real_sx_and_abs_cx + 4]
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
shl ecx, 16
add ecx, [putimg.real_sy_and_abs_cy + 4]
sub ecx, edi
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
; check mouse area for putpixel
call check_mouse_area_for_putpixel_new.1
cmp ecx, -1 ; SHIT HAPPENS?
jne .no_mouse_area
mov ecx, [esp]
jmp .sh
.no_mouse_area:
pop ecx
; store to LFB
mov [LFB_BASE+edx], eax
.skip:
add edx, 4
inc ebp
dec ecx
jnz .new_x
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
jmp put_image_end_32.finish
;------------------------------------------------------------------------------
; eax = x coordinate
; ebx = y coordinate
; ecx = xx RR GG BB
; xx flags:
; 0x01000000 color inversion
; 0x02000000 used for draw_rectangle without top line (for drawwindow_III and drawwindow_IV)
; edi = 0x00000001 force
align 4
__sys_putpixel:
pushad
cmp eax, [_display.width]
jge .exit
cmp ebx, [_display.height]
jge .exit
test edi, 1 ; force ?
jnz .forced
; not forced
mov edx, [d_width_calc_area + ebx*4]
add edx, [_WinMapAddress]
movzx edx, byte [eax+edx]
cmp edx, [CURRENT_TASK]
jne .exit
.forced:
; check for color inversion
test ecx, 0x01000000
jz .no_inv
push eax ebx edx edi
call [GETPIXEL]
pop edi edx ebx eax
not ecx
rol ecx, 8
mov cl, [esp+32-8+3]
ror ecx, 8
mov [esp+32-8], ecx
.no_inv:
call [PUTPIXEL] ; call the real put_pixel function
.exit:
popad
ret
;-----------------------------------------------------------------------------
; eax = x
; ebx = y
align 4
Vesa20_putpixel16:
mov ecx, eax
shl ecx, 16
mov cx, bx
; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [eax*2]; edi = x*2
mov eax, [esp+32-8+4]
; check for hardware cursor
cmp [_display.select_cursor], 0
jne @f
; check mouse area for putpixel
test eax, 0x04000000
jnz @f
call check_mouse_area_for_putpixel
@@:
; store to LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [LFB_BASE+ebx+edi], ax
ret
;-----------------------------------------------------------------------------
; eax = x
; ebx = y
align 4
Vesa20_putpixel16_new:
mov ecx, eax
shl ecx, 16
mov cx, bx
; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [eax*2]; edi = x*2
mov eax, [esp+32-8+4]
; check for hardware cursor
cmp [_display.select_cursor], select_cursor
jne @f
; check mouse area for putpixel
test eax, 0x04000000
jnz @f
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae @f
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb @f
rol ecx, 16
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae @f
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb @f
ror ecx, 16
call check_mouse_area_for_putpixel_new.1
@@:
; store to LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [LFB_BASE+ebx+edi], ax
ret
;-----------------------------------------------------------------------------
; eax = x
; ebx = y
align 4
Vesa20_putpixel24:
mov ecx, eax
shl ecx, 16
mov cx, bx
; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [eax+eax*2]; edi = x*3
mov eax, [esp+32-8+4]
; check for hardware cursor
cmp [_display.select_cursor], 0
jne @f
; check mouse area for putpixel
test eax, 0x04000000
jnz @f
call check_mouse_area_for_putpixel
@@:
; store to LFB
mov [LFB_BASE+ebx+edi], ax
shr eax, 16
mov [LFB_BASE+ebx+edi+2], al
ret
;-----------------------------------------------------------------------------
; eax = x
; ebx = y
align 4
Vesa20_putpixel24_new:
mov ecx, eax
shl ecx, 16
mov cx, bx
; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [eax+eax*2]; edi = x*3
mov eax, [esp+32-8+4]
; check for hardware cursor
cmp [_display.select_cursor], select_cursor
jne @f
; check mouse area for putpixel
test eax, 0x04000000
jnz @f
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae @f
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb @f
rol ecx, 16
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae @f
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb @f
ror ecx, 16
call check_mouse_area_for_putpixel_new.1
@@:
; store to LFB
mov [LFB_BASE+ebx+edi], ax
shr eax, 16
mov [LFB_BASE+ebx+edi+2], al
ret
;-----------------------------------------------------------------------------
; eax = x
; ebx = y
align 4
Vesa20_putpixel32:
mov ecx, eax
shl ecx, 16
mov cx, bx
; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier)
mov eax, [esp+32-8+4] ; eax = color
; check for hardware cursor
cmp [_display.select_cursor], 0
jne @f
; check mouse area for putpixel
test eax, 0x04000000
jnz @f
call check_mouse_area_for_putpixel
@@:
and eax, 0xffffff
; store to LFB
mov [LFB_BASE+edi], eax
ret
;-----------------------------------------------------------------------------
; eax = x
; ebx = y
align 4
Vesa20_putpixel32_new:
mov ecx, eax
shl ecx, 16
mov cx, bx
; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier)
mov eax, [esp+32-8+4] ; eax = color
; check for hardware cursor
cmp [_display.select_cursor], select_cursor
jne @f
; check mouse area for putpixel
test eax, 0x04000000
jnz @f
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae @f
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb @f
rol ecx, 16
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae @f
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb @f
ror ecx, 16
call check_mouse_area_for_putpixel_new.1
@@:
and eax, 0x00ffffff
; store to LFB
mov [LFB_BASE+edi], eax
ret
;-----------------------------------------------------------------------------
align 4
calculate_edi:
; mov edi, ebx
; imul edi, [Screen_Max_X]
; add edi, ebx
mov edi, [d_width_calc_area + ebx*4]
add edi, eax
ret
;-----------------------------------------------------------------------------
; DRAWLINE
;-----------------------------------------------------------------------------
; eax = x1 shl 16 + x2
; ebx = y1 shl 16 + y2
; ecx = color
; edi = force ?
align 4
__sys_draw_line:
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
pusha
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)
; correction for the remainder of the division
shl edx, 1
cmp ebp, edx
jb @f
inc eax
@@:
mov edx, ebp ; edx = counter (number of pixels to draw)
mov ebp, 1 shl 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)
; correction for the remainder of the division
shl edx, 1
cmp esi, edx
jb @f
inc eax
@@:
mov edx, esi ; edx = counter (number of pixels to draw)
mov esi, 1 shl 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
and ecx, 0xFBFFFFFF ; negate 0x04000000 save to mouseunder area
.draw:
push eax ebx
; correction for the remainder of the division
test ah, 0x80
jz @f
add eax, 1 shl 16
@@:
shr eax, 16
; correction for the remainder of the division
test bh, 0x80
jz @f
add ebx, 1 shl 16
@@:
shr ebx, 16
; and ecx, 0xFBFFFFFF ; negate 0x04000000 save to mouseunder area
; call [putpixel]
call __sys_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]
; and ecx, 0xFBFFFFFF ;n egate 0x04000000 save to mouseunder area
; call [putpixel]
call __sys_putpixel
.exit:
add esp, 6*4
popa
; call [draw_pointer]
ret
;------------------------------------------------------------------------------
; draw an horizontal line
; eax = x1
; edx = x2
; ebx = y
; ecx = color
; edi = force ?
align 4
hline:
push eax edx
cmp edx, eax ; make sure x2 is above x1
jge @f
xchg eax, edx
@@:
and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area
@@:
; call [putpixel]
call __sys_putpixel
inc eax
cmp eax, edx
jle @b
pop edx eax
ret
;------------------------------------------------------------------------------
; draw a vertical line
; eax = x
; ebx = y1
; edx = y2
; ecx = color
; edi = force ?
align 4
vline:
push ebx edx
cmp edx, ebx ; make sure y2 is above y1
jge @f
xchg ebx, edx
@@:
and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area
@@:
; call [putpixel]
call __sys_putpixel
inc ebx
cmp ebx, edx
jle @b
pop edx ebx
ret
;------------------------------------------------------------------------------
; eax cx
; ebx cy
; ecx xe
; edx ye
; edi color
align 4
vesa20_drawbar:
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 ?
.real_sx_and_abs_cx dd ?
.real_sy_and_abs_cy dd ?
.stack_data = 4*13
end virtual
pushad
sub esp, drbar.stack_data
mov [drbar.color], edi
sub edx, ebx
jle .exit
sub ecx, eax
jle .exit
mov [drbar.bar_sy], edx
mov [drbar.bar_sx], ecx
mov [drbar.bar_cx], eax
mov [drbar.bar_cy], ebx
mov edi, [TASK_BASE]
add eax, [edi-twdw + WDATA.box.left] ; win_cx
add ebx, [edi-twdw + WDATA.box.top] ; 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 + WDATA.box.width] ; ebx = wnd_sx
inc ebx ; WDATA.box.width is one pixel less than real window x-size
sub ebx, [drbar.bar_cx]
ja @f
.exit:
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 + WDATA.box.height] ; ebx = wnd_sy
inc ebx
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, [_display.width]
sub eax, [drbar.real_sx]
mov [drbar.line_inc_map], eax
; line_inc_scr
mov eax, [drbar.real_sx]
mov ebx, [_display.bytes_per_pixel]
imul eax, ebx
neg eax
add eax, [_display.pitch]
mov [drbar.line_inc_scr], eax
; pointer to screen
mov edx, [drbar.abs_cy]
; imul edx, [BytesPerScanLine]
mov edx, [BPSLine_calc_area+edx*4]
mov eax, [drbar.abs_cx]
imul eax, ebx
add edx, eax
; pointer to pixel map
mov eax, [drbar.abs_cy]
; imul eax, [Screen_Max_X]
; add eax, [drbar.abs_cy]
mov eax, [d_width_calc_area + eax*4]
add eax, [drbar.abs_cx]
add eax, [_WinMapAddress]
xchg eax, ebp
mov ebx, [drbar.real_sx]
add ebx, [drbar.abs_cx]
mov [drbar.real_sx_and_abs_cx], ebx
mov ebx, [drbar.real_sy]
add ebx, [drbar.abs_cy]
mov [drbar.real_sy_and_abs_cy], ebx
add edx, LFB_BASE
; get process number
mov ebx, [CURRENT_TASK] ; bl - process num
mov esi, [drbar.real_sy]
mov eax, [drbar.color] ; BBGGRR00
rol eax, 8
mov bh, al ; 0x80 drawing gradient bars
ror eax, 8
cmp byte [_display.bits_per_pixel], 16
je draw_bar_end_16
cmp byte [_display.bits_per_pixel], 24
je draw_bar_end_24
cmp byte [_display.bits_per_pixel], 32
je draw_bar_end_32
;--------------------------------------
; eax - color high RRGGBB
; bl - process num
; ecx - temp
; edx - pointer to screen
; esi - counter
; edi - counter
align 4
draw_bar_end_24:
; check for hardware cursor
mov ecx, [_display.select_cursor]
cmp ecx, select_cursor
je draw_bar_end_24_new
cmp ecx, 0
je draw_bar_end_24_old
.new_y:
mov edi, [drbar.real_sx]
.new_x:
cmp byte [ebp], bl
jne .skip
; store to LFB
mov [edx], ax
shr eax, 16
mov [edx + 2], al
.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]
; drawing gradient bars
test bh, 0x80
jz @f
test al, al
jz @f
dec al
@@:
dec esi
jnz .new_y
.end:
add esp, drbar.stack_data
popad
xor eax, eax
ret
;------------------------------------------------------------------------------
align 4
draw_bar_end_24_old:
.new_y:
mov edi, [drbar.real_sx]
.new_x:
cmp byte [ebp], bl
jne .skip
mov ecx, [drbar.real_sx_and_abs_cx]
sub ecx, edi
shl ecx, 16
add ecx, [drbar.real_sy_and_abs_cy]
sub ecx, esi
; check mouse area for putpixel
call check_mouse_area_for_putpixel
; store to LFB
mov [edx], ax
shr eax, 16
mov [edx + 2], al
mov eax, [drbar.color]
.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]
; drawing gradient bars
test bh, 0x80
jz @f
test al, al
jz @f
dec al
@@:
dec esi
jnz .new_y
jmp draw_bar_end_24.end
;------------------------------------------------------------------------------
align 4
draw_bar_end_24_new:
.new_y:
mov edi, [drbar.real_sx]
.new_x:
cmp byte [ebp], bl
jne .skip
mov ecx, [drbar.real_sy_and_abs_cy]
sub ecx, esi
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
rol ecx, 16
add ecx, [drbar.real_sx_and_abs_cx]
sub ecx, edi
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
ror ecx, 16
; check mouse area for putpixel
push eax
call check_mouse_area_for_putpixel_new.1
mov [edx], ax
shr eax, 16
mov [edx + 2], al
pop eax
jmp .skip
.no_mouse_area:
; store to LFB
mov [edx], ax
ror eax, 16
mov [edx + 2], al
rol eax, 16
.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]
; drawing gradient bars
test bh, 0x80
jz @f
test al, al
jz @f
dec al
@@:
dec esi
jnz .new_y
jmp draw_bar_end_24.end
;------------------------------------------------------------------------------
; eax - color high RRGGBB
; bl - process num
; ecx - temp
; edx - pointer to screen
; esi - counter
; edi - counter
draw_bar_end_32:
; check for hardware cursor
mov ecx, [_display.select_cursor]
cmp ecx, select_cursor
je draw_bar_end_32_new
cmp ecx, 0
je draw_bar_end_32_old
.new_y:
mov edi, [drbar.real_sx]
.new_x:
cmp byte [ebp], bl
jne .skip
; store to LFB
mov [edx], eax
mov eax, [drbar.color]
.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]
; drawing gradient bars
test bh, 0x80
jz @f
test al, al
jz @f
dec al
@@:
dec esi
jnz .new_y
.end:
add esp, drbar.stack_data
popad
cmp [SCR_MODE], 0x12
jne @f
call VGA_draw_bar
@@:
xor eax, eax
mov [EGA_counter], 1
ret
draw_bar_end_32_old:
.new_y:
mov edi, [drbar.real_sx]
.new_x:
cmp byte [ebp], bl
jne .skip
mov ecx, [drbar.real_sx_and_abs_cx]
sub ecx, edi
shl ecx, 16
add ecx, [drbar.real_sy_and_abs_cy]
sub ecx, esi
; check mouse area for putpixel
call check_mouse_area_for_putpixel
; store to LFB
mov [edx], eax
mov eax, [drbar.color]
.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]
; drawing gradient bars
test bh, 0x80
jz @f
test al, al
jz @f
dec al
@@:
dec esi
jnz .new_y
jmp draw_bar_end_32.end
;------------------------------------------------------------------------------
align 4
draw_bar_end_32_new:
.new_y:
mov edi, [drbar.real_sx]
.new_x:
cmp byte [ebp], bl
jne .skip
mov ecx, [drbar.real_sy_and_abs_cy]
sub ecx, esi
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
rol ecx, 16
add ecx, [drbar.real_sx_and_abs_cx]
sub ecx, edi
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
ror ecx, 16
; check mouse area for putpixel
push eax
call check_mouse_area_for_putpixel_new.1
mov [edx], eax
pop eax
jmp .skip
.no_mouse_area:
; store to LFB
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]
; drawing gradient bars
test bh, 0x80
jz @f
test al, al
jz @f
dec al
@@:
dec esi
jnz .new_y
jmp draw_bar_end_32.end
;------------------------------------------------------------------------------
; eax - color high RRGGBB
; bl - process num
; ecx - temp
; edx - pointer to screen
; esi - counter
; edi - counter
align 4
draw_bar_end_16:
; check for hardware cursor
mov ecx, [_display.select_cursor]
cmp ecx, select_cursor
je draw_bar_end_16_new
cmp ecx, 0
je draw_bar_end_16_old
.new_y:
mov edi, [drbar.real_sx]
.new_x:
cmp byte [ebp], bl
jne .skip
; convert to 16 bpp and store to LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [edx], ax
mov eax, [drbar.color]
.skip:
; add pixel
add edx, 2
inc ebp
dec edi
jnz .new_x
; add line
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
; drawing gradient bars
test bh, 0x80
jz @f
test al, al
jz @f
dec al
@@:
dec esi
jnz .new_y
.end:
add esp, drbar.stack_data
popad
cmp [SCR_MODE], 0x12
jne @f
call VGA_draw_bar
@@:
xor eax, eax
mov [EGA_counter], 1
ret
;------------------------------------------------------------------------------
align 4
draw_bar_end_16_old:
.new_y:
mov edi, [drbar.real_sx]
.new_x:
cmp byte [ebp], bl
jne .skip
mov ecx, [drbar.real_sx_and_abs_cx]
sub ecx, edi
shl ecx, 16
add ecx, [drbar.real_sy_and_abs_cy]
sub ecx, esi
; check mouse area for putpixel
call check_mouse_area_for_putpixel
; convert to 16 bpp and store to LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [edx], ax
mov eax, [drbar.color]
.skip:
; add pixel
add edx, 2
inc ebp
dec edi
jnz .new_x
; add line
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
; drawing gradient bars
test bh, 0x80
jz @f
test al, al
jz @f
dec al
@@:
dec esi
jnz .new_y
jmp draw_bar_end_16.end
;------------------------------------------------------------------------------
align 4
draw_bar_end_16_new:
.new_y:
mov edi, [drbar.real_sx]
.new_x:
cmp byte [ebp], bl
jne .skip
mov ecx, [drbar.real_sy_and_abs_cy]
sub ecx, esi
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
rol ecx, 16
add ecx, [drbar.real_sx_and_abs_cx]
sub ecx, edi
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
ror ecx, 16
; check mouse area for putpixel
push eax
call check_mouse_area_for_putpixel_new.1
push eax
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [edx], ax
pop eax
pop eax
jmp .skip
.no_mouse_area:
; convert to 16 bpp and store to LFB
push eax
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [edx], ax
pop eax
.skip:
; add pixel
add edx, 2
inc ebp
dec edi
jnz .new_x
; add line
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
; drawing gradient bars
test bh, 0x80
jz @f
test al, al
jz @f
dec al
@@:
dec esi
jnz .new_y
jmp draw_bar_end_16.end
;------------------------------------------------------------------------------
align 4
vesa20_drawbackground_tiled:
pushad
; External loop for all y from start to end
mov ebx, [draw_data+32+RECT.top] ; y start
dp2:
mov ebp, [draw_data+32+RECT.left] ; x start
; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
; and LFB data (output for our function) [edi]
; mov eax, [BytesPerScanLine]
; mul ebx
mov eax, [BPSLine_calc_area+ebx*4]
xchg ebp, eax
add ebp, eax
add ebp, eax
cmp byte [_display.bytes_per_pixel], 2
je @f
add ebp, eax
cmp byte [_display.bytes_per_pixel], 3
je @f
add ebp, eax
@@:
add ebp, LFB_BASE
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
call calculate_edi
xchg edi, ebp
add ebp, [_WinMapAddress]
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
; 2) Calculate offset in background memory block
push eax
xor edx, edx
mov eax, ebx
div dword [BgrDataHeight] ; edx := y mod BgrDataHeight
pop eax
push eax
mov ecx, [BgrDataWidth]
mov esi, edx
imul esi, ecx ; esi := (y mod BgrDataHeight) * BgrDataWidth
xor edx, edx
div ecx ; edx := x mod BgrDataWidth
sub ecx, edx
add esi, edx ; esi := (y mod BgrDataHeight)*BgrDataWidth + (x mod BgrDataWidth)
pop eax
lea esi, [esi*3]
add esi, [img_background]
xor edx, edx
inc edx
; 3) Loop through redraw rectangle and copy background data
; Registers meaning:
; eax = x, ebx = y (screen coordinates)
; ecx = deltax - number of pixels left in current tile block
; edx = 1
; esi -> bgr memory, edi -> output
; ebp = offset in WinMapAddress
dp3:
cmp [ebp], dl
jnz .next_pix
push eax ecx
mov ecx, eax
shl ecx, 16
add ecx, ebx
mov eax, [esi]
; check for hardware cursor
cmp [_display.select_cursor], select_cursor
je @f
cmp [_display.select_cursor], 0
jne .no_mouseunder
@@:
and eax, 0xffffff
; check mouse area for putpixel
call [_display.check_mouse]
.no_mouseunder:
cmp byte [_display.bits_per_pixel], 16
je .16bpp
; store to LFB
mov [edi], ax
shr eax, 16
mov [edi+2], al
pop ecx eax
jmp .next_pix
.16bpp:
; convert to 16 bpp and store to LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [edi], ax
pop ecx eax
; Advance to next pixel
.next_pix:
add esi, 3
add edi, [_display.bytes_per_pixel]
add ebp, edx
add eax, edx
cmp eax, [draw_data+32+RECT.right]
ja dp4
sub ecx, edx
jnz dp3
; next tile block on x-axis
mov ecx, [BgrDataWidth]
sub esi, ecx
sub esi, ecx
sub esi, ecx
jmp dp3
dp4:
; next scan line
inc ebx
cmp ebx, [draw_data+32+RECT.bottom]
jbe dp2
popad
mov [EGA_counter], 1
cmp [SCR_MODE], 0x12
jne @f
call VGA_drawbackground
@@:
ret
;------------------------------------------------------------------------------
align 4
vesa20_drawbackground_stretch:
pushad
; Helper variables
; calculate 2^32*(BgrDataWidth-1) mod (ScreenWidth-1)
mov eax, [BgrDataWidth]
dec eax
xor edx, edx
div dword [screen_workarea.right]
push eax ; high
xor eax, eax
div dword [screen_workarea.right]
push eax ; low
; the same for height
mov eax, [BgrDataHeight]
dec eax
xor edx, edx
div dword [screen_workarea.bottom]
push eax ; high
xor eax, eax
div dword [screen_workarea.bottom]
push eax ; low
; External loop for all y from start to end
mov ebx, [draw_data+32+RECT.top] ; y start
mov ebp, [draw_data+32+RECT.left] ; x start
; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
; and LFB data (output for our function) [edi]
; mov eax, [BytesPerScanLine]
; mul ebx
mov eax, [BPSLine_calc_area+ebx*4]
xchg ebp, eax
add ebp, eax
add ebp, eax
cmp byte [_display.bytes_per_pixel], 2
jz @f
add ebp, eax
cmp byte [_display.bytes_per_pixel], 3
jz @f
add ebp, eax
@@:
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
call calculate_edi
xchg edi, ebp
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
push ebx
push eax
; 2) Calculate offset in background memory block
mov eax, ebx
imul ebx, dword [esp+12]
mul dword [esp+8]
add edx, ebx ; edx:eax = y * 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
mov esi, edx
imul esi, [BgrDataWidth]
push edx
push eax
mov eax, [esp+8]
mul dword [esp+28]
push eax
mov eax, [esp+12]
mul dword [esp+28]
add [esp], edx
pop edx ; edx:eax = x * 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
add esi, edx
lea esi, [esi*3]
add esi, [img_background]
push eax
push edx
push esi
; 3) Smooth horizontal
bgr_resmooth0:
mov ecx, [esp+8]
mov edx, [esp+4]
mov esi, [esp]
push edi
mov edi, bgr_cur_line
call smooth_line
bgr_resmooth1:
mov eax, [esp+16+4]
inc eax
cmp eax, [BgrDataHeight]
jae bgr.no2nd
mov ecx, [esp+8+4]
mov edx, [esp+4+4]
mov esi, [esp+4]
add esi, [BgrDataWidth]
add esi, [BgrDataWidth]
add esi, [BgrDataWidth]
mov edi, bgr_next_line
call smooth_line
bgr.no2nd:
pop edi
sdp3:
xor esi, esi
mov ecx, [esp+12]
; 4) Loop through redraw rectangle and copy background data
; Registers meaning:
; esi = offset in current line, edi -> output
; ebp = offset in WinMapAddress
; dword [esp] = offset in bgr data
; qword [esp+4] = x * 2^32 * (BgrDataWidth-1) / (ScreenWidth-1)
; qword [esp+12] = y * 2^32 * (BgrDataHeight-1) / (ScreenHeight-1)
; dword [esp+20] = x
; dword [esp+24] = y
; precalculated constants:
; qword [esp+28] = 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
; qword [esp+36] = 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
sdp3a:
mov eax, [_WinMapAddress]
cmp [ebp+eax], byte 1
jnz snbgp
mov eax, [bgr_cur_line+esi]
test ecx, ecx
jz .novert
mov ebx, [bgr_next_line+esi]
call [overlapping_of_points_ptr]
.novert:
push ecx
; check for hardware cursor
cmp [_display.select_cursor], select_cursor
je @f
cmp [_display.select_cursor], 0
jne .no_mouseunder
@@:
mov ecx, [esp+20+4] ;x
shl ecx, 16
add ecx, [esp+24+4] ;y
; check mouse area for putpixel
call [_display.check_mouse]
.no_mouseunder:
cmp [_display.bits_per_pixel], 16
jne .not_16bpp
; convert to 16 bpp and store to LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [LFB_BASE+edi], ax
pop ecx
jmp snbgp
.not_16bpp:
; store to LFB
mov [LFB_BASE+edi], ax
shr eax, 16
mov [LFB_BASE+edi+2], al
pop ecx
snbgp:
add edi, [_display.bytes_per_pixel]
add ebp, 1
mov eax, [esp+20]
add eax, 1
mov [esp+20], eax
add esi, 4
cmp eax, [draw_data+32+RECT.right]
jbe sdp3a
sdp4:
; next y
mov ebx, [esp+24]
add ebx, 1
mov [esp+24], ebx
cmp ebx, [draw_data+32+RECT.bottom]
ja sdpdone
; advance edi, ebp to next scan line
sub eax, [draw_data+32+RECT.left]
sub ebp, eax
add ebp, [_display.width]
sub edi, eax
sub edi, eax
cmp byte [_display.bytes_per_pixel], 2
jz @f
sub edi, eax
cmp byte [_display.bytes_per_pixel], 3
jz @f
sub edi, eax
@@:
add edi, [_display.pitch]
; restore ecx,edx; advance esi to next background line
mov eax, [esp+28]
mov ebx, [esp+32]
add [esp+12], eax
mov eax, [esp+16]
adc [esp+16], ebx
sub eax, [esp+16]
mov ebx, eax
lea eax, [eax*3]
imul eax, [BgrDataWidth]
sub [esp], eax
mov eax, [draw_data+32+RECT.left]
mov [esp+20], eax
test ebx, ebx
jz sdp3
cmp ebx, -1
jnz bgr_resmooth0
push edi
mov esi, bgr_next_line
mov edi, bgr_cur_line
mov ecx, [_display.width]
rep movsd
jmp bgr_resmooth1
sdpdone:
add esp, 44
popad
mov [EGA_counter], 1
cmp [SCR_MODE], 0x12
jne @f
call VGA_drawbackground
@@:
ret
;--------------------------------------
align 4
smooth_line:
mov al, [esi+2]
shl eax, 16
mov ax, [esi]
test ecx, ecx
jz @f
mov ebx, [esi+2]
shr ebx, 8
call [overlapping_of_points_ptr]
@@:
stosd
mov eax, [esp+20+8]
add eax, 1
mov [esp+20+8], eax
cmp eax, [draw_data+32+RECT.right]
ja @f
add ecx, [esp+36+8]
mov eax, edx
adc edx, [esp+40+8]
sub eax, edx
lea eax, [eax*3]
sub esi, eax
jmp smooth_line
@@:
mov eax, [draw_data+32+RECT.left]
mov [esp+20+8], eax
ret
;------------------------------------------------------------------------------
align 16
overlapping_of_points:
if 0
; this version of procedure works, but is slower than next version
push ecx edx
mov edx, eax
push esi
shr ecx, 24
mov esi, ecx
mov ecx, ebx
movzx ebx, dl
movzx eax, cl
sub eax, ebx
movzx ebx, dh
imul eax, esi
add dl, ah
movzx eax, ch
sub eax, ebx
imul eax, esi
add dh, ah
ror ecx, 16
ror edx, 16
movzx eax, cl
movzx ebx, dl
sub eax, ebx
imul eax, esi
pop esi
add dl, ah
mov eax, edx
pop edx
ror eax, 16
pop ecx
ret
else
push ecx edx
mov edx, eax
push esi
shr ecx, 26
mov esi, ecx
mov ecx, ebx
shl esi, 9
movzx ebx, dl
movzx eax, cl
sub eax, ebx
movzx ebx, dh
add dl, [BgrAuxTable+(eax+0x100)+esi]
movzx eax, ch
sub eax, ebx
add dh, [BgrAuxTable+(eax+0x100)+esi]
ror ecx, 16
ror edx, 16
movzx eax, cl
movzx ebx, dl
sub eax, ebx
add dl, [BgrAuxTable+(eax+0x100)+esi]
pop esi
mov eax, edx
pop edx
ror eax, 16
pop ecx
ret
end if
;------------------------------------------------------------------------------
align 4
init_background:
mov edi, BgrAuxTable
xor edx, edx
.loop2:
mov eax, edx
shl eax, 8
neg eax
mov ecx, 0x200
.loop1:
mov byte [edi], ah
inc edi
add eax, edx
loop .loop1
add dl, 4
jnz .loop2
test byte [cpu_caps+(CAPS_MMX/8)], 1 shl (CAPS_MMX mod 8)
jz @f
mov [overlapping_of_points_ptr], overlapping_of_points_mmx
@@:
ret
;------------------------------------------------------------------------------
align 16
overlapping_of_points_mmx:
movd mm0, eax
movd mm4, eax
movd mm1, ebx
pxor mm2, mm2
punpcklbw mm0, mm2
punpcklbw mm1, mm2
psubw mm1, mm0
movd mm3, ecx
psrld mm3, 24
packuswb mm3, mm3
packuswb mm3, mm3
pmullw mm1, mm3
psrlw mm1, 8
packuswb mm1, mm2
paddb mm4, mm1
movd eax, mm4
ret
;------------------------------------------------------------------------------