Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1637 lines
45 KiB

  1. ;===============================================================================
  2. ;
  3. ; $Workfile: PATBLT.ASM $
  4. ;
  5. ; Contents:
  6. ; This file contains the assembly code for the pattern blit routine.
  7. ;
  8. ; Copyright (c) 1996, Cirrus Logic, Inc.
  9. ;
  10. ; $Log: X:/log/laguna/nt35/displays/cl546x/i386/PATBLT.ASM $
  11. ;
  12. ; Rev 1.21 Mar 04 1998 15:45:14 frido
  13. ; Added more shadowing.
  14. ;
  15. ; Rev 1.20 Jan 20 1998 11:45:22 frido
  16. ; Added shadowing for DRAWBLTDEF and BGCOLOR registers.
  17. ;
  18. ; Rev 1.19 Nov 04 1997 09:26:10 frido
  19. ; Fixed a typo (PPDEV into PDEV).
  20. ;
  21. ; Rev 1.18 Nov 03 1997 16:38:56 frido
  22. ; Added REQUIRE macros.
  23. ;
  24. ; Rev 1.17 29 Apr 1997 16:29:38 noelv
  25. ; Merged in new SWAT code.
  26. ; SWAT:
  27. ; SWAT: Rev 1.4 24 Apr 1997 10:52:56 frido
  28. ; SWAT: NT140b09 merge.
  29. ; SWAT:
  30. ; SWAT: Rev 1.3 19 Apr 1997 16:32:18 frido
  31. ; SWAT: Added automatic include file dependencies for BUILD.EXE.
  32. ; SWAT: Added SWAT.h include file.
  33. ; SWAT:
  34. ; SWAT: Rev 1.2 18 Apr 1997 00:26:12 frido
  35. ; SWAT: NT140b07 merge.
  36. ; SWAT:
  37. ; SWAT: Rev 1.1 15 Apr 1997 19:13:42 frido
  38. ; SWAT: Added SWAT6: striping in PatBlt.
  39. ;
  40. ; Rev 1.16 08 Apr 1997 11:47:28 einkauf
  41. ;
  42. ; add call to SYNC_W_3D for MCD coordination
  43. ;
  44. ; Rev 1.15 21 Mar 1997 10:10:18 noelv
  45. ; Synced PDEV between C code and ASM code.
  46. ; Added macro to log QFREE data.
  47. ; Consolidated do_flag and sw_test_flag into a single pointer_switch flag.
  48. ;
  49. ; Rev 1.14 07 Mar 1997 09:41:56 SueS
  50. ; Added NULL_BITBLT flag to assembly code. Changed order of include files.
  51. ;
  52. ; Rev 1.13 04 Feb 1997 11:57:34 SueS
  53. ; Added support for hardware clipping for the 5465.
  54. ;
  55. ; Rev 1.12 26 Nov 1996 11:38:02 bennyn
  56. ; Fixed the DSURF save bug
  57. ;
  58. ; Rev 1.11 21 Nov 1996 15:02:40 noelv
  59. ; DSURF (in EBX) was getting hammered before call to bCreateScreenFromDib.
  60. ;
  61. ; Rev 1.10 07 Oct 1996 09:51:00 bennyn
  62. ; Fixed push/pop worng order bug
  63. ;
  64. ; Rev 1.9 04 Oct 1996 16:47:50 bennyn
  65. ;
  66. ; Added DirectDraw YUV support
  67. ;
  68. ; Rev 1.8 22 Aug 1996 18:15:18 noelv
  69. ; Frido bug fix release 8-22.
  70. ;
  71. ; Rev 1.2 22 Aug 1996 17:12:52 frido
  72. ; #ddblt - Added check for bDirectDrawInUse.
  73. ;
  74. ; Rev 1.1 17 Aug 1996 15:32:14 frido
  75. ; #1244 - Fixed brush rotation for off-screen bitmaps.
  76. ;
  77. ; Rev 1.0 14 Aug 1996 17:14:36 frido
  78. ; Initial revision.
  79. ;
  80. ; Rev 1.6 01 May 1996 11:06:20 bennyn
  81. ;
  82. ; Modified for NT 4.0
  83. ;
  84. ; Rev 1.5 10 Apr 1996 13:39:32 NOELV
  85. ; Frido release 27
  86. ;
  87. ; Rev 1.15 08 Apr 1996 16:43:06 frido
  88. ; Changed EngBitBlt into PuntBitBlt.
  89. ;
  90. ; Rev 1.14 29 Feb 1996 22:57:24 frido
  91. ; Added check for destination in ROP and updated grDRAWBLTDEF.
  92. ;
  93. ; Rev 1.13 28 Feb 1996 22:40:18 frido
  94. ; Added Optimize.h.
  95. ;
  96. ; Rev 1.12 27 Feb 1996 16:39:52 frido
  97. ; Added device bitmap store/restore.
  98. ;
  99. ; Rev 1.11 26 Feb 1996 23:39:12 frido
  100. ;
  101. ;
  102. ; Rev 1.10 24 Feb 1996 01:22:52 frido
  103. ; Added device bitmaps.
  104. ;
  105. ; Rev 1.9 17 Feb 1996 21:46:26 frido
  106. ; Revamped brushing algorithmn.
  107. ;
  108. ; Rev 1.8 13 Feb 1996 16:51:36 frido
  109. ; Changed the layout of the PDEV structure.
  110. ; Changed the layout of all brush caches.
  111. ; Changed the number of brush caches.
  112. ;
  113. ; Rev 1.7 10 Feb 1996 21:49:46 frido
  114. ; Split monochrome and colored translation cache.
  115. ;
  116. ; Rev 1.6 08 Feb 1996 00:09:58 frido
  117. ; Added i386\ to include files.
  118. ; Changed meaning of cache_slot index.
  119. ;
  120. ; Rev 1.5 05 Feb 1996 17:35:20 frido
  121. ; Added translation cache.
  122. ;
  123. ; Rev 1.4 03 Feb 1996 12:21:58 frido
  124. ; Added more delays and checks for FIFOs.
  125. ;
  126. ; Rev 1.3 31 Jan 1996 17:05:52 frido
  127. ; Added more delays in the complex clipping.
  128. ;
  129. ; Rev 1.2 31 Jan 1996 13:47:36 frido
  130. ; Jumped to EngBitBlt in case of error.
  131. ; Added comments.
  132. ; Added delay in complex clipping.
  133. ; Fixed bug in rectangle clipping.
  134. ;
  135. ; Rev 1.1 25 Jan 1996 22:45:56 frido
  136. ; Removed bug in complex clipping.
  137. ;
  138. ; Rev 1.0 25 Jan 1996 22:03:28 frido
  139. ; Initial release.
  140. ;
  141. ;===============================================================================
  142. .386
  143. .MODEL FLAT, STDCALL
  144. OPTION PROLOGUE:None
  145. OPTION EPILOGUE:None
  146. .NOLIST
  147. INCLUDE i386\Macros.inc
  148. INCLUDE i386\WinNT.inc
  149. INCLUDE Optimize.h
  150. INCLUDE i386\Laguna.inc
  151. INCLUDE SWAT.h ;SWAT optimizations
  152. COMMENT ! ;automatic include file dependencies for BUILD.EXE
  153. #include "i386\Macros.inc"
  154. #include "i386\WinNT.inc"
  155. #include "Optimize.h"
  156. #include "i386\Laguna.inc"
  157. #include "SWAT.h"
  158. !
  159. .LIST
  160. IF USE_ASM
  161. .DATA
  162. IF POINTER_SWITCH_ENABLED
  163. EXTERN pointer_switch: DWORD
  164. ENDIF
  165. EXTERN ropFlags:BYTE
  166. ROP_PAT = 1
  167. ROP_SRC = 2
  168. ROP_DEST = 4
  169. .CODE
  170. ;-------------------------------------------------------------------------------
  171. ; Function prototypes.
  172. ;-------------------------------------------------------------------------------
  173. i386BitBlt PROTO PROC,
  174. psoTrg :DWORD,
  175. psoSrc :DWORD,
  176. psoMask :DWORD,
  177. pco :DWORD,
  178. pxlo :DWORD,
  179. prclTrg :DWORD,
  180. pptlSrc :DWORD,
  181. pptlMask :DWORD,
  182. pbo :DWORD,
  183. pptlBrush :DWORD,
  184. rop4 :DWORD
  185. PuntBitBlt PROTO PROC,
  186. psoTrg :DWORD,
  187. psoSrc :DWORD,
  188. psoMask :DWORD,
  189. pco :DWORD,
  190. pxlo :DWORD,
  191. prclTrg :DWORD,
  192. pptlSrc :DWORD,
  193. pptlMask :DWORD,
  194. pbo :DWORD,
  195. pptlBrush :DWORD,
  196. rop4 :DWORD
  197. CacheBrush PROTO PROC,
  198. ppdev :DWORD,
  199. pRbrush :DWORD
  200. CacheDither PROTO PROC,
  201. ppdev :DWORD,
  202. pRbrush :DWORD
  203. CacheMono PROTO PROC,
  204. ppdev :DWORD,
  205. pRbrush :DWORD
  206. Cache4BPP PROTO PROC,
  207. ppdev :DWORD,
  208. pRbrush :DWORD
  209. bCreateScreenFromDib PROTO PROC,
  210. ppdev :DWORD,
  211. pdsurf :DWORD
  212. IF SWAT6
  213. StripePatBlt PROTO PROC,
  214. ppdev :DWORD,
  215. x :DWORD,
  216. y :DWORD,
  217. cWidth :DWORD,
  218. cHeight :DWORD
  219. ENDIF
  220. ifdef WINNT_VER40
  221. Sync_w_3d_proc PROTO PROC,
  222. ppdev :PTR PDEV
  223. endif
  224. ;-------------------------------------------------------------------------------
  225. ; Stack frame for DrvBitBlt.
  226. ;-------------------------------------------------------------------------------
  227. espPTR = 0
  228. frmPTR = 0
  229. psoTrg_ TEXTEQU <DWORD PTR [esp + 4 + espPTR]>
  230. psoSrc_ TEXTEQU <DWORD PTR [esp + 8 + espPTR]>
  231. psoMask_ TEXTEQU <DWORD PTR [esp + 12 + espPTR]>
  232. pco_ TEXTEQU <DWORD PTR [esp + 16 + espPTR]>
  233. pxlo_ TEXTEQU <DWORD PTR [esp + 20 + espPTR]>
  234. prclTrg_ TEXTEQU <DWORD PTR [esp + 24 + espPTR]>
  235. pptlSrc_ TEXTEQU <DWORD PTR [esp + 28 + espPTR]>
  236. pptlMask_ TEXTEQU <DWORD PTR [esp + 32 + espPTR]>
  237. pbo_ TEXTEQU <DWORD PTR [esp + 36 + espPTR]>
  238. pptlBrush_ TEXTEQU <DWORD PTR [esp + 40 + espPTR]>
  239. rop4_ TEXTEQU <DWORD PTR [esp + 44 + espPTR]>
  240. ;-------------------------------------------------------------------------------
  241. ;
  242. ; Function: DrvBitBlt
  243. ;
  244. ; Description: Bit blit entry point for DDI.
  245. ;
  246. ; On entry: See Windows NT 3.51 DDK.
  247. ;
  248. ; Returns: BOOL - TRUE if the function was successful, FALSE otherwise.
  249. ;
  250. ; Destroyed: EAX, ECX, EDX.
  251. ;
  252. ;-------------------------------------------------------------------------------
  253. DrvBitBlt PROC PUBLIC,
  254. psoTrg :DWORD,
  255. psoSrc :DWORD,
  256. psoMask :DWORD,
  257. pco :DWORD,
  258. pxlo :DWORD,
  259. prclTrg :DWORD,
  260. pptlSrc :DWORD,
  261. pptlMask :DWORD,
  262. pbo :DWORD,
  263. pptlBrush :DWORD,
  264. rop4 :DWORD
  265. IF NULL_BITBLT
  266. cmp pointer_switch, 0 ; Has the cursor been moved to (0,0)?
  267. je NotNull ; No - continue on
  268. mov eax, 1 ; Make GDI think we succeeded
  269. ret 44 ; Return and release stack frame
  270. NotNull:
  271. ENDIF
  272. mov ecx, [psoTrg_] ;get pointer to target device
  273. ASSUME ecx:PTR SURFOBJ
  274. mov eax, [rop4_] ;get ROP4 code
  275. push_ esi
  276. push_ ebp
  277. push_ ebx
  278. push_ edi
  279. test ecx, ecx ;no target?
  280. jz Error ;indeed... pass the blit to GDI
  281. mov edi, [ecx].dhpdev ;get pointer to physical device
  282. ASSUME edi:PTR PDEV
  283. ;NVH test for bad PDEV pointer.
  284. test edi,edi
  285. jz Error
  286. ifdef WINNT_VER40
  287. ;SYNC_W_3D macro equivalent
  288. cmp [edi].NumMCDContexts, 0 ; is MCD alive?
  289. jle Sync_end ; no
  290. push eax ; save
  291. push ecx ; save
  292. push edi ; input to Sync_w_3d_proc
  293. call Sync_w_3d_proc
  294. pop ecx ; restore
  295. pop eax ; restore
  296. Sync_end:
  297. endif
  298. ; Turn_PTAG_on
  299. test [edi].DriverData.DrvSemaphore, DRVSEM_YUV_ON
  300. jz no_yuv_screen
  301. push ecx
  302. mov ecx, [edi].pLgREGS_real ; points to the MMIO registers
  303. mov DWORD PTR [ecx + grDRAWBLTDEF], 20002000h
  304. mov [edi].shadowDRAWBLTDEF, 20002000h
  305. mov WORD PTR [ecx + grPTAG], 0FFFFH
  306. pop ecx
  307. no_yuv_screen:
  308. sub ah, al ;the ROP must be ternary
  309. jnz GoSlow ;not a ternary ROP... use the "C" code
  310. test edi, edi ;any physical device?
  311. jz GoSlow ;nope... use the "C" code
  312. test [ropFlags + eax], ROP_SRC
  313. ;does the ROP need a source?
  314. mov ebx, [edi].hsurfEng ;get handle of surface
  315. jnz GoSlow ;yes it does... use the "C" code
  316. cmp [ecx].hsurf, ebx ;blit to screen?
  317. mov ebx, [ecx].dhsurf ;get pointer to device bitmap
  318. ASSUME ebx:PTR DSURF
  319. je @F ;yes
  320. cmp [ecx].iType, STYPE_DEVBITMAP
  321. ;blit to device bitmap?
  322. jne GoSlow ;no... use the "C" code
  323. ; NVH - Save EBX cause we need it
  324. push ebx ; if we call bCreateScreenFromDib
  325. mov ebx, [ebx].pso ; get pointer to DIB
  326. ASSUME ebx:PTR SURFOBJ
  327. or ebx, ebx ; do we have a DIB? (Is the bitmap on the host?)
  328. pop ebx ; NVH - Restore EBX.
  329. ASSUME ebx:PTR DSURF
  330. jz @F ; No. Device bitmap is already in the frame buffer.
  331. ; Move the device bitmap back into the frame buffer.
  332. push_ eax ; Save the rop code.
  333. INVOKE bCreateScreenFromDib, ; copy the DIB to off-screen
  334. edi, ; PPDEV
  335. ebx ; PDSURF
  336. or eax, eax ; Test for success.
  337. pop_ eax ; Restore the ROP code.
  338. jz Simulate ; Failed to move device bitmap into frame buffer.
  339. save_ 1
  340. IF 1 ;#1244
  341. @@: mov esi, [psoTrg_] ;get target object
  342. ASSUME esi:PTR SURFOBJ
  343. xor ecx, ecx ;zero x/y offset
  344. cmp [esi].iType, STYPE_DEVBITMAP
  345. mov esi, [esi].dhsurf
  346. jne @F ;destination is screen
  347. ASSUME esi:PTR DSURF
  348. mov ecx, [esi].packedXY ;get x/y offset of device bitmap
  349. @@: mov [edi].ptlOffset.x, ecx ;store packed x/y coordinate in PDEV
  350. ELSE
  351. @@:
  352. ENDIF
  353. mov esi, [pbo_] ;get pointer to brush
  354. ASSUME esi:PTR BRUSHOBJ
  355. mov cl, [ropFlags + eax] ;get ROP flags
  356. lea ebx, [eax + 10000000h] ;EBX holds tne DRAWBLTDEF value
  357. test cl, ROP_DEST ;test for destination
  358. jz @F ;no destination, keep DRAWBLTDEF
  359. or ebx, 01000000h ;set destination as frame buffer
  360. @@: test cl, ROP_PAT
  361. mov ebp, [edi].pLgREGS_real ;EBP points to the MMIO registers
  362. jz DoBlit ;the ROP doesn't need a pattern
  363. mov eax, [esi].iSolidColor ;get the solid color from the brush
  364. cmp eax, -1 ;do we have a solid color?
  365. jne SolidColor ;yes...
  366. IF 0 ;#ddblt
  367. cmp [edi].bDirectDrawInUse, 0
  368. ;is DirectDraw in use
  369. jne Error ;
  370. ENDIF
  371. mov eax, [esi].pvRbrush ;get the pointer to the realized brush
  372. or eax, eax
  373. jnz @F ;the brush is already realized...
  374. INVOKE BRUSHOBJ_pvGetRbrush, ;realize the brush
  375. esi
  376. or eax, eax
  377. jz Error ;we couldn't realize the brush...
  378. @@: mov esi, eax ;ESI holds the pointer to the brush
  379. ASSUME esi:PTR RBRUSH
  380. mov eax, [esi].iType ;get the brush type
  381. mov edx, [esi].cache_slot ;get the cache index for this brush
  382. mov ecx, [esi].iUniq ;get the unique value from brush
  383. cmp eax, BRUSH_4BPP ;dispatch brush
  384. jb MonoBrush ;monochrome brush
  385. je XlateBrush ;4-bpp brush
  386. cmp eax, BRUSH_DITHER
  387. je DitherBrush ;dither brush
  388. ;-------------------------------------------------------------------------------
  389. ; Load the patterned brush.
  390. ;-------------------------------------------------------------------------------
  391. cmp [edi].Ctable[edx].brushID, esi
  392. ;is it still the same brush?
  393. je BrushIsCached ;yes
  394. INVOKE CacheBrush, ;cache the brush into off-screen memory
  395. edi,
  396. esi
  397. jmp BrushIsCached
  398. ;-------------------------------------------------------------------------------
  399. ; Load the dithered brush.
  400. ;-------------------------------------------------------------------------------
  401. DitherBrush:
  402. cmp [edi].Dtable[edx].ulColor, ecx
  403. ;does the color still match?
  404. je BrushIsCached ;yes...
  405. INVOKE CacheDither, ;cache the brush into off-screen memory
  406. edi,
  407. esi
  408. jmp BrushIsCached
  409. ;-------------------------------------------------------------------------------
  410. ; Load the 4-bpp brush.
  411. ;-------------------------------------------------------------------------------
  412. XlateBrush:
  413. cmp [edi].Xtable[edx].iUniq, ecx
  414. ;does the ID still match?
  415. je BrushIsCached ;yes...
  416. INVOKE Cache4BPP, ;cache the brush into off-screen memory
  417. edi,
  418. esi
  419. jmp BrushIsCached
  420. ;-------------------------------------------------------------------------------
  421. ; Load the monochrome brush.
  422. ;-------------------------------------------------------------------------------
  423. MonoBrush:
  424. cmp [edi].Mtable[edx].iUniq, ecx
  425. ;does the ID still match?
  426. je IsMono ;yes...
  427. INVOKE CacheMono, ;cache the brush into off-screen memory
  428. edi,
  429. esi
  430. IsMono:
  431. or ebx, 000D0000h ;monochrome pattern
  432. mov eax, [esi].ulForeColor ;copy brush fore- and background colors
  433. mov edx, [esi].ulBackColor
  434. cmp [edi].shadowFGCOLOR, eax
  435. je @F
  436. REQUIRE 2, edi
  437. mov [ebp + grOP_opFGCOLOR], eax
  438. mov [edi].shadowFGCOLOR, eax
  439. @@: cmp [edi].shadowBGCOLOR, edx
  440. je @F
  441. REQUIRE 2, edi
  442. mov [ebp + grOP_opBGCOLOR], edx
  443. mov [edi].shadowBGCOLOR, edx
  444. @@:
  445. BrushIsCached:
  446. mov ecx, [pptlBrush_] ;get pointer to brush origin
  447. ASSUME ecx:PTR POINTL
  448. or ebx, 00090000h ;assume colored pattern
  449. mov dl, BYTE PTR [ecx].x ;get the brush x origin
  450. mov dh, BYTE PTR [ecx].y ;get the brush y origin
  451. IF 1 ;#1244
  452. add dl, BYTE PTR [edi].ptlOffset.x[0]
  453. add dh, BYTE PTR [edi].ptlOffset.x[2]
  454. ENDIF
  455. dec dl ;convert brush origin -x & 7
  456. dec dh
  457. xor edx, -1
  458. mov eax, [esi].cache_xy ;get the off-screen y position of brush
  459. and edx, 0707h
  460. REQUIRE 3, edi
  461. mov [ebp + grOP2_opMRDRAM], eax
  462. mov [ebp + grPATOFF], dx ;store brush origin
  463. jmp DoBlit
  464. ;-------------------------------------------------------------------------------
  465. ; Load the solid color for the pattern blit.
  466. ;-------------------------------------------------------------------------------
  467. SolidColor:
  468. cmp [edi].iBytesPerPixel, 2 ;test the number of bytes per pixel
  469. ja XlateDone ;larger than 2 (24-bpp or 32-bpp)...
  470. je @F
  471. mov ah, al ;expand the 8-bpp into AX
  472. @@: mov ecx, eax ;expand the 16-bpp into EAX
  473. shl eax, 16
  474. or eax, ecx
  475. XlateDone:
  476. or ebx, 00070000h ;source is solid color
  477. cmp [edi].shadowBGCOLOR, eax
  478. je @F
  479. REQUIRE 2, edi
  480. mov [ebp + grOP_opBGCOLOR], eax;store the solid color in background
  481. mov [edi].shadowBGCOLOR, eax
  482. @@:
  483. ;-------------------------------------------------------------------------------
  484. ; Perform the blitting.
  485. ;-------------------------------------------------------------------------------
  486. DoBlit:
  487. ; Turn off the PTAG
  488. cmp BYTE PTR [rop4_], 5ah
  489. jnz no_yuv_in_the_world
  490. test [edi].DriverData.DrvSemaphore, DRVSEM_YUV_ON
  491. jz no_yuv_in_the_world
  492. ;; v-normmi ebp already set to MMIO address
  493. ;; push ecx
  494. ;; mov ecx, [edi].pLgREGS_real ; points to the MMIO registers
  495. REQUIRE 3, edi
  496. mov DWORD PTR [ebp + grDRAWBLTDEF], 20002000h
  497. mov [edi].shadowDRAWBLTDEF, 20002000h
  498. mov WORD PTR [ebp + grPTAG], 0 ;if an xor rubber band, turn off ptag mask
  499. ;; pop ecx
  500. no_yuv_in_the_world:
  501. IF 1 ;#1244
  502. mov ecx, [edi].ptlOffset.x ;get packed x/y offset
  503. ELSE
  504. mov edi, [psoTrg_] ;get target object
  505. ASSUME edi:PTR SURFOBJ
  506. xor ecx, ecx ;zero x/y offset
  507. cmp [edi].iType, STYPE_DEVBITMAP
  508. mov edi, [edi].dhsurf
  509. jne @F ;destination is screen
  510. ASSUME edi:PTR DSURF
  511. mov ecx, [edi].packedXY ;get x/y offset of device bitmap
  512. @@:
  513. ENDIF
  514. mov edx, edi ;store pointer to PDEV
  515. ASSUME edx:PTR PDEV
  516. mov edi, [prclTrg_] ;get pointer to destination rectangle
  517. ASSUME edi:PTR RECTL
  518. mov esi, [pco_] ;get pointer to clipping object
  519. ASSUME esi:PTR CLIPOBJ
  520. cmp [edx].shadowDRAWBLTDEF, ebx
  521. je @F
  522. REQUIRE 2, edx
  523. mov [ebp + grDRAWBLTDEF], ebx
  524. mov [edx].shadowDRAWBLTDEF, ebx
  525. @@: ;store DRAWBLTDEF register
  526. or esi, esi ;any clipping object?
  527. jz @F ;no...
  528. cmp [esi].iDComplexity, DC_TRIVIAL
  529. ;clipping required?
  530. jne TestClip ;yes...
  531. IF SWAT6
  532. @@: mov eax, [edi].left ;get coordinates
  533. mov ebx, [edi].top
  534. mov esi, [edi].right
  535. mov edi, [edi].bottom
  536. sub esi, eax ;build width/height
  537. sub edi, ebx
  538. mov ebp, ecx ;split x/y offset into ECX(x) EBP(y)
  539. and ecx, 0000FFFFh
  540. shr ebp, 16
  541. add eax, ecx ;add x/y offset
  542. add ebx, ebp
  543. INVOKE StripePatBlt, edx, eax, ebx, esi, edi
  544. ELSE
  545. @@: push_ edx ;push ppdev on stack
  546. mov ebx, [edi].top ;EBX = prclTrg->top
  547. mov edx, [edi].bottom ;EDX = prclTrg->bottom
  548. mov eax, [edi].left ;EAX = prclTrg->left
  549. sub edx, ebx ;EDX = bottom - top (height)
  550. shl ebx, 16 ;EBX = top << 16
  551. mov esi, [edi].right ;ESI = prclTrg->right
  552. shl edx, 16 ;EDX = height << 16
  553. sub esi, eax ;ESI = right - left (width)
  554. or ebx, eax ;EBX = (top << 16) | left
  555. or edx, esi ;EDX = (height << 16) | width
  556. add ebx, ecx ;add xyOffset
  557. pop_ edi ;restore ppdev from stack
  558. REQUIRE 5, edi
  559. mov [ebp + grOP0_opRDRAM], ebx
  560. ;do the blit
  561. mov [ebp + grBLTEXT_EX], edx
  562. ENDIF
  563. Done:
  564. pop edi
  565. pop ebx
  566. pop ebp
  567. pop esi
  568. mov eax, 1
  569. ret 44
  570. TestClip:
  571. cmp [esi].iDComplexity, DC_RECT
  572. ;complex clipping required?
  573. jne ComplexClip ;yes...
  574. ;-------------------------------------------------------------------------------
  575. ; We have a clipped rectangle to check with.
  576. ;-------------------------------------------------------------------------------
  577. push edx ;store pointer to PDEV on stack
  578. push ecx ;store xyOffset on stack
  579. mov eax, [edi].left ;EAX = prclTrg->left
  580. mov ebx, [edi].top ;EBX = prclTrg->top
  581. mov ecx, [edi].right ;ECX = prclTrg->right
  582. mov edx, [edi].bottom ;EDX = prclTrg->bottom
  583. cmp eax, [esi].rclBounds.left
  584. ;EAX = max(pco->rclBounds.left, left)
  585. jg @F
  586. mov eax, [esi].rclBounds.left
  587. @@: cmp ebx, [esi].rclBounds.top;EBX = max(pco->rclBounds.top, top)
  588. jg @F
  589. mov ebx, [esi].rclBounds.top
  590. @@: cmp ecx, [esi].rclBounds.right
  591. ;ECX = min(pco->rclBounds.right, right)
  592. jl @F
  593. mov ecx, [esi].rclBounds.right
  594. @@: cmp edx, [esi].rclBounds.bottom
  595. ;EDX = min(pco->rclBounds.bottom,
  596. jl @F ; bottom)
  597. mov edx, [esi].rclBounds.bottom
  598. @@: pop esi ;restore xyOffset from stack
  599. pop edi ;restore pointer to PDEV from stack
  600. sub ecx, eax ;ECX = right - left (width)
  601. jle Done
  602. sub edx, ebx ;EDX = bottom - top (height)
  603. jle Done
  604. IF SWAT6
  605. mov ebp, esi ;split x/y offset into ESI(x) EBP(y)
  606. and esi, 0000FFFFh
  607. shr ebp, 16
  608. add eax, esi ;add x/y offset
  609. add ebx, ebp
  610. INVOKE StripePatBlt, edi, eax, ebx, ecx, edx
  611. ELSE
  612. shl ebx, 16 ;EBX = top << 16
  613. shl edx, 16 ;EDX = height << 16
  614. or ebx, eax ;EBX = (top << 16) | left
  615. or edx, ecx ;EDX = (height << 16) | width
  616. add ebx, esi ;add xyOffset
  617. REQUIRE 5, edi
  618. mov [ebp + grOP0_opRDRAM], ebx
  619. ;do the blit
  620. mov [ebp + grBLTEXT_EX], edx
  621. ENDIF ; SWAT6
  622. pop edi
  623. pop ebx
  624. pop ebp
  625. pop esi
  626. mov eax, 1
  627. ret 44
  628. ;-------------------------------------------------------------------------------
  629. ; We have a complex clipping object to check with.
  630. ;-------------------------------------------------------------------------------
  631. ComplexClip:
  632. enter_ <8 + SIZEOF(ENUMRECTS8)>;create stack frame
  633. offset_ TEXTEQU <DWORD PTR [esp + 0 + frmPTR]>
  634. pdev_ TEXTEQU <DWORD PTR [esp + 4 + frmPTR]>
  635. enum_ TEXTEQU <ENUMRECTS8 PTR [esp + 8 + frmPTR]>
  636. mov [pdev_], edx ;store offset to PDEV structure
  637. mov [offset_], ecx ;store xyOffset
  638. INVOKE CLIPOBJ_cEnumStart, ;start enumeration
  639. esi,
  640. 0,
  641. CT_RECTANGLES,
  642. CD_ANY,
  643. 0
  644. if DRIVER_5465 AND HW_CLIPPING AND (NOT SWAT6)
  645. ;; Set up hardware clipping
  646. mov eax, [pdev_]
  647. REQUIRE 6, eax
  648. add ebx, CLIPEN
  649. cmp [eax].shadowDRAWBLTDEF, ebx
  650. jne @F
  651. mov [ebp + grDRAWBLTDEF], ebx; use clipping
  652. mov [eax].shadowDRAWBLTDEF, ebx
  653. @@:
  654. mov ebx, [edi].top ; ebx = prclTrg->top
  655. shl ebx, 16 ;
  656. add ebx, [edi].left ; prclTrg->left
  657. add ebx, [offset_] ; add xyOffset
  658. mov [ebp + grOP0_opRDRAM], ebx
  659. push eax
  660. mov eax, [edi].bottom
  661. shl eax, 16
  662. add eax, [edi].right
  663. add eax, [offset_] ; add xyOffset
  664. sub eax, ebx
  665. mov [ebp + grBLTEXT], eax
  666. pop eax
  667. endif
  668. MoreComplex:
  669. lea ebx, [enum_] ;get a batch of rectangles
  670. INVOKE CLIPOBJ_bEnum,
  671. esi,
  672. SIZEOF(ENUMRECTS8),
  673. ebx
  674. cmp [enum_]._c, 0 ;any rectangles at all?
  675. je SkipArray ;no
  676. push_ esi ;store loop registers
  677. push_ eax
  678. lea esi, [enum_].arcl ;load pointer to rectangles
  679. ASSUME esi:PTR RECTL
  680. ArrayLoop:
  681. if DRIVER_5465 AND HW_CLIPPING AND (NOT SWAT6)
  682. mov eax, [esi].left ;EAX = prcl->left
  683. mov ebx, [esi].top ;EBX = prcl->top
  684. mov ecx, [esi].right ;ECX = prcl->right
  685. mov edx, [esi].bottom ;EDX = prcl->bottom
  686. else
  687. mov eax, [edi].left ;EAX = prclTrg->left
  688. mov ebx, [edi].top ;EBX = prclTrg->top
  689. mov ecx, [edi].right ;ECX = prclTrg->right
  690. mov edx, [edi].bottom ;EDX = prclTrg->bottom
  691. cmp eax, [esi].left ;EAX = max(prcl->left, left)
  692. jg @F
  693. mov eax, [esi].left
  694. @@: cmp ebx, [esi].top ;EBX = max(prcl->top, top)
  695. jg @F
  696. mov ebx, [esi].top
  697. @@: cmp ecx, [esi].right ;ECX = min(prcl->right, right)
  698. jl @F
  699. mov ecx, [esi].right
  700. @@: cmp edx, [esi].bottom ;EDX = min(prcl->bottom, bottom)
  701. jl @F
  702. mov edx, [esi].bottom
  703. endif
  704. @@: sub ecx, eax ;ECX = right - left (width)
  705. jle SkipClip ;nothing to draw
  706. sub edx, ebx ;EDX = bottom - top (height)
  707. jle SkipClip ;nothing to draw
  708. IF SWAT6
  709. push_ edi
  710. mov ebp, [offset_] ;get x/y offset
  711. mov edi, ebp ;split x/y offset into EBP(x) EDI(y)
  712. and ebp, 000FFFFh
  713. shr edi, 16
  714. add eax, ebp ;add x/y offset
  715. add ebx, edi
  716. mov edi, [pdev_] ;get pointer to PDEV
  717. INVOKE StripePatBlt, edi, eax, ebx, ecx, edx
  718. pop_ edi
  719. ELSE
  720. shl ebx, 16 ;EBX = top << 16
  721. shl edx, 16 ;EDX = height << 16
  722. or ebx, eax ;EBX = (top << 16) | left
  723. or edx, ecx ;EDX = (height << 16) | width
  724. mov eax, [pdev_] ;get offset to PDEV structure
  725. add ebx, [offset_] ;add xyOffset
  726. REQUIRE 5, eax
  727. if DRIVER_5465 AND HW_CLIPPING
  728. mov [ebp + grCLIPULE], ebx
  729. add edx, ebx
  730. ;do the blit
  731. mov [ebp + grCLIPLOR_EX], edx
  732. else
  733. mov [ebp + grOP0_opRDRAM], ebx
  734. ;do the blit
  735. mov [ebp + grBLTEXT_EX], edx
  736. endif
  737. ENDIF ; SWAT6
  738. SkipClip:
  739. add esi, SIZEOF(RECTL) ;next clipping rectangle
  740. dec [enum_]._c
  741. jnz ArrayLoop
  742. pop_ eax ;restore loop registers
  743. pop_ esi
  744. ASSUME esi:PTR CLIPOBJ
  745. SkipArray:
  746. or eax, eax ;are there more rectangles?
  747. jnz MoreComplex ;yes
  748. leave_ <8 + SIZEOF(ENUMRECTS8)>;clean up stack frame
  749. pop edi
  750. pop ebx
  751. pop ebp
  752. pop esi
  753. mov eax, 1
  754. ret 44
  755. ;-------------------------------------------------------------------------------
  756. ; Pass the bit blit to the "C" code.
  757. ;-------------------------------------------------------------------------------
  758. GoSlow:
  759. pop edi
  760. pop ebx
  761. pop ebp
  762. pop esi
  763. jmp i386BitBlt
  764. ;-------------------------------------------------------------------------------
  765. ; Pass the bit blit to the engine since we can't handle it.
  766. ;-------------------------------------------------------------------------------
  767. Simulate:
  768. load_ 1
  769. mov ebx, [ebx].pso ; get pointer to DIB
  770. mov [psoTrg_], ebx ;store the new DIB surface
  771. ;-------------------------------------------------------------------------------
  772. ; Pass the bit blit to the engine since we can't handle it.
  773. ;-------------------------------------------------------------------------------
  774. Error:
  775. pop edi
  776. pop ebx
  777. pop ebp
  778. pop esi
  779. jmp PuntBitBlt
  780. DrvBitBlt ENDP
  781. ;*****************************************************************************
  782. ;------ YUVBLT ---------------------------------------------------------------
  783. ;*****************************************************************************
  784. ; pmBLTDEF contents
  785. BD_op2 equ 0001h ; start of OP2 field
  786. BD_op1 equ 0010h ; start of OP1 field
  787. BD_op0 equ 0100h ; start of OP0 field
  788. BD_same equ 0800h ; OP1/OP2 use same data if set
  789. BD_res equ 1000h ; start of RES field
  790. BD_ydir equ 8000h ; y direction bit
  791. ; field values for BD_opN, BD_res.
  792. ; example:
  793. ; WRITE2 pmBLTDEF,(BD_op1*is_host_mono)+(BD_op2*(is_vram+is_pattern))+(BD_res*is_vram)
  794. is_vram equ 1
  795. is_host equ 2 ; not for BD_op0
  796. ; for BD_opN
  797. is_sram equ 0
  798. ; for BD_op1/2
  799. is_sram_mono equ 4
  800. is_vram_mono equ 5
  801. is_host_mono equ 6
  802. is_solid equ 7
  803. is_pattern equ 8
  804. ; for BD_res
  805. is_sram0 equ 4
  806. is_sram1 equ 5
  807. is_sram2 equ 6
  808. is_sram12 equ 7
  809. is_mono equ 4 ; already part of is_XXXX_mono above
  810. push_1 MACRO vArg:REQ
  811. push vArg
  812. YUVespPTR = YUVespPTR + 4
  813. YUVfrmPTR = YUVfrmPTR + 4
  814. ENDM
  815. pop_1 MACRO vArg:REQ
  816. pop vArg
  817. YUVespPTR = YUVespPTR - 4
  818. YUVfrmPTR = YUVfrmPTR - 4
  819. ENDM
  820. enter_1 MACRO vArg:REQ
  821. sub esp, vArg
  822. YUVespPTR = YUVespPTR + vArg
  823. YUVfrmPTR = 0
  824. ENDM
  825. leave_1 MACRO vArg:REQ
  826. add esp, vArg
  827. YUVespPTR = YUVespPTR - vArg
  828. ENDM
  829. ;-------------------------------------------------------------------------------
  830. ; Stack frame for YUVBlt.
  831. ;-------------------------------------------------------------------------------
  832. YUVespPTR = 0
  833. YUVfrmPTR = 0
  834. YUVpsoTrg_ TEXTEQU <DWORD PTR [esp + 4 + YUVespPTR]>
  835. YUVpsoSrc_ TEXTEQU <DWORD PTR [esp + 8 + YUVespPTR]>
  836. YUVpco_ TEXTEQU <DWORD PTR [esp + 12 + YUVespPTR]>
  837. YUVpxlo_ TEXTEQU <DWORD PTR [esp + 16 + YUVespPTR]>
  838. YUVprclTrg_ TEXTEQU <DWORD PTR [esp + 20 + YUVespPTR]>
  839. YUVpptlSrc_ TEXTEQU <DWORD PTR [esp + 24 + YUVespPTR]>
  840. ;-------------------------------------------------------------------------------
  841. ;
  842. ; Function: YUVBlt
  843. ;
  844. ; Description: Check and perform the YUV BLT
  845. ;
  846. ; Returns: BOOL - TRUE if YUV BLT was successful, FALSE otherwise.
  847. ;
  848. ;-------------------------------------------------------------------------------
  849. YUVBlt PROC PUBLIC,
  850. YUVpsoTrg :DWORD,
  851. YUVpsoSrc :DWORD,
  852. YUVpco :DWORD,
  853. YUVpxlo :DWORD,
  854. YUVprclTrg :DWORD,
  855. YUVpptlSrc :DWORD
  856. ;-----------------------------------------------------------
  857. ; Get the PDEV associated with the destination.
  858. mov ecx, [YUVpsoTrg_] ;get pointer to target device
  859. ASSUME ecx:PTR SURFOBJ
  860. test ecx, ecx ;no source?
  861. jz Gen_blt
  862. mov ecx, [ecx].dhpdev ;get pointer to physical device
  863. test ecx, ecx
  864. jnz yuv_blt_str
  865. mov ecx, [YUVpsoSrc_] ;get pointer to source device
  866. test ecx, ecx ;no source?
  867. jz Gen_blt
  868. mov ecx, [ecx].dhpdev ;get pointer to physical device
  869. test ecx, ecx
  870. jz Gen_blt
  871. ;-----------------------------------------------------------
  872. ; Check the source is the frame buffer.
  873. ; (YUVpsoSrc != NULL) && // Is there a source?
  874. ; (psoSrc->hsurf == ppdev->hsurfEng) // Is it the screen?
  875. ;
  876. yuv_blt_str:
  877. ASSUME ecx:PTR PDEV
  878. mov edx, ecx
  879. ASSUME edx:PTR PDEV
  880. ; Turn PTAG on
  881. test [ecx].DriverData.DrvSemaphore, DRVSEM_YUV_ON
  882. jz yuv_blt_str_1
  883. push ecx
  884. mov ecx, [ecx].pLgREGS_real ; points to the MMIO registers
  885. ;; v-normmi: REQUIRE defaults to ebp for LgREGS, need to specify ecx explicitly
  886. ;; REQUIRE 3, edx
  887. REQUIRE 3, edx, ecx
  888. cmp [edx].shadowDRAWBLTDEF, 20002000h
  889. je @F
  890. mov DWORD PTR [ecx + grDRAWBLTDEF], 20002000h
  891. mov [edx].shadowDRAWBLTDEF, 20002000h
  892. @@: mov WORD PTR [ecx + grPTAG], 0FFFFH
  893. pop ecx
  894. yuv_blt_str_1:
  895. ; Determine whether is screen to screen BLT
  896. mov eax, [ecx].hsurfEng ;get handle of surface
  897. mov ecx, [YUVpsoSrc_] ;get pointer to source device
  898. ASSUME ecx:PTR SURFOBJ
  899. test ecx, ecx ;no source?
  900. jz Gen_blt
  901. cmp [ecx].hsurf, eax ;blit to screen?
  902. jne Gen_blt
  903. ;-----------------------------------------------------------
  904. ; Check the destination is the frame buffer.
  905. ; (psoDest != NULL) && // Is there a dest?
  906. ; (psoDest->hsurf == ppdev->hsurfEng) // Is it the screen?
  907. mov ecx, [YUVpsoTrg_] ;get pointer to target device
  908. ASSUME ecx:PTR SURFOBJ
  909. test ecx, ecx ;no source?
  910. jz Gen_blt
  911. cmp [ecx].hsurf, eax ;blit to screen?
  912. je DevBlt_s2s_YUV_Window
  913. Gen_blt:
  914. mov eax, 0
  915. ret 24
  916. ;------------------------------------------------------------------------
  917. ; DEVBLT_S2S_YUV_WINDOW
  918. ;
  919. ; A yuv-ly code block to perform a laguna mixed frame buffer window blt.
  920. ;
  921. ESPOFFSET equ 28
  922. DevBlt_s2s_YUV_Window:
  923. enter_1 <ESPOFFSET> ;create stack frame
  924. push_1 ebp
  925. mov ebp, esp
  926. push_1 ebx
  927. push_1 edi
  928. push_1 esi
  929. LocptrPDEV_ TEXTEQU <DWORD PTR [ebp + 4]>
  930. LocSrcxOrg_ TEXTEQU <WORD PTR [ebp + 8]>
  931. LocSrcyOrg_ TEXTEQU <WORD PTR [ebp + 10]>
  932. LocSrcxExt_ TEXTEQU <WORD PTR [ebp + 12]>
  933. LocSrcyExt_ TEXTEQU <WORD PTR [ebp + 14]>
  934. LocYUVLeft_ TEXTEQU <WORD PTR [ebp + 16]>
  935. LocYUVTop_ TEXTEQU <WORD PTR [ebp + 18]>
  936. LocYUVXExt_ TEXTEQU <WORD PTR [ebp + 20]>
  937. LocYUVYExt_ TEXTEQU <WORD PTR [ebp + 22]>
  938. LocDstxOrg_ TEXTEQU <WORD PTR [ebp + 24]>
  939. LocDstyOrg_ TEXTEQU <WORD PTR [ebp + 26]>
  940. ;Save the argument pointers into local variables
  941. mov edi, edx
  942. ASSUME edi:PTR PDEV
  943. mov [LocptrPDEV_], edi
  944. ;-----------------------------------------------------------
  945. ; Test SRC rectange included the YUV rectange
  946. mov ecx, [YUVpptlSrc_] ;get pointer to src POINTER struct
  947. ASSUME ecx:PTR POINTL
  948. mov edx, [ecx].x
  949. mov [LocSrcxOrg_], dx
  950. shl edx, 16
  951. mov eax, [ecx].y
  952. mov [LocSrcyOrg_], ax
  953. mov dx, ax
  954. push_1 edx ;save the src org
  955. mov ecx, [YUVprclTrg_] ;get pointer to dst RECTL struct
  956. ASSUME ecx:PTR RECTL
  957. mov eax, [ecx].bottom
  958. mov edx, [ecx].top
  959. mov [LocDstyOrg_], dx
  960. sub eax, edx
  961. mov [LocSrcyExt_], ax
  962. shl eax, 16
  963. mov ebx, eax
  964. mov eax, [ecx].right
  965. mov edx, [ecx].left
  966. mov [LocDstxOrg_], dx
  967. sub eax, edx
  968. mov [LocSrcxExt_], ax
  969. mov bx, ax
  970. push_1 ebx ;save the XY extend
  971. ;get coords for last known YUV rectangle
  972. mov edi, [LocptrPDEV_]
  973. ASSUME edi:PTR PDEV
  974. mov cx, [edi].DriverData.YUVLeft
  975. mov [LocYUVLeft_], cx
  976. shl ecx, 16
  977. mov cx, [edi].DriverData.YUVTop
  978. mov [LocYUVTop_], cx
  979. mov dx, [edi].DriverData.YUVYExt
  980. mov [LocYUVYExt_], dx
  981. shl edx, 16 ;get yuv extents, x low (for later...)
  982. mov dx, [edi].DriverData.YUVXExt
  983. mov [LocYUVXExt_], dx
  984. pop_1 ebx
  985. pop_1 eax
  986. ; At this point eax = SRC org, ebx = SRC extend
  987. ; ecx = YUV org, edx = YUV extend
  988. ;test for invalidated yuv rectangle...
  989. test edx, edx
  990. jz normalBLT ;all zero indicates invalid rectangle
  991. cmp ax, cx
  992. jge normalBLT ;checked top
  993. rol eax, 16
  994. rol ecx, 16
  995. cmp ax, cx
  996. jge normalBLT ;checked left, x values now low
  997. add eax, ebx ;now we have right/bottom sides,
  998. add ecx, edx ;with the x values low
  999. cmp ax, cx
  1000. jle normalBLT
  1001. rol eax, 16
  1002. rol ecx, 16
  1003. cmp ax, cx
  1004. jle normalBLT
  1005. ; Okay... it's time for the show. We have now established that:
  1006. ; 1 - It's an onscreen to onscreen blt.
  1007. ; 2 - The last YUV rectangle drawn by Direct Draw is completely inside
  1008. ; of the source rectangle.
  1009. ; 3 - The last YUV rectangle is valid.
  1010. ;
  1011. ; We're going to do seven blts:
  1012. ;
  1013. ; Five are shown here:
  1014. ;
  1015. ; --5--
  1016. ; | |
  1017. ; 4 3 1
  1018. ; | |
  1019. ; --2--
  1020. ;
  1021. ; Region 3 is the YUV area.
  1022. ;
  1023. ; The two extra blts are dummy ones around the YUV blt, to prevent
  1024. ; screen corruption on the last packets of the surrounding blts.
  1025. ;
  1026. ; There are four movement cases, depending on the movement direction.
  1027. ; Because the rectangle is broken into five blts, I'm going to
  1028. ; "lead with a corner."
  1029. ; Up and to the right would result in an order of: 5-1-dummy-3-dummy-4-2
  1030. ; Down and to the right would result in an order of: 2-1-dummy-3-dummy-4-5
  1031. ; Down and to the left would result in an order of: 2-4-dummy-3-dummy-1-5
  1032. ; Up and to the left would result in an order of: 5-4-dummy-3-dummy-1-2
  1033. ; make the drawbltdef...
  1034. mov edi, 00cch + \
  1035. ((BD_op0*is_vram+BD_op1*is_vram+BD_res*is_vram) shl 16)
  1036. ; Determine the case, then push the necessary jump offsets on the stack,
  1037. ; in reverse order...
  1038. push YUV_exit ;jump address for when we are done
  1039. mov ax, [LocSrcxOrg_] ;get coords for src rect
  1040. shl eax, 16
  1041. mov ax, [LocSrcyOrg_]
  1042. mov cx, [LocDstxOrg_] ;get coords for dst rect
  1043. shl ecx, 16
  1044. mov cx, [LocDstyOrg_]
  1045. mov esi, ecx
  1046. sub esi, eax ;get delta from src to dest, useful later.
  1047. cmp ax, cx
  1048. jle YUV_going_down
  1049. push YUV_blt_two ;going up
  1050. mov ebx, YUV_blt_five
  1051. jmp YUV_check_left_right
  1052. YUV_going_down:
  1053. push YUV_blt_five ;going down
  1054. mov ebx, YUV_blt_two
  1055. or edi, 80000000h ;turn on blt upside-down-ness
  1056. YUV_check_left_right: ;okay, we've handled up/down, how about left/right?
  1057. rol eax, 16
  1058. rol ecx, 16
  1059. cmp ax, cx
  1060. jl YUV_going_right
  1061. push YUV_blt_one ;going left
  1062. mov edx, YUV_blt_four
  1063. jmp YUV_finish_offsets
  1064. YUV_going_right:
  1065. push YUV_blt_four ;going right
  1066. mov edx, YUV_blt_one
  1067. YUV_finish_offsets:
  1068. push YUV_blt_three
  1069. push edx ;blt four or one, whichever isn't already on the stack
  1070. ;no need to add pdevice origins... it's onscreen, eh?
  1071. ;right now, level cases have the y_dir bit turned on. if it's a move-left, we need to turn
  1072. ;it off, so that we don't wind up in the striping code.
  1073. test edi, 80000000h
  1074. jz YUV_go_do_it
  1075. rol eax, 16
  1076. rol ecx, 16
  1077. cmp ax, cx
  1078. jnz YUV_go_do_it ;it's not a perfectly level move...
  1079. rol eax, 16
  1080. rol ecx, 16
  1081. cmp ax, cx
  1082. jl YUV_go_do_it ;if to the right, leave it on.
  1083. and edi, 7fffffffh ;level move to the left.
  1084. YUV_go_do_it:
  1085. jmp ebx ;blt two or five, let's rock and roll!
  1086. YUV_blt_one:
  1087. ;src x prime: yuv left + yuv xext
  1088. ;src y prime: yuv top
  1089. ;x ext prime: (src x + xext) - (yuv left + yuv xext)
  1090. ;y ext prime: yuv yext
  1091. mov ax, [LocYUVLeft_]
  1092. add ax, [LocYUVXExt_]
  1093. shl eax, 16
  1094. mov ax, [LocYUVTop_] ;source point, y low
  1095. mov ecx, eax
  1096. add ecx, esi ;dest point, y low
  1097. mov dx, [LocYUVYExt_]
  1098. shl edx, 16
  1099. mov dx, [LocSrcxOrg_]
  1100. add dx, [LocSrcxExt_] ;(src x + xext)
  1101. mov bx, [LocYUVLeft_]
  1102. add bx, [LocYUVXExt_] ;(yuv left + yuv xext)
  1103. sub dx, bx ;x ext prime
  1104. jz yuv_one_done ;no right rgb rect, off screen edge
  1105. test edi, 80000000h ;are we in upside down mode?
  1106. jz @f
  1107. mov ebx, edx
  1108. rol ebx, 16 ;get y extent
  1109. dec bx
  1110. add ax, bx
  1111. add cx, bx ;bump srcy prime and desty prime by yext-1
  1112. @@:
  1113. cmp ax, cx
  1114. jnz @f
  1115. test edi, 80000000h
  1116. jnz YUV_i_really_hate_level_moves_to_the_right
  1117. @@:
  1118. rol eax, 16
  1119. rol ecx, 16
  1120. push esi
  1121. push ebp
  1122. mov esi, [LocptrPDEV_]
  1123. ASSUME esi:PTR PDEV
  1124. mov ebp, [esi].pLgREGS_real ; points to the MMIO registers
  1125. REQUIRE 9, esi
  1126. cmp [esi].shadowDRAWBLTDEF, edi
  1127. je @F
  1128. mov DWORD PTR [ebp + grDRAWBLTDEF], edi
  1129. mov [esi].shadowDRAWBLTDEF, edi
  1130. @@: mov DWORD PTR [ebp + grOP0_opRDRAM], ecx
  1131. mov DWORD PTR [ebp + grOP1_opRDRAM], eax
  1132. mov DWORD PTR [ebp + grBLTEXT_EX], edx
  1133. pop ebp
  1134. pop esi
  1135. yuv_one_done:
  1136. pop eax
  1137. jmp eax ;boing!
  1138. YUV_blt_two:
  1139. ;src x prime: known
  1140. ;src y prime: yuv top + yuv yext
  1141. ;x ext prime: known
  1142. ;y ext prime: (src y + yext) - (yuv top + yuv yext)
  1143. mov ax, [LocSrcxOrg_]
  1144. shl eax, 16
  1145. mov ax, [LocYUVTop_]
  1146. add ax, [LocYUVYExt_] ;source point, y low
  1147. mov ecx, eax
  1148. add ecx, esi ;dest point, y low
  1149. mov dx, [LocSrcyOrg_]
  1150. add dx, [LocSrcyExt_] ;(src y + yext)
  1151. mov bx, [LocYUVTop_]
  1152. add bx, [LocYUVYExt_] ;(yuv top + yuv yext)
  1153. sub dx, bx ;y ext prime
  1154. jz yuv_two_done ;no bottom rgb rect, off screen
  1155. shl edx, 16
  1156. mov dx, [LocSrcxExt_] ;extents, x low
  1157. test edi, 80000000h ;are we in upside down mode?
  1158. jz @f
  1159. mov ebx, edx
  1160. rol ebx, 16 ;get y extent
  1161. dec bx
  1162. add ax, bx
  1163. add cx, bx ;bump srcy prime and desty prime by yext-1
  1164. @@:
  1165. cmp ax, cx
  1166. jnz @f
  1167. test edi, 80000000h
  1168. jnz YUV_i_really_hate_level_moves_to_the_right
  1169. @@:
  1170. rol eax, 16
  1171. rol ecx, 16
  1172. push esi
  1173. push ebp
  1174. mov esi, [LocptrPDEV_]
  1175. ASSUME esi:PTR PDEV
  1176. mov ebp, [esi].pLgREGS_real ; points to the MMIO registers
  1177. REQUIRE 9, esi
  1178. cmp [esi].shadowDRAWBLTDEF, edi
  1179. je @F
  1180. mov DWORD PTR [ebp + grDRAWBLTDEF], edi
  1181. mov [esi].shadowDRAWBLTDEF, edi
  1182. @@: mov DWORD PTR [ebp + grOP0_opRDRAM], ecx
  1183. mov DWORD PTR [ebp + grOP1_opRDRAM], eax
  1184. mov DWORD PTR [ebp + grBLTEXT_EX], edx
  1185. pop ebp
  1186. pop esi
  1187. yuv_two_done:
  1188. pop eax
  1189. jmp eax ;boing!
  1190. YUV_blt_three: ;the YUV blt itself...
  1191. ;just use the yuv coords
  1192. ;YUV_blt_dummy_off
  1193. mov ebx, 400000CCh ;bogus move from rdram to sram
  1194. push esi
  1195. push ebp
  1196. mov esi, [LocptrPDEV_]
  1197. ASSUME esi:PTR PDEV
  1198. mov ebp, [esi].pLgREGS_real ;points to the MMIO registers
  1199. REQUIRE 5, esi
  1200. cmp [esi].shadowDRAWBLTDEF, edi
  1201. je @F
  1202. mov DWORD PTR [ebp + grDRAWBLTDEF], edi
  1203. mov [esi].shadowDRAWBLTDEF, edi
  1204. @@: mov DWORD PTR [ebp + grBLTEXT_EX], 00010001h
  1205. pop ebp
  1206. pop esi
  1207. ;------
  1208. mov ax, [LocYUVLeft_]
  1209. shl eax, 16
  1210. mov ax, [LocYUVTop_] ;y low
  1211. mov ecx, eax
  1212. add ecx, esi ;dest, y low
  1213. mov dx, [LocYUVYExt_]
  1214. shl edx, 16
  1215. mov dx, [LocYUVXExt_] ;extents, x lot
  1216. test edi, 80000000h ;are we in upside down mode?
  1217. jz @f
  1218. mov ebx, edx
  1219. rol ebx, 16 ;get y extent
  1220. dec bx
  1221. add ax, bx
  1222. add cx, bx ;bump srcy prime and desty prime by yext-1
  1223. @@:
  1224. rol eax, 16
  1225. rol ecx, 16
  1226. mov ebx, edi
  1227. or ebx, 0400h ;do that funky 9th bit thing.
  1228. push esi
  1229. push ebp
  1230. mov esi, [LocptrPDEV_]
  1231. ASSUME esi:PTR PDEV
  1232. mov ebp, [esi].pLgREGS_real ;points to the MMIO registers
  1233. REQUIRE 9, esi
  1234. cmp [esi].shadowDRAWBLTDEF, ebx
  1235. je @F
  1236. mov DWORD PTR [ebp + grDRAWBLTDEF], ebx
  1237. mov [esi].shadowDRAWBLTDEF, ebx
  1238. @@: mov DWORD PTR [ebp + grOP0_opRDRAM], ecx
  1239. mov DWORD PTR [ebp + grOP1_opRDRAM], eax
  1240. mov DWORD PTR [ebp + grBLTEXT_EX], edx
  1241. pop ebp
  1242. pop esi
  1243. ;YUV_blt_dummy_on
  1244. mov ebx, 400004CCh ;bogus move from rdram to sram
  1245. push esi
  1246. push ebp
  1247. mov esi, [LocptrPDEV_]
  1248. ASSUME esi:PTR PDEV
  1249. mov ebp, [esi].pLgREGS_real ;points to the MMIO registers
  1250. REQUIRE 5, esi
  1251. cmp [esi].shadowDRAWBLTDEF, edi
  1252. je @F
  1253. mov DWORD PTR [ebp + grDRAWBLTDEF], edi
  1254. mov [esi].shadowDRAWBLTDEF, edi
  1255. @@: mov DWORD PTR [ebp + grBLTEXT_EX], 00010001h
  1256. pop ebp
  1257. pop esi
  1258. ;------
  1259. pop eax
  1260. jmp eax ;boing!
  1261. YUV_blt_four:
  1262. ;src x prime: known
  1263. ;src y prime: yuv top
  1264. ;x ext prime: yuv left - src x
  1265. ;y ext prime: yuv yext
  1266. mov ax, [LocSrcxOrg_]
  1267. shl eax, 16
  1268. mov ax, [LocYUVTop_] ;source point, y low
  1269. mov ecx, eax
  1270. add ecx, esi ;dest point, y low
  1271. mov dx, [LocYUVYExt_]
  1272. shl edx, 16
  1273. mov dx, [LocYUVLeft_]
  1274. sub dx, [LocSrcxOrg_] ;extents, x low
  1275. jz yuv_four_done ;no left rgb rect, off screen edge
  1276. test edi, 80000000h ;are we in upside down mode?
  1277. jz @f
  1278. mov ebx, edx
  1279. rol ebx, 16 ;get y extent
  1280. dec bx
  1281. add ax, bx
  1282. add cx, bx ;bump srcy prime and desty prime by yext-1
  1283. @@:
  1284. cmp ax, cx
  1285. jnz @f
  1286. test edi, 80000000h
  1287. jnz YUV_i_really_hate_level_moves_to_the_right
  1288. @@:
  1289. rol eax, 16
  1290. rol ecx, 16
  1291. push esi
  1292. push ebp
  1293. mov esi, [LocptrPDEV_]
  1294. ASSUME esi:PTR PDEV
  1295. mov ebp, [esi].pLgREGS_real ;points to the MMIO registers
  1296. REQUIRE 9, esi
  1297. cmp [esi].shadowDRAWBLTDEF, edi
  1298. je @F
  1299. mov DWORD PTR [ebp + grDRAWBLTDEF], edi
  1300. mov [esi].shadowDRAWBLTDEF, edi
  1301. @@: mov DWORD PTR [ebp + grOP0_opRDRAM], ecx
  1302. mov DWORD PTR [ebp + grOP1_opRDRAM], eax
  1303. mov DWORD PTR [ebp + grBLTEXT_EX], edx
  1304. pop ebp
  1305. pop esi
  1306. yuv_four_done:
  1307. pop eax
  1308. jmp eax ;boing!
  1309. YUV_blt_five:
  1310. ;src xy prime: known
  1311. ;x ext prime : known
  1312. ;y ext prime : yuv top - src top
  1313. mov ax, [LocSrcxOrg_] ;;source point, y low
  1314. shl eax, 16
  1315. mov ax, [LocSrcyOrg_]
  1316. mov ecx, eax
  1317. add ecx, esi ;dest point, y low
  1318. mov dx, [LocYUVTop_]
  1319. sub dx, word ptr [LocSrcyOrg_]
  1320. shl edx, 16
  1321. mov dx, [LocSrcxExt_] ;x low
  1322. test edi, 80000000h ;are we in upside down mode?
  1323. jz @f
  1324. mov ebx, edx
  1325. rol ebx, 16 ;get y extent
  1326. dec bx
  1327. add ax, bx
  1328. add cx, bx ;bump srcy prime and desty prime by yext-1
  1329. @@:
  1330. cmp ax, cx
  1331. jnz @f
  1332. test edi, 80000000h
  1333. jnz YUV_i_really_hate_level_moves_to_the_right
  1334. @@:
  1335. rol eax, 16
  1336. rol ecx, 16
  1337. push esi
  1338. push ebp
  1339. mov esi, [LocptrPDEV_]
  1340. ASSUME esi:PTR PDEV
  1341. mov ebp, [esi].pLgREGS_real ;points to the MMIO registers
  1342. REQUIRE 9, esi
  1343. cmp [esi].shadowDRAWBLTDEF, edi
  1344. je @F
  1345. mov DWORD PTR [ebp + grDRAWBLTDEF], edi
  1346. mov [esi].shadowDRAWBLTDEF, edi
  1347. @@: mov DWORD PTR [ebp + grOP0_opRDRAM], ecx
  1348. mov DWORD PTR [ebp + grOP1_opRDRAM], eax
  1349. mov DWORD PTR [ebp + grBLTEXT_EX], edx
  1350. pop ebp
  1351. pop esi
  1352. pop eax
  1353. jmp eax ;boing!
  1354. YUV_i_really_hate_level_moves_to_the_right:
  1355. push esi
  1356. push ebp
  1357. mov esi, [LocptrPDEV_]
  1358. ASSUME esi:PTR PDEV
  1359. mov ebp, [esi].pLgREGS_real ;points to the MMIO registers
  1360. cmp [esi].shadowDRAWBLTDEF, edi
  1361. je @F
  1362. REQUIRE 2, esi
  1363. mov DWORD PTR [ebp + grDRAWBLTDEF], edi
  1364. mov [esi].shadowDRAWBLTDEF, edi
  1365. @@: pop ebp
  1366. pop esi
  1367. ; now get ready for inner loop. shift x-coordinates into place
  1368. mov ebx, ecx
  1369. rol ebx, 16 ;dest, x low
  1370. mov ecx, eax
  1371. rol ecx, 16 ;src, x low
  1372. ; translate the x coordinates
  1373. add bx, dx
  1374. add cx, dx
  1375. mov eax, edx
  1376. ; Because in Win95 LG_SRAM_PIXELS has difference values depends on
  1377. ; the pixel depth.
  1378. ; LG_SRAM_PIXELS: 32bpp 30
  1379. ; 24bpp 40
  1380. ; 16bpp 60
  1381. ; 8bpp 120
  1382. ;
  1383. ; The following code is the equivalent to
  1384. ; mov ax, LG_SRAM_PIXELS ; make it wide as possible
  1385. push esi
  1386. mov esi, [LocptrPDEV_]
  1387. ASSUME esi:PTR PDEV
  1388. mov esi, [esi].iBytesPerPixel
  1389. mov ax, 30
  1390. cmp esi, 4
  1391. je got_LG_SRAM_PIXELS
  1392. mov ax, 40
  1393. cmp esi, 3
  1394. je got_LG_SRAM_PIXELS
  1395. mov ax, 60
  1396. cmp esi, 2
  1397. je got_LG_SRAM_PIXELS
  1398. mov ax, 120
  1399. got_LG_SRAM_PIXELS:
  1400. pop esi
  1401. ; mov ax, LG_SRAM_PIXELS ; make it wide as possible
  1402. align 2
  1403. YUV_STRIPE_loop:
  1404. cmp ax, dx ; wider than blit?
  1405. jle @f ; no, use the actual width
  1406. mov ax, dx ; load remaining width
  1407. @@:
  1408. sub cx, ax ; offset srcX by width
  1409. sub bx, ax ; offset dstX by width
  1410. push esi
  1411. push ebp
  1412. mov esi, [LocptrPDEV_]
  1413. ASSUME esi:PTR PDEV
  1414. mov ebp, [esi].pLgREGS_real ;points to the MMIO registers
  1415. REQUIRE 7, esi
  1416. mov DWORD PTR [ebp + grOP0_opRDRAM], ebx
  1417. mov DWORD PTR [ebp + grOP1_opRDRAM], ecx
  1418. mov DWORD PTR [ebp + grBLTEXT_EX], eax
  1419. pop ebp
  1420. pop esi
  1421. sub dx, ax ; update remaining width count
  1422. jnz YUV_STRIPE_loop ; any pixels left?
  1423. pop eax
  1424. jmp eax ; boing!
  1425. YUV_exit:
  1426. ; Good has triumphed over evil... the mixed mode window has moved without flickering.
  1427. ; We need to update the YUV rectangle location. It just moved, right?
  1428. mov ax, [LocYUVLeft_]
  1429. shl eax, 16
  1430. mov ax, [LocYUVTop_] ;source, y low
  1431. add eax, esi ;dest, y low
  1432. mov edi, [LocptrPDEV_]
  1433. mov [edi].DriverData.YUVTop, ax
  1434. rol eax, 16
  1435. mov [edi].DriverData.YUVLeft, ax ;all better.
  1436. mov eax, 1 ; indicate it is YUV exit
  1437. jmp YUV_ret
  1438. normalBLT:
  1439. ; But before we go... invalidate the yuv rect!
  1440. mov edi, [LocptrPDEV_]
  1441. mov [edi].DriverData.YUVXExt, word ptr 0
  1442. mov [edi].DriverData.YUVYExt, word ptr 0
  1443. mov eax, 0 ; indicate it is normalBLT
  1444. YUV_ret:
  1445. pop_1 esi
  1446. pop_1 edi
  1447. pop_1 ebx
  1448. pop_1 ebp
  1449. leave_1 <ESPOFFSET> ;clean up stack frame
  1450. ret 24 ;we're done. it's time to go home.
  1451. YUVBlt ENDP
  1452. ENDIF ; USE_ASM
  1453. END