Subversion Repositories Kolibri OS

Rev

Rev 2430 | Rev 2436 | 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: 2435 $
  21.  
  22.  
  23. ; If you're planning to write your own video driver I suggest
  24. ; you replace the VESA12.INC file and see those instructions.
  25.  
  26. ;Screen_Max_X             equ     0xfe00
  27. ;Screen_Max_Y            equ     0xfe04
  28. ;BytesPerScanLine        equ     0xfe08
  29. ;LFBAddress              equ     0xfe80
  30. ;ScreenBPP               equ     0xfbf1
  31.  
  32.  
  33.  
  34. ;-----------------------------------------------------------------------------
  35. ; getpixel
  36. ;
  37. ; in:
  38. ; eax = x coordinate
  39. ; ebx = y coordinate
  40. ;
  41. ; ret:
  42. ; ecx = 00 RR GG BB
  43. ;-----------------------------------------------------------------------------
  44. align 4
  45. getpixel:
  46.         push    eax ebx edx edi
  47.         call    dword [GETPIXEL]
  48.         pop     edi edx ebx eax
  49.         ret
  50. ;-----------------------------------------------------------------------------
  51. align 4
  52. Vesa20_getpixel24:
  53. ; eax = x
  54. ; ebx = y
  55. ;--------------------------------------
  56. ; check mouse area for putpixel
  57.         test    ecx, 0x04000000  ; don't load to mouseunder area
  58.         jnz     .no_mouseunder
  59.         call    [_display.check_m_pixel]
  60.         test    ecx, ecx        ;0xff000000
  61.         jnz     @f
  62. .no_mouseunder:
  63. ;--------------------------------------
  64.         imul    ebx, [BytesPerScanLine] ; ebx = y * y multiplier
  65.         lea     edi, [eax+eax*2]; edi = x*3
  66.         add     edi, ebx      ; edi = x*3+(y*y multiplier)
  67.         mov     ecx, [LFB_BASE+edi]
  68. ;--------------------------------------
  69. align 4
  70. @@:
  71.         and     ecx, 0xffffff
  72.         ret
  73. ;-----------------------------------------------------------------------------
  74. align 4
  75. Vesa20_getpixel32:
  76. ;--------------------------------------
  77. ; check mouse area for putpixel
  78.         test    ecx, 0x04000000  ; don't load to mouseunder area
  79.         jnz     .no_mouseunder
  80.         call    [_display.check_m_pixel]
  81.         test    ecx, ecx        ;0xff000000
  82.         jnz     @f
  83. .no_mouseunder:
  84. ;--------------------------------------
  85.         imul    ebx, [BytesPerScanLine] ; ebx = y * y multiplier
  86.         lea     edi, [ebx+eax*4]; edi = x*4+(y*y multiplier)
  87.         mov     ecx, [LFB_BASE+edi]
  88. ;--------------------------------------
  89. align 4
  90. @@:
  91.         and     ecx, 0xffffff
  92.         ret
  93. ;-----------------------------------------------------------------------------
  94. virtual at esp
  95.  putimg:
  96.    .real_sx        dd ?
  97.    .real_sy        dd ?
  98.    .image_sx       dd ?
  99.    .image_sy       dd ?
  100.    .image_cx       dd ?
  101.    .image_cy       dd ?
  102.    .pti            dd ?
  103.    .abs_cx         dd ?
  104.    .abs_cy         dd ?
  105.    .line_increment dd ?
  106.    .winmap_newline dd ?
  107.    .screen_newline dd ?
  108.    .real_sx_and_abs_cx dd ?
  109.    .real_sy_and_abs_cy dd ?
  110.    .stack_data = 4*14
  111.    .edi         dd      ?
  112.    .esi         dd      ?
  113.    .ebp         dd      ?
  114.    .esp         dd      ?
  115.    .ebx         dd      ?
  116.    .edx         dd      ?
  117.    .ecx         dd      ?
  118.    .eax         dd      ?
  119.    .ret_addr    dd      ?
  120.    .arg_0       dd      ?
  121. end virtual
  122. ;-----------------------------------------------------------------------------
  123. align 16
  124. ; ebx = pointer
  125. ; ecx = size [x|y]
  126. ; edx = coordinates [x|y]
  127. ; ebp = pointer to 'get' function
  128. ; esi = pointer to 'init' function
  129. ; edi = parameter for 'get' function
  130. vesa20_putimage:
  131.         pushad
  132.         sub     esp, putimg.stack_data
  133. ; save pointer to image
  134.         mov     [putimg.pti], ebx
  135. ; unpack the size
  136.         mov     eax, ecx
  137.         and     ecx, 0xFFFF
  138.         shr     eax, 16
  139.         mov     [putimg.image_sx], eax
  140.         mov     [putimg.image_sy], ecx
  141. ; unpack the coordinates
  142.         mov     eax, edx
  143.         and     edx, 0xFFFF
  144.         shr     eax, 16
  145.         mov     [putimg.image_cx], eax
  146.         mov     [putimg.image_cy], edx
  147. ; calculate absolute (i.e. screen) coordinates
  148.         mov     eax, [TASK_BASE]
  149.         mov     ebx, [eax-twdw + WDATA.box.left]
  150.         add     ebx, [putimg.image_cx]
  151.         mov     [putimg.abs_cx], ebx
  152.         mov     ebx, [eax-twdw + WDATA.box.top]
  153.         add     ebx, [putimg.image_cy]
  154.         mov     [putimg.abs_cy], ebx
  155. ; real_sx = MIN(wnd_sx-image_cx, image_sx);
  156.         mov     ebx, [eax-twdw + WDATA.box.width]; ebx = wnd_sx
  157. ; \begin{diamond}[20.08.2006]
  158. ; note that WDATA.box.width is one pixel less than real window x-size
  159.         inc     ebx
  160. ; \end{diamond}[20.08.2006]
  161.         sub     ebx, [putimg.image_cx]
  162.         ja      @f
  163.         add     esp, putimg.stack_data
  164.         popad
  165.         ret
  166. ;--------------------------------------
  167. align 4
  168. @@:
  169.         cmp     ebx, [putimg.image_sx]
  170.         jbe     .end_x
  171.         mov     ebx, [putimg.image_sx]
  172. ;--------------------------------------
  173. align 4
  174. .end_x:
  175.         mov     [putimg.real_sx], ebx
  176. ; init real_sy
  177.         mov     ebx, [eax-twdw + WDATA.box.height]; ebx = wnd_sy
  178. ; \begin{diamond}[20.08.2006]
  179.         inc     ebx
  180. ; \end{diamond}[20.08.2006]
  181.         sub     ebx, [putimg.image_cy]
  182.         ja      @f
  183.         add     esp, putimg.stack_data
  184.         popad
  185.         ret
  186. ;--------------------------------------
  187. align 4
  188. @@:
  189.         cmp     ebx, [putimg.image_sy]
  190.         jbe     .end_y
  191.         mov     ebx, [putimg.image_sy]
  192. ;--------------------------------------
  193. align 4
  194. .end_y:
  195.         mov     [putimg.real_sy], ebx
  196. ; line increment
  197.         mov     eax, [putimg.image_sx]
  198.         mov     ecx, [putimg.real_sx]
  199.         sub     eax, ecx
  200. ;;     imul    eax, [putimg.source_bpp]
  201. ;     lea     eax, [eax + eax * 2]
  202.         call    esi
  203.         add     eax, [putimg.arg_0]
  204.         mov     [putimg.line_increment], eax
  205. ; winmap new line increment
  206.         mov     eax, [Screen_Max_X]
  207.         inc     eax
  208.         sub     eax, [putimg.real_sx]
  209.         mov     [putimg.winmap_newline], eax
  210. ; screen new line increment
  211.         mov     eax, [BytesPerScanLine]
  212.         movzx   ebx, byte [ScreenBPP]
  213.         shr     ebx, 3
  214.         imul    ecx, ebx
  215.         sub     eax, ecx
  216.         mov     [putimg.screen_newline], eax
  217. ; pointer to image
  218.         mov     esi, [putimg.pti]
  219. ; pointer to screen
  220.         mov     edx, [putimg.abs_cy]
  221.         imul    edx, [BytesPerScanLine]
  222.         mov     eax, [putimg.abs_cx]
  223.         movzx   ebx, byte [ScreenBPP]
  224.         shr     ebx, 3
  225.         imul    eax, ebx
  226.         add     edx, eax
  227. ; pointer to pixel map
  228.         mov     eax, [putimg.abs_cy]
  229.         imul    eax, [Screen_Max_X]
  230.         add     eax, [putimg.abs_cy]
  231.         add     eax, [putimg.abs_cx]
  232.         add     eax, [_WinMapAddress]
  233.         xchg    eax, ebp
  234. ;--------------------------------------
  235.         mov     ecx, [putimg.real_sx]
  236.         add     ecx, [putimg.abs_cx]
  237.         mov     [putimg.real_sx_and_abs_cx], ecx
  238.         mov     ecx, [putimg.real_sy]
  239.         add     ecx, [putimg.abs_cy]
  240.         mov     [putimg.real_sy_and_abs_cy], ecx
  241. ;--------------------------------------
  242. ; get process number
  243.         mov     ebx, [CURRENT_TASK]
  244.         cmp     byte [ScreenBPP], 32
  245.         je      put_image_end_32
  246. ;--------------------------------------
  247. put_image_end_24:
  248.         mov     edi, [putimg.real_sy]
  249.         cmp     [_display.select_cursor], 0
  250.         jne     put_image_end_24_new
  251. ;--------------------------------------
  252. align 4
  253. .new_line:
  254.         mov     ecx, [putimg.real_sx]
  255. ;--------------------------------------
  256. align 4
  257. .new_x:
  258.         push    [putimg.edi]
  259.         mov     eax, [putimg.ebp+4]
  260.         call    eax
  261.         cmp     [ebp], bl
  262.         jne     .skip
  263. ;--------------------------------------
  264.         push    ecx
  265.  
  266.         neg     ecx
  267.         add     ecx, [putimg.real_sx_and_abs_cx + 4]
  268.         shl     ecx, 16
  269.         add     ecx, [putimg.real_sy_and_abs_cy + 4]
  270.         sub     ecx, edi
  271.  
  272. ; check mouse area for putpixel
  273.         call    check_mouse_area_for_putpixel
  274.         pop     ecx
  275. ; store to real LFB
  276.         mov     [LFB_BASE+edx], ax
  277.         shr     eax, 16
  278.         mov     [LFB_BASE+edx+2], al
  279. ;--------------------------------------
  280. align 4
  281. .skip:
  282.         add     edx, 3
  283.         inc     ebp
  284.         dec     ecx
  285.         jnz     .new_x
  286.  
  287.         add     esi, [putimg.line_increment]
  288.         add     edx, [putimg.screen_newline];[BytesPerScanLine]
  289.         add     ebp, [putimg.winmap_newline];[Screen_Max_X]
  290.  
  291.         cmp     [putimg.ebp], putimage_get1bpp
  292.         jz      .correct
  293.         cmp     [putimg.ebp], putimage_get2bpp
  294.         jz      .correct
  295.         cmp     [putimg.ebp], putimage_get4bpp
  296.         jnz     @f
  297. ;--------------------------------------
  298. align 4
  299. .correct:
  300.         mov     eax, [putimg.edi]
  301.         mov     byte [eax], 80h
  302. ;--------------------------------------
  303. align 4
  304. @@:
  305.         dec     edi
  306.         jnz     .new_line
  307. ;--------------------------------------
  308. align 4
  309. .finish:
  310.         add     esp, putimg.stack_data
  311.         popad
  312.         ret
  313. ;--------------------------------------
  314. align 4
  315. put_image_end_24_new:
  316. ;--------------------------------------
  317. align 4
  318. .new_line:
  319.         mov     ecx, [putimg.real_sx]
  320. ;--------------------------------------
  321. align 4
  322. .new_x:
  323.         push    [putimg.edi]
  324.         mov     eax, [putimg.ebp+4]
  325.         call    eax
  326.         cmp     [ebp], bl
  327.         jne     .skip
  328. ;--------------------------------------
  329.         push    ecx
  330.         mov     ecx, [putimg.real_sy_and_abs_cy + 4]
  331.         sub     ecx, edi
  332. ;--------------------------------------
  333. ; check for Y
  334.         cmp     cx, [Y_UNDER_subtraction_CUR_hot_y]
  335.         jb      .no_mouse_area
  336.  
  337.         cmp     cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
  338.         jae     .no_mouse_area
  339.  
  340.         rol     ecx, 16
  341.         add     ecx, [putimg.real_sx_and_abs_cx + 4]
  342.         sub     ecx, [esp]
  343. ;--------------------------------------
  344. ; check for X
  345.         cmp     cx, [X_UNDER_subtraction_CUR_hot_x]
  346.         jb      .no_mouse_area
  347.  
  348.         cmp     cx, [X_UNDER_sub_CUR_hot_x_add_curh]
  349.         jae     .no_mouse_area
  350. ;--------------------------------------
  351. ; check mouse area for putpixel
  352.         call    check_mouse_area_for_putpixel_new.1
  353. ;--------------------------------------
  354. align 4
  355. .no_mouse_area:
  356.         pop     ecx
  357. ; store to real LFB
  358.         mov     [LFB_BASE+edx], ax
  359.         shr     eax, 16
  360.         mov     [LFB_BASE+edx+2], al
  361. ;--------------------------------------
  362. align 4
  363. .skip:
  364.         add     edx, 3
  365.         inc     ebp
  366.         dec     ecx
  367.         jnz     .new_x
  368.  
  369.         add     esi, [putimg.line_increment]
  370.         add     edx, [putimg.screen_newline];[BytesPerScanLine]
  371.         add     ebp, [putimg.winmap_newline];[Screen_Max_X]
  372.  
  373.         cmp     [putimg.ebp], putimage_get1bpp
  374.         jz      .correct
  375.         cmp     [putimg.ebp], putimage_get2bpp
  376.         jz      .correct
  377.         cmp     [putimg.ebp], putimage_get4bpp
  378.         jnz     @f
  379. ;--------------------------------------
  380. align 4
  381. .correct:
  382.         mov     eax, [putimg.edi]
  383.         mov     byte [eax], 80h
  384. ;--------------------------------------
  385. align 4
  386. @@:
  387.         dec     edi
  388.         jnz     .new_line
  389.         jmp     put_image_end_24.finish
  390. ;------------------------------------------------------------------------------
  391. align 4
  392. put_image_end_32:
  393.         mov     edi, [putimg.real_sy]
  394.         cmp     [_display.select_cursor], 0
  395.         jne     put_image_end_32_new
  396. ;--------------------------------------
  397. align 4
  398. .new_line:
  399.         mov     ecx, [putimg.real_sx]
  400. ;--------------------------------------
  401. align 4
  402. .new_x:
  403.         push    [putimg.edi]
  404.         mov     eax, [putimg.ebp+4]
  405.         call    eax
  406.         cmp     [ebp], bl
  407.         jne     .skip
  408. ;--------------------------------------
  409.         push    ecx
  410.  
  411.         neg     ecx
  412.         add     ecx, [putimg.real_sx_and_abs_cx + 4]
  413.         shl     ecx, 16
  414.         add     ecx, [putimg.real_sy_and_abs_cy + 4]
  415.         sub     ecx, edi
  416.  
  417. ; check mouse area for putpixel
  418.         call    check_mouse_area_for_putpixel
  419.         pop     ecx
  420. ; store to real LFB
  421.         mov     [LFB_BASE+edx], eax
  422. ;--------------------------------------
  423. align 4
  424. .skip:
  425.         add     edx, 4
  426.         inc     ebp
  427.         dec     ecx
  428.         jnz     .new_x
  429.  
  430.         add     esi, [putimg.line_increment]
  431.         add     edx, [putimg.screen_newline];[BytesPerScanLine]
  432.         add     ebp, [putimg.winmap_newline];[Screen_Max_X]
  433.  
  434.         cmp     [putimg.ebp], putimage_get1bpp
  435.         jz      .correct
  436.         cmp     [putimg.ebp], putimage_get2bpp
  437.         jz      .correct
  438.         cmp     [putimg.ebp], putimage_get4bpp
  439.         jnz     @f
  440. ;--------------------------------------
  441. align 4
  442. .correct:
  443.         mov     eax, [putimg.edi]
  444.         mov     byte [eax], 80h
  445. ;--------------------------------------
  446. align 4
  447. @@:
  448.         dec     edi
  449.         jnz     .new_line
  450. ;--------------------------------------
  451. align 4
  452. .finish:
  453.         add     esp, putimg.stack_data
  454.         popad
  455.         call    VGA__putimage
  456.         mov     [EGA_counter], 1
  457.         ret
  458. ;--------------------------------------
  459. align 4
  460. put_image_end_32_new:
  461. ;--------------------------------------
  462. align 4
  463. .new_line:
  464.         mov     ecx, [putimg.real_sx]
  465. ;--------------------------------------
  466. align 4
  467. .new_x:
  468.         push    [putimg.edi]
  469.         mov     eax, [putimg.ebp+4]
  470.         call    eax
  471.         cmp     [ebp], bl
  472.         jne     .skip
  473. ;--------------------------------------
  474.         push    ecx
  475.         mov     ecx, [putimg.real_sy_and_abs_cy + 4]
  476.         sub     ecx, edi
  477. ;--------------------------------------
  478. ; check for Y
  479.         cmp     cx, [Y_UNDER_subtraction_CUR_hot_y]
  480.         jb      .no_mouse_area
  481.  
  482.         cmp     cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
  483.         jae     .no_mouse_area
  484.  
  485.         rol     ecx, 16
  486.         add     ecx, [putimg.real_sx_and_abs_cx + 4]
  487.         sub     ecx, [esp]
  488. ;--------------------------------------
  489. ; check for X
  490.         cmp     cx, [X_UNDER_subtraction_CUR_hot_x]
  491.         jb      .no_mouse_area
  492.  
  493.         cmp     cx, [X_UNDER_sub_CUR_hot_x_add_curh]
  494.         jae     .no_mouse_area
  495. ;--------------------------------------
  496. ; check mouse area for putpixel
  497.         call    check_mouse_area_for_putpixel_new.1
  498. ;--------------------------------------
  499. align 4
  500. .no_mouse_area:
  501.         pop     ecx
  502. ; store to real LFB
  503.         mov     [LFB_BASE+edx], eax
  504. ;--------------------------------------
  505. align 4
  506. .skip:
  507.         add     edx, 4
  508.         inc     ebp
  509.         dec     ecx
  510.         jnz     .new_x
  511.  
  512.         add     esi, [putimg.line_increment]
  513.         add     edx, [putimg.screen_newline];[BytesPerScanLine]
  514.         add     ebp, [putimg.winmap_newline];[Screen_Max_X]
  515.  
  516.         cmp     [putimg.ebp], putimage_get1bpp
  517.         jz      .correct
  518.         cmp     [putimg.ebp], putimage_get2bpp
  519.         jz      .correct
  520.         cmp     [putimg.ebp], putimage_get4bpp
  521.         jnz     @f
  522. ;--------------------------------------
  523. align 4
  524. .correct:
  525.         mov     eax, [putimg.edi]
  526.         mov     byte [eax], 80h
  527. ;--------------------------------------
  528. align 4
  529. @@:
  530.         dec     edi
  531.         jnz     .new_line
  532.         jmp     put_image_end_32.finish
  533. ;------------------------------------------------------------------------------
  534. align 4
  535. __sys_putpixel:
  536.  
  537. ; eax = x coordinate
  538. ; ebx = y coordinate
  539. ; ecx = ?? RR GG BB    ; 0x01000000 negation
  540.                        ; 0x02000000 used for draw_rectangle without top line
  541.                        ;            for example drawwindow_III and drawwindow_IV
  542. ; edi = 0x00000001 force
  543.  
  544. ;;;        mov  [novesachecksum], dword 0
  545.         pushad
  546.         cmp     [Screen_Max_X], eax
  547.         jb      .exit
  548.         cmp     [Screen_Max_Y], ebx
  549.         jb      .exit
  550.         test    edi, 1           ; force ?
  551.         jnz     .forced
  552.  
  553. ; not forced:
  554.  
  555.         push    eax
  556.         mov     edx, [_display.width]; screen x size
  557.         imul    edx, ebx
  558.         add     eax, [_WinMapAddress]
  559.         movzx   edx, byte [eax+edx]
  560.         cmp     edx, [CURRENT_TASK]
  561.         pop     eax
  562.         jne     .exit
  563. ;--------------------------------------
  564. align 4
  565. .forced:
  566. ; check if negation
  567.         test    ecx, 0x01000000
  568.         jz      .noneg
  569.  
  570.         call    getpixel
  571.         not     ecx
  572.  
  573.         rol     ecx, 8
  574.         mov     cl, [esp+32-8+3]
  575.         ror     ecx, 8
  576.         mov     [esp+32-8], ecx
  577. ;--------------------------------------
  578. align 4
  579. .noneg:
  580. ; OK to set pixel
  581.         call    dword [PUTPIXEL]; call the real put_pixel function
  582. ;--------------------------------------
  583. align 4
  584. .exit:
  585.         popad
  586.         ret
  587. ;-----------------------------------------------------------------------------
  588. align 4
  589. Vesa20_putpixel24:
  590. ; eax = x
  591. ; ebx = y
  592.         mov     ecx, eax
  593.         shl     ecx, 16
  594.         mov     cx, bx
  595.  
  596.         imul    ebx, [BytesPerScanLine]  ; ebx = y * y multiplier
  597.         lea     edi, [eax+eax*2]; edi = x*3
  598.         mov     eax, [esp+32-8+4]
  599. ;--------------------------------------
  600. ; check mouse area for putpixel
  601.         test    eax, 0x04000000
  602.         jnz     @f
  603.         call    [_display.check_mouse]
  604. ;--------------------------------------
  605. align 4
  606. @@:
  607. ; store to real LFB
  608.         mov     [LFB_BASE+ebx+edi], ax
  609.         shr     eax, 16
  610.         mov     [LFB_BASE+ebx+edi+2], al
  611. ;--------------------------------------
  612.         ret
  613. ;-----------------------------------------------------------------------------
  614. align 4
  615. Vesa20_putpixel32:
  616. ; eax = x
  617. ; ebx = y
  618.         mov     ecx, eax
  619.         shl     ecx, 16
  620.         mov     cx, bx
  621.  
  622.         imul    ebx, [BytesPerScanLine]  ; ebx = y * y multiplier
  623.         lea     edi, [ebx+eax*4]; edi = x*4+(y*y multiplier)
  624.         mov     eax, [esp+32-8+4]; eax = color
  625. ;--------------------------------------
  626. ; check mouse area for putpixel
  627.         test    eax, 0x04000000
  628.         jnz     @f
  629.         call    [_display.check_mouse]
  630. ;--------------------------------------
  631. align 4
  632. @@:
  633.         and     eax, 0xffffff
  634. ; store to real LFB
  635.         mov     [LFB_BASE+edi], eax
  636. ;--------------------------------------
  637.         ret
  638. ;-----------------------------------------------------------------------------
  639. align 4
  640. calculate_edi:
  641.         mov     edi, ebx
  642.         imul    edi, [Screen_Max_X]
  643.         add     edi, ebx
  644.         add     edi, eax
  645.         ret
  646. ;-----------------------------------------------------------------------------
  647. ; DRAWLINE
  648. ;-----------------------------------------------------------------------------
  649. align 4
  650. __sys_draw_line:
  651. ; draw a line
  652. ; eax = HIWORD = x1
  653. ;       LOWORD = x2
  654. ; ebx = HIWORD = y1
  655. ;       LOWORD = y2
  656. ; ecx = color
  657. ; edi = force ?
  658.         pusha
  659.  
  660. dl_x1 equ esp+20
  661. dl_y1 equ esp+16
  662. dl_x2 equ esp+12
  663. dl_y2 equ esp+8
  664. dl_dx equ esp+4
  665. dl_dy equ esp+0
  666.  
  667.         xor     edx, edx   ; clear edx
  668.         xor     esi, esi   ; unpack arguments
  669.         xor     ebp, ebp
  670.         mov     si, ax     ; esi = x2
  671.         mov     bp, bx     ; ebp = y2
  672.         shr     eax, 16    ; eax = x1
  673.         shr     ebx, 16    ; ebx = y1
  674.         push    eax        ; save x1
  675.         push    ebx        ; save y1
  676.         push    esi        ; save x2
  677.         push    ebp        ; save y2
  678. ; checking x-axis...
  679.         sub     esi, eax   ; esi = x2-x1
  680.         push    esi        ; save y2-y1
  681.         jl      .x2lx1     ; is x2 less than x1 ?
  682.         jg      .no_vline  ; x1 > x2 ?
  683.         mov     edx, ebp   ; else (if x1=x2)
  684.         call    vline
  685.         push    edx ; necessary to rightly restore stack frame at .exit
  686.         jmp     .exit
  687. ;--------------------------------------
  688. align 4
  689. .x2lx1:
  690.         neg     esi         ; get esi absolute value
  691. ;--------------------------------------
  692. align 4
  693. .no_vline:
  694. ; checking y-axis...
  695.         sub     ebp, ebx    ; ebp = y2-y1
  696.         push    ebp         ; save y2-y1
  697.         jl      .y2ly1      ; is y2 less than y1 ?
  698.         jg      .no_hline   ; y1 > y2 ?
  699.         mov     edx, [dl_x2]; else (if y1=y2)
  700.         call    hline
  701.         jmp     .exit
  702. ;--------------------------------------
  703. align 4
  704. .y2ly1:
  705.         neg     ebp         ; get ebp absolute value
  706. ;--------------------------------------
  707. align 4
  708. .no_hline:
  709.         cmp     ebp, esi
  710.         jle     .x_rules    ; |y2-y1| < |x2-x1|  ?
  711.         cmp     [dl_y2], ebx; make sure y1 is at the begining
  712.         jge     .no_reverse1
  713.         neg     dword [dl_dx]
  714.         mov     edx, [dl_x2]
  715.         mov     [dl_x2], eax
  716.         mov     [dl_x1], edx
  717.         mov     edx, [dl_y2]
  718.         mov     [dl_y2], ebx
  719.         mov     [dl_y1], edx
  720. ;--------------------------------------
  721. align 4
  722. .no_reverse1:
  723.         mov     eax, [dl_dx]
  724.         cdq                 ; extend eax sing to edx
  725.         shl     eax, 16     ; using 16bit fix-point maths
  726.         idiv    ebp         ; eax = ((x2-x1)*65536)/(y2-y1)
  727. ;--------------------------------------
  728. ; correction for the remainder of the division
  729.         shl     edx, 1
  730.         cmp     ebp, edx
  731.         jb      @f
  732.         inc     eax
  733. ;--------------------------------------
  734. align 4
  735. @@:
  736. ;--------------------------------------
  737.         mov     edx, ebp    ; edx = counter (number of pixels to draw)
  738.         mov     ebp, 1 *65536; <<16   ; ebp = dy = 1.0
  739.         mov     esi, eax    ; esi = dx
  740.         jmp     .y_rules
  741. ;--------------------------------------
  742. align 4
  743. .x_rules:
  744.         cmp     [dl_x2], eax ; make sure x1 is at the begining
  745.         jge     .no_reverse2
  746.         neg     dword [dl_dy]
  747.         mov     edx, [dl_x2]
  748.         mov     [dl_x2], eax
  749.         mov     [dl_x1], edx
  750.         mov     edx, [dl_y2]
  751.         mov     [dl_y2], ebx
  752.         mov     [dl_y1], edx
  753. ;--------------------------------------
  754. align 4
  755. .no_reverse2:
  756.         xor     edx, edx
  757.         mov     eax, [dl_dy]
  758.         cdq                 ; extend eax sing to edx
  759.         shl     eax, 16     ; using 16bit fix-point maths
  760.         idiv    esi         ; eax = ((y2-y1)*65536)/(x2-x1)
  761. ;--------------------------------------
  762. ; correction for the remainder of the division
  763.         shl     edx, 1
  764.         cmp     esi, edx
  765.         jb      @f
  766.         inc     eax
  767. ;--------------------------------------
  768. align 4
  769. @@:
  770. ;--------------------------------------
  771.         mov     edx, esi    ; edx = counter (number of pixels to draw)
  772.         mov     esi, 1 *65536;<< 16   ; esi = dx = 1.0
  773.         mov     ebp, eax    ; ebp = dy
  774. ;--------------------------------------
  775. align 4
  776. .y_rules:
  777.         mov     eax, [dl_x1]
  778.         mov     ebx, [dl_y1]
  779.         shl     eax, 16
  780.         shl     ebx, 16
  781. ;-----------------------------------------------------------------------------
  782. align 4
  783. .draw:
  784.         push    eax ebx
  785. ;--------------------------------------
  786. ; correction for the remainder of the division
  787.         test    ah, 0x80
  788.         jz      @f
  789.         add     eax, 1 shl 16
  790. ;--------------------------------------
  791. align 4
  792. @@:
  793. ;--------------------------------------
  794.         shr     eax, 16
  795. ;--------------------------------------
  796. ; correction for the remainder of the division
  797.         test    bh, 0x80
  798.         jz      @f
  799.         add     ebx, 1 shl 16
  800. ;--------------------------------------
  801. align 4
  802. @@:
  803. ;--------------------------------------
  804.         shr     ebx, 16
  805.         and     ecx, 0xFBFFFFFF  ;negate 0x04000000 save to mouseunder area
  806.         call    [putpixel]
  807.         pop     ebx eax
  808.         add     ebx, ebp     ; y = y+dy
  809.         add     eax, esi     ; x = x+dx
  810.         dec     edx
  811.         jnz     .draw
  812. ; force last drawn pixel to be at (x2,y2)
  813.         mov     eax, [dl_x2]
  814.         mov     ebx, [dl_y2]
  815.         and     ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area
  816.         call    [putpixel]
  817. ;--------------------------------------
  818. align 4
  819. .exit:
  820.         add     esp, 6*4
  821.         popa
  822. ;        call    [draw_pointer]
  823.         ret
  824. ;------------------------------------------------------------------------------
  825. align 4
  826. hline:
  827. ; draw an horizontal line
  828. ; eax = x1
  829. ; edx = x2
  830. ; ebx = y
  831. ; ecx = color
  832. ; edi = force ?
  833.         push    eax edx
  834.         cmp     edx, eax   ; make sure x2 is above x1
  835.         jge     @f
  836.         xchg    eax, edx
  837. ;--------------------------------------
  838. align 4
  839. @@:
  840.         and     ecx, 0xFBFFFFFF  ;negate 0x04000000 save to mouseunder area
  841.         call    [putpixel]
  842.         inc     eax
  843.         cmp     eax, edx
  844.         jle     @b
  845.         pop     edx eax
  846.         ret
  847. ;------------------------------------------------------------------------------
  848. align 4
  849. vline:
  850. ; draw a vertical line
  851. ; eax = x
  852. ; ebx = y1
  853. ; edx = y2
  854. ; ecx = color
  855. ; edi = force ?
  856.         push    ebx edx
  857.         cmp     edx, ebx   ; make sure y2 is above y1
  858.         jge     @f
  859.         xchg    ebx, edx
  860. ;--------------------------------------
  861. align 4
  862. @@:
  863.         and     ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area
  864.         call    [putpixel]
  865.         inc     ebx
  866.         cmp     ebx, edx
  867.         jle     @b
  868.         pop     edx ebx
  869.         ret
  870. ;------------------------------------------------------------------------------
  871. align 4
  872. virtual at esp
  873. drbar:
  874.      .bar_sx       dd ?
  875.      .bar_sy       dd ?
  876.      .bar_cx       dd ?
  877.      .bar_cy       dd ?
  878.      .abs_cx       dd ?
  879.      .abs_cy       dd ?
  880.      .real_sx      dd ?
  881.      .real_sy      dd ?
  882.      .color        dd ?
  883.      .line_inc_scr dd ?
  884.      .line_inc_map dd ?
  885.      .real_sx_and_abs_cx dd ?
  886.      .real_sy_and_abs_cy dd ?
  887.      .stack_data = 4*13
  888. end virtual
  889. ;--------------------------------------
  890. align 4
  891. ; eax   cx
  892. ; ebx   cy
  893. ; ecx   xe
  894. ; edx   ye
  895. ; edi   color
  896. vesa20_drawbar:
  897.         pushad
  898.         sub     esp, drbar.stack_data
  899.         mov     [drbar.color], edi
  900.         sub     edx, ebx
  901.         jle     .exit       ;// mike.dld, 2005-01-29
  902.         sub     ecx, eax
  903.         jle     .exit       ;// mike.dld, 2005-01-29
  904.         mov     [drbar.bar_sy], edx
  905.         mov     [drbar.bar_sx], ecx
  906.         mov     [drbar.bar_cx], eax
  907.         mov     [drbar.bar_cy], ebx
  908.         mov     edi, [TASK_BASE]
  909.         add     eax, [edi-twdw + WDATA.box.left]; win_cx
  910.         add     ebx, [edi-twdw + WDATA.box.top]; win_cy
  911.         mov     [drbar.abs_cx], eax
  912.         mov     [drbar.abs_cy], ebx
  913. ; real_sx = MIN(wnd_sx-bar_cx, bar_sx);
  914.         mov     ebx, [edi-twdw + WDATA.box.width]; ebx = wnd_sx
  915. ; \begin{diamond}[20.08.2006]
  916. ; note that WDATA.box.width is one pixel less than real window x-size
  917.         inc     ebx
  918. ; \end{diamond}[20.08.2006]
  919.         sub     ebx, [drbar.bar_cx]
  920.         ja      @f
  921. ;--------------------------------------
  922. align 4
  923. .exit:                       ;// mike.dld, 2005-01-29
  924.         add     esp, drbar.stack_data
  925.         popad
  926.         xor     eax, eax
  927.         inc     eax
  928.         ret
  929. ;--------------------------------------
  930. align 4
  931. @@:
  932.         cmp     ebx, [drbar.bar_sx]
  933.         jbe     .end_x
  934.         mov     ebx, [drbar.bar_sx]
  935. ;--------------------------------------
  936. align 4
  937. .end_x:
  938.         mov     [drbar.real_sx], ebx
  939. ; real_sy = MIN(wnd_sy-bar_cy, bar_sy);
  940.         mov     ebx, [edi-twdw + WDATA.box.height]; ebx = wnd_sy
  941. ; \begin{diamond}[20.08.2006]
  942.         inc     ebx
  943. ; \end{diamond}
  944.         sub     ebx, [drbar.bar_cy]
  945.         ja      @f
  946.         add     esp, drbar.stack_data
  947.         popad
  948.         xor     eax, eax
  949.         inc     eax
  950.         ret
  951. ;--------------------------------------
  952. align 4
  953. @@:
  954.         cmp     ebx, [drbar.bar_sy]
  955.         jbe     .end_y
  956.         mov     ebx, [drbar.bar_sy]
  957. ;--------------------------------------
  958. align 4
  959. .end_y:
  960.         mov     [drbar.real_sy], ebx
  961. ; line_inc_map
  962.         mov     eax, [Screen_Max_X]
  963.         sub     eax, [drbar.real_sx]
  964.         inc     eax
  965.         mov     [drbar.line_inc_map], eax
  966. ; line_inc_scr
  967.         mov     eax, [drbar.real_sx]
  968.         movzx   ebx, byte [ScreenBPP]
  969.         shr     ebx, 3
  970.         imul    eax, ebx
  971.         neg     eax
  972.         add     eax, [BytesPerScanLine]
  973.         mov     [drbar.line_inc_scr], eax
  974. ; pointer to screen
  975.         mov     edx, [drbar.abs_cy]
  976.         imul    edx, [BytesPerScanLine]
  977.         mov     eax, [drbar.abs_cx]
  978. ;     movzx   ebx, byte [ScreenBPP]
  979. ;     shr     ebx, 3
  980.         imul    eax, ebx
  981.         add     edx, eax
  982. ; pointer to pixel map
  983.         mov     eax, [drbar.abs_cy]
  984.         imul    eax, [Screen_Max_X]
  985.         add     eax, [drbar.abs_cy]
  986.         add     eax, [drbar.abs_cx]
  987.         add     eax, [_WinMapAddress]
  988.         xchg    eax, ebp
  989. ;--------------------------------------
  990.         mov     ebx, [drbar.real_sx]
  991.         add     ebx, [drbar.abs_cx]
  992.         mov     [drbar.real_sx_and_abs_cx], ebx
  993.         mov     ebx, [drbar.real_sy]
  994.         add     ebx, [drbar.abs_cy]
  995.         mov     [drbar.real_sy_and_abs_cy], ebx
  996.  
  997.         add     edx, LFB_BASE
  998. ;--------------------------------------
  999. ; get process number
  1000.         mov     ebx, [CURRENT_TASK]
  1001.         cmp     byte [ScreenBPP], 24
  1002.         jne     draw_bar_end_32
  1003. ;--------------------------------------
  1004. align 4
  1005. draw_bar_end_24:
  1006.         mov     eax, [drbar.color] ;; BBGGRR00
  1007.         mov     bh, al             ;; bh  = BB
  1008.         shr     eax, 8             ;; eax = RRGG
  1009. ; eax - color high   RRGG
  1010. ; bl - process num
  1011. ; bh - color low    BB
  1012. ; ecx - temp
  1013. ; edx - pointer to screen
  1014. ; esi - counter
  1015. ; edi - counter
  1016.         mov     esi, [drbar.real_sy]
  1017.         cmp     [_display.select_cursor], 0
  1018.         jne     draw_bar_end_24_new
  1019. ;--------------------------------------
  1020. align 4
  1021. .new_y:
  1022.         mov     edi, [drbar.real_sx]
  1023. ;--------------------------------------
  1024. align 4
  1025. .new_x:
  1026.         cmp     byte [ebp], bl
  1027.         jne     .skip
  1028. ;--------------------------------------
  1029.         push    eax
  1030.  
  1031.         mov     ecx, [drbar.real_sx_and_abs_cx + 4]
  1032.         sub     ecx, edi
  1033.         shl     ecx, 16
  1034.         add     ecx, [drbar.real_sy_and_abs_cy + 4]
  1035.         sub     ecx, esi
  1036.  
  1037.         shl     eax, 8
  1038.         mov     al, bh
  1039. ; check mouse area for putpixel
  1040.         call    check_mouse_area_for_putpixel
  1041. ; store to real LFB
  1042.         mov     [edx], ax
  1043.         shr     eax, 16
  1044.         mov     [edx + 2], al
  1045.         pop     eax
  1046. ;--------------------------------------
  1047. align 4
  1048. .skip:
  1049. ; add pixel
  1050.         add     edx, 3
  1051.         inc     ebp
  1052.         dec     edi
  1053.         jnz     .new_x
  1054. ; add line
  1055.         add     edx, [drbar.line_inc_scr]
  1056.         add     ebp, [drbar.line_inc_map]
  1057. ; <Ivan 15.10.04> drawing gradient bars
  1058.         test    eax, 0x00800000
  1059.         jz      @f
  1060.         test    bh, bh
  1061.         jz      @f
  1062.         dec     bh
  1063. ;--------------------------------------
  1064. align 4
  1065. @@:
  1066. ; </Ivan 15.10.04>
  1067.         dec     esi
  1068.         jnz     .new_y
  1069. ;--------------------------------------
  1070. align 4
  1071. .end:
  1072.         add     esp, drbar.stack_data
  1073.         popad
  1074.         xor     eax, eax
  1075.         ret
  1076. ;--------------------------------------
  1077. align 4
  1078. draw_bar_end_24_new:
  1079. ;--------------------------------------
  1080. align 4
  1081. .new_y:
  1082.         mov     edi, [drbar.real_sx]
  1083. ;--------------------------------------
  1084. align 4
  1085. .new_x:
  1086.         cmp     byte [ebp], bl
  1087.         jne     .skip
  1088. ;--------------------------------------
  1089.         mov     ecx, [drbar.real_sy_and_abs_cy]
  1090.         sub     ecx, esi
  1091. ;--------------------------------------
  1092. ; check for Y
  1093.         cmp     cx, [Y_UNDER_subtraction_CUR_hot_y]
  1094.         jb      .no_mouse_area
  1095.  
  1096.         cmp     cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
  1097.         jae     .no_mouse_area
  1098.  
  1099.         rol     ecx, 16
  1100.         add     ecx, [drbar.real_sx_and_abs_cx]
  1101.         sub     ecx, edi
  1102. ;--------------------------------------
  1103. ; check for X
  1104.         cmp     cx, [X_UNDER_subtraction_CUR_hot_x]
  1105.         jb      .no_mouse_area
  1106.  
  1107.         cmp     cx, [X_UNDER_sub_CUR_hot_x_add_curh]
  1108.         jae     .no_mouse_area
  1109. ;--------------------------------------
  1110. ; check mouse area for putpixel
  1111.         push    eax
  1112.  
  1113.         shl     eax, 8
  1114.         mov     al, bh
  1115.  
  1116.         call    check_mouse_area_for_putpixel_new.1
  1117. ; store to real LFB
  1118.         mov     [edx], ax
  1119.         shr     eax, 16
  1120.         mov     [edx + 2], al
  1121.         pop     eax
  1122.         jmp     .skip
  1123. ; store to real LFB
  1124. ;--------------------------------------
  1125. align 4
  1126. .no_mouse_area:
  1127.         mov     [edx], bh
  1128.         mov     [edx + 1], ax
  1129. ;--------------------------------------
  1130. align 4
  1131. .skip:
  1132. ; add pixel
  1133.         add     edx, 3
  1134.         inc     ebp
  1135.         dec     edi
  1136.         jnz     .new_x
  1137. ; add line
  1138.         add     edx, [drbar.line_inc_scr]
  1139.         add     ebp, [drbar.line_inc_map]
  1140. ; <Ivan 15.10.04> drawing gradient bars
  1141.         test    eax, 0x00800000
  1142.         jz      @f
  1143.         test    bh, bh
  1144.         jz      @f
  1145.         dec     bh
  1146. ;--------------------------------------
  1147. align 4
  1148. @@:
  1149. ; </Ivan 15.10.04>
  1150.         dec     esi
  1151.         jnz     .new_y
  1152.         jmp     draw_bar_end_24.end
  1153. ;--------------------------------------
  1154. align 4
  1155. draw_bar_end_32:
  1156.         mov     eax, [drbar.color] ;; BBGGRR00
  1157.         mov     esi, [drbar.real_sy]
  1158.         cmp     [_display.select_cursor], 0
  1159.         jne     draw_bar_end_32_new
  1160. ;--------------------------------------
  1161. align 4
  1162. .new_y:
  1163.         mov     edi, [drbar.real_sx]
  1164. ;--------------------------------------
  1165. align 4
  1166. .new_x:
  1167.         cmp     byte [ebp], bl
  1168.         jne     .skip
  1169. ;--------------------------------------
  1170.         push    eax
  1171.  
  1172.         mov     ecx, [drbar.real_sx_and_abs_cx + 4]
  1173.         sub     ecx, edi
  1174.         shl     ecx, 16
  1175.         add     ecx, [drbar.real_sy_and_abs_cy + 4]
  1176.         sub     ecx, esi
  1177.  
  1178. ; check mouse area for putpixel
  1179.         call    check_mouse_area_for_putpixel
  1180. ; store to real LFB
  1181.         mov     [edx], eax
  1182.         pop     eax
  1183. ;--------------------------------------
  1184. align 4
  1185. .skip:
  1186. ; add pixel
  1187.         add     edx, 4
  1188.         inc     ebp
  1189.         dec     edi
  1190.         jnz     .new_x
  1191. ; add line
  1192.         add     edx, [drbar.line_inc_scr]
  1193.         add     ebp, [drbar.line_inc_map]
  1194. ; <Ivan 15.10.04> drawing gradient bars
  1195.         test    eax, 0x80000000
  1196.         jz      @f
  1197.         test    al, al
  1198.         jz      @f
  1199.         dec     al
  1200. ;--------------------------------------
  1201. align 4
  1202. @@:
  1203. ; </Ivan 15.10.04>
  1204.         dec     esi
  1205.         jnz     .new_y
  1206. ;--------------------------------------
  1207. align 4
  1208. .end:
  1209.         add     esp, drbar.stack_data
  1210.         popad
  1211.         call    VGA_draw_bar
  1212.         xor     eax, eax
  1213.         mov     [EGA_counter], 1
  1214.         ret
  1215. ;--------------------------------------
  1216. align 4
  1217. draw_bar_end_32_new:
  1218. ;--------------------------------------
  1219. align 4
  1220. .new_y:
  1221.         mov     edi, [drbar.real_sx]
  1222. ;--------------------------------------
  1223. align 4
  1224. .new_x:
  1225.         cmp     byte [ebp], bl
  1226.         jne     .skip
  1227. ;--------------------------------------
  1228.         mov     ecx, [drbar.real_sy_and_abs_cy]
  1229.         sub     ecx, esi
  1230. ;--------------------------------------
  1231. ; check for Y
  1232.         cmp     cx, [Y_UNDER_subtraction_CUR_hot_y]
  1233.         jb      .no_mouse_area
  1234.  
  1235.         cmp     cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
  1236.         jae     .no_mouse_area
  1237.  
  1238.         rol     ecx, 16
  1239.         add     ecx, [drbar.real_sx_and_abs_cx]
  1240.         sub     ecx, edi
  1241. ;--------------------------------------
  1242. ; check for X
  1243.         cmp     cx, [X_UNDER_subtraction_CUR_hot_x]
  1244.         jb      .no_mouse_area
  1245.  
  1246.         cmp     cx, [X_UNDER_sub_CUR_hot_x_add_curh]
  1247.         jae     .no_mouse_area
  1248. ;--------------------------------------
  1249. ; check mouse area for putpixel
  1250.         push    eax
  1251.         call    check_mouse_area_for_putpixel_new.1
  1252.         mov     [edx], eax
  1253.         pop     eax
  1254.         jmp     .skip
  1255. ; store to real LFB
  1256. ;--------------------------------------
  1257. align 4
  1258. .no_mouse_area:
  1259.         mov     [edx], eax
  1260. ;--------------------------------------
  1261. align 4
  1262. .skip:
  1263. ; add pixel
  1264.         add     edx, 4
  1265.         inc     ebp
  1266.         dec     edi
  1267.         jnz     .new_x
  1268. ; add line
  1269.         add     edx, [drbar.line_inc_scr]
  1270.         add     ebp, [drbar.line_inc_map]
  1271. ; <Ivan 15.10.04> drawing gradient bars
  1272.         test    eax, 0x80000000
  1273.         jz      @f
  1274.         test    al, al
  1275.         jz      @f
  1276.         dec     al
  1277. ;--------------------------------------
  1278. align 4
  1279. @@:
  1280. ; </Ivan 15.10.04>
  1281.         dec     esi
  1282.         jnz     .new_y
  1283.         jmp     draw_bar_end_32.end
  1284. ;------------------------------------------------------------------------------
  1285. align 4
  1286. vesa20_drawbackground_tiled:
  1287.         pushad
  1288. ; External loop for all y from start to end
  1289.         mov     ebx, [draw_data+32+RECT.top]    ; y start
  1290. ;--------------------------------------
  1291. align 4
  1292. dp2:
  1293.         mov     ebp, [draw_data+32+RECT.left]   ; x start
  1294. ; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
  1295. ;                       and LFB data (output for our function) [edi]
  1296.         mov     eax, [BytesPerScanLine]
  1297.         mul     ebx
  1298.         xchg    ebp, eax
  1299.         add     ebp, eax
  1300.         add     ebp, eax
  1301.         add     ebp, eax
  1302.         cmp     [ScreenBPP], byte 24    ; 24 or 32 bpp ? - x size
  1303.         jz      @f
  1304.         add     ebp, eax
  1305. ;--------------------------------------
  1306. align 4
  1307. @@:
  1308.         add     ebp, LFB_BASE
  1309. ; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
  1310.         call    calculate_edi
  1311.         xchg    edi, ebp
  1312.         add     ebp, [_WinMapAddress]
  1313. ; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
  1314. ; 2) Calculate offset in background memory block
  1315.         push    eax
  1316.         xor     edx, edx
  1317.         mov     eax, ebx
  1318.         div     dword [BgrDataHeight]   ; edx := y mod BgrDataHeight
  1319.         pop     eax
  1320.         push    eax
  1321.         mov     ecx, [BgrDataWidth]
  1322.         mov     esi, edx
  1323.         imul    esi, ecx                ; esi := (y mod BgrDataHeight) * BgrDataWidth
  1324.         xor     edx, edx
  1325.         div     ecx             ; edx := x mod BgrDataWidth
  1326.         sub     ecx, edx
  1327.         add     esi, edx        ; esi := (y mod BgrDataHeight)*BgrDataWidth + (x mod BgrDataWidth)
  1328.         pop     eax
  1329.         lea     esi, [esi*3]
  1330.         add     esi, [img_background]
  1331.         xor     edx, edx
  1332.         inc     edx
  1333. ; 3) Loop through redraw rectangle and copy background data
  1334. ; Registers meaning:
  1335. ; eax = x, ebx = y (screen coordinates)
  1336. ; ecx = deltax - number of pixels left in current tile block
  1337. ; edx = 1
  1338. ; esi -> bgr memory, edi -> output
  1339. ; ebp = offset in WinMapAddress
  1340. ;--------------------------------------
  1341. align 4
  1342. dp3:
  1343.         cmp     [ebp], dl
  1344.         jnz     nbgp
  1345. ;--------------------------------------
  1346.         push    eax ecx
  1347.  
  1348.         mov     ecx, eax
  1349.         shl     ecx, 16
  1350.         add     ecx, ebx
  1351.  
  1352.         mov     eax, [esi]
  1353.         and     eax, 0xffffff
  1354. ; check mouse area for putpixel
  1355.         call    [_display.check_mouse]
  1356. ; store to real LFB
  1357.         mov     [edi], ax
  1358.         shr     eax, 16
  1359.         mov     [edi+2], al
  1360.  
  1361.         pop     ecx eax
  1362. ;--------------------------------------
  1363. align 4
  1364. nbgp:
  1365.         add     esi, 3
  1366.         add     edi, 3
  1367. ;--------------------------------------
  1368. align 4
  1369. @@:
  1370.         cmp     [ScreenBPP], byte 25    ; 24 or 32 bpp?
  1371.         sbb     edi, -1         ; +1 for 32 bpp
  1372. ; I do not use 'inc eax' because this is slightly slower then 'add eax,1'
  1373.         add     ebp, edx
  1374.         add     eax, edx
  1375.         cmp     eax, [draw_data+32+RECT.right]
  1376.         ja      dp4
  1377.         sub     ecx, edx
  1378.         jnz     dp3
  1379. ; next tile block on x-axis
  1380.         mov     ecx, [BgrDataWidth]
  1381.         sub     esi, ecx
  1382.         sub     esi, ecx
  1383.         sub     esi, ecx
  1384.         jmp     dp3
  1385. ;--------------------------------------
  1386. align 4
  1387. dp4:
  1388. ; next scan line
  1389.         inc     ebx
  1390.         cmp     ebx, [draw_data+32+RECT.bottom]
  1391.         jbe     dp2
  1392.         popad
  1393.         mov     [EGA_counter], 1
  1394.         call    VGA_drawbackground
  1395.         ret
  1396. ;------------------------------------------------------------------------------
  1397. align 4
  1398. vesa20_drawbackground_stretch:
  1399.         pushad
  1400. ; Helper variables
  1401. ; calculate 2^32*(BgrDataWidth-1) mod (ScreenWidth-1)
  1402.         mov     eax, [BgrDataWidth]
  1403.         dec     eax
  1404.         xor     edx, edx
  1405.         div     dword [Screen_Max_X]
  1406.         push    eax     ; high
  1407.         xor     eax, eax
  1408.         div     dword [Screen_Max_X]
  1409.         push    eax     ; low
  1410. ; the same for height
  1411.         mov     eax, [BgrDataHeight]
  1412.         dec     eax
  1413.         xor     edx, edx
  1414.         div     dword [Screen_Max_Y]
  1415.         push    eax     ; high
  1416.         xor     eax, eax
  1417.         div     dword [Screen_Max_Y]
  1418.         push    eax     ; low
  1419. ; External loop for all y from start to end
  1420.         mov     ebx, [draw_data+32+RECT.top]    ; y start
  1421.         mov     ebp, [draw_data+32+RECT.left]   ; x start
  1422. ; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
  1423. ;                       and LFB data (output for our function) [edi]
  1424.         mov     eax, [BytesPerScanLine]
  1425.         mul     ebx
  1426.         xchg    ebp, eax
  1427.         add     ebp, eax
  1428.         add     ebp, eax
  1429.         add     ebp, eax
  1430.         cmp     [ScreenBPP], byte 24    ; 24 or 32 bpp ? - x size
  1431.         jz      @f
  1432.         add     ebp, eax
  1433. ;--------------------------------------
  1434. align 4
  1435. @@:
  1436. ; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
  1437.         call    calculate_edi
  1438.         xchg    edi, ebp
  1439. ; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
  1440.         push    ebx
  1441.         push    eax
  1442. ; 2) Calculate offset in background memory block
  1443.         mov     eax, ebx
  1444.         imul    ebx, dword [esp+12]
  1445.         mul     dword [esp+8]
  1446.         add     edx, ebx        ; edx:eax = y * 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
  1447.         mov     esi, edx
  1448.         imul    esi, [BgrDataWidth]
  1449.         push    edx
  1450.         push    eax
  1451.         mov     eax, [esp+8]
  1452.         mul     dword [esp+28]
  1453.         push    eax
  1454.         mov     eax, [esp+12]
  1455.         mul     dword [esp+28]
  1456.         add     [esp], edx
  1457.         pop     edx             ; edx:eax = x * 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
  1458.         add     esi, edx
  1459.         lea     esi, [esi*3]
  1460.         add     esi, [img_background]
  1461.         push    eax
  1462.         push    edx
  1463.         push    esi
  1464. ; 3) Smooth horizontal
  1465. ;--------------------------------------
  1466. align 4
  1467. bgr_resmooth0:
  1468.         mov     ecx, [esp+8]
  1469.         mov     edx, [esp+4]
  1470.         mov     esi, [esp]
  1471.         push    edi
  1472.         mov     edi, bgr_cur_line
  1473.         call    smooth_line
  1474. ;--------------------------------------
  1475. align 4
  1476. bgr_resmooth1:
  1477.         mov     eax, [esp+16+4]
  1478.         inc     eax
  1479.         cmp     eax, [BgrDataHeight]
  1480.         jae     bgr.no2nd
  1481.         mov     ecx, [esp+8+4]
  1482.         mov     edx, [esp+4+4]
  1483.         mov     esi, [esp+4]
  1484.         add     esi, [BgrDataWidth]
  1485.         add     esi, [BgrDataWidth]
  1486.         add     esi, [BgrDataWidth]
  1487.         mov     edi, bgr_next_line
  1488.         call    smooth_line
  1489. ;--------------------------------------
  1490. align 4
  1491. bgr.no2nd:
  1492.         pop     edi
  1493. ;--------------------------------------
  1494. align 4
  1495. sdp3:
  1496.         xor     esi, esi
  1497.         mov     ecx, [esp+12]
  1498. ; 4) Loop through redraw rectangle and copy background data
  1499. ; Registers meaning:
  1500. ; esi = offset in current line, edi -> output
  1501. ; ebp = offset in WinMapAddress
  1502. ; dword [esp] = offset in bgr data
  1503. ; qword [esp+4] = x * 2^32 * (BgrDataWidth-1) / (ScreenWidth-1)
  1504. ; qword [esp+12] = y * 2^32 * (BgrDataHeight-1) / (ScreenHeight-1)
  1505. ; dword [esp+20] = x
  1506. ; dword [esp+24] = y
  1507. ; precalculated constants:
  1508. ; qword [esp+28] = 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
  1509. ; qword [esp+36] = 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
  1510. ;--------------------------------------
  1511. align 4
  1512. sdp3a:
  1513.         mov     eax, [_WinMapAddress]
  1514.         cmp     [ebp+eax], byte 1
  1515.         jnz     snbgp
  1516.         mov     eax, [bgr_cur_line+esi]
  1517.         test    ecx, ecx
  1518.         jz      .novert
  1519.         mov     ebx, [bgr_next_line+esi]
  1520.         call    [overlapping_of_points_ptr]
  1521. ;--------------------------------------
  1522. align 4
  1523. .novert:
  1524.         push    ecx
  1525.         mov     ecx, [esp+20+4]        ;x
  1526.         shl     ecx, 16
  1527.         add     ecx, [esp+24+4]        ;y
  1528. ; check mouse area for putpixel
  1529.         call    [_display.check_mouse]
  1530. ; store to real LFB
  1531.         mov     [LFB_BASE+edi], ax
  1532.         shr     eax, 16
  1533.         mov     [LFB_BASE+edi+2], al
  1534.         pop     ecx
  1535. ;--------------------------------------
  1536. align 4
  1537. snbgp:
  1538.         cmp     [ScreenBPP], byte 25
  1539.         sbb     edi, -4
  1540.         add     ebp, 1
  1541.         mov     eax, [esp+20]
  1542.         add     eax, 1
  1543.         mov     [esp+20], eax
  1544.         add     esi, 4
  1545.         cmp     eax, [draw_data+32+RECT.right]
  1546.         jbe     sdp3a
  1547. ;--------------------------------------
  1548. align 4
  1549. sdp4:
  1550. ; next y
  1551.         mov     ebx, [esp+24]
  1552.         add     ebx, 1
  1553.         mov     [esp+24], ebx
  1554.         cmp     ebx, [draw_data+32+RECT.bottom]
  1555.         ja      sdpdone
  1556. ; advance edi, ebp to next scan line
  1557.         sub     eax, [draw_data+32+RECT.left]
  1558.         sub     ebp, eax
  1559.         add     ebp, [Screen_Max_X]
  1560.         add     ebp, 1
  1561.         sub     edi, eax
  1562.         sub     edi, eax
  1563.         sub     edi, eax
  1564.         cmp     [ScreenBPP], byte 24
  1565.         jz      @f
  1566.         sub     edi, eax
  1567. ;--------------------------------------
  1568. align 4
  1569. @@:
  1570.         add     edi, [BytesPerScanLine]
  1571. ; restore ecx,edx; advance esi to next background line
  1572.         mov     eax, [esp+28]
  1573.         mov     ebx, [esp+32]
  1574.         add     [esp+12], eax
  1575.         mov     eax, [esp+16]
  1576.         adc     [esp+16], ebx
  1577.         sub     eax, [esp+16]
  1578.         mov     ebx, eax
  1579.         lea     eax, [eax*3]
  1580.         imul    eax, [BgrDataWidth]
  1581.         sub     [esp], eax
  1582.         mov     eax, [draw_data+32+RECT.left]
  1583.         mov     [esp+20], eax
  1584.         test    ebx, ebx
  1585.         jz      sdp3
  1586.         cmp     ebx, -1
  1587.         jnz     bgr_resmooth0
  1588.         push    edi
  1589.         mov     esi, bgr_next_line
  1590.         mov     edi, bgr_cur_line
  1591.         mov     ecx, [Screen_Max_X]
  1592.         inc     ecx
  1593.         rep movsd
  1594.         jmp     bgr_resmooth1
  1595. ;--------------------------------------
  1596. align 4
  1597. sdpdone:
  1598.         add     esp, 44
  1599.         popad
  1600.         mov     [EGA_counter], 1
  1601.         call    VGA_drawbackground
  1602.         ret
  1603.  
  1604. uglobal
  1605. ;--------------------------------------
  1606. align 4
  1607. bgr_cur_line    rd      1920    ; maximum width of screen
  1608. bgr_next_line   rd      1920
  1609. ;--------------------------------------
  1610. endg
  1611. ;--------------------------------------
  1612. align 4
  1613. smooth_line:
  1614.         mov     al, [esi+2]
  1615.         shl     eax, 16
  1616.         mov     ax, [esi]
  1617.         test    ecx, ecx
  1618.         jz      @f
  1619.         mov     ebx, [esi+2]
  1620.         shr     ebx, 8
  1621.         call    [overlapping_of_points_ptr]
  1622. ;--------------------------------------
  1623. align 4
  1624. @@:
  1625.         stosd
  1626.         mov     eax, [esp+20+8]
  1627.         add     eax, 1
  1628.         mov     [esp+20+8], eax
  1629.         cmp     eax, [draw_data+32+RECT.right]
  1630.         ja      @f
  1631.         add     ecx, [esp+36+8]
  1632.         mov     eax, edx
  1633.         adc     edx, [esp+40+8]
  1634.         sub     eax, edx
  1635.         lea     eax, [eax*3]
  1636.         sub     esi, eax
  1637.         jmp     smooth_line
  1638. ;--------------------------------------
  1639. align 4
  1640. @@:
  1641.         mov     eax, [draw_data+32+RECT.left]
  1642.         mov     [esp+20+8], eax
  1643.         ret
  1644. ;------------------------------------------------------------------------------
  1645. align 16
  1646. overlapping_of_points:
  1647. if 0
  1648. ; this version of procedure works, but is slower than next version
  1649.         push    ecx edx
  1650.         mov     edx, eax
  1651.         push    esi
  1652.         shr     ecx, 24
  1653.         mov     esi, ecx
  1654.         mov     ecx, ebx
  1655.         movzx   ebx, dl
  1656.         movzx   eax, cl
  1657.         sub     eax, ebx
  1658.         movzx   ebx, dh
  1659.         imul    eax, esi
  1660.         add     dl, ah
  1661.         movzx   eax, ch
  1662.         sub     eax, ebx
  1663.         imul    eax, esi
  1664.         add     dh, ah
  1665.         ror     ecx, 16
  1666.         ror     edx, 16
  1667.         movzx   eax, cl
  1668.         movzx   ebx, dl
  1669.         sub     eax, ebx
  1670.         imul    eax, esi
  1671.         pop     esi
  1672.         add     dl, ah
  1673.         mov     eax, edx
  1674.         pop     edx
  1675.         ror     eax, 16
  1676.         pop     ecx
  1677.         ret
  1678. else
  1679.         push    ecx edx
  1680.         mov     edx, eax
  1681.         push    esi
  1682.         shr     ecx, 26
  1683.         mov     esi, ecx
  1684.         mov     ecx, ebx
  1685.         shl     esi, 9
  1686.         movzx   ebx, dl
  1687.         movzx   eax, cl
  1688.         sub     eax, ebx
  1689.         movzx   ebx, dh
  1690.         add     dl, [BgrAuxTable+(eax+0x100)+esi]
  1691.         movzx   eax, ch
  1692.         sub     eax, ebx
  1693.         add     dh, [BgrAuxTable+(eax+0x100)+esi]
  1694.         ror     ecx, 16
  1695.         ror     edx, 16
  1696.         movzx   eax, cl
  1697.         movzx   ebx, dl
  1698.         sub     eax, ebx
  1699.         add     dl, [BgrAuxTable+(eax+0x100)+esi]
  1700.         pop     esi
  1701.         mov     eax, edx
  1702.         pop     edx
  1703.         ror     eax, 16
  1704.         pop     ecx
  1705.         ret
  1706. end if
  1707.  
  1708. iglobal
  1709. ;--------------------------------------
  1710. align 4
  1711. overlapping_of_points_ptr       dd      overlapping_of_points
  1712. ;--------------------------------------
  1713. endg
  1714. ;------------------------------------------------------------------------------
  1715. align 4
  1716. init_background:
  1717.         mov     edi, BgrAuxTable
  1718.         xor     edx, edx
  1719. ;--------------------------------------
  1720. align 4
  1721. .loop2:
  1722.         mov     eax, edx
  1723.         shl     eax, 8
  1724.         neg     eax
  1725.         mov     ecx, 0x200
  1726. ;--------------------------------------
  1727. align 4
  1728. .loop1:
  1729.         mov     byte [edi], ah
  1730.         inc     edi
  1731.         add     eax, edx
  1732.         loop    .loop1
  1733.         add     dl, 4
  1734.         jnz     .loop2
  1735.         test    byte [cpu_caps+(CAPS_MMX/8)], 1 shl (CAPS_MMX mod 8)
  1736.         jz      @f
  1737.         mov     [overlapping_of_points_ptr], overlapping_of_points_mmx
  1738. ;--------------------------------------
  1739. align 4
  1740. @@:
  1741.         ret
  1742. ;------------------------------------------------------------------------------
  1743. align 16
  1744. overlapping_of_points_mmx:
  1745.         movd    mm0, eax
  1746.         movd    mm4, eax
  1747.         movd    mm1, ebx
  1748.         pxor    mm2, mm2
  1749.         punpcklbw mm0, mm2
  1750.         punpcklbw mm1, mm2
  1751.         psubw   mm1, mm0
  1752.         movd    mm3, ecx
  1753.         psrld   mm3, 24
  1754.         packuswb mm3, mm3
  1755.         packuswb mm3, mm3
  1756.         pmullw  mm1, mm3
  1757.         psrlw   mm1, 8
  1758.         packuswb mm1, mm2
  1759.         paddb   mm4, mm1
  1760.         movd    eax, mm4
  1761.         ret
  1762. ;------------------------------------------------------------------------------
  1763.