Subversion Repositories Kolibri OS

Rev

Rev 2288 | Rev 2423 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;  VESA20.INC                                                  ;;
  7. ;;                                                              ;;
  8. ;;  Vesa 2.0 functions for MenuetOS                             ;;
  9. ;;                                                              ;;
  10. ;;  Copyright 2002 Ville Turjanmaa                              ;;
  11. ;;  Alexey, kgaz@crosswindws.net                                ;;
  12. ;;  - Voodoo compatible graphics                                ;;
  13. ;;  Juan M. Caravaca                                            ;;
  14. ;;  - Graphics optimimizations eg. drawline                     ;;
  15. ;;                                                              ;;
  16. ;;  See file COPYING for details                                ;;
  17. ;;                                                              ;;
  18. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  19.  
  20. $Revision: 2353 $
  21.  
  22.  
  23. ; If you're planning to write your own video driver I suggest
  24. ; you replace the VESA12.INC file and see those instructions.
  25.  
  26. ;Screen_Max_X             equ     0xfe00
  27. ;Screen_Max_Y            equ     0xfe04
  28. ;BytesPerScanLine        equ     0xfe08
  29. ;LFBAddress              equ     0xfe80
  30. ;ScreenBPP               equ     0xfbf1
  31.  
  32.  
  33.  
  34. ;*************************************************
  35. ; getpixel
  36. ;
  37. ; in:
  38. ; eax = x coordinate
  39. ; ebx = y coordinate
  40. ;
  41. ; ret:
  42. ; ecx = 00 RR GG BB
  43.  
  44. getpixel:
  45.         push    eax ebx edx edi
  46.         call    dword [GETPIXEL]
  47.         pop     edi edx ebx eax
  48.         ret
  49.  
  50. Vesa20_getpixel24:
  51. ; eax = x
  52. ; ebx = y
  53.         imul    ebx, [BytesPerScanLine] ; ebx = y * y multiplier
  54.         lea     edi, [eax+eax*2]; edi = x*3
  55.         add     edi, ebx      ; edi = x*3+(y*y multiplier)
  56.         mov     ecx, [LFB_BASE+edi]
  57.         and     ecx, 0xffffff
  58.         ret
  59.  
  60. Vesa20_getpixel32:
  61.         imul    ebx, [BytesPerScanLine] ; ebx = y * y multiplier
  62.         lea     edi, [ebx+eax*4]; edi = x*4+(y*y multiplier)
  63.         mov     ecx, [LFB_BASE+edi]
  64.         and     ecx, 0xffffff
  65.         ret
  66.  
  67. ;*************************************************
  68.  
  69. virtual at esp
  70.  putimg:
  71.    .real_sx        dd ?
  72.    .real_sy        dd ?
  73.    .image_sx       dd ?
  74.    .image_sy       dd ?
  75.    .image_cx       dd ?
  76.    .image_cy       dd ?
  77.    .pti            dd ?
  78.    .abs_cx         dd ?
  79.    .abs_cy         dd ?
  80.    .line_increment dd ?
  81.    .winmap_newline dd ?
  82.    .screen_newline dd ?
  83.    .stack_data = 4*12
  84.    .edi         dd      ?
  85.    .esi         dd      ?
  86.    .ebp         dd      ?
  87.    .esp         dd      ?
  88.    .ebx         dd      ?
  89.    .edx         dd      ?
  90.    .ecx         dd      ?
  91.    .eax         dd      ?
  92.    .ret_addr    dd      ?
  93.    .arg_0       dd      ?
  94. end virtual
  95.  
  96. align 16
  97. ; ebx = pointer
  98. ; ecx = size [x|y]
  99. ; edx = coordinates [x|y]
  100. ; ebp = pointer to 'get' function
  101. ; esi = pointer to 'init' function
  102. ; edi = parameter for 'get' function
  103.  
  104. vesa20_putimage:
  105.         pushad
  106.         call    [_display.disable_mouse]
  107.         sub     esp, putimg.stack_data
  108. ; save pointer to image
  109.         mov     [putimg.pti], ebx
  110. ; unpack the size
  111.         mov     eax, ecx
  112.         and     ecx, 0xFFFF
  113.         shr     eax, 16
  114.         mov     [putimg.image_sx], eax
  115.         mov     [putimg.image_sy], ecx
  116. ; unpack the coordinates
  117.         mov     eax, edx
  118.         and     edx, 0xFFFF
  119.         shr     eax, 16
  120.         mov     [putimg.image_cx], eax
  121.         mov     [putimg.image_cy], edx
  122. ; calculate absolute (i.e. screen) coordinates
  123.         mov     eax, [TASK_BASE]
  124.         mov     ebx, [eax-twdw + WDATA.box.left]
  125.         add     ebx, [putimg.image_cx]
  126.         mov     [putimg.abs_cx], ebx
  127.         mov     ebx, [eax-twdw + WDATA.box.top]
  128.         add     ebx, [putimg.image_cy]
  129.         mov     [putimg.abs_cy], ebx
  130. ; real_sx = MIN(wnd_sx-image_cx, image_sx);
  131.         mov     ebx, [eax-twdw + WDATA.box.width]; ebx = wnd_sx
  132. ; \begin{diamond}[20.08.2006]
  133. ; note that WDATA.box.width is one pixel less than real window x-size
  134.         inc     ebx
  135. ; \end{diamond}[20.08.2006]
  136.         sub     ebx, [putimg.image_cx]
  137.         ja      @f
  138.         add     esp, putimg.stack_data
  139.         popad
  140.         ret
  141. @@:
  142.         cmp     ebx, [putimg.image_sx]
  143.         jbe     .end_x
  144.         mov     ebx, [putimg.image_sx]
  145. .end_x:
  146.         mov     [putimg.real_sx], ebx
  147. ; init real_sy
  148.         mov     ebx, [eax-twdw + WDATA.box.height]; ebx = wnd_sy
  149. ; \begin{diamond}[20.08.2006]
  150.         inc     ebx
  151. ; \end{diamond}[20.08.2006]
  152.         sub     ebx, [putimg.image_cy]
  153.         ja      @f
  154.         add     esp, putimg.stack_data
  155.         popad
  156.         ret
  157. @@:
  158.         cmp     ebx, [putimg.image_sy]
  159.         jbe     .end_y
  160.         mov     ebx, [putimg.image_sy]
  161. .end_y:
  162.         mov     [putimg.real_sy], ebx
  163. ; line increment
  164.         mov     eax, [putimg.image_sx]
  165.         mov     ecx, [putimg.real_sx]
  166.         sub     eax, ecx
  167. ;;     imul    eax, [putimg.source_bpp]
  168. ;     lea     eax, [eax + eax * 2]
  169.         call    esi
  170.         add     eax, [putimg.arg_0]
  171.         mov     [putimg.line_increment], eax
  172. ; winmap new line increment
  173.         mov     eax, [Screen_Max_X]
  174.         inc     eax
  175.         sub     eax, [putimg.real_sx]
  176.         mov     [putimg.winmap_newline], eax
  177. ; screen new line increment
  178.         mov     eax, [BytesPerScanLine]
  179.         movzx   ebx, byte [ScreenBPP]
  180.         shr     ebx, 3
  181.         imul    ecx, ebx
  182.         sub     eax, ecx
  183.         mov     [putimg.screen_newline], eax
  184. ; pointer to image
  185.         mov     esi, [putimg.pti]
  186. ; pointer to screen
  187.         mov     edx, [putimg.abs_cy]
  188.         imul    edx, [BytesPerScanLine]
  189.         mov     eax, [putimg.abs_cx]
  190.         movzx   ebx, byte [ScreenBPP]
  191.         shr     ebx, 3
  192.         imul    eax, ebx
  193.         add     edx, eax
  194. ; pointer to pixel map
  195.         mov     eax, [putimg.abs_cy]
  196.         imul    eax, [Screen_Max_X]
  197.         add     eax, [putimg.abs_cy]
  198.         add     eax, [putimg.abs_cx]
  199.         add     eax, [_WinMapAddress]
  200.         xchg    eax, ebp
  201. ; get process number
  202.         mov     ebx, [CURRENT_TASK]
  203.         cmp     byte [ScreenBPP], 32
  204.         je      put_image_end_32
  205. ;put_image_end_24:
  206.         mov     edi, [putimg.real_sy]
  207. align   4
  208. .new_line:
  209.         mov     ecx, [putimg.real_sx]
  210. ;     push    ebp edx
  211. align   4
  212. .new_x:
  213.         push    [putimg.edi]
  214.         mov     eax, [putimg.ebp+4]
  215.         call    eax
  216.         cmp     [ebp], bl
  217.         jne     .skip
  218. ;     mov     eax, [esi]        ; eax = RRBBGGRR
  219.         mov     [LFB_BASE+edx], ax
  220.         shr     eax, 16
  221.         mov     [LFB_BASE+edx+2], al
  222. .skip:
  223. ;     add     esi, 3 ;[putimg.source_bpp]
  224.         add     edx, 3
  225.         inc     ebp
  226.         dec     ecx
  227.         jnz     .new_x
  228. ;     pop     edx ebp
  229.         add     esi, [putimg.line_increment]
  230.         add     edx, [putimg.screen_newline];[BytesPerScanLine]
  231.         add     ebp, [putimg.winmap_newline];[Screen_Max_X]
  232. ;     inc     ebp
  233.         cmp     [putimg.ebp], putimage_get1bpp
  234.         jz      .correct
  235.         cmp     [putimg.ebp], putimage_get2bpp
  236.         jz      .correct
  237.         cmp     [putimg.ebp], putimage_get4bpp
  238.         jnz     @f
  239. .correct:
  240.         mov     eax, [putimg.edi]
  241.         mov     byte [eax], 80h
  242. @@:
  243.         dec     edi
  244.         jnz     .new_line
  245. .finish:
  246.         add     esp, putimg.stack_data
  247.         popad
  248.         ret
  249.  
  250. put_image_end_32:
  251.         mov     edi, [putimg.real_sy]
  252. align   4
  253. .new_line:
  254.         mov     ecx, [putimg.real_sx]
  255. ;     push    ebp edx
  256. align   4
  257. .new_x:
  258.         push    [putimg.edi]
  259.         mov     eax, [putimg.ebp+4]
  260.         call    eax
  261.         cmp     [ebp], bl
  262.         jne     .skip
  263. ;     mov     eax, [esi]        ; ecx = RRBBGGRR
  264.         mov     [LFB_BASE+edx], eax
  265. .skip:
  266. ;     add     esi, [putimg.source_bpp]
  267.         add     edx, 4
  268.         inc     ebp
  269.         dec     ecx
  270.         jnz     .new_x
  271. ;     pop     edx ebp
  272.         add     esi, [putimg.line_increment]
  273.         add     edx, [putimg.screen_newline];[BytesPerScanLine]
  274.         add     ebp, [putimg.winmap_newline];[Screen_Max_X]
  275. ;     inc     ebp
  276.         cmp     [putimg.ebp], putimage_get1bpp
  277.         jz      .correct
  278.         cmp     [putimg.ebp], putimage_get2bpp
  279.         jz      .correct
  280.         cmp     [putimg.ebp], putimage_get4bpp
  281.         jnz     @f
  282. .correct:
  283.         mov     eax, [putimg.edi]
  284.         mov     byte [eax], 80h
  285. @@:
  286.         dec     edi
  287.         jnz     .new_line
  288. .finish:
  289.         add     esp, putimg.stack_data
  290.         popad
  291.         call    VGA__putimage
  292.         mov     [EGA_counter], 1
  293.         ret
  294.  
  295.  
  296. ;*************************************************
  297. align 4
  298. __sys_putpixel:
  299.  
  300. ; eax = x coordinate
  301. ; ebx = y coordinate
  302. ; ecx = ?? RR GG BB    ; 0x01000000 negation
  303. ; edi = 0x00000001 force
  304.  
  305. ;;;        mov  [novesachecksum], dword 0
  306.         pushad
  307.         cmp     [Screen_Max_X], eax
  308.         jb      .exit
  309.         cmp     [Screen_Max_Y], ebx
  310.         jb      .exit
  311.         test    edi, 1           ; force ?
  312.         jnz     .forced
  313.  
  314. ; not forced:
  315.  
  316.         push    eax
  317.         mov     edx, [_display.width]; screen x size
  318.         imul    edx, ebx
  319.         add     eax, [_WinMapAddress]
  320.         movzx   edx, byte [eax+edx]
  321.         cmp     edx, [CURRENT_TASK]
  322.         pop     eax
  323.         jne     .exit
  324.  
  325. .forced:
  326. ; check if negation
  327.         test    ecx, 0x01000000
  328.         jz      .noneg
  329.         call    getpixel
  330.         not     ecx
  331.         mov     [esp+32-8], ecx
  332. .noneg:
  333. ; OK to set pixel
  334.         call    dword [PUTPIXEL]; call the real put_pixel function
  335. .exit:
  336.         popad
  337.         ret
  338.  
  339. align 4
  340. Vesa20_putpixel24:
  341. ; eax = x
  342. ; ebx = y
  343.         imul    ebx, [BytesPerScanLine]  ; ebx = y * y multiplier
  344.         lea     edi, [eax+eax*2]; edi = x*3
  345.         mov     eax, [esp+32-8+4]
  346.         mov     [LFB_BASE+ebx+edi], ax
  347.         shr     eax, 16
  348.         mov     [LFB_BASE+ebx+edi+2], al
  349.         ret
  350.  
  351.  
  352. align 4
  353. Vesa20_putpixel32:
  354. ; eax = x
  355. ; ebx = y
  356.         imul    ebx, [BytesPerScanLine]  ; ebx = y * y multiplier
  357.         lea     edi, [ebx+eax*4]; edi = x*4+(y*y multiplier)
  358.         mov     eax, [esp+32-8+4]; eax = color
  359.         mov     [LFB_BASE+edi], eax
  360.         ret
  361.  
  362. ;*************************************************
  363.  
  364. ;align 4
  365. calculate_edi:
  366.         mov     edi, ebx
  367.         imul    edi, [Screen_Max_X]
  368.         add     edi, ebx
  369.         add     edi, eax
  370.         ret
  371.  
  372. ;*************************************************
  373.  
  374. ; DRAWLINE
  375.  
  376. align 4
  377. __sys_draw_line:
  378. ;     inc   [mouse_pause]
  379.         call    [_display.disable_mouse]
  380.  
  381. ; draw a line
  382. ; eax = HIWORD = x1
  383. ;       LOWORD = x2
  384. ; ebx = HIWORD = y1
  385. ;       LOWORD = y2
  386. ; ecx = color
  387. ; edi = force ?
  388.         pusha
  389.  
  390. dl_x1 equ esp+20
  391. dl_y1 equ esp+16
  392. dl_x2 equ esp+12
  393. dl_y2 equ esp+8
  394. dl_dx equ esp+4
  395. dl_dy equ esp+0
  396.  
  397.         xor     edx, edx   ; clear edx
  398.         xor     esi, esi   ; unpack arguments
  399.         xor     ebp, ebp
  400.         mov     si, ax     ; esi = x2
  401.         mov     bp, bx     ; ebp = y2
  402.         shr     eax, 16    ; eax = x1
  403.         shr     ebx, 16    ; ebx = y1
  404.         push    eax        ; save x1
  405.         push    ebx        ; save y1
  406.         push    esi        ; save x2
  407.         push    ebp        ; save y2
  408. ; checking x-axis...
  409.         sub     esi, eax   ; esi = x2-x1
  410.         push    esi        ; save y2-y1
  411.         jl      .x2lx1     ; is x2 less than x1 ?
  412.         jg      .no_vline  ; x1 > x2 ?
  413.         mov     edx, ebp   ; else (if x1=x2)
  414.         call    vline
  415.         push    edx ; necessary to rightly restore stack frame at .exit
  416.         jmp     .exit
  417. .x2lx1:
  418.         neg     esi         ; get esi absolute value
  419. .no_vline:
  420. ; checking y-axis...
  421.         sub     ebp, ebx    ; ebp = y2-y1
  422.         push    ebp         ; save y2-y1
  423.         jl      .y2ly1      ; is y2 less than y1 ?
  424.         jg      .no_hline   ; y1 > y2 ?
  425.         mov     edx, [dl_x2]; else (if y1=y2)
  426.         call    hline
  427.         jmp     .exit
  428.  
  429. .y2ly1:
  430.         neg     ebp         ; get ebp absolute value
  431. .no_hline:
  432.         cmp     ebp, esi
  433.         jle     .x_rules    ; |y2-y1| < |x2-x1|  ?
  434.         cmp     [dl_y2], ebx; make sure y1 is at the begining
  435.         jge     .no_reverse1
  436.         neg     dword [dl_dx]
  437.         mov     edx, [dl_x2]
  438.         mov     [dl_x2], eax
  439.         mov     [dl_x1], edx
  440.         mov     edx, [dl_y2]
  441.         mov     [dl_y2], ebx
  442.         mov     [dl_y1], edx
  443. .no_reverse1:
  444.         mov     eax, [dl_dx]
  445.         cdq                 ; extend eax sing to edx
  446.         shl     eax, 16     ; using 16bit fix-point maths
  447.         idiv    ebp         ; eax = ((x2-x1)*65536)/(y2-y1)
  448. ;--------------------------------------
  449. ; correction for the remainder of the division
  450.         shl     edx, 1
  451.         cmp     ebp, edx
  452.         jb      @f
  453.         inc     eax
  454. @@:
  455. ;--------------------------------------
  456.         mov     edx, ebp    ; edx = counter (number of pixels to draw)
  457.         mov     ebp, 1 *65536; <<16   ; ebp = dy = 1.0
  458.         mov     esi, eax    ; esi = dx
  459.         jmp     .y_rules
  460.  
  461. .x_rules:
  462.         cmp     [dl_x2], eax ; make sure x1 is at the begining
  463.         jge     .no_reverse2
  464.         neg     dword [dl_dy]
  465.         mov     edx, [dl_x2]
  466.         mov     [dl_x2], eax
  467.         mov     [dl_x1], edx
  468.         mov     edx, [dl_y2]
  469.         mov     [dl_y2], ebx
  470.         mov     [dl_y1], edx
  471. .no_reverse2:
  472.         xor     edx, edx
  473.         mov     eax, [dl_dy]
  474.         cdq                 ; extend eax sing to edx
  475.         shl     eax, 16     ; using 16bit fix-point maths
  476.         idiv    esi         ; eax = ((y2-y1)*65536)/(x2-x1)
  477. ;--------------------------------------
  478. ; correction for the remainder of the division
  479.         shl     edx, 1
  480.         cmp     esi, edx
  481.         jb      @f
  482.         inc     eax
  483. @@:
  484. ;--------------------------------------
  485.         mov     edx, esi    ; edx = counter (number of pixels to draw)
  486.         mov     esi, 1 *65536;<< 16   ; esi = dx = 1.0
  487.         mov     ebp, eax    ; ebp = dy
  488. .y_rules:
  489.         mov     eax, [dl_x1]
  490.         mov     ebx, [dl_y1]
  491.         shl     eax, 16
  492.         shl     ebx, 16
  493. ;-----------------------------------------------------------------------------
  494. align 4
  495. .draw:
  496.         push    eax ebx
  497. ;--------------------------------------
  498. ; correction for the remainder of the division
  499.         test    ah, 0x80
  500.         jz      @f
  501.         add     eax, 1 shl 16
  502. @@:
  503. ;--------------------------------------
  504.         shr     eax, 16
  505. ;--------------------------------------
  506. ; correction for the remainder of the division
  507.         test    bh, 0x80
  508.         jz      @f
  509.         add     ebx, 1 shl 16
  510. @@:
  511. ;--------------------------------------
  512.         shr     ebx, 16
  513.         call    [putpixel]
  514.         pop     ebx eax
  515.         add     ebx, ebp     ; y = y+dy
  516.         add     eax, esi     ; x = x+dx
  517.         dec     edx
  518.         jnz     .draw
  519. ; force last drawn pixel to be at (x2,y2)
  520.         mov     eax, [dl_x2]
  521.         mov     ebx, [dl_y2]
  522.         call    [putpixel]
  523. .exit:
  524.         add     esp, 6*4
  525.         popa
  526. ;     dec   [mouse_pause]
  527.         call    [draw_pointer]
  528.         ret
  529.  
  530.  
  531. hline:
  532. ; draw an horizontal line
  533. ; eax = x1
  534. ; edx = x2
  535. ; ebx = y
  536. ; ecx = color
  537. ; edi = force ?
  538.         push    eax edx
  539.         cmp     edx, eax   ; make sure x2 is above x1
  540.         jge     @f
  541.         xchg    eax, edx
  542. align   4
  543. @@:
  544.         call    [putpixel]
  545.         inc     eax
  546.         cmp     eax, edx
  547.         jle     @b
  548.         pop     edx eax
  549.         ret
  550.  
  551.  
  552. vline:
  553. ; draw a vertical line
  554. ; eax = x
  555. ; ebx = y1
  556. ; edx = y2
  557. ; ecx = color
  558. ; edi = force ?
  559.         push    ebx edx
  560.         cmp     edx, ebx   ; make sure y2 is above y1
  561.         jge     @f
  562.         xchg    ebx, edx
  563. align   4
  564. @@:
  565.         call    [putpixel]
  566.         inc     ebx
  567.         cmp     ebx, edx
  568.         jle     @b
  569.         pop     edx ebx
  570.         ret
  571.  
  572.  
  573. ;*************************************************
  574.  
  575.  
  576. virtual at esp
  577. drbar:
  578.      .bar_sx       dd ?
  579.      .bar_sy       dd ?
  580.      .bar_cx       dd ?
  581.      .bar_cy       dd ?
  582.      .abs_cx       dd ?
  583.      .abs_cy       dd ?
  584.      .real_sx      dd ?
  585.      .real_sy      dd ?
  586.      .color        dd ?
  587.      .line_inc_scr dd ?
  588.      .line_inc_map dd ?
  589.      .stack_data = 4*11
  590. end virtual
  591.  
  592. align 4
  593. ; eax   cx
  594. ; ebx   cy
  595. ; ecx   xe
  596. ; edx   ye
  597. ; edi   color
  598. vesa20_drawbar:
  599.         pushad
  600.         call    [_display.disable_mouse]
  601.         sub     esp, drbar.stack_data
  602.         mov     [drbar.color], edi
  603.         sub     edx, ebx
  604.         jle     .exit       ;// mike.dld, 2005-01-29
  605.         sub     ecx, eax
  606.         jle     .exit       ;// mike.dld, 2005-01-29
  607.         mov     [drbar.bar_sy], edx
  608.         mov     [drbar.bar_sx], ecx
  609.         mov     [drbar.bar_cx], eax
  610.         mov     [drbar.bar_cy], ebx
  611.         mov     edi, [TASK_BASE]
  612.         add     eax, [edi-twdw + WDATA.box.left]; win_cx
  613.         add     ebx, [edi-twdw + WDATA.box.top]; win_cy
  614.         mov     [drbar.abs_cx], eax
  615.         mov     [drbar.abs_cy], ebx
  616. ; real_sx = MIN(wnd_sx-bar_cx, bar_sx);
  617.         mov     ebx, [edi-twdw + WDATA.box.width]; ebx = wnd_sx
  618. ; \begin{diamond}[20.08.2006]
  619. ; note that WDATA.box.width is one pixel less than real window x-size
  620.         inc     ebx
  621. ; \end{diamond}[20.08.2006]
  622.         sub     ebx, [drbar.bar_cx]
  623.         ja      @f
  624. .exit:                       ;// mike.dld, 2005-01-29
  625.         add     esp, drbar.stack_data
  626.         popad
  627.         xor     eax, eax
  628.         inc     eax
  629.         ret
  630. @@:
  631.         cmp     ebx, [drbar.bar_sx]
  632.         jbe     .end_x
  633.         mov     ebx, [drbar.bar_sx]
  634. .end_x:
  635.         mov     [drbar.real_sx], ebx
  636. ; real_sy = MIN(wnd_sy-bar_cy, bar_sy);
  637.         mov     ebx, [edi-twdw + WDATA.box.height]; ebx = wnd_sy
  638. ; \begin{diamond}[20.08.2006]
  639.         inc     ebx
  640. ; \end{diamond}
  641.         sub     ebx, [drbar.bar_cy]
  642.         ja      @f
  643.         add     esp, drbar.stack_data
  644.         popad
  645.         xor     eax, eax
  646.         inc     eax
  647.         ret
  648. @@:
  649.         cmp     ebx, [drbar.bar_sy]
  650.         jbe     .end_y
  651.         mov     ebx, [drbar.bar_sy]
  652. .end_y:
  653.         mov     [drbar.real_sy], ebx
  654. ; line_inc_map
  655.         mov     eax, [Screen_Max_X]
  656.         sub     eax, [drbar.real_sx]
  657.         inc     eax
  658.         mov     [drbar.line_inc_map], eax
  659. ; line_inc_scr
  660.         mov     eax, [drbar.real_sx]
  661.         movzx   ebx, byte [ScreenBPP]
  662.         shr     ebx, 3
  663.         imul    eax, ebx
  664.         neg     eax
  665.         add     eax, [BytesPerScanLine]
  666.         mov     [drbar.line_inc_scr], eax
  667. ; pointer to screen
  668.         mov     edx, [drbar.abs_cy]
  669.         imul    edx, [BytesPerScanLine]
  670.         mov     eax, [drbar.abs_cx]
  671. ;     movzx   ebx, byte [ScreenBPP]
  672. ;     shr     ebx, 3
  673.         imul    eax, ebx
  674.         add     edx, eax
  675. ; pointer to pixel map
  676.         mov     eax, [drbar.abs_cy]
  677.         imul    eax, [Screen_Max_X]
  678.         add     eax, [drbar.abs_cy]
  679.         add     eax, [drbar.abs_cx]
  680.         add     eax, [_WinMapAddress]
  681.         xchg    eax, ebp
  682. ; get process number
  683.         mov     ebx, [CURRENT_TASK]
  684.         cmp     byte [ScreenBPP], 24
  685.         jne     draw_bar_end_32
  686. draw_bar_end_24:
  687.         mov     eax, [drbar.color] ;; BBGGRR00
  688.         mov     bh, al             ;; bh  = BB
  689.         shr     eax, 8             ;; eax = RRGG
  690. ; eax - color high   RRGG
  691. ; bl - process num
  692. ; bh - color low    BB
  693. ; ecx - temp
  694. ; edx - pointer to screen
  695. ; esi - counter
  696. ; edi - counter
  697.         mov     esi, [drbar.real_sy]
  698. align   4
  699. .new_y:
  700.         mov     edi, [drbar.real_sx]
  701. align   4
  702. .new_x:
  703.         cmp     byte [ebp], bl
  704.         jne     .skip
  705.  
  706.         mov     [LFB_BASE+edx], bh
  707.         mov     [LFB_BASE+edx + 1], ax
  708. .skip:
  709. ; add pixel
  710.         add     edx, 3
  711.         inc     ebp
  712.         dec     edi
  713.         jnz     .new_x
  714. ; add line
  715.         add     edx, [drbar.line_inc_scr]
  716.         add     ebp, [drbar.line_inc_map]
  717. ; <Ivan 15.10.04> drawing gradient bars
  718.         test    eax, 0x00800000
  719.         jz      @f
  720.         test    bh, bh
  721.         jz      @f
  722.         dec     bh
  723. @@:
  724. ; </Ivan 15.10.04>
  725.         dec     esi
  726.         jnz     .new_y
  727.         add     esp, drbar.stack_data
  728.         popad
  729.         xor     eax, eax
  730.         ret
  731.  
  732. draw_bar_end_32:
  733.         mov     eax, [drbar.color] ;; BBGGRR00
  734.         mov     esi, [drbar.real_sy]
  735. align   4
  736. .new_y:
  737.         mov     edi, [drbar.real_sx]
  738. align   4
  739. .new_x:
  740.         cmp     byte [ebp], bl
  741.         jne     .skip
  742.  
  743.         mov     [LFB_BASE+edx], eax
  744. .skip:
  745. ; add pixel
  746.         add     edx, 4
  747.         inc     ebp
  748.         dec     edi
  749.         jnz     .new_x
  750. ; add line
  751.         add     edx, [drbar.line_inc_scr]
  752.         add     ebp, [drbar.line_inc_map]
  753. ; <Ivan 15.10.04> drawing gradient bars
  754.         test    eax, 0x80000000
  755.         jz      @f
  756.         test    al, al
  757.         jz      @f
  758.         dec     al
  759. @@:
  760. ; </Ivan 15.10.04>
  761.         dec     esi
  762.         jnz     .new_y
  763.         add     esp, drbar.stack_data
  764.         popad
  765.         call    VGA_draw_bar
  766.         xor     eax, eax
  767.         mov     [EGA_counter], 1
  768.         ret
  769.  
  770. align 4
  771. vesa20_drawbackground_tiled:
  772.         call    [_display.disable_mouse]
  773.         pushad
  774. ; External loop for all y from start to end
  775.         mov     ebx, [draw_data+32+RECT.top]    ; y start
  776. dp2:
  777.         mov     ebp, [draw_data+32+RECT.left]   ; x start
  778. ; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
  779. ;                       and LFB data (output for our function) [edi]
  780.         mov     eax, [BytesPerScanLine]
  781.         mul     ebx
  782.         xchg    ebp, eax
  783.         add     ebp, eax
  784.         add     ebp, eax
  785.         add     ebp, eax
  786.         cmp     [ScreenBPP], byte 24    ; 24 or 32 bpp ? - x size
  787.         jz      @f
  788.         add     ebp, eax
  789. @@:
  790.         add     ebp, LFB_BASE
  791. ; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
  792.         call    calculate_edi
  793.         xchg    edi, ebp
  794.         add     ebp, [_WinMapAddress]
  795. ; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
  796. ; 2) Calculate offset in background memory block
  797.         push    eax
  798.         xor     edx, edx
  799.         mov     eax, ebx
  800.         div     dword [BgrDataHeight]   ; edx := y mod BgrDataHeight
  801.         pop     eax
  802.         push    eax
  803.         mov     ecx, [BgrDataWidth]
  804.         mov     esi, edx
  805.         imul    esi, ecx                ; esi := (y mod BgrDataHeight) * BgrDataWidth
  806.         xor     edx, edx
  807.         div     ecx             ; edx := x mod BgrDataWidth
  808.         sub     ecx, edx
  809.         add     esi, edx        ; esi := (y mod BgrDataHeight)*BgrDataWidth + (x mod BgrDataWidth)
  810.         pop     eax
  811.         lea     esi, [esi*3]
  812.         add     esi, [img_background]
  813.         xor     edx, edx
  814.         inc     edx
  815. ; 3) Loop through redraw rectangle and copy background data
  816. ; Registers meaning:
  817. ; eax = x, ebx = y (screen coordinates)
  818. ; ecx = deltax - number of pixels left in current tile block
  819. ; edx = 1
  820. ; esi -> bgr memory, edi -> output
  821. ; ebp = offset in WinMapAddress
  822. dp3:
  823.         cmp     [ebp], dl
  824.         jnz     nbgp
  825.         movsb
  826.         movsb
  827.         movsb
  828.         jmp     @f
  829. nbgp:
  830.         add     esi, 3
  831.         add     edi, 3
  832. @@:
  833.         cmp     [ScreenBPP], byte 25    ; 24 or 32 bpp?
  834.         sbb     edi, -1         ; +1 for 32 bpp
  835. ; I do not use 'inc eax' because this is slightly slower then 'add eax,1'
  836.         add     ebp, edx
  837.         add     eax, edx
  838.         cmp     eax, [draw_data+32+RECT.right]
  839.         ja      dp4
  840.         sub     ecx, edx
  841.         jnz     dp3
  842. ; next tile block on x-axis
  843.         mov     ecx, [BgrDataWidth]
  844.         sub     esi, ecx
  845.         sub     esi, ecx
  846.         sub     esi, ecx
  847.         jmp     dp3
  848. dp4:
  849. ; next scan line
  850.         inc     ebx
  851.         cmp     ebx, [draw_data+32+RECT.bottom]
  852.         jbe     dp2
  853.         popad
  854.         mov     [EGA_counter], 1
  855.         call    VGA_drawbackground
  856.         ret
  857.  
  858. ; ----------
  859.  
  860.  
  861. vesa20_drawbackground_stretch:
  862.         call    [_display.disable_mouse]
  863.         pushad
  864. ; Helper variables
  865. ; calculate 2^32*(BgrDataWidth-1) mod (ScreenWidth-1)
  866.         mov     eax, [BgrDataWidth]
  867.         dec     eax
  868.         xor     edx, edx
  869.         div     dword [Screen_Max_X]
  870.         push    eax     ; high
  871.         xor     eax, eax
  872.         div     dword [Screen_Max_X]
  873.         push    eax     ; low
  874. ; the same for height
  875.         mov     eax, [BgrDataHeight]
  876.         dec     eax
  877.         xor     edx, edx
  878.         div     dword [Screen_Max_Y]
  879.         push    eax     ; high
  880.         xor     eax, eax
  881.         div     dword [Screen_Max_Y]
  882.         push    eax     ; low
  883. ; External loop for all y from start to end
  884.         mov     ebx, [draw_data+32+RECT.top]    ; y start
  885.         mov     ebp, [draw_data+32+RECT.left]   ; x start
  886. ; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
  887. ;                       and LFB data (output for our function) [edi]
  888.         mov     eax, [BytesPerScanLine]
  889.         mul     ebx
  890.         xchg    ebp, eax
  891.         add     ebp, eax
  892.         add     ebp, eax
  893.         add     ebp, eax
  894.         cmp     [ScreenBPP], byte 24    ; 24 or 32 bpp ? - x size
  895.         jz      @f
  896.         add     ebp, eax
  897. @@:
  898. ; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
  899.         call    calculate_edi
  900.         xchg    edi, ebp
  901. ; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
  902.         push    ebx
  903.         push    eax
  904. ; 2) Calculate offset in background memory block
  905.         mov     eax, ebx
  906.         imul    ebx, dword [esp+12]
  907.         mul     dword [esp+8]
  908.         add     edx, ebx        ; edx:eax = y * 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
  909.         mov     esi, edx
  910.         imul    esi, [BgrDataWidth]
  911.         push    edx
  912.         push    eax
  913.         mov     eax, [esp+8]
  914.         mul     dword [esp+28]
  915.         push    eax
  916.         mov     eax, [esp+12]
  917.         mul     dword [esp+28]
  918.         add     [esp], edx
  919.         pop     edx             ; edx:eax = x * 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
  920.         add     esi, edx
  921.         lea     esi, [esi*3]
  922.         add     esi, [img_background]
  923.         push    eax
  924.         push    edx
  925.         push    esi
  926. ; 3) Smooth horizontal
  927. bgr_resmooth0:
  928.         mov     ecx, [esp+8]
  929.         mov     edx, [esp+4]
  930.         mov     esi, [esp]
  931.         push    edi
  932.         mov     edi, bgr_cur_line
  933.         call    smooth_line
  934. bgr_resmooth1:
  935.         mov     eax, [esp+16+4]
  936.         inc     eax
  937.         cmp     eax, [BgrDataHeight]
  938.         jae     bgr.no2nd
  939.         mov     ecx, [esp+8+4]
  940.         mov     edx, [esp+4+4]
  941.         mov     esi, [esp+4]
  942.         add     esi, [BgrDataWidth]
  943.         add     esi, [BgrDataWidth]
  944.         add     esi, [BgrDataWidth]
  945.         mov     edi, bgr_next_line
  946.         call    smooth_line
  947. bgr.no2nd:
  948.         pop     edi
  949. sdp3:
  950.         xor     esi, esi
  951.         mov     ecx, [esp+12]
  952. ; 4) Loop through redraw rectangle and copy background data
  953. ; Registers meaning:
  954. ; esi = offset in current line, edi -> output
  955. ; ebp = offset in WinMapAddress
  956. ; dword [esp] = offset in bgr data
  957. ; qword [esp+4] = x * 2^32 * (BgrDataWidth-1) / (ScreenWidth-1)
  958. ; qword [esp+12] = y * 2^32 * (BgrDataHeight-1) / (ScreenHeight-1)
  959. ; dword [esp+20] = x
  960. ; dword [esp+24] = y
  961. ; precalculated constants:
  962. ; qword [esp+28] = 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
  963. ; qword [esp+36] = 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
  964. sdp3a:
  965.         mov     eax, [_WinMapAddress]
  966.         cmp     [ebp+eax], byte 1
  967.         jnz     snbgp
  968.         mov     eax, [bgr_cur_line+esi]
  969.         test    ecx, ecx
  970.         jz      .novert
  971.         mov     ebx, [bgr_next_line+esi]
  972.         call    [overlapping_of_points_ptr]
  973. .novert:
  974.  
  975.         mov     [LFB_BASE+edi], ax
  976.         shr     eax, 16
  977.  
  978.         mov     [LFB_BASE+edi+2], al
  979. snbgp:
  980.         cmp     [ScreenBPP], byte 25
  981.         sbb     edi, -4
  982.         add     ebp, 1
  983.         mov     eax, [esp+20]
  984.         add     eax, 1
  985.         mov     [esp+20], eax
  986.         add     esi, 4
  987.         cmp     eax, [draw_data+32+RECT.right]
  988.         jbe     sdp3a
  989. sdp4:
  990. ; next y
  991.         mov     ebx, [esp+24]
  992.         add     ebx, 1
  993.         mov     [esp+24], ebx
  994.         cmp     ebx, [draw_data+32+RECT.bottom]
  995.         ja      sdpdone
  996. ; advance edi, ebp to next scan line
  997.         sub     eax, [draw_data+32+RECT.left]
  998.         sub     ebp, eax
  999.         add     ebp, [Screen_Max_X]
  1000.         add     ebp, 1
  1001.         sub     edi, eax
  1002.         sub     edi, eax
  1003.         sub     edi, eax
  1004.         cmp     [ScreenBPP], byte 24
  1005.         jz      @f
  1006.         sub     edi, eax
  1007. @@:
  1008.         add     edi, [BytesPerScanLine]
  1009. ; restore ecx,edx; advance esi to next background line
  1010.         mov     eax, [esp+28]
  1011.         mov     ebx, [esp+32]
  1012.         add     [esp+12], eax
  1013.         mov     eax, [esp+16]
  1014.         adc     [esp+16], ebx
  1015.         sub     eax, [esp+16]
  1016.         mov     ebx, eax
  1017.         lea     eax, [eax*3]
  1018.         imul    eax, [BgrDataWidth]
  1019.         sub     [esp], eax
  1020.         mov     eax, [draw_data+32+RECT.left]
  1021.         mov     [esp+20], eax
  1022.         test    ebx, ebx
  1023.         jz      sdp3
  1024.         cmp     ebx, -1
  1025.         jnz     bgr_resmooth0
  1026.         push    edi
  1027.         mov     esi, bgr_next_line
  1028.         mov     edi, bgr_cur_line
  1029.         mov     ecx, [Screen_Max_X]
  1030.         inc     ecx
  1031.         rep movsd
  1032.         jmp     bgr_resmooth1
  1033. sdpdone:
  1034.         add     esp, 44
  1035.         popad
  1036.         mov     [EGA_counter], 1
  1037.         call    VGA_drawbackground
  1038.         ret
  1039.  
  1040. uglobal
  1041. align 4
  1042. bgr_cur_line    rd      1920    ; maximum width of screen
  1043. bgr_next_line   rd      1920
  1044. endg
  1045.  
  1046. smooth_line:
  1047.         mov     al, [esi+2]
  1048.         shl     eax, 16
  1049.         mov     ax, [esi]
  1050.         test    ecx, ecx
  1051.         jz      @f
  1052.         mov     ebx, [esi+2]
  1053.         shr     ebx, 8
  1054.         call    [overlapping_of_points_ptr]
  1055. @@:
  1056.         stosd
  1057.         mov     eax, [esp+20+8]
  1058.         add     eax, 1
  1059.         mov     [esp+20+8], eax
  1060.         cmp     eax, [draw_data+32+RECT.right]
  1061.         ja      @f
  1062.         add     ecx, [esp+36+8]
  1063.         mov     eax, edx
  1064.         adc     edx, [esp+40+8]
  1065.         sub     eax, edx
  1066.         lea     eax, [eax*3]
  1067.         sub     esi, eax
  1068.         jmp     smooth_line
  1069. @@:
  1070.         mov     eax, [draw_data+32+RECT.left]
  1071.         mov     [esp+20+8], eax
  1072.         ret
  1073.  
  1074. align 16
  1075. overlapping_of_points:
  1076. if 0
  1077. ; this version of procedure works, but is slower than next version
  1078.         push    ecx edx
  1079.         mov     edx, eax
  1080.         push    esi
  1081.         shr     ecx, 24
  1082.         mov     esi, ecx
  1083.         mov     ecx, ebx
  1084.         movzx   ebx, dl
  1085.         movzx   eax, cl
  1086.         sub     eax, ebx
  1087.         movzx   ebx, dh
  1088.         imul    eax, esi
  1089.         add     dl, ah
  1090.         movzx   eax, ch
  1091.         sub     eax, ebx
  1092.         imul    eax, esi
  1093.         add     dh, ah
  1094.         ror     ecx, 16
  1095.         ror     edx, 16
  1096.         movzx   eax, cl
  1097.         movzx   ebx, dl
  1098.         sub     eax, ebx
  1099.         imul    eax, esi
  1100.         pop     esi
  1101.         add     dl, ah
  1102.         mov     eax, edx
  1103.         pop     edx
  1104.         ror     eax, 16
  1105.         pop     ecx
  1106.         ret
  1107. else
  1108.         push    ecx edx
  1109.         mov     edx, eax
  1110.         push    esi
  1111.         shr     ecx, 26
  1112.         mov     esi, ecx
  1113.         mov     ecx, ebx
  1114.         shl     esi, 9
  1115.         movzx   ebx, dl
  1116.         movzx   eax, cl
  1117.         sub     eax, ebx
  1118.         movzx   ebx, dh
  1119.         add     dl, [BgrAuxTable+(eax+0x100)+esi]
  1120.         movzx   eax, ch
  1121.         sub     eax, ebx
  1122.         add     dh, [BgrAuxTable+(eax+0x100)+esi]
  1123.         ror     ecx, 16
  1124.         ror     edx, 16
  1125.         movzx   eax, cl
  1126.         movzx   ebx, dl
  1127.         sub     eax, ebx
  1128.         add     dl, [BgrAuxTable+(eax+0x100)+esi]
  1129.         pop     esi
  1130.         mov     eax, edx
  1131.         pop     edx
  1132.         ror     eax, 16
  1133.         pop     ecx
  1134.         ret
  1135. end if
  1136.  
  1137. iglobal
  1138. align 4
  1139. overlapping_of_points_ptr       dd      overlapping_of_points
  1140. endg
  1141.  
  1142. init_background:
  1143.         mov     edi, BgrAuxTable
  1144.         xor     edx, edx
  1145. .loop2:
  1146.         mov     eax, edx
  1147.         shl     eax, 8
  1148.         neg     eax
  1149.         mov     ecx, 0x200
  1150. .loop1:
  1151.         mov     byte [edi], ah
  1152.         inc     edi
  1153.         add     eax, edx
  1154.         loop    .loop1
  1155.         add     dl, 4
  1156.         jnz     .loop2
  1157.         test    byte [cpu_caps+(CAPS_MMX/8)], 1 shl (CAPS_MMX mod 8)
  1158.         jz      @f
  1159.         mov     [overlapping_of_points_ptr], overlapping_of_points_mmx
  1160. @@:
  1161.         ret
  1162.  
  1163. align 16
  1164. overlapping_of_points_mmx:
  1165.         movd    mm0, eax
  1166.         movd    mm4, eax
  1167.         movd    mm1, ebx
  1168.         pxor    mm2, mm2
  1169.         punpcklbw mm0, mm2
  1170.         punpcklbw mm1, mm2
  1171.         psubw   mm1, mm0
  1172.         movd    mm3, ecx
  1173.         psrld   mm3, 24
  1174.         packuswb mm3, mm3
  1175.         packuswb mm3, mm3
  1176.         pmullw  mm1, mm3
  1177.         psrlw   mm1, 8
  1178.         packuswb mm1, mm2
  1179.         paddb   mm4, mm1
  1180.         movd    eax, mm4
  1181.         ret
  1182.