Subversion Repositories Kolibri OS

Rev

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