Subversion Repositories Kolibri OS

Rev

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

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