Subversion Repositories Kolibri OS

Rev

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