Subversion Repositories Kolibri OS

Rev

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