Subversion Repositories Kolibri OS

Rev

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