From 7413c9cd9ddbfc1072ae8b2bd06cf462a0ad1e1c Mon Sep 17 00:00:00 2001 From: "Artem Jerdev (art_zh)" Date: Tue, 10 May 2011 12:43:03 +0000 Subject: [PATCH] 1) gfx reverted to stable version 1710 2) Phenom and Fusion CPUs supported 3) RDMSR syscall added git-svn-id: svn://kolibrios.org@1928 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/branches/Kolibri-A/trunk/bus/HT.inc | 47 +- kernel/branches/Kolibri-A/trunk/const.inc | 2 +- .../branches/Kolibri-A/trunk/core/syscall.inc | 34 +- kernel/branches/Kolibri-A/trunk/data32.inc | 2 +- .../branches/Kolibri-A/trunk/hid/mousedrv.inc | 1 + kernel/branches/Kolibri-A/trunk/kernel.asm | 5 +- kernel/branches/Kolibri-A/trunk/kernel32.inc | 2 +- .../branches/Kolibri-A/trunk/video/vesa20.inc | 1064 +++++++++++++++++ 8 files changed, 1124 insertions(+), 33 deletions(-) create mode 100644 kernel/branches/Kolibri-A/trunk/video/vesa20.inc diff --git a/kernel/branches/Kolibri-A/trunk/bus/HT.inc b/kernel/branches/Kolibri-A/trunk/bus/HT.inc index e9592fb15..58734c446 100644 --- a/kernel/branches/Kolibri-A/trunk/bus/HT.inc +++ b/kernel/branches/Kolibri-A/trunk/bus/HT.inc @@ -136,12 +136,16 @@ rs7xx_pcie_init: call rs7xx_nbconfig_flush_pci mov eax, ebx and eax, 0xFFE00000 ; valid bits [31..21] - jz $ ; NB BAR3 may be invisible! + jz $ ; invalid map! .addr_found: mov dword[mmio_pcie_cfg_addr-OS_BASE], eax ; physical address (lower 32 bits) add dword[mmio_pcie_cfg_lim-OS_BASE], eax - or eax, (PG_NOCACHE + PG_SHARED + PG_LARGE + PG_UW) ; by the way, UW is unsafe! +; ---- common mapping procedure ---- +; (eax = phys. address of PCIe conf.space) +; +map_pcie_pages: + or eax, (PG_NOCACHE + PG_SHARED + PG_LARGE + PG_UW) ; UW is unsafe, fix it! mov ecx, PCIe_CONFIG_SPACE ; linear address mov ebx, ecx shr ebx, 20 @@ -167,6 +171,32 @@ rs7xx_pcie_init: .pcie_cfg_mapped: ret ; <<< OK >>> +; ---- stepping 10h CPUs and Fusion APUs: the configspace is stored in MSR_C001_0058 ---- +align 4 +fusion_pcie_init: + mov ecx, 0xC0010058 + rdmsr + or edx, edx + jnz $ ; PCIe is in the upper memory. Stop. + xchg dl, al + mov dword[mmio_pcie_cfg_addr-OS_BASE], eax ; store the physical address + mov ecx, edx + and dl, 1 + jz $ ; bit[0] = 1 means no PCIe mapping allowed. Stop. + shr cl, 2 ; ecx = log2(number of buses) + mov word[PCIe_bus_range-OS_BASE], cx + sub cl, 2 + jae @f + xor cl, cl +@@: + shl edx, cl ; edx = number of 4M pages to map + mov word[mmio_pcie_cfg_pdes-OS_BASE], dx + shl edx, 22 + dec edx + add edx, eax ; the upper configspace limit + mov dword[mmio_pcie_cfg_lim-OS_BASE], edx + + jmp map_pcie_pages ; ================================================================================ @@ -278,6 +308,19 @@ rs780_write_htiu: pop edx ret +;------------------------------------------------ +align 4 +sys_rdmsr: +; in: [esp+8] = MSR# +; out: [esp+8] = MSR[63:32] +; [eax] = MSR[31: 0] +;------------------------------------------------ + push ecx edx + mov ecx, [esp+16] + rdmsr + mov [esp+16], edx + pop edx ecx + ret diff --git a/kernel/branches/Kolibri-A/trunk/const.inc b/kernel/branches/Kolibri-A/trunk/const.inc index c2eaf3166..389eff89f 100644 --- a/kernel/branches/Kolibri-A/trunk/const.inc +++ b/kernel/branches/Kolibri-A/trunk/const.inc @@ -6,7 +6,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; $Revision$ - + dpl0 equ 10010000b ; data read dpl0 drw0 equ 10010010b ; data read/write dpl0 diff --git a/kernel/branches/Kolibri-A/trunk/core/syscall.inc b/kernel/branches/Kolibri-A/trunk/core/syscall.inc index cba0ba1d7..99f9dacaa 100644 --- a/kernel/branches/Kolibri-A/trunk/core/syscall.inc +++ b/kernel/branches/Kolibri-A/trunk/core/syscall.inc @@ -17,7 +17,7 @@ cross_order: mov edx, esi mov esi, edi movzx edi, byte[esp+28 + 4] - sub edi, 53 ; all zeroes before + sub edi, 53 ; all zeroes before call dword [servetable+edi*4] ret @@ -44,28 +44,10 @@ i40: align 32 syscall_entry: - push ecx ; sti -; and eax, 3 -; call dword [servetable3 + eax * 4] - - mov edi, [esp+4] - mov ecx, [esp+8] - mov edx, [esp+12] - mov ebx, [esp+16] - and al, 1 - jz .hline - mov eax, [esp+20] - sti - call vline - jmp .done -.hline: - mov eax, [esp+20] - sti - call hline -.done: - - + push ecx + and eax, 3 + call dword [servetable3 + eax * 4] pop ecx sysret @@ -85,7 +67,7 @@ iglobal dd 0 dd 0 dd 0 - dd 0 ; 62-PCI functions + dd 0 ; 62-PCI functions dd sys_msg_board ; 63-System message board ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -118,7 +100,7 @@ iglobal dd sys_setup ; 21-SetMidiBase,SetKeymap,SetShiftKeymap,. dd sys_settime ; 22-setting date,time,clock and alarm-clock dd sys_wait_event_timeout ; 23-TimeOutWaitForEvent - dd undefined_syscall ; syscall_cdaudio ; 24-PlayCdTrack,StopCd and GetCdPlaylist + dd undefined_syscall ; syscall_cdaudio ; 24-PlayCdTrack,StopCd and GetCdPlaylist dd undefined_syscall ; 25-reserved dd sys_getsetup ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,. dd undefined_syscall ; 27-reserved @@ -173,8 +155,8 @@ iglobal align 4 servetable3: ; Kolibri-A special service - dd hline ; 0 - dd vline ; 1 + dd sys_rdmsr ; 0 + dd paleholder ; 1 dd paleholder ; 2 dd sys_end ; last diff --git a/kernel/branches/Kolibri-A/trunk/data32.inc b/kernel/branches/Kolibri-A/trunk/data32.inc index f12bdb148..4adcb1211 100644 --- a/kernel/branches/Kolibri-A/trunk/data32.inc +++ b/kernel/branches/Kolibri-A/trunk/data32.inc @@ -7,7 +7,7 @@ $Revision$ - + keymap: db '6',27 diff --git a/kernel/branches/Kolibri-A/trunk/hid/mousedrv.inc b/kernel/branches/Kolibri-A/trunk/hid/mousedrv.inc index 7a5572afa..b1c96d176 100644 --- a/kernel/branches/Kolibri-A/trunk/hid/mousedrv.inc +++ b/kernel/branches/Kolibri-A/trunk/hid/mousedrv.inc @@ -7,6 +7,7 @@ $Revision$ + ; check mouse ; diff --git a/kernel/branches/Kolibri-A/trunk/kernel.asm b/kernel/branches/Kolibri-A/trunk/kernel.asm index 295921b75..e79515028 100644 --- a/kernel/branches/Kolibri-A/trunk/kernel.asm +++ b/kernel/branches/Kolibri-A/trunk/kernel.asm @@ -55,7 +55,7 @@ ;; on all copies. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - + include 'macros.inc' $Revision$ @@ -219,7 +219,8 @@ diff16 "32-bit code start ",0,$ call init_BIOS32 ; (init.inc - to be removed later) ; PCIe extended config space access - call rs7xx_pcie_init ; (bus/HT.inc) +; call rs7xx_pcie_init ; (bus/HT.inc) + call fusion_pcie_init ; (bus/HT.inc) ; MEMORY MODEL call init_mem ; (init.inc) diff --git a/kernel/branches/Kolibri-A/trunk/kernel32.inc b/kernel/branches/Kolibri-A/trunk/kernel32.inc index a8f14b938..5ff0d156f 100644 --- a/kernel/branches/Kolibri-A/trunk/kernel32.inc +++ b/kernel/branches/Kolibri-A/trunk/kernel32.inc @@ -15,7 +15,7 @@ $Revision$ - + struc POINT { .x dd ? diff --git a/kernel/branches/Kolibri-A/trunk/video/vesa20.inc b/kernel/branches/Kolibri-A/trunk/video/vesa20.inc new file mode 100644 index 000000000..20638c3e7 --- /dev/null +++ b/kernel/branches/Kolibri-A/trunk/video/vesa20.inc @@ -0,0 +1,1064 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2008. 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: 1708 $ + + +;************************************************* +; getpixel +; +; in: +; eax = x coordinate +; ebx = y coordinate +; +; ret: +; ecx = 00 RR GG BB + + +get_pixel: + mov ecx, [BytesPerScanLine] + imul ecx, ebx + lea ecx, [ecx+eax*4] ; ecx = x*4+(y*y multiplier) + mov ecx, [ecx+LFB_BASE] + 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 ? + .winmap_newline dd ? + .screen_newline dd ? + .stack_data = 4*12 + .edi dd ? + .esi dd ? + .ebp dd ? + .esp dd ? + .ebx dd ? + .edx dd ? + .ecx dd ? + .eax dd ? + .ret_addr dd ? + .arg_0 dd ? +end virtual + +align 16 +; 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 + +vesa20_putimage: + pushad + call [_display.disable_mouse] + 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 + call esi + add eax, [putimg.arg_0] + mov [putimg.line_increment], eax +; winmap new line increment + mov eax, [Screen_Max_X] + inc eax + sub eax, [putimg.real_sx] + mov [putimg.winmap_newline], eax +; screen new line increment + mov eax, [BytesPerScanLine] + shl ecx, 1 + shl ecx, 1 + 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 eax, [putimg.abs_cx] + shl eax, 1 + shl eax, 1 + add edx, eax +; pointer to pixel map + mov eax, [putimg.abs_cy] + imul eax, [Screen_Max_X] + add eax, [putimg.abs_cy] + add eax, [putimg.abs_cx] + add eax, [_WinMapAddress] + xchg eax, ebp +; get process number + mov ebx, [CURRENT_TASK] + +put_image_end_32: + mov edi, [putimg.real_sy] +align 4 +.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 + 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] ;[BytesPerScanLine] + add ebp, [putimg.winmap_newline] ;[Screen_Max_X] + 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 +__sys_putpixel: + +; eax = x coordinate +; ebx = y coordinate +; ecx = ?? RR GG BB ; 0x01000000 negation +; edi = 0x00000001 force + + cmp [Screen_Max_X], eax + jb .exit + cmp [Screen_Max_Y], ebx + jb .exit +.check_forced: + test edi,1 ; force ? + jnz .checked + +.not_forced: + push edx + mov edx,[_display.width] ; screen x size + imul edx, ebx + add edx, [_WinMapAddress] + movzx edx, byte [eax+edx] + cmp edx, [CURRENT_TASK] + pop edx + jne .exit + +; OK to set pixel +.checked: + push ebx + imul ebx, [BytesPerScanLine] + lea ebx, [ebx+eax*4] + test ecx,0x01000000 + jz .noneg + mov ecx, [LFB_BASE+ebx] + not ecx + and ecx, 0x01FFFFFF +.noneg: + mov [LFB_BASE+ebx], ecx + pop ebx +.exit: + ret + + + +align 4 +put_pixel: ; left for compatibility with 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 + mov [LFB_BASE+edi], ecx + ret + + +;************************************************* + +;align 4 +calculate_edi: + mov edi, ebx + imul edi, [Screen_Max_X] + add edi, ebx + add edi, eax + ret + +;************************************************* + +; DRAWLINE + +align 4 +__sys_draw_line: + call [_display.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 + call [draw_pointer] + ret + +align 4 +hline: +; ------------ draw a horizontal line ------------- +; eax = x1 +; edx = x2 +; ebx = y +; ecx = color +; edi = force ? + cmp ebx, [Screen_Max_Y] + jge .out + push eax ebp esi ebx edx + bt ecx, 24 ; color inversion check + rcl edi,1 ; forced graphics check + + mov ebp, [_display.width] ; ebp = screen co-ords base + imul ebp, ebx + add ebp, [_WinMapAddress] + + cmp edx, eax ; to make sure x2 > x1 + jge @f + xchg eax, edx +@@: + cmp eax, [Screen_Max_X] + jge .exit + imul ebx, [BytesPerScanLine] + add ebx, LFB_BASE + cmp edx, [Screen_Max_X] ; last check + jb .draw + mov edx, [Screen_Max_X] + +.draw: ; -- the line --- + jmp dword [hline.drawtable + edi*4] ; a coolhack (C) Serge + +align 4 +.invert_color: + mov ecx, [ebx+eax*4] + xor ecx, 0x00FFFFFF + or ecx, 0x01000000 ; keep bit[24] high ! +align 4 +.check_overlap: + movzx esi, byte [ebp+eax] ; check whether the line covered by other windows + cmp esi, [CURRENT_TASK] + je .putpixel + jmp .nextpixel +align 4 +.invert_force: + mov ecx, [ebx+eax*4] + xor ecx, 0x00FFFFFF + or ecx, 0x01000000 ; keep bit[24] high ! +align 4 +.putpixel: + mov [ebx+eax*4], ecx +align 4 +.nextpixel: + inc eax + cmp eax, edx + ja .exit + jmp dword [hline.drawtable + edi*4] ; close the loop + +.exit: + shr edi, 1 ; restore the 'force' bit + pop edx ebx esi ebp eax +.out: + ret +align 4 +.drawtable: +dd .check_overlap ; general case +dd .invert_color +dd .putpixel ; force to draw it +dd .invert_force + + +align 4 +vline: +; --------- draw a vertical line ------------ +; eax = x +; ebx = y1 +; edx = y2 +; ecx = color +; edi = force ? + cmp eax, [Screen_Max_X] + jge .out + push eax ebp esi ebx edx + mov ebp, [_display.width] ; ebp = screen co-ords base + imul ebp, ebx + add ebp, [_WinMapAddress] + add ebp, eax + + cmp edx, ebx ; to make sure y2 > y1 + jge @f + xchg ebx, edx +@@: + cmp ebx, [Screen_Max_Y] + jge .exit + push ebx + imul ebx, [BytesPerScanLine] + shl eax, 1 + shl eax, 1 + add eax, ebx + add eax, LFB_BASE + pop ebx ; restore ebx = y1 + cmp edx, [Screen_Max_Y] ; the last check + jb .draw + mov edx, [Screen_Max_Y] ; to prevent off-screen drawing + +.draw: + jmp dword [vline.drawtable + edi*4] +align 4 +.invert_color: + mov ecx, [eax] + xor ecx, 0x00FFFFFF + or ecx, 0x01000000 +align 4 +.check_overlap: + movzx esi, byte [ebp] + cmp esi, [CURRENT_TASK] + je .putpixel + jmp .nextpixel + +align 4 +.invert_force: + mov ecx, [eax] + xor ecx, 0x00FFFFFF + or ecx, 0x01000000 +align 4 +.putpixel: + mov [eax], ecx +align 4 +.nextpixel: + add eax, [BytesPerScanLine] + add ebp, [_display.width] + inc ebx + cmp ebx, edx + ja .exit + jmp dword [vline.drawtable + edi*4] +.exit: + shr edi, 1 + pop edx ebx esi ebp eax +.out: + ret +align 4 +.drawtable: +dd .check_overlap ; general case +dd .invert_color +dd .putpixel ; force to draw it +dd .invert_force + + +;************************************************* + + +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 [_display.disable_mouse] + 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 +; note that WDATA.box.width is one pixel less than real window x-size + inc ebx + 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, [Screen_Max_X] + sub eax, [drbar.real_sx] + inc eax + mov [drbar.line_inc_map], eax +; line_inc_scr + mov eax, [drbar.real_sx] + shl eax, 1 + shl eax, 1 + 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] + shl eax, 1 + shl eax, 1 + add edx, eax +; pointer to pixel map + mov eax, [drbar.abs_cy] + imul eax, [Screen_Max_X] + add eax, [drbar.abs_cy] + add eax, [drbar.abs_cx] + add eax, [_WinMapAddress] + xchg eax, ebp +; get process number + mov ebx, [CURRENT_TASK] + +draw_bar_end_32: +; eax - color high RRGG +; bl - process num +; bh - color low BB +; ecx - temp +; edx - pointer to screen +; esi - counter +; edi - counter + 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 [LFB_BASE+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 eax, 0x80000000 + jz @f + test al, al + jz @f + dec al +@@: +; + dec esi + jnz .new_y + add esp, drbar.stack_data + popad + xor eax, eax + ret + + +align 4 +vesa20_drawbackground_tiled: + call [_display.disable_mouse] + 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 + xchg ebp, eax + add ebp, eax + add ebp, eax + add ebp, eax + 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 nbgp + movsb + movsb + movsb + jmp @f +nbgp: + add esi, 3 + add edi, 3 +@@: + inc edi ; +1 for 32 bpp + 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 + ret + +; ---------- + + +vesa20_drawbackground_stretch: + call [_display.disable_mouse] + pushad +; Helper variables +; calculate 2^32*(BgrDataWidth-1) mod (ScreenWidth-1) + mov eax, [BgrDataWidth] + dec eax + xor edx, edx + div dword [Screen_Max_X] + push eax ; high + xor eax, eax + div dword [Screen_Max_X] + push eax ; low +; the same for height + mov eax, [BgrDataHeight] + dec eax + xor edx, edx + div dword [Screen_Max_Y] + push eax ; high + xor eax, eax + div dword [Screen_Max_Y] + 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 + xchg ebp, eax + add ebp, eax + add ebp, eax + add ebp, eax + 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: + + mov [LFB_BASE+edi], ax + shr eax, 16 + + mov [LFB_BASE+edi+2], al +snbgp: + add edi, 4 + inc ebp + mov eax, [esp+20] + inc eax + mov [esp+20], eax + add esi, 4 + cmp eax, [draw_data+32+RECT.right] + jbe sdp3a +sdp4: +; next y + mov ebx, [esp+24] + inc ebx + 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, [Screen_Max_X] + inc ebp + sub edi, eax + sub edi, eax + sub edi, eax + sub edi, eax + add edi, [BytesPerScanLine] +; 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, [Screen_Max_X] + inc ecx + rep movsd + jmp bgr_resmooth1 +sdpdone: + add esp, 44 + popad + ret + +uglobal +align 4 +bgr_cur_line rd 1920 ; maximum width of screen +bgr_next_line rd 1920 +endg + +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] + inc eax + 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: + 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 + +iglobal +align 4 +overlapping_of_points_ptr dd overlapping_of_points +endg + +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 +diff16 "VESA2 code end ",0,$ +diff16 "VESA2 code size",get_pixel,$ +