Subversion Repositories Kolibri OS

Rev

Rev 444 | Go to most recent revision | Blame | 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. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. format MS COFF
  9.  
  10. include 'proc32.inc'
  11. include 'imports.inc'
  12.  
  13. API_VERSION     equ 0x01000100
  14.  
  15. DEBUG           equ 1
  16.  
  17. VID_ATI         equ 0x1002
  18.  
  19. LOAD_FROM_FILE  equ 0
  20. LOAD_FROM_MEM   equ 1
  21. LOAD_INDIRECT   equ 2
  22. LOAD_SYSTEM     equ 3
  23.  
  24. SRV_GETVERSION  equ 0
  25.  
  26. struc BITMAPINFOHEADER {
  27.   .biSize          dd ? ; DWORD
  28.   .biWidth         dd ? ; LONG
  29.   .biHeight        dd ? ; LONG
  30.   .biPlanes        dw ? ; WORD
  31.   .biBitCount      dw ? ; WORD
  32.   .biCompression   dd ? ; DWORD
  33.   .biSizeImage     dd ? ; DWORD
  34.   .biXPelsPerMeter dd ? ; LONG
  35.   .biYPelsPerMeter dd ? ; LONG
  36.   .biClrUsed       dd ? ; DWORD
  37.   .biClrImportant  dd ? ; DWORD
  38. }
  39.  
  40. virtual at 0
  41.   BI BITMAPINFOHEADER
  42. end virtual
  43.  
  44. struc CURSOR
  45. {;common object header
  46.    .magic       dd ?   ;'CURS'
  47.    .destroy     dd ?   ;internal destructor
  48.    .fd          dd ?   ;next object in list
  49.    .bk          dd ?   ;prev object in list
  50.    .pid         dd ?   ;owner id
  51.  
  52.  ;cursor data
  53.    .base        dd ?   ;allocated memory
  54.    .hot_x       dd ?   ;hotspot coords
  55.    .hot_y       dd ?
  56. }
  57. virtual at 0
  58.   CURSOR CURSOR
  59. end virtual
  60.  
  61. CURSOR_SIZE     equ 32
  62.  
  63. R8500       equ 0x514C  ;R200
  64. R9000       equ 0x4966  ;RV250
  65. R9200       equ 0x5961  ;RV280
  66. R9500       equ 0x4144  ;R300
  67. R9500P      equ 0x4E45  ;R300
  68. R9550       equ 0x4153  ;RV350
  69. R9600       equ 0x4150  ;RV350
  70. R9600XT     equ 0x4152  ;RV360
  71. R9700P      equ 0x4E44  ;R300
  72. R9800       equ 0x4E49  ;R350
  73. R9800P      equ 0x4E48  ;R350
  74. R9800XT     equ 0x4E4A  ;R360
  75.  
  76. OS_BASE         equ 0x80000000
  77. SLOT_BASE       equ (OS_BASE+0x0080000)
  78.  
  79. PG_SW        equ 0x003
  80. PG_NOCACHE   equ 0x018
  81.  
  82. struc IOCTL
  83. {  .handle           dd ?
  84.    .io_code          dd ?
  85.    .input            dd ?
  86.    .inp_size         dd ?
  87.    .output           dd ?
  88.    .out_size         dd ?
  89. }
  90.  
  91. virtual at 0
  92.   IOCTL IOCTL
  93. end virtual
  94.  
  95. ;MMIO                   equ 0F9000000h
  96. RD_RB3D_CNTL            equ 1c3ch
  97.  
  98. RD_MEM_CNTL                equ 0140h
  99. RD_CRTC_GEN_CNTL           equ 0050h
  100. RD_CRTC_CUR_EN             equ 10000h
  101. RD_DISPLAY_BASE_ADDR       equ 023ch
  102. RD_DEFAULT_OFFSET          equ 16e0h
  103. CUR_HORZ_VERT_OFF          equ 0268h
  104. CUR_HORZ_VERT_POSN         equ 0264h
  105. CUR_OFFSET                 equ 0260h
  106. RD_RB3D_CNTL               equ 1c3ch
  107. RD_RBBM_STATUS             equ 0e40h
  108. RD_RBBM_FIFOCNT_MASK       equ 007fh
  109. RD_RBBM_ACTIVE             equ 80000000h
  110. RD_TIMEOUT                 equ 2000000
  111.  
  112. RD_DP_GUI_MASTER_CNTL      equ 0146ch
  113. RD_DP_BRUSH_BKGD_CLR       equ 01478h
  114. RD_DP_BRUSH_FRGD_CLR       equ 0147ch
  115. RD_DP_SRC_BKGD_CLR         equ 015dch
  116. RD_DP_SRC_FRGD_CLR         equ 015d8h
  117. RD_DP_CNTL                 equ 016c0h
  118. RD_DP_DATATYPE             equ 016c4h
  119. RD_DP_WRITE_MASK           equ 016cch
  120. RD_DP_SRC_SOURCE_MEMORY    equ (2 shl 24)
  121. RD_DP_SRC_SOURCE_HOST_DATA equ (3 shl 24)
  122. RD_DEFAULT_SC_BOTTOM_RIGHT equ 16e8h
  123. RD_GMC_BRUSH_SOLID_COLOR   equ (13 shl 4)
  124. RD_DEFAULT_SC_RIGHT_MAX    equ 1fffh
  125. RD_DEFAULT_SC_BOTTOM_MAX   equ 1fff0000h
  126. RD_GMC_DST_DATATYPE_SHIFT  equ 8
  127.  
  128. RD_ROP3_S                  equ 00cc0000h
  129. RD_ROP3_P                  equ 00f00000h
  130.  
  131. RD_RB2D_DSTCACHE_MODE      equ 03428h
  132. RD_RB2D_DSTCACHE_CTLSTAT   equ 0342ch
  133. RD_RB2D_DC_FLUSH_ALL       equ 000fh
  134. RD_RB2D_DC_BUSY            equ 80000000h
  135.  
  136. RD_GMC_BRUSH_SOLID_COLOR   equ 000000D0h
  137. RD_GMC_SRC_DATATYPE_COLOR  equ (3 shl 12)
  138. RD_GMC_CLR_CMP_CNTL_DIS    equ (1 shl 28)
  139. RD_GMC_WR_MSK_DIS          equ (1 shl 30)
  140.  
  141. cmdSolidFill               equ 73f036d0h
  142.  
  143. RD_DST_PITCH_OFFSET        equ 142ch
  144. RD_SRC_PITCH_OFFSET        equ 1428h
  145.  
  146. RD_DST_X_LEFT_TO_RIGHT     equ 1
  147. RD_DST_Y_TOP_TO_BOTTOM     equ 2
  148. RD_DST_Y_X                 equ 1438h
  149. RD_DST_WIDTH_HEIGHT        equ 1598h
  150. RD_DST_LINE_START          equ 1600h
  151. RD_DST_LINE_END            equ 1604h
  152. R300_MEM_NUM_CHANNELS_MASK equ 0003h
  153.  
  154. macro rdr op1, op2
  155. {
  156.      mov edi, [ati_io]
  157.      mov op1, [edi+op2]
  158. }
  159.  
  160. macro wrr dest, src
  161. {
  162.      mov edi, [ati_io]
  163.      mov dword [edi+dest], src
  164. }
  165.  
  166.  
  167. public START
  168. public service_proc
  169. public version
  170.  
  171. CURSOR_IMAGE_OFFSET  equ 0x00500000
  172.  
  173. DRV_ENTRY equ 1
  174. DRV_EXIT  equ -1
  175.  
  176. section '.flat' code readable align 16
  177.  
  178. proc START stdcall, state:dword
  179.  
  180.            cmp [state], 1
  181.            jne .exit
  182.  
  183.      if DEBUG
  184.            mov esi, msgInit
  185.            call SysMsgBoardStr
  186.      end if
  187.  
  188.            call detect_ati
  189.            test eax, eax
  190.            jz .fail
  191.  
  192.            call init_ati
  193.            test eax, eax
  194.            jz .fail
  195.  
  196.            or eax, -1
  197.            mov [cursor_map], eax
  198.            mov [cursor_map+4], eax
  199.            mov edx, cursor_map
  200.            mov [cursor_start], edx
  201.            add edx, 8
  202.            mov [cursor_end], edx
  203.  
  204.            stdcall RegService, sz_ati_srv, service_proc
  205.            test eax, eax
  206.            jz .fail
  207.            mov dword [SetHwCursor], drvCursorPos ;enable hardware cursor
  208.            mov dword [HwCursorRestore], drv_restore
  209.            mov dword [HwCursorCreate], ati_cursor
  210.            ret
  211. .fail:
  212.      if DEBUG
  213.            mov esi, msgFail
  214.            call SysMsgBoardStr
  215.      end if
  216.  
  217. .exit:
  218.            xor eax, eax
  219. ;           mov ebx, SetHwCursor
  220. ;           mov dword [ebx], eax    ;force disable hardware cursor
  221.            ret
  222. endp
  223.  
  224. handle     equ  IOCTL.handle
  225. io_code    equ  IOCTL.io_code
  226. input      equ  IOCTL.input
  227. inp_size   equ  IOCTL.inp_size
  228. output     equ  IOCTL.output
  229. out_size   equ  IOCTL.out_size
  230.  
  231. align 4
  232. proc service_proc stdcall, ioctl:dword
  233.  
  234.            mov ebx, [ioctl]
  235.            cmp [ebx+io_code], SRV_GETVERSION
  236.            jne .fail
  237.  
  238.            mov eax, [ebx+output]
  239.            cmp [ebx+out_size], 4
  240.            jne .fail
  241.            mov [eax], dword API_VERSION
  242.            xor eax, eax
  243.            ret
  244. .fail:
  245.            or eax, -1
  246.            ret
  247. endp
  248.  
  249. restore   handle
  250. restore   io_code
  251. restore   input
  252. restore   inp_size
  253. restore   output
  254. restore   out_size
  255.  
  256. align 4
  257. proc detect_ati
  258.            locals
  259.              last_bus dd ?
  260.            endl
  261.  
  262.            xor eax, eax
  263.            mov [bus], eax
  264.            inc eax
  265.            call PciApi
  266.            cmp eax, -1
  267.            je .err
  268.  
  269.            mov [last_bus], eax
  270.  
  271. .next_bus:
  272.            and [devfn], 0
  273. .next_dev:
  274.            stdcall PciRead32, [bus], [devfn], dword 0
  275.            test eax, eax
  276.            jz .next
  277.            cmp eax, -1
  278.            je .next
  279.  
  280.            mov edi, devices
  281. @@:
  282.            mov ebx, [edi]
  283.            test ebx, ebx
  284.            jz .next
  285.  
  286.            cmp eax, ebx
  287.            je .found
  288.            add edi, 4
  289.            jmp @B
  290.  
  291. .next:
  292.            inc [devfn]
  293.            cmp [devfn], 256
  294.            jb  .next_dev
  295.            mov eax, [bus]
  296.            inc eax
  297.            mov [bus], eax
  298.            cmp eax, [last_bus]
  299.            jna .next_bus
  300.            xor eax, eax
  301.            ret
  302. .found:
  303.            xor eax, eax
  304.            inc eax
  305.            ret
  306. .err:
  307.            xor eax, eax
  308.            ret
  309. endp
  310.  
  311. align 4
  312. proc init_ati
  313.  
  314.            stdcall AllocKernelSpace, dword 0x10000
  315.            test eax, eax
  316.            jz .fail
  317.  
  318.            mov [ati_io], eax
  319.  
  320.            stdcall PciRead32, [bus], [devfn], dword 0x18
  321.            and eax, 0xFFFF0000
  322.            mov esi, eax
  323.  
  324.            mov edi, [ati_io]
  325.            mov edx, 16
  326. @@:
  327.            stdcall MapPage,edi,esi,PG_SW+PG_NOCACHE
  328.            add edi, 0x1000
  329.            add esi, 0x1000
  330.            dec edx
  331.            jnz @B
  332.  
  333.            mov edi, [ati_io]
  334.            mov dword [edi+RD_RB3D_CNTL], 0
  335.            call engRestore
  336.  
  337.            mov edi, [ati_io]
  338.            mov eax, [edi+0x50]
  339.            mov ebx,3
  340.            shl ebx,20
  341.            not ebx
  342.            and eax,ebx
  343.            mov ebx, 2
  344.            shl ebx,20
  345.            or eax, ebx
  346.            mov [edi+0x50], eax
  347.  
  348.            call drvShowCursor
  349.            xor eax, eax
  350.            inc eax
  351. .fail:
  352.            ret
  353. endp
  354.  
  355. align 4
  356. drv_restore:
  357.            ret 8
  358.  
  359. align 4
  360. drvShowCursor:
  361.            mov edi, [ati_io]
  362.  
  363.            mov eax, [edi+RD_CRTC_GEN_CNTL]
  364.            bts eax,16
  365.            mov [edi+RD_CRTC_GEN_CNTL], eax
  366.            ret
  367.  
  368. align 4
  369. proc drvCursorPos stdcall, hcursor:dword, x:dword, y:dword
  370.            pushfd
  371.            cli
  372.  
  373.            xor eax, eax
  374.            xor edx, edx
  375.            mov esi, [hcursor]
  376.            mov ebx, [x]
  377.            mov ecx, [y]
  378.  
  379.            sub ebx, [esi+CURSOR.hot_x]
  380.            jnc @F
  381.            neg ebx
  382.            mov eax, ebx
  383.            shl eax, 16
  384.            xor ebx, ebx
  385. @@:
  386.            sub ecx, [esi+CURSOR.hot_y]
  387.            jnc @F
  388.            neg ecx
  389.            mov ax, cx
  390.            mov edx, ecx
  391.            xor ecx, ecx
  392. @@:
  393.            or eax, 0x80000000
  394.            wrr CUR_HORZ_VERT_OFF, eax
  395.  
  396.            shl ebx, 16
  397.            mov bx, cx
  398.            or ebx, 0x80000000
  399.            wrr CUR_HORZ_VERT_POSN, ebx
  400.  
  401.            shl edx, 8
  402.            add edx, [esi+CURSOR.base]
  403.            sub edx, LFBAddress
  404.            wrr CUR_OFFSET, edx
  405.            popfd
  406.            ret
  407. endp
  408.  
  409. align 4
  410. proc video_alloc
  411.  
  412.            pushfd
  413.            cli
  414.            mov ebx, [cursor_start]
  415.            mov ecx, [cursor_end]
  416. .l1:
  417.            bsf eax,[ebx];
  418.            jnz .found
  419.            add ebx,4
  420.            cmp ebx, ecx
  421.            jb .l1
  422.            popfd
  423.            xor eax,eax
  424.            ret
  425. .found:
  426.            btr [ebx], eax
  427.            popfd
  428.  
  429.            mov [cursor_start],ebx
  430.            sub ebx, cursor_map
  431.            lea eax,[eax+ebx*8]
  432.  
  433.            shl eax,14
  434.            add eax, LFBAddress+CURSOR_IMAGE_OFFSET
  435.            ret
  436. endp
  437.  
  438. align 4
  439. video_free:
  440.            pushfd
  441.            cli
  442.            sub eax, LFBAddress+CURSOR_IMAGE_OFFSET
  443.            shr eax, 14
  444.            mov ebx, cursor_map
  445.            bts [ebx], eax
  446.            shr eax, 3
  447.            and eax, not 3
  448.            add eax, ebx
  449.            cmp [cursor_start], eax
  450.            ja @f
  451.            popfd
  452.            ret
  453. @@:
  454.            mov [cursor_start], eax
  455.            popfd
  456.            ret
  457.  
  458. ; param
  459. ;  eax= pid
  460. ;  ebx= src
  461. ;  ecx= flags
  462.  
  463. align 4
  464. ati_cursor:
  465. .src     equ esp
  466. .flags   equ esp+4
  467. .hcursor equ esp+8
  468.  
  469.            sub esp, 4          ;space for .hcursor
  470.            push ecx
  471.            push ebx
  472.  
  473.            mov ebx, eax
  474.            mov eax, CURSOR_SIZE
  475.            call CreateObject
  476.            test eax, eax
  477.            jz .fail
  478.  
  479.            mov [.hcursor],eax
  480.  
  481.            xor ebx, ebx
  482.            mov [eax+CURSOR.magic], 'CURS'
  483.            mov [eax+CURSOR.destroy], destroy_cursor
  484.            mov [eax+CURSOR.hot_x], ebx
  485.            mov [eax+CURSOR.hot_y], ebx
  486.  
  487.            call video_alloc
  488.            mov edi, [.hcursor]
  489.            mov [edi+CURSOR.base], eax
  490.  
  491.            mov esi, [.src]
  492.            mov ebx, [.flags]
  493.            cmp bx, LOAD_INDIRECT
  494.            je .indirect
  495.  
  496.            movzx ecx, word [esi+10]
  497.            movzx edx, word [esi+12]
  498.            mov [edi+CURSOR.hot_x], ecx
  499.            mov [edi+CURSOR.hot_y], edx
  500.  
  501.            stdcall ati_init_cursor, eax, esi
  502.            mov eax, [.hcursor]
  503. .fail:
  504.            add esp, 12
  505.            ret
  506. .indirect:
  507.            shr ebx, 16
  508.            movzx ecx, bh
  509.            movzx edx, bl
  510.            mov [edi+CURSOR.hot_x], ecx
  511.            mov [edi+CURSOR.hot_y], edx
  512.  
  513.            mov edi, eax
  514.            mov ebx, eax
  515.            mov ecx, 64*64
  516.            xor eax,eax
  517.            cld
  518.            rep stosd
  519.            mov edi, ebx
  520.  
  521.            mov esi, [.src]
  522.            mov ebx, 32
  523.            cld
  524. @@:
  525.            mov ecx, 32
  526.            rep movsd
  527.            add edi, 128
  528.            dec ebx
  529.            jnz @B
  530.            mov eax, [.hcursor]
  531.            add esp, 12
  532.            ret
  533.  
  534. align 4
  535. destroy_cursor:
  536.  
  537.            push eax
  538.            mov eax, [eax+CURSOR.base]
  539.            call video_free
  540.            pop eax
  541.  
  542.            call DestroyObject
  543.            ret
  544.  
  545. align 4
  546. proc ati_init_cursor stdcall, dst:dword, src:dword
  547.            locals
  548.              rBase    dd ?
  549.              pQuad    dd ?
  550.              pBits    dd ?
  551.              pAnd     dd ?
  552.              width    dd ?
  553.              height   dd ?
  554.              counter  dd ?
  555.            endl
  556.  
  557.            mov esi, [src]
  558.            add esi,[esi+18]
  559.            mov eax,esi
  560.  
  561.            cmp [esi+BI.biBitCount], 24
  562.            je .img_24
  563.            cmp [esi+BI.biBitCount], 8
  564.            je .img_8
  565.            cmp [esi+BI.biBitCount], 4
  566.            je .img_4
  567.  
  568. .img_2:
  569.            add eax, [esi]
  570.            mov [pQuad],eax
  571.            add eax,8
  572.            mov [pBits],eax
  573.            add eax, 128
  574.            mov [pAnd],eax
  575.            mov eax,[esi+4]
  576.            mov [width],eax
  577.            mov ebx,[esi+8]
  578.            shr ebx,1
  579.            mov [height],ebx
  580.  
  581.            mov edi, pCursor
  582.            add edi, 32*31*4
  583.            mov [rBase],edi
  584.  
  585.            mov esi,[pQuad]
  586. .l21:
  587.            mov ebx, [pBits]
  588.            mov ebx, [ebx]
  589.            bswap ebx
  590.            mov eax, [pAnd]
  591.            mov eax, [eax]
  592.            bswap eax
  593.            mov [counter], 32
  594. @@:
  595.            xor edx, edx
  596.            shl eax,1
  597.            setc dl
  598.            dec edx
  599.  
  600.            xor ecx, ecx
  601.            shl ebx,1
  602.            setc cl
  603.            mov ecx, [esi+ecx*4]
  604.            and ecx, edx
  605.            and edx, 0xFF000000
  606.            or edx, ecx
  607.            mov [edi], edx
  608.  
  609.            add edi, 4
  610.            dec [counter]
  611.            jnz @B
  612.  
  613.            add [pBits], 4
  614.            add [pAnd], 4
  615.            mov edi,[rBase]
  616.            sub edi,128
  617.            mov [rBase],edi
  618.            sub [height],1
  619.            jnz .l21
  620.            jmp .copy
  621. .img_4:
  622.            add eax, [esi]
  623.            mov [pQuad],eax
  624.            add eax,64
  625.            mov [pBits],eax
  626.            add eax, 0x200
  627.            mov [pAnd],eax
  628.            mov eax,[esi+4]
  629.            mov [width],eax
  630.            mov ebx,[esi+8]
  631.            shr ebx,1
  632.            mov [height],ebx
  633.  
  634.            mov edi, pCursor
  635.            add edi, 32*31*4
  636.            mov [rBase],edi
  637.  
  638.            mov esi,[pQuad]
  639.            mov ebx, [pBits]
  640. .l4:
  641.            mov eax, [pAnd]
  642.            mov eax, [eax]
  643.            bswap eax
  644.            mov [counter], 16
  645. @@:
  646.            xor edx, edx
  647.            shl eax,1
  648.            setc dl
  649.            dec edx
  650.  
  651.            movzx ecx, byte [ebx]
  652.            and cl, 0xF0
  653.            shr ecx, 2
  654.            mov ecx, [esi+ecx]
  655.            and ecx, edx
  656.            and edx, 0xFF000000
  657.            or edx, ecx
  658.            mov [edi], edx
  659.  
  660.            xor edx, edx
  661.            shl eax,1
  662.            setc dl
  663.            dec edx
  664.  
  665.            movzx ecx, byte [ebx]
  666.            and cl, 0x0F
  667.            mov ecx, [esi+ecx*4]
  668.            and ecx, edx
  669.            and edx, 0xFF000000
  670.            or edx, ecx
  671.            mov [edi+4], edx
  672.  
  673.            inc ebx
  674.            add edi, 8
  675.            dec [counter]
  676.            jnz @B
  677.  
  678.            add [pAnd], 4
  679.            mov edi,[rBase]
  680.            sub edi,128
  681.            mov [rBase],edi
  682.            sub [height],1
  683.            jnz .l4
  684.            jmp .copy
  685. .img_8:
  686.            add eax, [esi]
  687.            mov [pQuad],eax
  688.            add eax,1024
  689.            mov [pBits],eax
  690.            add eax, 1024
  691.            mov [pAnd],eax
  692.            mov eax,[esi+4]
  693.            mov [width],eax
  694.            mov ebx,[esi+8]
  695.            shr ebx,1
  696.            mov [height],ebx
  697.  
  698.            mov edi, pCursor
  699.            add edi, 32*31*4
  700.            mov [rBase],edi
  701.  
  702.            mov esi,[pQuad]
  703.            mov ebx, [pBits]
  704. .l81:
  705.            mov eax, [pAnd]
  706.            mov eax, [eax]
  707.            bswap eax
  708.            mov [counter], 32
  709. @@:
  710.            xor edx, edx
  711.            shl eax,1
  712.            setc dl
  713.            dec edx
  714.  
  715.            movzx ecx,  byte [ebx]
  716.            mov ecx, [esi+ecx*4]
  717.            and ecx, edx
  718.            and edx, 0xFF000000
  719.            or edx, ecx
  720.            mov [edi], edx
  721.  
  722.            inc ebx
  723.            add edi, 4
  724.            dec [counter]
  725.            jnz @B
  726.  
  727.            add [pAnd], 4
  728.            mov edi,[rBase]
  729.            sub edi,128
  730.            mov [rBase],edi
  731.            sub [height],1
  732.            jnz .l81
  733.            jmp .copy
  734. .img_24:
  735.            add eax, [esi]
  736.            mov [pQuad],eax
  737.            add eax, 0xC00
  738.            mov [pAnd],eax
  739.            mov eax,[esi+BI.biWidth]
  740.            mov [width],eax
  741.            mov ebx,[esi+BI.biHeight]
  742.            shr ebx,1
  743.            mov [height],ebx
  744.  
  745.            mov edi, pCursor
  746.            add edi, 32*31*4
  747.            mov [rBase],edi
  748.  
  749.            mov esi,[pAnd]
  750.            mov ebx, [pQuad]
  751. .row_24:
  752.            mov eax, [esi]
  753.            bswap eax
  754.            mov [counter], 32
  755. @@:
  756.            xor edx, edx
  757.            shl eax,1
  758.            setc dl
  759.            dec edx
  760.  
  761.            mov ecx, [ebx]
  762.            and ecx, 0x00FFFFFF
  763.            and ecx, edx
  764.            and edx, 0xFF000000
  765.            or edx, ecx
  766.            mov [edi], edx
  767.            add ebx, 3
  768.            add edi, 4
  769.            dec [counter]
  770.            jnz @B
  771.  
  772.            add esi, 4
  773.            mov edi,[rBase]
  774.            sub edi,128
  775.            mov [rBase],edi
  776.            sub [height],1
  777.            jnz .row_24
  778. .copy:
  779.            mov edi, [dst]
  780.            mov ecx, 64*64
  781.            xor eax,eax
  782.            rep stosd
  783.  
  784.            mov esi, pCursor
  785.            mov edi, [dst]
  786.            mov ebx, 32
  787.            cld
  788. @@:
  789.            mov ecx, 32
  790.            rep movsd
  791.            add edi, 128
  792.            dec ebx
  793.            jnz @B
  794.            ret
  795. endp
  796.  
  797. align 4
  798. proc engFlush
  799.  
  800.            mov edi, [ati_io]
  801.  
  802.            mov eax, [edi+RD_RB2D_DSTCACHE_CTLSTAT]
  803.            or eax,RD_RB2D_DC_FLUSH_ALL
  804.            mov [edi+RD_RB2D_DSTCACHE_CTLSTAT],eax
  805.  
  806.            mov ecx, RD_TIMEOUT
  807. @@:
  808.            mov eax,[edi+RD_RB2D_DSTCACHE_CTLSTAT]
  809.            and eax, RD_RB2D_DC_BUSY
  810.            jz .exit
  811.  
  812.            sub ecx,1
  813.            jnz @B
  814. .exit:
  815.            ret
  816. endp
  817.  
  818. align 4
  819. engWaitForFifo:
  820. cnt equ bp+8
  821.            push ebp
  822.            mov ebp, esp
  823.  
  824.            mov edi, [ati_io]
  825.  
  826.            mov ecx, RD_TIMEOUT
  827. @@:
  828.            mov eax, [edi+RD_RBBM_STATUS]
  829.            and eax, RD_RBBM_FIFOCNT_MASK
  830.            cmp eax, [ebp+8]
  831.            jae .exit
  832.  
  833.            sub ecx,1
  834.            jmp @B
  835.  
  836. .exit:
  837.            leave
  838.            ret 4
  839.  
  840. align 4
  841. proc engWaitForIdle
  842.  
  843.            push dword 64
  844.            call engWaitForFifo
  845.  
  846.            mov edi, [ati_io]
  847.            mov ecx ,RD_TIMEOUT
  848. @@:
  849.            mov eax, [edi+RD_RBBM_STATUS]
  850.            and eax,RD_RBBM_ACTIVE
  851.            jz .exit
  852.  
  853.            sub ecx,1
  854.            jnz @B
  855. .exit:
  856.            call engFlush
  857.            ret
  858. endp
  859.  
  860. align 4
  861. proc engRestore
  862.  
  863. ;             push dword 1
  864. ;             call engWaitForFifo
  865.  
  866. ;             mov dword  [MMIO+RD_RB2D_DSTCACHE_MODE], 0
  867.  
  868.            push dword 3
  869.            call engWaitForFifo
  870.  
  871.            mov edi, [ati_io]
  872.  
  873.            mov eax, [edi+RD_DISPLAY_BASE_ADDR]
  874.            shr eax, 10d
  875.            or eax,(64d shl 22d)
  876.            mov [edi+RD_DEFAULT_OFFSET],eax
  877.            mov [edi+RD_SRC_PITCH_OFFSET],eax
  878.            mov [edi+RD_DST_PITCH_OFFSET],eax
  879.  
  880.            push dword 1
  881.            call engWaitForFifo
  882.  
  883.            mov edi, [ati_io]
  884.            mov eax, [edi+RD_DP_DATATYPE]
  885.            btr eax, 29d
  886.            mov [edi+RD_DP_DATATYPE],eax
  887.  
  888.            push dword 1
  889.            call engWaitForFifo
  890.  
  891.            mov edi, [ati_io]
  892.            mov dword [edi+RD_DEFAULT_SC_BOTTOM_RIGHT],\
  893.                      (RD_DEFAULT_SC_RIGHT_MAX or RD_DEFAULT_SC_BOTTOM_MAX)
  894.  
  895.            push dword 1
  896.            call engWaitForFifo
  897.  
  898.            mov edi, [ati_io]
  899.            mov dword [edi+RD_DP_GUI_MASTER_CNTL],\
  900.                      (RD_GMC_BRUSH_SOLID_COLOR or \
  901.                       RD_GMC_SRC_DATATYPE_COLOR or \
  902.                      (6 shl RD_GMC_DST_DATATYPE_SHIFT) or \
  903.                       RD_GMC_CLR_CMP_CNTL_DIS or \
  904.                       RD_ROP3_P or \
  905.                       RD_GMC_WR_MSK_DIS)
  906.  
  907.  
  908.            push dword 7
  909.            call engWaitForFifo
  910.  
  911.            mov edi, [ati_io]
  912.  
  913.            mov dword [edi+RD_DST_LINE_START],0
  914.            mov dword [edi+RD_DST_LINE_END], 0
  915.            mov dword [edi+RD_DP_BRUSH_FRGD_CLR], 808000ffh
  916.            mov dword [edi+RD_DP_BRUSH_BKGD_CLR], 002020ffh
  917.            mov dword [edi+RD_DP_SRC_FRGD_CLR],   808000ffh
  918.            mov dword [edi+RD_DP_SRC_BKGD_CLR],   004000ffh
  919.            mov dword [edi+RD_DP_WRITE_MASK],0ffffffffh
  920.  
  921.            call engWaitForIdle
  922.  
  923.            ret
  924. endp
  925.  
  926. align 4
  927. engSetupSolidFill:
  928.            push ebp
  929.            mov ebp, esp
  930.  
  931.            push dword 3
  932.            call engWaitForFifo
  933.  
  934.            wrr RD_DP_GUI_MASTER_CNTL, cmdSolidFill
  935.  
  936.            mov eax, [ebp+8]
  937.            wrr RD_DP_BRUSH_FRGD_CLR,eax
  938.  
  939.            mov edi, [ati_io]
  940.            mov dword [edi+RD_DP_CNTL],(RD_DST_X_LEFT_TO_RIGHT or RD_DST_Y_TOP_TO_BOTTOM)
  941.            leave
  942.            ret 4
  943.  
  944.  
  945. align 4
  946. drvSolidFill:
  947. ;x:word,y:word,w:word,h:word,color:dword
  948.             push ebp
  949.             mov ebp, esp
  950. x equ ebp+8
  951. y equ ebp+12
  952. w equ ebp+16
  953. h equ ebp+20
  954. color equ ebp+24
  955.  
  956.            push dword [ebp+24]
  957.            call engSetupSolidFill
  958.  
  959.            push dword 2
  960.            call engWaitForFifo
  961.  
  962.            mov edi, [ati_io]
  963.  
  964.            mov eax, [y]
  965.            mov ebx, [x]
  966.            shl eax,16
  967.            or eax, ebx
  968.  
  969.            mov ecx,  [w]
  970.            mov edx,  [h]
  971.            shl ecx,16
  972.            or ecx, edx
  973.            mov [edi+RD_DST_Y_X], eax
  974.            mov [edi+RD_DST_WIDTH_HEIGHT], ecx
  975.            call engFlush
  976.            leave
  977.            ret 20
  978.  
  979. align 4
  980. devices dd (R8500   shl 16)+VID_ATI
  981.         dd (R9000   shl 16)+VID_ATI
  982.         dd (R9200   shl 16)+VID_ATI
  983.         dd (R9500   shl 16)+VID_ATI
  984.         dd (R9500P  shl 16)+VID_ATI
  985.         dd (R9550   shl 16)+VID_ATI
  986.         dd (R9600   shl 16)+VID_ATI
  987.         dd (R9600XT shl 16)+VID_ATI
  988.         dd (R9700P  shl 16)+VID_ATI
  989.         dd (R9800   shl 16)+VID_ATI
  990.         dd (R9800P  shl 16)+VID_ATI
  991.         dd (R9800XT shl 16)+VID_ATI
  992.         dd 0    ;terminator
  993.  
  994. version      dd (5 shl 16) or (API_VERSION and 0xFFFF)
  995.  
  996. sz_ati_srv   db 'HWCURSOR',0
  997.  
  998. msgInit      db 'detect hardware...',13,10,0
  999. msgPCI       db 'PCI accsess not supported',13,10,0
  1000. msgFail      db 'device not found',13,10,0
  1001. msg_neg      db 'neg ecx',13,10,0
  1002. buff         db 8 dup(0)
  1003.              db 13,10, 0
  1004.  
  1005. section '.data' data readable writable align 16
  1006.  
  1007. pCursor  db 4096 dup(?)
  1008.  
  1009. cursor_map     rd 2
  1010. cursor_start   rd 1
  1011. cursor_end     rd 1
  1012.  
  1013. bus            dd ?
  1014. devfn          dd ?
  1015. ati_io         dd ?
  1016.  
  1017.  
  1018.  
  1019.