Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2015. 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: 6593 $
  21.  
  22. uglobal
  23. align 4
  24.         bgr_cur_line    rd 1920         ; maximum width of screen
  25.         bgr_next_line   rd 1920
  26. endg
  27.  
  28. iglobal
  29. align 4
  30.         overlapping_of_points_ptr       dd overlapping_of_points
  31. endg
  32.  
  33.  
  34. ;-----------------------------------------------------------------------------
  35. ; eax = x
  36. ; ebx = y
  37.  
  38. align 4
  39. Vesa20_getpixel16:
  40.  
  41.         ; check for hardware cursor
  42.         cmp     [_display.select_cursor], select_cursor
  43.         je      @f
  44.         cmp     [_display.select_cursor], 0
  45.         jne     .no_mouseunder
  46.   @@:
  47.  
  48.         ; check mouse area for putpixel
  49.         test    ecx, 0x04000000         ; don't load to mouseunder area
  50.         jnz     .no_mouseunder
  51.         call    [_display.check_m_pixel]
  52.         test    ecx, ecx                ; 0xff000000
  53.         jnz     @f
  54.  
  55.   .no_mouseunder:
  56. ;        imul    ebx, [BytesPerScanLine] ; ebx = y * y multiplier
  57.         mov     ebx, [BPSLine_calc_area+ebx*4]
  58.         lea     edi, [eax*2]            ; edi = x*2
  59.         add     edi, ebx                ; edi = x*2+(y*y multiplier)
  60.  
  61.         movzx   ecx, word[LFB_BASE+edi]
  62.         shl     ecx, 3
  63.         ror     ecx, 8
  64.         shl     cx, 2
  65.         ror     ecx, 8
  66.         shl     cl, 3
  67.         rol     ecx, 16
  68.   @@:
  69.         and     ecx, 0x00ffffff
  70.         ret
  71.  
  72. ;-----------------------------------------------------------------------------
  73. ; eax = x
  74. ; ebx = y
  75.  
  76. align 4
  77. Vesa20_getpixel24:
  78.  
  79.         ; check for hardware cursor
  80.         cmp     [_display.select_cursor], select_cursor
  81.         je      @f
  82.         cmp     [_display.select_cursor], 0
  83.         jne     .no_mouseunder
  84.   @@:
  85.  
  86.         ; check mouse area for putpixel
  87.         test    ecx, 0x04000000         ; don't load to mouseunder area
  88.         jnz     .no_mouseunder
  89.         call    [_display.check_m_pixel]
  90.         test    ecx, ecx                ; 0xff000000
  91.         jnz     @f
  92.  
  93.   .no_mouseunder:
  94. ;        imul    ebx, [BytesPerScanLine] ; ebx = y * y multiplier
  95.         mov     ebx, [BPSLine_calc_area+ebx*4]
  96.         lea     edi, [eax+eax*2]        ; edi = x*3
  97.         add     edi, ebx                ; edi = x*3+(y*y multiplier)
  98.  
  99.         mov     ecx, [LFB_BASE+edi]
  100.   @@:
  101.         and     ecx, 0x00ffffff
  102.         ret
  103.  
  104. ;-----------------------------------------------------------------------------
  105. ; eax = x
  106. ; ebx = y
  107.  
  108. align 4
  109. Vesa20_getpixel32:
  110.  
  111.         ; check for hardware cursor
  112.         cmp     [_display.select_cursor], select_cursor
  113.         je      @f
  114.         cmp     [_display.select_cursor], 0
  115.         jne     .no_mouseunder
  116.   @@:
  117.  
  118.         ; check mouse area for putpixel
  119.         test    ecx, 0x04000000         ; don't load to mouseunder area
  120.         jnz     .no_mouseunder
  121.         call    [_display.check_m_pixel]
  122.         test    ecx, ecx                ; 0xff000000
  123.         jnz     @f
  124.  
  125.   .no_mouseunder:
  126. ;        imul    ebx, [BytesPerScanLine] ; ebx = y * y multiplier
  127.         mov     ebx, [BPSLine_calc_area+ebx*4]
  128.         lea     edi, [ebx+eax*4]        ; edi = x*4+(y*y multiplier)
  129.  
  130.         mov     ecx, [LFB_BASE+edi]
  131.   @@:
  132.         and     ecx, 0x00ffffff
  133.         ret
  134.  
  135. ;-----------------------------------------------------------------------------
  136. ; ebx = pointer
  137. ; ecx = size [x|y]
  138. ; edx = coordinates [x|y]
  139. ; ebp = pointer to 'get' function
  140. ; esi = pointer to 'init' function
  141. ; edi = parameter for 'get' function
  142.  
  143. align 16
  144. vesa20_putimage:
  145.  
  146. virtual at esp
  147.  putimg:
  148.    .real_sx        dd ?
  149.    .real_sy        dd ?
  150.    .image_sx       dd ?
  151.    .image_sy       dd ?
  152.    .image_cx       dd ?
  153.    .image_cy       dd ?
  154.    .pti            dd ?
  155.    .abs_cx         dd ?
  156.    .abs_cy         dd ?
  157.    .line_increment dd ?
  158.    .winmap_newline dd ?
  159.    .screen_newline dd ?
  160.    .real_sx_and_abs_cx dd ?
  161.    .real_sy_and_abs_cy dd ?
  162.    .stack_data = 4*14
  163.    .edi         dd      ?
  164.    .esi         dd      ?
  165.    .ebp         dd      ?
  166.    .esp         dd      ?
  167.    .ebx         dd      ?
  168.    .edx         dd      ?
  169.    .ecx         dd      ?
  170.    .eax         dd      ?
  171.    .ret_addr    dd      ?
  172.    .arg_0       dd      ?
  173. end virtual
  174.  
  175.         pushad
  176.         sub     esp, putimg.stack_data
  177. ; save pointer to image
  178.         mov     [putimg.pti], ebx
  179. ; unpack the size
  180.         mov     eax, ecx
  181.         and     ecx, 0xFFFF
  182.         shr     eax, 16
  183.         mov     [putimg.image_sx], eax
  184.         mov     [putimg.image_sy], ecx
  185. ; unpack the coordinates
  186.         mov     eax, edx
  187.         and     edx, 0xFFFF
  188.         shr     eax, 16
  189.         mov     [putimg.image_cx], eax
  190.         mov     [putimg.image_cy], edx
  191. ; calculate absolute (i.e. screen) coordinates
  192.         mov     eax, [TASK_BASE]
  193.         mov     ebx, [eax-twdw + WDATA.box.left]
  194.         add     ebx, [putimg.image_cx]
  195.         mov     [putimg.abs_cx], ebx
  196.         mov     ebx, [eax-twdw + WDATA.box.top]
  197.         add     ebx, [putimg.image_cy]
  198.         mov     [putimg.abs_cy], ebx
  199. ; real_sx = MIN(wnd_sx-image_cx, image_sx);
  200.         mov     ebx, [eax-twdw + WDATA.box.width]       ; ebx = wnd_sx
  201.         inc     ebx                                     ; WDATA.box.width is one pixel less than real window x-size
  202.         sub     ebx, [putimg.image_cx]
  203.         ja      @f
  204.         add     esp, putimg.stack_data
  205.         popad
  206.         ret
  207.  
  208.   @@:
  209.         cmp     ebx, [putimg.image_sx]
  210.         jbe     .end_x
  211.         mov     ebx, [putimg.image_sx]
  212.   .end_x:
  213.         mov     [putimg.real_sx], ebx
  214. ; init real_sy
  215.         mov     ebx, [eax-twdw + WDATA.box.height]      ; ebx = wnd_sy
  216.         inc     ebx
  217.         sub     ebx, [putimg.image_cy]
  218.         ja      @f
  219.         add     esp, putimg.stack_data
  220.         popad
  221.         ret
  222.  
  223.   @@:
  224.         cmp     ebx, [putimg.image_sy]
  225.         jbe     .end_y
  226.         mov     ebx, [putimg.image_sy]
  227.   .end_y:
  228.         mov     [putimg.real_sy], ebx
  229. ; line increment
  230.         mov     eax, [putimg.image_sx]
  231.         mov     ecx, [putimg.real_sx]
  232.         sub     eax, ecx
  233. ;;     imul    eax, [putimg.source_bpp]
  234. ;     lea     eax, [eax + eax * 2]
  235.         call    esi
  236.         add     eax, [putimg.arg_0]
  237.         mov     [putimg.line_increment], eax
  238. ; winmap new line increment
  239.         mov     eax, [_display.width]
  240.         sub     eax, [putimg.real_sx]
  241.         mov     [putimg.winmap_newline], eax
  242. ; screen new line increment
  243.         mov     eax, [_display.lfb_pitch]
  244.         mov     ebx, [_display.bytes_per_pixel]
  245.         imul    ecx, ebx
  246.         sub     eax, ecx
  247.         mov     [putimg.screen_newline], eax
  248. ; pointer to image
  249.         mov     esi, [putimg.pti]
  250. ; pointer to screen
  251.         mov     edx, [putimg.abs_cy]
  252. ;        imul    edx, [BytesPerScanLine]
  253.         mov     edx, [BPSLine_calc_area+edx*4]
  254.         mov     eax, [putimg.abs_cx]
  255.         imul    eax, ebx
  256.         add     edx, eax
  257. ; pointer to pixel map
  258.         mov     eax, [putimg.abs_cy]
  259. ;        imul    eax, [Screen_Max_X]
  260. ;        add     eax, [putimg.abs_cy]
  261.         mov     eax, [d_width_calc_area + eax*4]
  262.  
  263.         add     eax, [putimg.abs_cx]
  264.         add     eax, [_display.win_map]
  265.         xchg    eax, ebp
  266.  
  267.         mov     ecx, [putimg.real_sx]
  268.         add     ecx, [putimg.abs_cx]
  269.         mov     [putimg.real_sx_and_abs_cx], ecx
  270.         mov     ecx, [putimg.real_sy]
  271.         add     ecx, [putimg.abs_cy]
  272.         mov     [putimg.real_sy_and_abs_cy], ecx
  273.  
  274. ; get process number
  275.         mov     ebx, [CURRENT_TASK]
  276.  
  277.         cmp     byte [_display.bits_per_pixel], 16
  278.         je      put_image_end_16
  279.         cmp     byte [_display.bits_per_pixel], 24
  280.         je      put_image_end_24
  281.         cmp     byte [_display.bits_per_pixel], 32
  282.         je      put_image_end_32
  283.  
  284. ;------------------------------------------------------------------------------
  285.  
  286. put_image_end_16:
  287.  
  288.         mov     edi, [putimg.real_sy]
  289.  
  290. ; check for hardware cursor
  291.         mov     ecx, [_display.select_cursor]
  292.         cmp     ecx, select_cursor
  293.         je      put_image_end_16_new
  294.         cmp     ecx, 0
  295.         je      put_image_end_16_old
  296.   .new_line:
  297.         mov     ecx, [putimg.real_sx]
  298.   .new_x:
  299.         push    [putimg.edi]
  300.         mov     eax, [putimg.ebp+4]
  301.         call    eax
  302.         cmp     [ebp], bl
  303.         jne     .skip
  304. ; convert to 16 bpp and store to LFB
  305.         and     eax, 00000000111110001111110011111000b
  306.         shr     ah, 2
  307.         shr     ax, 3
  308.         ror     eax, 8
  309.         add     al, ah
  310.         rol     eax, 8
  311.         mov     [LFB_BASE+edx], ax
  312.   .skip:
  313.         add     edx, 2
  314.         inc     ebp
  315.         dec     ecx
  316.         jnz     .new_x
  317.  
  318.         add     esi, [putimg.line_increment]
  319.         add     edx, [putimg.screen_newline]
  320.         add     ebp, [putimg.winmap_newline]
  321.  
  322.         cmp     [putimg.ebp], putimage_get1bpp
  323.         jz      .correct
  324.         cmp     [putimg.ebp], putimage_get2bpp
  325.         jz      .correct
  326.         cmp     [putimg.ebp], putimage_get4bpp
  327.         jnz     @f
  328.   .correct:
  329.         mov     eax, [putimg.edi]
  330.         mov     byte [eax], 80h
  331.   @@:
  332.         dec     edi
  333.         jnz     .new_line
  334.   .finish:
  335.         add     esp, putimg.stack_data
  336.         popad
  337.         ret
  338.  
  339. ;------------------------------------------------------------------------------
  340.  
  341. align 4
  342. put_image_end_16_old:
  343.  
  344.   .new_line:
  345.         mov     ecx, [putimg.real_sx]
  346.   .new_x:
  347.         push    [putimg.edi]
  348.         mov     eax, [putimg.ebp+4]
  349.         call    eax
  350.         cmp     [ebp], bl
  351.         jne     .skip
  352.  
  353.         push    ecx
  354.         neg     ecx
  355.         add     ecx, [putimg.real_sx_and_abs_cx + 4]
  356.         shl     ecx, 16
  357.         add     ecx, [putimg.real_sy_and_abs_cy + 4]
  358.         sub     ecx, edi
  359.  
  360. ; check mouse area for putpixel
  361.         call    check_mouse_area_for_putpixel
  362.         pop     ecx
  363.  
  364. ; convert to 16 bpp and store to LFB
  365. ;;        and     eax, 00000000111110001111110011111000b
  366. ;;        shr     ah, 2
  367. ;;        shr     ax, 3
  368. ;;        ror     eax, 8
  369. ;;        add     al, ah
  370. ;;        rol     eax, 8
  371.         mov     [LFB_BASE+edx], ax
  372.   .skip:
  373.         inc     edx
  374.         inc     edx
  375.         inc     ebp
  376.         dec     ecx
  377.         jnz     .new_x
  378.  
  379.         add     esi, [putimg.line_increment]
  380.         add     edx, [putimg.screen_newline]
  381.         add     ebp, [putimg.winmap_newline]
  382.  
  383.         cmp     [putimg.ebp], putimage_get1bpp
  384.         jz      .correct
  385.         cmp     [putimg.ebp], putimage_get2bpp
  386.         jz      .correct
  387.         cmp     [putimg.ebp], putimage_get4bpp
  388.         jnz     @f
  389.   .correct:
  390.         mov     eax, [putimg.edi]
  391.         mov     byte [eax], 80h
  392.   @@:
  393.         dec     edi
  394.         jnz     .new_line
  395.         jmp     put_image_end_16.finish
  396.  
  397. ;------------------------------------------------------------------------------
  398.  
  399. align 4
  400. put_image_end_16_new:
  401.  
  402.   .new_line:
  403.         mov     ecx, [putimg.real_sx]
  404.  
  405.   .new_x:
  406.         push    [putimg.edi]
  407.         mov     eax, [putimg.ebp+4]
  408.         call    eax
  409.  
  410.         cmp     [ebp], bl
  411.         jne     .skip
  412.  
  413.         push    ecx
  414.   .sh:
  415.         neg     ecx
  416.         add     ecx, [putimg.real_sx_and_abs_cx + 4]
  417.  
  418. ; check for X
  419.         cmp     cx, [X_UNDER_sub_CUR_hot_x_add_curh]
  420.         jae     .no_mouse_area
  421.  
  422.         sub     cx, [X_UNDER_subtraction_CUR_hot_x]
  423.         jb      .no_mouse_area
  424.  
  425.         shl     ecx, 16
  426.         add     ecx, [putimg.real_sy_and_abs_cy + 4]
  427.         sub     ecx, edi
  428.  
  429. ; check for Y
  430.         cmp     cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
  431.         jae     .no_mouse_area
  432.  
  433.         sub     cx, [Y_UNDER_subtraction_CUR_hot_y]
  434.         jb      .no_mouse_area
  435.  
  436. ; check mouse area for putpixel
  437.         call    check_mouse_area_for_putpixel_new.1
  438.         cmp     ecx, -1                 ; SHIT HAPPENS?
  439.         jne     .no_mouse_area
  440.  
  441.         mov     ecx, [esp]
  442.         jmp     .sh
  443.  
  444.   .no_mouse_area:
  445.         pop     ecx
  446. ; convert to 16 bpp and store to LFB
  447.         and     eax, 00000000111110001111110011111000b
  448.         shr     ah, 2
  449.         shr     ax, 3
  450.         ror     eax, 8
  451.         add     al, ah
  452.         rol     eax, 8
  453.         mov     [LFB_BASE+edx], ax
  454.  
  455.   .skip:
  456.         add     edx, 2
  457.         inc     ebp
  458.         dec     ecx
  459.         jnz     .new_x
  460.  
  461.         add     esi, [putimg.line_increment]
  462.         add     edx, [putimg.screen_newline]
  463.         add     ebp, [putimg.winmap_newline]
  464.  
  465.         cmp     [putimg.ebp], putimage_get1bpp
  466.         jz      .correct
  467.         cmp     [putimg.ebp], putimage_get2bpp
  468.         jz      .correct
  469.         cmp     [putimg.ebp], putimage_get4bpp
  470.         jnz     @f
  471.  
  472.   .correct:
  473.         mov     eax, [putimg.edi]
  474.         mov     byte [eax], 80h
  475.  
  476.   @@:
  477.         dec     edi
  478.         jnz     .new_line
  479.         jmp     put_image_end_16.finish
  480.  
  481. ;------------------------------------------------------------------------------
  482.  
  483. align 4
  484. put_image_end_24:
  485.  
  486.         mov     edi, [putimg.real_sy]
  487.  
  488. ; check for hardware cursor
  489.         mov     ecx, [_display.select_cursor]
  490.         cmp     ecx, select_cursor
  491.         je      put_image_end_24_new
  492.         cmp     ecx, 0
  493.         je      put_image_end_24_old
  494.   .new_line:
  495.         mov     ecx, [putimg.real_sx]
  496.   .new_x:
  497.         push    [putimg.edi]
  498.         mov     eax, [putimg.ebp+4]
  499.         call    eax
  500.         cmp     [ebp], bl
  501.         jne     .skip
  502.  
  503. ; store to LFB
  504.         mov     [LFB_BASE+edx], ax
  505.         shr     eax, 16
  506.         mov     [LFB_BASE+edx+2], al
  507.  
  508.   .skip:
  509.         add     edx, 3
  510.         inc     ebp
  511.         dec     ecx
  512.         jnz     .new_x
  513.  
  514.         add     esi, [putimg.line_increment]
  515.         add     edx, [putimg.screen_newline]
  516.         add     ebp, [putimg.winmap_newline]
  517.  
  518.         cmp     [putimg.ebp], putimage_get1bpp
  519.         jz      .correct
  520.         cmp     [putimg.ebp], putimage_get2bpp
  521.         jz      .correct
  522.         cmp     [putimg.ebp], putimage_get4bpp
  523.         jnz     @f
  524.   .correct:
  525.         mov     eax, [putimg.edi]
  526.         mov     byte [eax], 80h
  527.   @@:
  528.         dec     edi
  529.         jnz     .new_line
  530.   .finish:
  531.         add     esp, putimg.stack_data
  532.         popad
  533.         ret
  534.  
  535. ;------------------------------------------------------------------------------
  536.  
  537. align 4
  538. put_image_end_24_old:
  539.  
  540.   .new_line:
  541.         mov     ecx, [putimg.real_sx]
  542. ;--------------------------------------
  543. align 4
  544. .new_x:
  545.         push    [putimg.edi]
  546.         mov     eax, [putimg.ebp+4]
  547.         call    eax
  548.         cmp     [ebp], bl
  549.         jne     .skip
  550.  
  551.         push    ecx
  552.         neg     ecx
  553.         add     ecx, [putimg.real_sx_and_abs_cx + 4]
  554.         shl     ecx, 16
  555.         add     ecx, [putimg.real_sy_and_abs_cy + 4]
  556.         sub     ecx, edi
  557.  
  558. ; check mouse area for putpixel
  559.         call    check_mouse_area_for_putpixel
  560.         pop     ecx
  561. ; store to LFB
  562.         mov     [LFB_BASE+edx], ax
  563.         shr     eax, 16
  564.         mov     [LFB_BASE+edx+2], al
  565.  
  566.   .skip:
  567.         add     edx, 3
  568.         inc     ebp
  569.         dec     ecx
  570.         jnz     .new_x
  571.  
  572.         add     esi, [putimg.line_increment]
  573.         add     edx, [putimg.screen_newline]
  574.         add     ebp, [putimg.winmap_newline]
  575.  
  576.         cmp     [putimg.ebp], putimage_get1bpp
  577.         jz      .correct
  578.         cmp     [putimg.ebp], putimage_get2bpp
  579.         jz      .correct
  580.         cmp     [putimg.ebp], putimage_get4bpp
  581.         jnz     @f
  582.  
  583.   .correct:
  584.         mov     eax, [putimg.edi]
  585.         mov     byte [eax], 80h
  586.  
  587.   @@:
  588.         dec     edi
  589.         jnz     .new_line
  590.         jmp     put_image_end_24.finish
  591.  
  592. ;------------------------------------------------------------------------------
  593.  
  594. align 4
  595. put_image_end_24_new:
  596.  
  597.   .new_line:
  598.         mov     ecx, [putimg.real_sx]
  599.  
  600.   .new_x:
  601.         push    [putimg.edi]
  602.         mov     eax, [putimg.ebp+4]
  603.         call    eax
  604.         cmp     [ebp], bl
  605.         jne     .skip
  606.  
  607.         push    ecx
  608.   .sh:
  609.         neg     ecx
  610.         add     ecx, [putimg.real_sx_and_abs_cx + 4]
  611.  
  612. ; check for X
  613.         cmp     cx, [X_UNDER_sub_CUR_hot_x_add_curh]
  614.         jae     .no_mouse_area
  615.  
  616.         sub     cx, [X_UNDER_subtraction_CUR_hot_x]
  617.         jb      .no_mouse_area
  618.  
  619.         shl     ecx, 16
  620.  
  621.         add     ecx, [putimg.real_sy_and_abs_cy + 4]
  622.         sub     ecx, edi
  623.  
  624. ; check for Y
  625.         cmp     cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
  626.         jae     .no_mouse_area
  627.  
  628.         sub     cx, [Y_UNDER_subtraction_CUR_hot_y]
  629.         jb      .no_mouse_area
  630.  
  631. ; check mouse area for putpixel
  632.         call    check_mouse_area_for_putpixel_new.1
  633.         cmp     ecx, -1         ; SHIT HAPPENS?
  634.         jne     .no_mouse_area
  635.  
  636.         mov     ecx, [esp]
  637.         jmp     .sh
  638.  
  639.   .no_mouse_area:
  640.         pop     ecx
  641.  
  642. ; store to LFB
  643.         mov     [LFB_BASE+edx], ax
  644.         shr     eax, 16
  645.         mov     [LFB_BASE+edx+2], al
  646.  
  647.   .skip:
  648.         add     edx, 3
  649.         inc     ebp
  650.         dec     ecx
  651.         jnz     .new_x
  652.  
  653.         add     esi, [putimg.line_increment]
  654.         add     edx, [putimg.screen_newline]
  655.         add     ebp, [putimg.winmap_newline]
  656.  
  657.         cmp     [putimg.ebp], putimage_get1bpp
  658.         jz      .correct
  659.         cmp     [putimg.ebp], putimage_get2bpp
  660.         jz      .correct
  661.         cmp     [putimg.ebp], putimage_get4bpp
  662.         jnz     @f
  663.  
  664.   .correct:
  665.         mov     eax, [putimg.edi]
  666.         mov     byte [eax], 80h
  667.  
  668.   @@:
  669.         dec     edi
  670.         jnz     .new_line
  671.         jmp     put_image_end_24.finish
  672.  
  673. ;------------------------------------------------------------------------------
  674.  
  675. align 4
  676. put_image_end_32:
  677.  
  678.         mov     edi, [putimg.real_sy]
  679.  
  680. ; check for hardware cursor
  681.         mov     ecx, [_display.select_cursor]
  682.         cmp     ecx, select_cursor
  683.         je      put_image_end_32_new
  684.         cmp     ecx, 0
  685.         je      put_image_end_32_old
  686.  
  687.   .new_line:
  688.         mov     ecx, [putimg.real_sx]
  689.  
  690.   .new_x:
  691.         push    [putimg.edi]
  692.         mov     eax, [putimg.ebp+4]
  693.         call    eax
  694.         cmp     [ebp], bl
  695.         jne     .skip
  696.  
  697. ; store to LFB
  698.         mov     [LFB_BASE+edx], eax
  699.  
  700.   .skip:
  701.         add     edx, 4
  702.         inc     ebp
  703.         dec     ecx
  704.         jnz     .new_x
  705.  
  706.         add     esi, [putimg.line_increment]
  707.         add     edx, [putimg.screen_newline]
  708.         add     ebp, [putimg.winmap_newline]
  709.  
  710.         cmp     [putimg.ebp], putimage_get1bpp
  711.         jz      .correct
  712.         cmp     [putimg.ebp], putimage_get2bpp
  713.         jz      .correct
  714.         cmp     [putimg.ebp], putimage_get4bpp
  715.         jnz     @f
  716.  
  717.   .correct:
  718.         mov     eax, [putimg.edi]
  719.         mov     byte [eax], 80h
  720.  
  721.   @@:
  722.         dec     edi
  723.         jnz     .new_line
  724.  
  725.   .finish:
  726.         add     esp, putimg.stack_data
  727.         popad
  728.         cmp     [SCR_MODE], 0x12
  729.         jne     @f
  730.         call    VGA__putimage
  731.   @@:
  732.         mov     [EGA_counter], 1
  733.         ret
  734.  
  735. ;------------------------------------------------------------------------------
  736.  
  737. align 4
  738. put_image_end_32_old:
  739.  
  740.   .new_line:
  741.         mov     ecx, [putimg.real_sx]
  742.   .new_x:
  743.         push    [putimg.edi]
  744.         mov     eax, [putimg.ebp+4]
  745.         call    eax
  746.         cmp     [ebp], bl
  747.         jne     .skip
  748.  
  749.         push    ecx
  750.         neg     ecx
  751.         add     ecx, [putimg.real_sx_and_abs_cx + 4]
  752.         shl     ecx, 16
  753.         add     ecx, [putimg.real_sy_and_abs_cy + 4]
  754.         sub     ecx, edi
  755.  
  756. ; check mouse area for putpixel
  757.         call    check_mouse_area_for_putpixel
  758.         pop     ecx
  759. ; store to LFB
  760.         mov     [LFB_BASE+edx], eax
  761.  
  762.   .skip:
  763.         add     edx, 4
  764.         inc     ebp
  765.         dec     ecx
  766.         jnz     .new_x
  767.  
  768.         add     esi, [putimg.line_increment]
  769.         add     edx, [putimg.screen_newline]
  770.         add     ebp, [putimg.winmap_newline]
  771.  
  772.         cmp     [putimg.ebp], putimage_get1bpp
  773.         jz      .correct
  774.         cmp     [putimg.ebp], putimage_get2bpp
  775.         jz      .correct
  776.         cmp     [putimg.ebp], putimage_get4bpp
  777.         jnz     @f
  778.  
  779.   .correct:
  780.         mov     eax, [putimg.edi]
  781.         mov     byte [eax], 80h
  782.  
  783.   @@:
  784.         dec     edi
  785.         jnz     .new_line
  786.         jmp     put_image_end_32.finish
  787.  
  788. ;------------------------------------------------------------------------------
  789.  
  790. align 4
  791. put_image_end_32_new:
  792.  
  793.   .new_line:
  794.         mov     ecx, [putimg.real_sx]
  795.  
  796.   .new_x:
  797.         push    [putimg.edi]
  798.         mov     eax, [putimg.ebp+4]
  799.         call    eax
  800.         cmp     [ebp], bl
  801.         jne     .skip
  802.  
  803.         push    ecx
  804.  
  805.   .sh:
  806.         neg     ecx
  807.         add     ecx, [putimg.real_sx_and_abs_cx + 4]
  808.  
  809. ; check for X
  810.         cmp     cx, [X_UNDER_sub_CUR_hot_x_add_curh]
  811.         jae     .no_mouse_area
  812.         sub     cx, [X_UNDER_subtraction_CUR_hot_x]
  813.         jb      .no_mouse_area
  814.         shl     ecx, 16
  815.  
  816.         add     ecx, [putimg.real_sy_and_abs_cy + 4]
  817.         sub     ecx, edi
  818.  
  819. ; check for Y
  820.         cmp     cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
  821.         jae     .no_mouse_area
  822.         sub     cx, [Y_UNDER_subtraction_CUR_hot_y]
  823.         jb      .no_mouse_area
  824.  
  825. ; check mouse area for putpixel
  826.         call    check_mouse_area_for_putpixel_new.1
  827.         cmp     ecx, -1         ; SHIT HAPPENS?
  828.         jne     .no_mouse_area
  829.  
  830.         mov     ecx, [esp]
  831.         jmp     .sh
  832.  
  833.   .no_mouse_area:
  834.         pop     ecx
  835.  
  836. ; store to LFB
  837.         mov     [LFB_BASE+edx], eax
  838.  
  839.   .skip:
  840.         add     edx, 4
  841.         inc     ebp
  842.         dec     ecx
  843.         jnz     .new_x
  844.  
  845.         add     esi, [putimg.line_increment]
  846.         add     edx, [putimg.screen_newline]
  847.         add     ebp, [putimg.winmap_newline]
  848.  
  849.         cmp     [putimg.ebp], putimage_get1bpp
  850.         jz      .correct
  851.         cmp     [putimg.ebp], putimage_get2bpp
  852.         jz      .correct
  853.         cmp     [putimg.ebp], putimage_get4bpp
  854.         jnz     @f
  855.  
  856.   .correct:
  857.         mov     eax, [putimg.edi]
  858.         mov     byte [eax], 80h
  859.  
  860.   @@:
  861.         dec     edi
  862.         jnz     .new_line
  863.         jmp     put_image_end_32.finish
  864.  
  865. ;------------------------------------------------------------------------------
  866. ; eax = x coordinate
  867. ; ebx = y coordinate
  868. ; ecx = xx RR GG BB
  869. ; xx flags:
  870. ; 0x01000000 color inversion
  871. ; 0x02000000 used for draw_rectangle without top line (for drawwindow_III and drawwindow_IV)
  872. ; edi = 0x00000001 force
  873.  
  874. align 4
  875. __sys_putpixel:
  876.  
  877.         pushad
  878.         cmp     eax, [_display.width]
  879.         jge     .exit
  880.         cmp     ebx, [_display.height]
  881.         jge     .exit
  882.         test    edi, 1          ; force ?
  883.         jnz     .forced
  884.  
  885. ; not forced
  886.         mov     edx, [d_width_calc_area + ebx*4]
  887.         add     edx, [_display.win_map]
  888.         movzx   edx, byte [eax+edx]
  889.         cmp     edx, [CURRENT_TASK]
  890.         jne     .exit
  891.  
  892.   .forced:
  893. ; check for color inversion
  894.         test    ecx, 0x01000000
  895.         jz      .no_inv
  896.  
  897.         push    eax ebx edx edi
  898.         call    [GETPIXEL]
  899.         pop     edi edx ebx eax
  900.  
  901.         not     ecx
  902.         rol     ecx, 8
  903.         mov     cl, [esp+32-8+3]
  904.         ror     ecx, 8
  905.         mov     [esp+32-8], ecx
  906.   .no_inv:
  907.         call    [PUTPIXEL]      ; call the real put_pixel function
  908.   .exit:
  909.         popad
  910.         ret
  911.  
  912. ;-----------------------------------------------------------------------------
  913. ; eax = x
  914. ; ebx = y
  915.  
  916. align 4
  917. Vesa20_putpixel16:
  918.  
  919.         mov     ecx, eax
  920.         shl     ecx, 16
  921.         mov     cx, bx
  922.  
  923. ;        imul    ebx, [BytesPerScanLine]  ; ebx = y * y multiplier
  924.         mov     ebx, [BPSLine_calc_area+ebx*4]
  925.         lea     edi, [eax*2]; edi = x*2
  926.         mov     eax, [esp+32-8+4]
  927.  
  928. ; check for hardware cursor
  929.         cmp     [_display.select_cursor], 0
  930.         jne     @f
  931. ; check mouse area for putpixel
  932.         test    eax, 0x04000000
  933.         jnz     @f
  934.         call    check_mouse_area_for_putpixel
  935.   @@:
  936. ; store to LFB
  937.         and     eax, 00000000111110001111110011111000b
  938.         shr     ah, 2
  939.         shr     ax, 3
  940.         ror     eax, 8
  941.         add     al, ah
  942.         rol     eax, 8
  943.  
  944.         mov     [LFB_BASE+ebx+edi], ax
  945.         ret
  946.  
  947. ;-----------------------------------------------------------------------------
  948. ; eax = x
  949. ; ebx = y
  950.  
  951. align 4
  952. Vesa20_putpixel16_new:
  953.  
  954.         mov     ecx, eax
  955.         shl     ecx, 16
  956.         mov     cx, bx
  957.  
  958. ;        imul    ebx, [BytesPerScanLine]  ; ebx = y * y multiplier
  959.         mov     ebx, [BPSLine_calc_area+ebx*4]
  960.         lea     edi, [eax*2]; edi = x*2
  961.         mov     eax, [esp+32-8+4]
  962.  
  963. ; check for hardware cursor
  964.         cmp     [_display.select_cursor], select_cursor
  965.         jne     @f
  966. ; check mouse area for putpixel
  967.         test    eax, 0x04000000
  968.         jnz     @f
  969.  
  970. ; check for Y
  971.         cmp     cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
  972.         jae     @f
  973.         sub     cx, [Y_UNDER_subtraction_CUR_hot_y]
  974.         jb      @f
  975.         rol     ecx, 16
  976.  
  977. ; check for X
  978.         cmp     cx, [X_UNDER_sub_CUR_hot_x_add_curh]
  979.         jae     @f
  980.         sub     cx, [X_UNDER_subtraction_CUR_hot_x]
  981.         jb      @f
  982.         ror     ecx, 16
  983.  
  984.         call    check_mouse_area_for_putpixel_new.1
  985.   @@:
  986. ; store to LFB
  987.         and     eax, 00000000111110001111110011111000b
  988.         shr     ah, 2
  989.         shr     ax, 3
  990.         ror     eax, 8
  991.         add     al, ah
  992.         rol     eax, 8
  993.  
  994.         mov     [LFB_BASE+ebx+edi], ax
  995.         ret
  996.  
  997. ;-----------------------------------------------------------------------------
  998. ; eax = x
  999. ; ebx = y
  1000.  
  1001. align 4
  1002. Vesa20_putpixel24:
  1003.  
  1004.         mov     ecx, eax
  1005.         shl     ecx, 16
  1006.         mov     cx, bx
  1007.  
  1008. ;        imul    ebx, [BytesPerScanLine]  ; ebx = y * y multiplier
  1009.         mov     ebx, [BPSLine_calc_area+ebx*4]
  1010.         lea     edi, [eax+eax*2]; edi = x*3
  1011.         mov     eax, [esp+32-8+4]
  1012.  
  1013. ; check for hardware cursor
  1014.         cmp     [_display.select_cursor], 0
  1015.         jne     @f
  1016. ; check mouse area for putpixel
  1017.         test    eax, 0x04000000
  1018.         jnz     @f
  1019.         call    check_mouse_area_for_putpixel
  1020.   @@:
  1021.  
  1022. ; store to LFB
  1023.         mov     [LFB_BASE+ebx+edi], ax
  1024.         shr     eax, 16
  1025.         mov     [LFB_BASE+ebx+edi+2], al
  1026.         ret
  1027.  
  1028. ;-----------------------------------------------------------------------------
  1029. ; eax = x
  1030. ; ebx = y
  1031.  
  1032. align 4
  1033. Vesa20_putpixel24_new:
  1034.  
  1035.         mov     ecx, eax
  1036.         shl     ecx, 16
  1037.         mov     cx, bx
  1038.  
  1039. ;        imul    ebx, [BytesPerScanLine]  ; ebx = y * y multiplier
  1040.         mov     ebx, [BPSLine_calc_area+ebx*4]
  1041.         lea     edi, [eax+eax*2]; edi = x*3
  1042.         mov     eax, [esp+32-8+4]
  1043.  
  1044. ; check for hardware cursor
  1045.         cmp     [_display.select_cursor], select_cursor
  1046.         jne     @f
  1047. ; check mouse area for putpixel
  1048.         test    eax, 0x04000000
  1049.         jnz     @f
  1050.  
  1051. ; check for Y
  1052.         cmp     cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
  1053.         jae     @f
  1054.         sub     cx, [Y_UNDER_subtraction_CUR_hot_y]
  1055.         jb      @f
  1056.         rol     ecx, 16
  1057.  
  1058. ; check for X
  1059.         cmp     cx, [X_UNDER_sub_CUR_hot_x_add_curh]
  1060.         jae     @f
  1061.         sub     cx, [X_UNDER_subtraction_CUR_hot_x]
  1062.         jb      @f
  1063.         ror     ecx, 16
  1064.  
  1065.         call    check_mouse_area_for_putpixel_new.1
  1066.   @@:
  1067. ; store to LFB
  1068.         mov     [LFB_BASE+ebx+edi], ax
  1069.         shr     eax, 16
  1070.         mov     [LFB_BASE+ebx+edi+2], al
  1071.         ret
  1072.  
  1073. ;-----------------------------------------------------------------------------
  1074. ; eax = x
  1075. ; ebx = y
  1076.  
  1077. align 4
  1078. Vesa20_putpixel32:
  1079.  
  1080.         mov     ecx, eax
  1081.         shl     ecx, 16
  1082.         mov     cx, bx
  1083.  
  1084. ;        imul    ebx, [BytesPerScanLine]  ; ebx = y * y multiplier
  1085.         mov     ebx, [BPSLine_calc_area+ebx*4]
  1086.         lea     edi, [ebx+eax*4]        ; edi = x*4+(y*y multiplier)
  1087.         mov     eax, [esp+32-8+4]       ; eax = color
  1088.  
  1089. ; check for hardware cursor
  1090.         cmp     [_display.select_cursor], 0
  1091.         jne     @f
  1092. ; check mouse area for putpixel
  1093.         test    eax, 0x04000000
  1094.         jnz     @f
  1095.         call    check_mouse_area_for_putpixel
  1096.   @@:
  1097.         and     eax, 0xffffff
  1098. ; store to LFB
  1099.         mov     [LFB_BASE+edi], eax
  1100.         ret
  1101.  
  1102. ;-----------------------------------------------------------------------------
  1103. ; eax = x
  1104. ; ebx = y
  1105.  
  1106. align 4
  1107. Vesa20_putpixel32_new:
  1108.  
  1109.         mov     ecx, eax
  1110.         shl     ecx, 16
  1111.         mov     cx, bx
  1112.  
  1113. ;        imul    ebx, [BytesPerScanLine]  ; ebx = y * y multiplier
  1114.         mov     ebx, [BPSLine_calc_area+ebx*4]
  1115.         lea     edi, [ebx+eax*4]        ; edi = x*4+(y*y multiplier)
  1116.         mov     eax, [esp+32-8+4]       ; eax = color
  1117.  
  1118. ; check for hardware cursor
  1119.         cmp     [_display.select_cursor], select_cursor
  1120.         jne     @f
  1121. ; check mouse area for putpixel
  1122.         test    eax, 0x04000000
  1123.         jnz     @f
  1124.  
  1125. ; check for Y
  1126.         cmp     cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
  1127.         jae     @f
  1128.         sub     cx, [Y_UNDER_subtraction_CUR_hot_y]
  1129.         jb      @f
  1130.         rol     ecx, 16
  1131.  
  1132. ; check for X
  1133.         cmp     cx, [X_UNDER_sub_CUR_hot_x_add_curh]
  1134.         jae     @f
  1135.         sub     cx, [X_UNDER_subtraction_CUR_hot_x]
  1136.         jb      @f
  1137.         ror     ecx, 16
  1138.  
  1139.         call    check_mouse_area_for_putpixel_new.1
  1140.   @@:
  1141.         and     eax, 0x00ffffff
  1142. ; store to LFB
  1143.         mov     [LFB_BASE+edi], eax
  1144.         ret
  1145.  
  1146. ;-----------------------------------------------------------------------------
  1147.  
  1148. align 4
  1149. calculate_edi:
  1150. ;        mov     edi, ebx
  1151. ;        imul    edi, [Screen_Max_X]
  1152. ;        add     edi, ebx
  1153.         mov     edi, [d_width_calc_area + ebx*4]
  1154.         add     edi, eax
  1155.         ret
  1156.  
  1157.  
  1158. ;-----------------------------------------------------------------------------
  1159. ; DRAWLINE
  1160. ;-----------------------------------------------------------------------------
  1161. ; eax = x1 shl 16 + x2
  1162. ; ebx = y1 shl 16 + y2
  1163. ; ecx = color
  1164. ; edi = force ?
  1165.  
  1166. align 4
  1167. __sys_draw_line:
  1168.  
  1169. dl_x1 equ esp+20
  1170. dl_y1 equ esp+16
  1171. dl_x2 equ esp+12
  1172. dl_y2 equ esp+8
  1173. dl_dx equ esp+4
  1174. dl_dy equ esp+0
  1175.  
  1176.         pusha
  1177.  
  1178.         xor     edx, edx        ; clear edx
  1179.         xor     esi, esi        ; unpack arguments
  1180.         xor     ebp, ebp
  1181.         mov     si, ax          ; esi = x2
  1182.         mov     bp, bx          ; ebp = y2
  1183.         shr     eax, 16         ; eax = x1
  1184.         shr     ebx, 16         ; ebx = y1
  1185.         push    eax             ; save x1
  1186.         push    ebx             ; save y1
  1187.         push    esi             ; save x2
  1188.         push    ebp             ; save y2
  1189. ; checking x-axis...
  1190.         sub     esi, eax        ; esi = x2-x1
  1191.         push    esi             ; save y2-y1
  1192.         jl      .x2lx1          ; is x2 less than x1 ?
  1193.         jg      .no_vline       ; x1 > x2 ?
  1194.         mov     edx, ebp        ; else (if x1=x2)
  1195.         call    vline
  1196.         push    edx             ; necessary to rightly restore stack frame at .exit
  1197.         jmp     .exit
  1198.  
  1199.   .x2lx1:
  1200.         neg     esi             ; get esi absolute value
  1201.  
  1202.   .no_vline:
  1203. ; checking y-axis...
  1204.         sub     ebp, ebx        ; ebp = y2-y1
  1205.         push    ebp             ; save y2-y1
  1206.         jl      .y2ly1          ; is y2 less than y1 ?
  1207.         jg      .no_hline       ; y1 > y2 ?
  1208.         mov     edx, [dl_x2]    ; else (if y1=y2)
  1209.         call    hline
  1210.         jmp     .exit
  1211.  
  1212.   .y2ly1:
  1213.         neg     ebp             ; get ebp absolute value
  1214.  
  1215.   .no_hline:
  1216.         cmp     ebp, esi
  1217.         jle     .x_rules        ; |y2-y1| < |x2-x1|  ?
  1218.         cmp     [dl_y2], ebx    ; make sure y1 is at the begining
  1219.         jge     .no_reverse1
  1220.         neg     dword [dl_dx]
  1221.         mov     edx, [dl_x2]
  1222.         mov     [dl_x2], eax
  1223.         mov     [dl_x1], edx
  1224.         mov     edx, [dl_y2]
  1225.         mov     [dl_y2], ebx
  1226.         mov     [dl_y1], edx
  1227.  
  1228.   .no_reverse1:
  1229.         mov     eax, [dl_dx]
  1230.         cdq                     ; extend eax sing to edx
  1231.         shl     eax, 16         ; using 16bit fix-point maths
  1232.         idiv    ebp             ; eax = ((x2-x1)*65536)/(y2-y1)
  1233.  
  1234. ; correction for the remainder of the division
  1235.         shl     edx, 1
  1236.         cmp     ebp, edx
  1237.         jb      @f
  1238.         inc     eax
  1239.   @@:
  1240.         mov     edx, ebp        ; edx = counter (number of pixels to draw)
  1241.         mov     ebp, 1 shl 16   ; ebp = dy = 1.0
  1242.         mov     esi, eax        ; esi = dx
  1243.         jmp     .y_rules
  1244.   .x_rules:
  1245.         cmp     [dl_x2], eax    ; make sure x1 is at the begining
  1246.         jge     .no_reverse2
  1247.         neg     dword [dl_dy]
  1248.         mov     edx, [dl_x2]
  1249.         mov     [dl_x2], eax
  1250.         mov     [dl_x1], edx
  1251.         mov     edx, [dl_y2]
  1252.         mov     [dl_y2], ebx
  1253.         mov     [dl_y1], edx
  1254.   .no_reverse2:
  1255.         xor     edx, edx
  1256.         mov     eax, [dl_dy]
  1257.         cdq                     ; extend eax sing to edx
  1258.         shl     eax, 16         ; using 16bit fix-point maths
  1259.         idiv    esi             ; eax = ((y2-y1)*65536)/(x2-x1)
  1260. ; correction for the remainder of the division
  1261.         shl     edx, 1
  1262.         cmp     esi, edx
  1263.         jb      @f
  1264.         inc     eax
  1265.   @@:
  1266.         mov     edx, esi        ; edx = counter (number of pixels to draw)
  1267.         mov     esi, 1 shl 16   ; esi = dx = 1.0
  1268.         mov     ebp, eax        ; ebp = dy
  1269.  
  1270.   .y_rules:
  1271.         mov     eax, [dl_x1]
  1272.         mov     ebx, [dl_y1]
  1273.         shl     eax, 16
  1274.         shl     ebx, 16
  1275.  
  1276.         and     ecx, 0xFBFFFFFF ; negate 0x04000000 save to mouseunder area
  1277.   .draw:
  1278.         push    eax ebx
  1279.  
  1280. ; correction for the remainder of the division
  1281.         test    ah, 0x80
  1282.         jz      @f
  1283.         add     eax, 1 shl 16
  1284.   @@:
  1285.         shr     eax, 16
  1286. ; correction for the remainder of the division
  1287.         test    bh, 0x80
  1288.         jz      @f
  1289.         add     ebx, 1 shl 16
  1290.   @@:
  1291.         shr     ebx, 16
  1292. ;        and     ecx, 0xFBFFFFFF  ; negate 0x04000000 save to mouseunder area
  1293. ;        call    [putpixel]
  1294.         call    __sys_putpixel
  1295.         pop     ebx eax
  1296.         add     ebx, ebp     ; y = y+dy
  1297.         add     eax, esi     ; x = x+dx
  1298.         dec     edx
  1299.         jnz     .draw
  1300. ; force last drawn pixel to be at (x2,y2)
  1301.         mov     eax, [dl_x2]
  1302.         mov     ebx, [dl_y2]
  1303. ;        and     ecx, 0xFBFFFFFF ;n egate 0x04000000 save to mouseunder area
  1304. ;        call    [putpixel]
  1305.         call    __sys_putpixel
  1306.  
  1307.   .exit:
  1308.         add     esp, 6*4
  1309.         popa
  1310. ;        call    [draw_pointer]
  1311.         ret
  1312.  
  1313. ;------------------------------------------------------------------------------
  1314. ; draw an horizontal line
  1315. ; eax = x1
  1316. ; edx = x2
  1317. ; ebx = y
  1318. ; ecx = color
  1319. ; edi = force ?
  1320.  
  1321. align 4
  1322. hline:
  1323.  
  1324.         push    eax edx
  1325.         cmp     edx, eax   ; make sure x2 is above x1
  1326.         jge     @f
  1327.         xchg    eax, edx
  1328.   @@:
  1329.         and     ecx, 0xFBFFFFFF  ;negate 0x04000000 save to mouseunder area
  1330.   @@:
  1331. ;        call    [putpixel]
  1332.         call    __sys_putpixel
  1333.         inc     eax
  1334.         cmp     eax, edx
  1335.         jle     @b
  1336.         pop     edx eax
  1337.         ret
  1338.  
  1339. ;------------------------------------------------------------------------------
  1340. ; draw a vertical line
  1341. ; eax = x
  1342. ; ebx = y1
  1343. ; edx = y2
  1344. ; ecx = color
  1345. ; edi = force ?
  1346.  
  1347. align 4
  1348. vline:
  1349.  
  1350.         push    ebx edx
  1351.         cmp     edx, ebx   ; make sure y2 is above y1
  1352.         jge     @f
  1353.         xchg    ebx, edx
  1354.   @@:
  1355.         and     ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area
  1356.   @@:
  1357. ;        call    [putpixel]
  1358.         call    __sys_putpixel
  1359.         inc     ebx
  1360.         cmp     ebx, edx
  1361.         jle     @b
  1362.         pop     edx ebx
  1363.         ret
  1364.  
  1365. ;------------------------------------------------------------------------------
  1366. ; eax   cx
  1367. ; ebx   cy
  1368. ; ecx   xe
  1369. ; edx   ye
  1370. ; edi   color
  1371.  
  1372. align 4
  1373. vesa20_drawbar:
  1374.  
  1375. virtual at esp
  1376. drbar:
  1377.      .bar_sx       dd ?
  1378.      .bar_sy       dd ?
  1379.      .bar_cx       dd ?
  1380.      .bar_cy       dd ?
  1381.      .abs_cx       dd ?
  1382.      .abs_cy       dd ?
  1383.      .real_sx      dd ?
  1384.      .real_sy      dd ?
  1385.      .color        dd ?
  1386.      .line_inc_scr dd ?
  1387.      .line_inc_map dd ?
  1388.      .real_sx_and_abs_cx dd ?
  1389.      .real_sy_and_abs_cy dd ?
  1390.      .stack_data = 4*13
  1391. end virtual
  1392.  
  1393.         pushad
  1394.         sub     esp, drbar.stack_data
  1395.         mov     [drbar.color], edi
  1396.         sub     edx, ebx
  1397.         jle     .exit
  1398.         sub     ecx, eax
  1399.         jle     .exit
  1400.         mov     [drbar.bar_sy], edx
  1401.         mov     [drbar.bar_sx], ecx
  1402.         mov     [drbar.bar_cx], eax
  1403.         mov     [drbar.bar_cy], ebx
  1404.         mov     edi, [TASK_BASE]
  1405.         add     eax, [edi-twdw + WDATA.box.left]        ; win_cx
  1406.         add     ebx, [edi-twdw + WDATA.box.top]         ; win_cy
  1407.         mov     [drbar.abs_cx], eax
  1408.         mov     [drbar.abs_cy], ebx
  1409. ; real_sx = MIN(wnd_sx-bar_cx, bar_sx);
  1410.         mov     ebx, [edi-twdw + WDATA.box.width]       ; ebx = wnd_sx
  1411.         inc     ebx                                     ; WDATA.box.width is one pixel less than real window x-size
  1412.         sub     ebx, [drbar.bar_cx]
  1413.         ja      @f
  1414.   .exit:
  1415.         add     esp, drbar.stack_data
  1416.         popad
  1417.         xor     eax, eax
  1418.         inc     eax
  1419.         ret
  1420.   @@:
  1421.         cmp     ebx, [drbar.bar_sx]
  1422.         jbe     .end_x
  1423.         mov     ebx, [drbar.bar_sx]
  1424.   .end_x:
  1425.         mov     [drbar.real_sx], ebx
  1426. ; real_sy = MIN(wnd_sy-bar_cy, bar_sy);
  1427.         mov     ebx, [edi-twdw + WDATA.box.height]      ; ebx = wnd_sy
  1428.         inc     ebx
  1429.         sub     ebx, [drbar.bar_cy]
  1430.         ja      @f
  1431.         add     esp, drbar.stack_data
  1432.         popad
  1433.         xor     eax, eax
  1434.         inc     eax
  1435.         ret
  1436.   @@:
  1437.         cmp     ebx, [drbar.bar_sy]
  1438.         jbe     .end_y
  1439.         mov     ebx, [drbar.bar_sy]
  1440.   .end_y:
  1441.         mov     [drbar.real_sy], ebx
  1442. ; line_inc_map
  1443.         mov     eax, [_display.width]
  1444.         sub     eax, [drbar.real_sx]
  1445.         mov     [drbar.line_inc_map], eax
  1446. ; line_inc_scr
  1447.         mov     eax, [drbar.real_sx]
  1448.         mov     ebx, [_display.bytes_per_pixel]
  1449.         imul    eax, ebx
  1450.         neg     eax
  1451.         add     eax, [_display.lfb_pitch]
  1452.         mov     [drbar.line_inc_scr], eax
  1453. ; pointer to screen
  1454.         mov     edx, [drbar.abs_cy]
  1455. ;        imul    edx, [BytesPerScanLine]
  1456.         mov     edx, [BPSLine_calc_area+edx*4]
  1457.         mov     eax, [drbar.abs_cx]
  1458.         imul    eax, ebx
  1459.         add     edx, eax
  1460. ; pointer to pixel map
  1461.         mov     eax, [drbar.abs_cy]
  1462. ;        imul    eax, [Screen_Max_X]
  1463. ;        add     eax, [drbar.abs_cy]
  1464.         mov     eax, [d_width_calc_area + eax*4]
  1465.  
  1466.         add     eax, [drbar.abs_cx]
  1467.         add     eax, [_display.win_map]
  1468.         xchg    eax, ebp
  1469.  
  1470.         mov     ebx, [drbar.real_sx]
  1471.         add     ebx, [drbar.abs_cx]
  1472.         mov     [drbar.real_sx_and_abs_cx], ebx
  1473.         mov     ebx, [drbar.real_sy]
  1474.         add     ebx, [drbar.abs_cy]
  1475.         mov     [drbar.real_sy_and_abs_cy], ebx
  1476.  
  1477.         add     edx, LFB_BASE
  1478.  
  1479. ; get process number
  1480.         mov     ebx, [CURRENT_TASK]  ; bl - process num
  1481.         mov     esi, [drbar.real_sy]
  1482.         mov     eax, [drbar.color] ; BBGGRR00
  1483.         rol     eax, 8
  1484.         mov     bh, al  ; 0x80 drawing gradient bars
  1485.         ror     eax, 8
  1486.  
  1487.         cmp     byte [_display.bits_per_pixel], 16
  1488.         je      draw_bar_end_16
  1489.         cmp     byte [_display.bits_per_pixel], 24
  1490.         je      draw_bar_end_24
  1491.         cmp     byte [_display.bits_per_pixel], 32
  1492.         je      draw_bar_end_32
  1493.  
  1494. ;--------------------------------------
  1495. ; eax - color high   RRGGBB
  1496. ; bl - process num
  1497. ; ecx - temp
  1498. ; edx - pointer to screen
  1499. ; esi - counter
  1500. ; edi - counter
  1501.  
  1502. align 4
  1503. draw_bar_end_24:
  1504.  
  1505. ; check for hardware cursor
  1506.         mov     ecx, [_display.select_cursor]
  1507.         cmp     ecx, select_cursor
  1508.         je      draw_bar_end_24_new
  1509.         cmp     ecx, 0
  1510.         je      draw_bar_end_24_old
  1511.   .new_y:
  1512.         mov     edi, [drbar.real_sx]
  1513.   .new_x:
  1514.         cmp     byte [ebp], bl
  1515.         jne     .skip
  1516.  
  1517. ; store to LFB
  1518.         mov     [edx], ax
  1519.         shr     eax, 16
  1520.         mov     [edx + 2], al
  1521.   .skip:
  1522. ; add pixel
  1523.         add     edx, 3
  1524.         inc     ebp
  1525.         dec     edi
  1526.         jnz     .new_x
  1527. ; add line
  1528.         add     edx, [drbar.line_inc_scr]
  1529.         add     ebp, [drbar.line_inc_map]
  1530. ; drawing gradient bars
  1531.         test    bh, 0x80
  1532.         jz      @f
  1533.         test    al, al
  1534.         jz      @f
  1535.         dec     al
  1536.   @@:
  1537.         dec     esi
  1538.         jnz     .new_y
  1539.   .end:
  1540.         add     esp, drbar.stack_data
  1541.         popad
  1542.         xor     eax, eax
  1543.         ret
  1544.  
  1545. ;------------------------------------------------------------------------------
  1546.  
  1547. align 4
  1548. draw_bar_end_24_old:
  1549.  
  1550.   .new_y:
  1551.         mov     edi, [drbar.real_sx]
  1552.   .new_x:
  1553.         cmp     byte [ebp], bl
  1554.         jne     .skip
  1555.  
  1556.         mov     ecx, [drbar.real_sx_and_abs_cx]
  1557.         sub     ecx, edi
  1558.         shl     ecx, 16
  1559.         add     ecx, [drbar.real_sy_and_abs_cy]
  1560.         sub     ecx, esi
  1561. ; check mouse area for putpixel
  1562.         call    check_mouse_area_for_putpixel
  1563. ; store to LFB
  1564.         mov     [edx], ax
  1565.         shr     eax, 16
  1566.         mov     [edx + 2], al
  1567.         mov     eax, [drbar.color]
  1568.   .skip:
  1569. ; add pixel
  1570.         add     edx, 3
  1571.         inc     ebp
  1572.         dec     edi
  1573.         jnz     .new_x
  1574. ; add line
  1575.         add     edx, [drbar.line_inc_scr]
  1576.         add     ebp, [drbar.line_inc_map]
  1577. ; drawing gradient bars
  1578.         test    bh, 0x80
  1579.         jz      @f
  1580.         test    al, al
  1581.         jz      @f
  1582.         dec     al
  1583.   @@:
  1584.         dec     esi
  1585.         jnz     .new_y
  1586.         jmp     draw_bar_end_24.end
  1587.  
  1588. ;------------------------------------------------------------------------------
  1589.  
  1590. align 4
  1591. draw_bar_end_24_new:
  1592.  
  1593.   .new_y:
  1594.         mov     edi, [drbar.real_sx]
  1595.   .new_x:
  1596.         cmp     byte [ebp], bl
  1597.         jne     .skip
  1598.  
  1599.         mov     ecx, [drbar.real_sy_and_abs_cy]
  1600.         sub     ecx, esi
  1601.  
  1602. ; check for Y
  1603.         cmp     cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
  1604.         jae     .no_mouse_area
  1605.         sub     cx, [Y_UNDER_subtraction_CUR_hot_y]
  1606.         jb      .no_mouse_area
  1607.         rol     ecx, 16
  1608.         add     ecx, [drbar.real_sx_and_abs_cx]
  1609.         sub     ecx, edi
  1610.  
  1611. ; check for X
  1612.         cmp     cx, [X_UNDER_sub_CUR_hot_x_add_curh]
  1613.         jae     .no_mouse_area
  1614.         sub     cx, [X_UNDER_subtraction_CUR_hot_x]
  1615.         jb      .no_mouse_area
  1616.         ror     ecx, 16
  1617.  
  1618. ; check mouse area for putpixel
  1619.         push    eax
  1620.         call    check_mouse_area_for_putpixel_new.1
  1621.         mov     [edx], ax
  1622.         shr     eax, 16
  1623.         mov     [edx + 2], al
  1624.         pop     eax
  1625.         jmp     .skip
  1626.  
  1627.   .no_mouse_area:
  1628. ; store to LFB
  1629.         mov     [edx], ax
  1630.         ror     eax, 16
  1631.         mov     [edx + 2], al
  1632.         rol     eax, 16
  1633.   .skip:
  1634.  
  1635. ; add pixel
  1636.         add     edx, 3
  1637.         inc     ebp
  1638.         dec     edi
  1639.         jnz     .new_x
  1640.  
  1641. ; add line
  1642.         add     edx, [drbar.line_inc_scr]
  1643.         add     ebp, [drbar.line_inc_map]
  1644.  
  1645. ; drawing gradient bars
  1646.         test    bh, 0x80
  1647.         jz      @f
  1648.         test    al, al
  1649.         jz      @f
  1650.         dec     al
  1651.   @@:
  1652.         dec     esi
  1653.         jnz     .new_y
  1654.         jmp     draw_bar_end_24.end
  1655.  
  1656. ;------------------------------------------------------------------------------
  1657. ; eax - color high   RRGGBB
  1658. ; bl - process num
  1659. ; ecx - temp
  1660. ; edx - pointer to screen
  1661. ; esi - counter
  1662. ; edi - counter
  1663.  
  1664. draw_bar_end_32:
  1665.  
  1666. ; check for hardware cursor
  1667.         mov     ecx, [_display.select_cursor]
  1668.         cmp     ecx, select_cursor
  1669.         je      draw_bar_end_32_new
  1670.         cmp     ecx, 0
  1671.         je      draw_bar_end_32_old
  1672.  
  1673.   .new_y:
  1674.         mov     edi, [drbar.real_sx]
  1675.   .new_x:
  1676.         cmp     byte [ebp], bl
  1677.         jne     .skip
  1678.  
  1679. ; store to LFB
  1680.         mov     [edx], eax
  1681.         mov     eax, [drbar.color]
  1682.   .skip:
  1683.  
  1684. ; add pixel
  1685.         add     edx, 4
  1686.         inc     ebp
  1687.         dec     edi
  1688.         jnz     .new_x
  1689.  
  1690. ; add line
  1691.         add     edx, [drbar.line_inc_scr]
  1692.         add     ebp, [drbar.line_inc_map]
  1693.  
  1694. ; drawing gradient bars
  1695.         test    bh, 0x80
  1696.         jz      @f
  1697.         test    al, al
  1698.         jz      @f
  1699.         dec     al
  1700.   @@:
  1701.         dec     esi
  1702.         jnz     .new_y
  1703.   .end:
  1704.         add     esp, drbar.stack_data
  1705.         popad
  1706.         cmp     [SCR_MODE], 0x12
  1707.         jne     @f
  1708.         call    VGA_draw_bar
  1709.   @@:
  1710.         xor     eax, eax
  1711.         mov     [EGA_counter], 1
  1712.         ret
  1713.  
  1714. draw_bar_end_32_old:
  1715.  
  1716.   .new_y:
  1717.         mov     edi, [drbar.real_sx]
  1718.   .new_x:
  1719.         cmp     byte [ebp], bl
  1720.         jne     .skip
  1721.  
  1722.         mov     ecx, [drbar.real_sx_and_abs_cx]
  1723.         sub     ecx, edi
  1724.         shl     ecx, 16
  1725.         add     ecx, [drbar.real_sy_and_abs_cy]
  1726.         sub     ecx, esi
  1727.  
  1728. ; check mouse area for putpixel
  1729.         call    check_mouse_area_for_putpixel
  1730. ; store to LFB
  1731.         mov     [edx], eax
  1732.         mov     eax, [drbar.color]
  1733.   .skip:
  1734. ; add pixel
  1735.         add     edx, 4
  1736.         inc     ebp
  1737.         dec     edi
  1738.         jnz     .new_x
  1739. ; add line
  1740.         add     edx, [drbar.line_inc_scr]
  1741.         add     ebp, [drbar.line_inc_map]
  1742. ; drawing gradient bars
  1743.         test    bh, 0x80
  1744.         jz      @f
  1745.         test    al, al
  1746.         jz      @f
  1747.         dec     al
  1748.   @@:
  1749.         dec     esi
  1750.         jnz     .new_y
  1751.         jmp     draw_bar_end_32.end
  1752.  
  1753. ;------------------------------------------------------------------------------
  1754.  
  1755. align 4
  1756. draw_bar_end_32_new:
  1757.  
  1758.   .new_y:
  1759.         mov     edi, [drbar.real_sx]
  1760.   .new_x:
  1761.         cmp     byte [ebp], bl
  1762.         jne     .skip
  1763.  
  1764.         mov     ecx, [drbar.real_sy_and_abs_cy]
  1765.         sub     ecx, esi
  1766.  
  1767. ; check for Y
  1768.         cmp     cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
  1769.         jae     .no_mouse_area
  1770.         sub     cx, [Y_UNDER_subtraction_CUR_hot_y]
  1771.         jb      .no_mouse_area
  1772.         rol     ecx, 16
  1773.         add     ecx, [drbar.real_sx_and_abs_cx]
  1774.         sub     ecx, edi
  1775.  
  1776. ; check for X
  1777.         cmp     cx, [X_UNDER_sub_CUR_hot_x_add_curh]
  1778.         jae     .no_mouse_area
  1779.         sub     cx, [X_UNDER_subtraction_CUR_hot_x]
  1780.         jb      .no_mouse_area
  1781.         ror     ecx, 16
  1782.  
  1783. ; check mouse area for putpixel
  1784.         push    eax
  1785.         call    check_mouse_area_for_putpixel_new.1
  1786.         mov     [edx], eax
  1787.         pop     eax
  1788.         jmp     .skip
  1789.   .no_mouse_area:
  1790.  
  1791. ; store to LFB
  1792.         mov     [edx], eax
  1793.   .skip:
  1794.  
  1795. ; add pixel
  1796.         add     edx, 4
  1797.         inc     ebp
  1798.         dec     edi
  1799.         jnz     .new_x
  1800.  
  1801. ; add line
  1802.         add     edx, [drbar.line_inc_scr]
  1803.         add     ebp, [drbar.line_inc_map]
  1804.  
  1805. ; drawing gradient bars
  1806.         test    bh, 0x80
  1807.         jz      @f
  1808.         test    al, al
  1809.         jz      @f
  1810.         dec     al
  1811.   @@:
  1812.         dec     esi
  1813.         jnz     .new_y
  1814.         jmp     draw_bar_end_32.end
  1815.  
  1816. ;------------------------------------------------------------------------------
  1817. ; eax - color high   RRGGBB
  1818. ; bl - process num
  1819. ; ecx - temp
  1820. ; edx - pointer to screen
  1821. ; esi - counter
  1822. ; edi - counter
  1823.  
  1824. align 4
  1825. draw_bar_end_16:
  1826.  
  1827. ; check for hardware cursor
  1828.         mov     ecx, [_display.select_cursor]
  1829.         cmp     ecx, select_cursor
  1830.         je      draw_bar_end_16_new
  1831.         cmp     ecx, 0
  1832.         je      draw_bar_end_16_old
  1833.   .new_y:
  1834.         mov     edi, [drbar.real_sx]
  1835.   .new_x:
  1836.         cmp     byte [ebp], bl
  1837.         jne     .skip
  1838. ; convert to 16 bpp and store to LFB
  1839.         and     eax, 00000000111110001111110011111000b
  1840.         shr     ah, 2
  1841.         shr     ax, 3
  1842.         ror     eax, 8
  1843.         add     al, ah
  1844.         rol     eax, 8
  1845.         mov     [edx], ax
  1846.         mov     eax, [drbar.color]
  1847.   .skip:
  1848.  
  1849. ; add pixel
  1850.         add     edx, 2
  1851.         inc     ebp
  1852.         dec     edi
  1853.         jnz     .new_x
  1854. ; add line
  1855.         add     edx, [drbar.line_inc_scr]
  1856.         add     ebp, [drbar.line_inc_map]
  1857. ; drawing gradient bars
  1858.         test    bh, 0x80
  1859.         jz      @f
  1860.         test    al, al
  1861.         jz      @f
  1862.         dec     al
  1863.   @@:
  1864.         dec     esi
  1865.         jnz     .new_y
  1866.   .end:
  1867.         add     esp, drbar.stack_data
  1868.         popad
  1869.         cmp     [SCR_MODE], 0x12
  1870.         jne     @f
  1871.         call    VGA_draw_bar
  1872.   @@:
  1873.         xor     eax, eax
  1874.         mov     [EGA_counter], 1
  1875.         ret
  1876.  
  1877. ;------------------------------------------------------------------------------
  1878.  
  1879. align 4
  1880. draw_bar_end_16_old:
  1881.  
  1882.   .new_y:
  1883.         mov     edi, [drbar.real_sx]
  1884.   .new_x:
  1885.         cmp     byte [ebp], bl
  1886.         jne     .skip
  1887.  
  1888.         mov     ecx, [drbar.real_sx_and_abs_cx]
  1889.         sub     ecx, edi
  1890.         shl     ecx, 16
  1891.         add     ecx, [drbar.real_sy_and_abs_cy]
  1892.         sub     ecx, esi
  1893.  
  1894. ; check mouse area for putpixel
  1895.         call    check_mouse_area_for_putpixel
  1896. ; convert to 16 bpp and store to LFB
  1897.         and     eax, 00000000111110001111110011111000b
  1898.         shr     ah, 2
  1899.         shr     ax, 3
  1900.         ror     eax, 8
  1901.         add     al, ah
  1902.         rol     eax, 8
  1903.         mov     [edx], ax
  1904.         mov     eax, [drbar.color]
  1905. .skip:
  1906.  
  1907. ; add pixel
  1908.         add     edx, 2
  1909.         inc     ebp
  1910.         dec     edi
  1911.         jnz     .new_x
  1912.  
  1913. ; add line
  1914.         add     edx, [drbar.line_inc_scr]
  1915.         add     ebp, [drbar.line_inc_map]
  1916.  
  1917. ; drawing gradient bars
  1918.         test    bh, 0x80
  1919.         jz      @f
  1920.         test    al, al
  1921.         jz      @f
  1922.         dec     al
  1923.   @@:
  1924.         dec     esi
  1925.         jnz     .new_y
  1926.         jmp     draw_bar_end_16.end
  1927.  
  1928. ;------------------------------------------------------------------------------
  1929.  
  1930. align 4
  1931. draw_bar_end_16_new:
  1932.  
  1933.   .new_y:
  1934.         mov     edi, [drbar.real_sx]
  1935.   .new_x:
  1936.         cmp     byte [ebp], bl
  1937.         jne     .skip
  1938.  
  1939.         mov     ecx, [drbar.real_sy_and_abs_cy]
  1940.         sub     ecx, esi
  1941.  
  1942. ; check for Y
  1943.         cmp     cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
  1944.         jae     .no_mouse_area
  1945.         sub     cx, [Y_UNDER_subtraction_CUR_hot_y]
  1946.         jb      .no_mouse_area
  1947.         rol     ecx, 16
  1948.         add     ecx, [drbar.real_sx_and_abs_cx]
  1949.         sub     ecx, edi
  1950.  
  1951. ; check for X
  1952.         cmp     cx, [X_UNDER_sub_CUR_hot_x_add_curh]
  1953.         jae     .no_mouse_area
  1954.         sub     cx, [X_UNDER_subtraction_CUR_hot_x]
  1955.         jb      .no_mouse_area
  1956.         ror     ecx, 16
  1957.  
  1958. ; check mouse area for putpixel
  1959.         push    eax
  1960.         call    check_mouse_area_for_putpixel_new.1
  1961.         push    eax
  1962.         and     eax, 00000000111110001111110011111000b
  1963.         shr     ah, 2
  1964.         shr     ax, 3
  1965.         ror     eax, 8
  1966.         add     al, ah
  1967.         rol     eax, 8
  1968.         mov     [edx], ax
  1969.         pop     eax
  1970.         pop     eax
  1971.         jmp     .skip
  1972.  
  1973.   .no_mouse_area:
  1974. ; convert to 16 bpp and store to LFB
  1975.         push    eax
  1976.         and     eax, 00000000111110001111110011111000b
  1977.         shr     ah, 2
  1978.         shr     ax, 3
  1979.         ror     eax, 8
  1980.         add     al, ah
  1981.         rol     eax, 8
  1982.         mov     [edx], ax
  1983.         pop     eax
  1984.   .skip:
  1985.  
  1986. ; add pixel
  1987.         add     edx, 2
  1988.         inc     ebp
  1989.         dec     edi
  1990.         jnz     .new_x
  1991.  
  1992. ; add line
  1993.         add     edx, [drbar.line_inc_scr]
  1994.         add     ebp, [drbar.line_inc_map]
  1995.  
  1996. ; drawing gradient bars
  1997.         test    bh, 0x80
  1998.         jz      @f
  1999.         test    al, al
  2000.         jz      @f
  2001.         dec     al
  2002.   @@:
  2003.         dec     esi
  2004.         jnz     .new_y
  2005.         jmp     draw_bar_end_16.end
  2006.  
  2007. ;------------------------------------------------------------------------------
  2008.  
  2009. align 4
  2010. vesa20_drawbackground_tiled:
  2011.  
  2012.         pushad
  2013. ; External loop for all y from start to end
  2014.         mov     ebx, [draw_data+32+RECT.top]    ; y start
  2015.   dp2:
  2016.         mov     ebp, [draw_data+32+RECT.left]   ; x start
  2017. ; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
  2018. ;    and LFB data (output for our function) [edi]
  2019. ;        mov     eax, [BytesPerScanLine]
  2020. ;        mul     ebx
  2021.         mov     eax, [BPSLine_calc_area+ebx*4]
  2022.         xchg    ebp, eax
  2023.         add     ebp, eax
  2024.         add     ebp, eax
  2025.         cmp     byte [_display.bytes_per_pixel], 2
  2026.         je      @f
  2027.         add     ebp, eax
  2028.         cmp     byte [_display.bytes_per_pixel], 3
  2029.         je      @f
  2030.         add     ebp, eax
  2031.  
  2032.   @@:
  2033.         add     ebp, LFB_BASE
  2034. ; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
  2035.         call    calculate_edi
  2036.         xchg    edi, ebp
  2037.         add     ebp, [_display.win_map]
  2038. ; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
  2039. ; 2) Calculate offset in background memory block
  2040.         push    eax
  2041.         xor     edx, edx
  2042.         mov     eax, ebx
  2043.         div     dword [BgrDataHeight]   ; edx := y mod BgrDataHeight
  2044.         pop     eax
  2045.         push    eax
  2046.         mov     ecx, [BgrDataWidth]
  2047.         mov     esi, edx
  2048.         imul    esi, ecx                ; esi := (y mod BgrDataHeight) * BgrDataWidth
  2049.         xor     edx, edx
  2050.         div     ecx             ; edx := x mod BgrDataWidth
  2051.         sub     ecx, edx
  2052.         add     esi, edx        ; esi := (y mod BgrDataHeight)*BgrDataWidth + (x mod BgrDataWidth)
  2053.         pop     eax
  2054.         lea     esi, [esi*3]
  2055.         add     esi, [img_background]
  2056.         xor     edx, edx
  2057.         inc     edx
  2058. ; 3) Loop through redraw rectangle and copy background data
  2059. ; Registers meaning:
  2060. ; eax = x, ebx = y (screen coordinates)
  2061. ; ecx = deltax - number of pixels left in current tile block
  2062. ; edx = 1
  2063. ; esi -> bgr memory, edi -> output
  2064. ; ebp = offset in WinMapAddress
  2065.   dp3:
  2066.         cmp     [ebp], dl
  2067.         jnz     .next_pix
  2068.  
  2069.         push    eax ecx
  2070.         mov     ecx, eax
  2071.         shl     ecx, 16
  2072.         add     ecx, ebx
  2073.  
  2074.         mov     eax, [esi]
  2075.  
  2076. ; check for hardware cursor
  2077.         cmp     [_display.select_cursor], select_cursor
  2078.         je      @f
  2079.         cmp     [_display.select_cursor], 0
  2080.         jne     .no_mouseunder
  2081.   @@:
  2082.         and     eax, 0xffffff
  2083. ; check mouse area for putpixel
  2084.         call    [_display.check_mouse]
  2085.   .no_mouseunder:
  2086.  
  2087.         cmp     byte [_display.bits_per_pixel], 16
  2088.         je      .16bpp
  2089. ; store to LFB
  2090.         mov     [edi], ax
  2091.         shr     eax, 16
  2092.         mov     [edi+2], al
  2093.         pop     ecx eax
  2094.         jmp     .next_pix
  2095.  
  2096.   .16bpp:
  2097. ; convert to 16 bpp and store to LFB
  2098.         and     eax, 00000000111110001111110011111000b
  2099.         shr     ah, 2
  2100.         shr     ax, 3
  2101.         ror     eax, 8
  2102.         add     al, ah
  2103.         rol     eax, 8
  2104.         mov     [edi], ax
  2105.         pop     ecx eax
  2106.  
  2107. ; Advance to next pixel
  2108.   .next_pix:
  2109.         add     esi, 3
  2110.         add     edi, [_display.bytes_per_pixel]
  2111.  
  2112.         add     ebp, edx
  2113.         add     eax, edx
  2114.         cmp     eax, [draw_data+32+RECT.right]
  2115.         ja      dp4
  2116.         sub     ecx, edx
  2117.         jnz     dp3
  2118.  
  2119. ; next tile block on x-axis
  2120.         mov     ecx, [BgrDataWidth]
  2121.         sub     esi, ecx
  2122.         sub     esi, ecx
  2123.         sub     esi, ecx
  2124.         jmp     dp3
  2125.  
  2126.   dp4:
  2127. ; next scan line
  2128.         inc     ebx
  2129.         cmp     ebx, [draw_data+32+RECT.bottom]
  2130.         jbe     dp2
  2131.         popad
  2132.         mov     [EGA_counter], 1
  2133.         cmp     [SCR_MODE], 0x12
  2134.         jne     @f
  2135.         call    VGA_drawbackground
  2136.   @@:
  2137.         ret
  2138.  
  2139. ;------------------------------------------------------------------------------
  2140.  
  2141. align 4
  2142. vesa20_drawbackground_stretch:
  2143.  
  2144.         pushad
  2145. ; Helper variables
  2146. ; calculate 2^32*(BgrDataWidth-1) mod (ScreenWidth-1)
  2147.         mov     eax, [BgrDataWidth]
  2148.         dec     eax
  2149.         xor     edx, edx
  2150.         div     dword [_display.width]
  2151.         push    eax     ; high
  2152.         xor     eax, eax
  2153.         div     dword [_display.width]
  2154.         push    eax     ; low
  2155.  
  2156. ; the same for height
  2157.         mov     eax, [BgrDataHeight]
  2158.         dec     eax
  2159.         xor     edx, edx
  2160.         div     dword [_display.height]
  2161.         push    eax     ; high
  2162.         xor     eax, eax
  2163.         div     dword [_display.height]
  2164.         push    eax     ; low
  2165.  
  2166. ; External loop for all y from start to end
  2167.         mov     ebx, [draw_data+32+RECT.top]    ; y start
  2168.         mov     ebp, [draw_data+32+RECT.left]   ; x start
  2169. ; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
  2170. ;                       and LFB data (output for our function) [edi]
  2171. ;        mov     eax, [BytesPerScanLine]
  2172. ;        mul     ebx
  2173.         mov     eax, [BPSLine_calc_area+ebx*4]
  2174.         xchg    ebp, eax
  2175.         add     ebp, eax
  2176.         add     ebp, eax
  2177.         cmp     byte [_display.bytes_per_pixel], 2
  2178.         jz      @f
  2179.         add     ebp, eax
  2180.         cmp     byte [_display.bytes_per_pixel], 3
  2181.         jz      @f
  2182.         add     ebp, eax
  2183.   @@:
  2184.  
  2185. ; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
  2186.         call    calculate_edi
  2187.         xchg    edi, ebp
  2188.  
  2189. ; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
  2190.         push    ebx
  2191.         push    eax
  2192. ; 2) Calculate offset in background memory block
  2193.         mov     eax, ebx
  2194.         imul    ebx, dword [esp+12]
  2195.         mul     dword [esp+8]
  2196.         add     edx, ebx        ; edx:eax = y * 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
  2197.         mov     esi, edx
  2198.         imul    esi, [BgrDataWidth]
  2199.         push    edx
  2200.         push    eax
  2201.         mov     eax, [esp+8]
  2202.         mul     dword [esp+28]
  2203.         push    eax
  2204.         mov     eax, [esp+12]
  2205.         mul     dword [esp+28]
  2206.         add     [esp], edx
  2207.         pop     edx             ; edx:eax = x * 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
  2208.         add     esi, edx
  2209.         lea     esi, [esi*3]
  2210.         add     esi, [img_background]
  2211.         push    eax
  2212.         push    edx
  2213.         push    esi
  2214.  
  2215. ; 3) Smooth horizontal
  2216.   bgr_resmooth0:
  2217.         mov     ecx, [esp+8]
  2218.         mov     edx, [esp+4]
  2219.         mov     esi, [esp]
  2220.         push    edi
  2221.         mov     edi, bgr_cur_line
  2222.         call    smooth_line
  2223.  
  2224.   bgr_resmooth1:
  2225.         mov     eax, [esp+16+4]
  2226.         inc     eax
  2227.         cmp     eax, [BgrDataHeight]
  2228.         jae     bgr.no2nd
  2229.         mov     ecx, [esp+8+4]
  2230.         mov     edx, [esp+4+4]
  2231.         mov     esi, [esp+4]
  2232.         add     esi, [BgrDataWidth]
  2233.         add     esi, [BgrDataWidth]
  2234.         add     esi, [BgrDataWidth]
  2235.         mov     edi, bgr_next_line
  2236.         call    smooth_line
  2237.  
  2238.   bgr.no2nd:
  2239.         pop     edi
  2240.  
  2241.   sdp3:
  2242.         xor     esi, esi
  2243.         mov     ecx, [esp+12]
  2244.  
  2245. ; 4) Loop through redraw rectangle and copy background data
  2246. ; Registers meaning:
  2247. ; esi = offset in current line, edi -> output
  2248. ; ebp = offset in WinMapAddress
  2249. ; dword [esp] = offset in bgr data
  2250. ; qword [esp+4] = x * 2^32 * (BgrDataWidth-1) / (ScreenWidth-1)
  2251. ; qword [esp+12] = y * 2^32 * (BgrDataHeight-1) / (ScreenHeight-1)
  2252. ; dword [esp+20] = x
  2253. ; dword [esp+24] = y
  2254. ; precalculated constants:
  2255. ; qword [esp+28] = 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
  2256. ; qword [esp+36] = 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
  2257.  
  2258.   sdp3a:
  2259.         mov     eax, [_display.win_map]
  2260.         cmp     [ebp+eax], byte 1
  2261.         jnz     snbgp
  2262.         mov     eax, [bgr_cur_line+esi]
  2263.         test    ecx, ecx
  2264.         jz      .novert
  2265.         mov     ebx, [bgr_next_line+esi]
  2266.         call    [overlapping_of_points_ptr]
  2267.  
  2268.   .novert:
  2269.         push    ecx
  2270. ; check for hardware cursor
  2271.         cmp     [_display.select_cursor], select_cursor
  2272.         je      @f
  2273.         cmp     [_display.select_cursor], 0
  2274.         jne     .no_mouseunder
  2275.   @@:
  2276.         mov     ecx, [esp+20+4]        ;x
  2277.         shl     ecx, 16
  2278.         add     ecx, [esp+24+4]        ;y
  2279. ; check mouse area for putpixel
  2280.         call    [_display.check_mouse]
  2281.   .no_mouseunder:
  2282.  
  2283.         cmp     [_display.bits_per_pixel], 16
  2284.         jne     .not_16bpp
  2285. ; convert to 16 bpp and store to LFB
  2286.         and     eax, 00000000111110001111110011111000b
  2287.         shr     ah, 2
  2288.         shr     ax, 3
  2289.         ror     eax, 8
  2290.         add     al, ah
  2291.         rol     eax, 8
  2292.         mov     [LFB_BASE+edi], ax
  2293.         pop     ecx
  2294.         jmp     snbgp
  2295.   .not_16bpp:
  2296.  
  2297. ; store to LFB
  2298.         mov     [LFB_BASE+edi], ax
  2299.         shr     eax, 16
  2300.         mov     [LFB_BASE+edi+2], al
  2301.         pop     ecx
  2302.  
  2303.   snbgp:
  2304.         add     edi, [_display.bytes_per_pixel]
  2305.         add     ebp, 1
  2306.         mov     eax, [esp+20]
  2307.         add     eax, 1
  2308.         mov     [esp+20], eax
  2309.         add     esi, 4
  2310.         cmp     eax, [draw_data+32+RECT.right]
  2311.         jbe     sdp3a
  2312.  
  2313.   sdp4:
  2314. ; next y
  2315.         mov     ebx, [esp+24]
  2316.         add     ebx, 1
  2317.         mov     [esp+24], ebx
  2318.         cmp     ebx, [draw_data+32+RECT.bottom]
  2319.         ja      sdpdone
  2320.  
  2321. ; advance edi, ebp to next scan line
  2322.         sub     eax, [draw_data+32+RECT.left]
  2323.         sub     ebp, eax
  2324.         add     ebp, [_display.width]
  2325.         sub     edi, eax
  2326.         sub     edi, eax
  2327.         cmp     byte [_display.bytes_per_pixel], 2
  2328.         jz      @f
  2329.         sub     edi, eax
  2330.         cmp     byte [_display.bytes_per_pixel], 3
  2331.         jz      @f
  2332.         sub     edi, eax
  2333.  
  2334.   @@:
  2335.         add     edi, [_display.lfb_pitch]
  2336. ; restore ecx,edx; advance esi to next background line
  2337.         mov     eax, [esp+28]
  2338.         mov     ebx, [esp+32]
  2339.         add     [esp+12], eax
  2340.         mov     eax, [esp+16]
  2341.         adc     [esp+16], ebx
  2342.         sub     eax, [esp+16]
  2343.         mov     ebx, eax
  2344.         lea     eax, [eax*3]
  2345.         imul    eax, [BgrDataWidth]
  2346.         sub     [esp], eax
  2347.         mov     eax, [draw_data+32+RECT.left]
  2348.         mov     [esp+20], eax
  2349.         test    ebx, ebx
  2350.         jz      sdp3
  2351.         cmp     ebx, -1
  2352.         jnz     bgr_resmooth0
  2353.         push    edi
  2354.         mov     esi, bgr_next_line
  2355.         mov     edi, bgr_cur_line
  2356.         mov     ecx, [_display.width]
  2357.         rep movsd
  2358.         jmp     bgr_resmooth1
  2359.  
  2360.   sdpdone:
  2361.         add     esp, 44
  2362.         popad
  2363.         mov     [EGA_counter], 1
  2364.         cmp     [SCR_MODE], 0x12
  2365.         jne     @f
  2366.         call    VGA_drawbackground
  2367.   @@:
  2368.         ret
  2369.  
  2370. ;--------------------------------------
  2371.  
  2372. align 4
  2373. smooth_line:
  2374.         mov     al, [esi+2]
  2375.         shl     eax, 16
  2376.         mov     ax, [esi]
  2377.         test    ecx, ecx
  2378.         jz      @f
  2379.         mov     ebx, [esi+2]
  2380.         shr     ebx, 8
  2381.         call    [overlapping_of_points_ptr]
  2382.   @@:
  2383.         stosd
  2384.         mov     eax, [esp+20+8]
  2385.         add     eax, 1
  2386.         mov     [esp+20+8], eax
  2387.         cmp     eax, [draw_data+32+RECT.right]
  2388.         ja      @f
  2389.         add     ecx, [esp+36+8]
  2390.         mov     eax, edx
  2391.         adc     edx, [esp+40+8]
  2392.         sub     eax, edx
  2393.         lea     eax, [eax*3]
  2394.         sub     esi, eax
  2395.         jmp     smooth_line
  2396.   @@:
  2397.         mov     eax, [draw_data+32+RECT.left]
  2398.         mov     [esp+20+8], eax
  2399.         ret
  2400.  
  2401. ;------------------------------------------------------------------------------
  2402.  
  2403. align 16
  2404. overlapping_of_points:
  2405. if 0
  2406. ; this version of procedure works, but is slower than next version
  2407.         push    ecx edx
  2408.         mov     edx, eax
  2409.         push    esi
  2410.         shr     ecx, 24
  2411.         mov     esi, ecx
  2412.         mov     ecx, ebx
  2413.         movzx   ebx, dl
  2414.         movzx   eax, cl
  2415.         sub     eax, ebx
  2416.         movzx   ebx, dh
  2417.         imul    eax, esi
  2418.         add     dl, ah
  2419.         movzx   eax, ch
  2420.         sub     eax, ebx
  2421.         imul    eax, esi
  2422.         add     dh, ah
  2423.         ror     ecx, 16
  2424.         ror     edx, 16
  2425.         movzx   eax, cl
  2426.         movzx   ebx, dl
  2427.         sub     eax, ebx
  2428.         imul    eax, esi
  2429.         pop     esi
  2430.         add     dl, ah
  2431.         mov     eax, edx
  2432.         pop     edx
  2433.         ror     eax, 16
  2434.         pop     ecx
  2435.         ret
  2436. else
  2437.         push    ecx edx
  2438.         mov     edx, eax
  2439.         push    esi
  2440.         shr     ecx, 26
  2441.         mov     esi, ecx
  2442.         mov     ecx, ebx
  2443.         shl     esi, 9
  2444.         movzx   ebx, dl
  2445.         movzx   eax, cl
  2446.         sub     eax, ebx
  2447.         movzx   ebx, dh
  2448.         add     dl, [BgrAuxTable+(eax+0x100)+esi]
  2449.         movzx   eax, ch
  2450.         sub     eax, ebx
  2451.         add     dh, [BgrAuxTable+(eax+0x100)+esi]
  2452.         ror     ecx, 16
  2453.         ror     edx, 16
  2454.         movzx   eax, cl
  2455.         movzx   ebx, dl
  2456.         sub     eax, ebx
  2457.         add     dl, [BgrAuxTable+(eax+0x100)+esi]
  2458.         pop     esi
  2459.         mov     eax, edx
  2460.         pop     edx
  2461.         ror     eax, 16
  2462.         pop     ecx
  2463.         ret
  2464. end if
  2465.  
  2466.  
  2467. ;------------------------------------------------------------------------------
  2468.  
  2469. align 4
  2470. init_background:
  2471.  
  2472.         mov     edi, BgrAuxTable
  2473.         xor     edx, edx
  2474.  
  2475.   .loop2:
  2476.         mov     eax, edx
  2477.         shl     eax, 8
  2478.         neg     eax
  2479.         mov     ecx, 0x200
  2480.  
  2481.   .loop1:
  2482.         mov     byte [edi], ah
  2483.         inc     edi
  2484.         add     eax, edx
  2485.         loop    .loop1
  2486.         add     dl, 4
  2487.         jnz     .loop2
  2488.         test    byte [cpu_caps+(CAPS_MMX/8)], 1 shl (CAPS_MMX mod 8)
  2489.         jz      @f
  2490.         mov     [overlapping_of_points_ptr], overlapping_of_points_mmx
  2491.   @@:
  2492.         ret
  2493.  
  2494. ;------------------------------------------------------------------------------
  2495.  
  2496. align 16
  2497. overlapping_of_points_mmx:
  2498.  
  2499.         movd    mm0, eax
  2500.         movd    mm4, eax
  2501.         movd    mm1, ebx
  2502.         pxor    mm2, mm2
  2503.         punpcklbw mm0, mm2
  2504.         punpcklbw mm1, mm2
  2505.         psubw   mm1, mm0
  2506.         movd    mm3, ecx
  2507.         psrld   mm3, 24
  2508.         packuswb mm3, mm3
  2509.         packuswb mm3, mm3
  2510.         pmullw  mm1, mm3
  2511.         psrlw   mm1, 8
  2512.         packuswb mm1, mm2
  2513.         paddb   mm4, mm1
  2514.         movd    eax, mm4
  2515.  
  2516.         ret
  2517.  
  2518. ;------------------------------------------------------------------------------
  2519.