Subversion Repositories Kolibri OS

Rev

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