Subversion Repositories Kolibri OS

Rev

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