Subversion Repositories Kolibri OS

Rev

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