Subversion Repositories Kolibri OS

Rev

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

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