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.

1509 lines
50 KiB

  1. ;---------------------------Module-Header------------------------------;
  2. ; Module Name: scroll.asm
  3. ;
  4. ; Copyright (c) 1992-1993 Microsoft Corporation
  5. ;-----------------------------------------------------------------------;
  6. ;-----------------------------------------------------------------------;
  7. ; VOID vPlanarCopyBits(ppdev, prclDest, pptlSrc);
  8. ;
  9. ; Input:
  10. ;
  11. ; ppdev - surface on which to copy
  12. ; prcldest - pointer to destination rectangle
  13. ; pptlsrc - pointer to source upper left corner
  14. ;
  15. ; Performs accelerated SRCCOPY screen-to-screen blts.
  16. ;
  17. ;-----------------------------------------------------------------------;
  18. ;
  19. ; NOTE: This handles only quad-pixel aligned blits!
  20. ;
  21. ; NOTE: Assumes all rectangles have positive heights and widths. Will
  22. ; not work properly if this is not the case.
  23. ;
  24. ;-----------------------------------------------------------------------;
  25. ;-----------------------------------------------------------------------;
  26. ; Set LOOP_UNROLL_SHIFT to the log2 of the number of times you want loops in
  27. ; this module unrolled. For example, LOOP_UNROLL_SHIFT of 3 yields 2**3 = 8
  28. ; times unrolling. This is the only thing you need to change to control
  29. ; unrolling.
  30. LOOP_UNROLL_SHIFT equ 1
  31. ;-----------------------------------------------------------------------;
  32. .386
  33. .model small,c
  34. assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
  35. assume fs:nothing,gs:nothing
  36. .xlist
  37. include stdcall.inc ;calling convention cmacros
  38. include i386\strucs.inc
  39. include i386\driver.inc
  40. include i386\unroll.inc
  41. include i386\egavga.inc
  42. .list
  43. ;-----------------------------------------------------------------------;
  44. .code
  45. EXTRNP bPuntScreenToScreenCopyBits,20
  46. .data
  47. ; Bits for block copier tables:
  48. BLOCK_RIGHT_TO_LEFT equ 4
  49. BLOCK_LEFT_EDGE equ 2
  50. BLOCK_RIGHT_EDGE equ 1
  51. ;-----------------------------------------------------------------------;
  52. ; Table of block copiers for various horizontal directions, with the
  53. ; look-up index a 3-bit field as follows:
  54. ;
  55. ; Bit 2 (BLOCK_RIGHT_TO_LEFT) = 1 if right-to-left copy
  56. ; Bit 1 (BLOCK_LEFT_EDGE) = 1 if left edge must be copied
  57. ; Bit 0 (BLOCK_RIGHT_EDGE) = 1 if right edge must be copied
  58. align 4
  59. MasterBlockTable label dword
  60. dd copy_just_middle_block
  61. dd Block_WR
  62. dd Block_LW
  63. dd Block_LWR
  64. dd copy_just_middle_block
  65. dd Block_RW
  66. dd Block_WL
  67. dd Block_RWL
  68. align 4
  69. TopToBottomLoopTable label dword
  70. dd 0 ;Not used - unbanked case
  71. dd top_to_bottom_1RW
  72. dd top_to_bottom_2RW
  73. dd top_to_bottom_2RW
  74. align 4
  75. BottomToTopLoopTable label dword
  76. dd 0 ;Not used - unbanked case
  77. dd bottom_to_top_1RW
  78. dd bottom_to_top_2RW
  79. dd bottom_to_top_2RW
  80. align 4
  81. SetUpForCopyDirection label dword
  82. dd left_to_right_top_to_bottom ;CD_RIGHTDOWN
  83. dd right_to_left_top_to_bottom ;CD_LEFTDOWN
  84. dd left_to_right_bottom_to_top ;CD_RIGHTUP
  85. dd right_to_left_bottom_to_top ;CD_LEFTUP
  86. LeftMaskTable label dword
  87. dd 01111b
  88. dd 01100b
  89. RightMaskTable label dword
  90. dd 00000b
  91. dd 00011b
  92. ;-----------------------------------------------------------------------;
  93. .code
  94. Block_WR:
  95. push offset copy_right_block
  96. jmp copy_middle_block
  97. Block_LW:
  98. push offset copy_middle_block
  99. jmp copy_left_block
  100. Block_LWR:
  101. push offset copy_right_block
  102. push offset copy_middle_block
  103. jmp copy_left_block
  104. Block_RW:
  105. push offset copy_middle_block
  106. jmp copy_right_block
  107. Block_WL:
  108. push offset copy_left_block
  109. jmp copy_middle_block
  110. Block_RWL:
  111. push offset copy_left_block
  112. push offset copy_middle_block
  113. jmp copy_right_block
  114. ;-----------------------------------------------------------------------;
  115. cProc vPlanarCopyBits,12,< \
  116. uses esi edi ebx, \
  117. ppdev: ptr PDEV, \
  118. prclDest: ptr RECTL, \
  119. pptlSrc: ptr POINTL >
  120. ; Variables used in block copiers:
  121. local pfnCopyBlocks: ptr ;pointer to block copy routines
  122. local ulMiddleSrc: dword ;bitmap offset to 1st source
  123. local ulMiddleDest: dword ;bitmap offset to 1st dest
  124. local lMiddleDelta: dword ;delta from end of middle scan to next
  125. local ulBlockHeight: dword ;number of scans to be copied in block
  126. local cjMiddle: dword ;number of bytes to be copied on scan
  127. local ulLeftSrc: dword ;bitmap offset to left source byte edge
  128. local ulLeftDest: dword ;bitmap offset to left dest byte edge
  129. local ulRightSrc: dword ;bitmap offset to right source byte edge
  130. local ulRightDest: dword ;bitmap offset to right dest byte edge
  131. local lDelta: dword ;delta between scans
  132. local ulLeftMask: dword ;byte mask for left-edge copies
  133. local ulRightMask: dword ;byte mask for right-edge copies
  134. local rclDest[size RECTL]: byte ;left and right values always valid
  135. local ptlSrc[size POINTL]: byte ;x value always valid
  136. local ulCurrentSrcScan: dword ;real current source scan
  137. local ulCurrentDestScan: dword ;real current destination scan
  138. local ulLastDestScan: dword ;last destination scan
  139. ; Set the bit mask to disable all bits, so we can copy through the latches:
  140. mov edx,VGA_BASE + GRAF_ADDR
  141. mov eax,(0 shl 8) + GRAF_BIT_MASK
  142. out dx,ax
  143. ; Figure out which direction to do the copies:
  144. mov esi,pptlSrc
  145. mov edi,prclDest
  146. mov eax,[esi].ptl_y
  147. cmp eax,[edi].yTop
  148. jl planar_bottom_to_top
  149. mov eax,[esi].ptl_x
  150. cmp eax,[edi].xLeft
  151. jge short left_to_right_top_to_bottom ; CD_RIGHTDOWN
  152. jmp right_to_left_top_to_bottom ; CD_LEFTDOWN
  153. planar_bottom_to_top:
  154. mov eax,[esi].ptl_x
  155. cmp eax,[edi].xLeft
  156. jge left_to_right_bottom_to_top ; CD_RIGHTUP
  157. jmp right_to_left_bottom_to_top ; CD_LEFTUP
  158. all_done:
  159. ; Enable bit mask for all bits:
  160. mov edx,VGA_BASE + GRAF_ADDR
  161. mov eax,(0ffh shl 8) + GRAF_BIT_MASK
  162. out dx,ax
  163. ; Enable writes to all planes and reset direction flag:
  164. mov edx,VGA_BASE + SEQ_DATA
  165. mov al,MM_ALL
  166. out dx,al
  167. cld
  168. cRet vPlanarCopyBits
  169. ;=======================================================================;
  170. ;==================== Direction Dependent Setup ========================;
  171. ;=======================================================================;
  172. ;-----------------------------------------------------------------------;
  173. ; Set-up code for left-to-right, top-to-bottom copies.
  174. ;
  175. ; Input:
  176. ; esi - pptlSrc
  177. ; edi - prclDest
  178. ;-----------------------------------------------------------------------;
  179. public left_to_right_top_to_bottom
  180. left_to_right_top_to_bottom::
  181. ; Need to set-up: ulMiddleSrc, ulMiddleDest, lMiddleDelta, cjMiddle
  182. ; ulLeftSrc, ulLeftDest, ulLeftMask
  183. ; lDelta
  184. ; ulRightSrc, ulRightDest, ulRightMask
  185. ; ulCurrentDestScan, ulLastDestScan
  186. ; pfnCopyBlocks
  187. ; ptlSrc.x, rclDest.left, rclDest.right
  188. ; lDelta = ppdev->lPlanarScan
  189. ; ulCurrentSrcScan = pptl->y
  190. ; ulLeftSrc = pptl->y * lDelta + (pptl->x >> 1)
  191. ; ulCurrentDestScan = prclDest->top
  192. ; ulLeftDest = prclDest->top * lDelta + (prclDest->left >> 1)
  193. ;
  194. ; ulMiddleSrc = ulLeftSrc
  195. ; ulMiddleDest = ulLeftDest
  196. ;
  197. ; cjMiddle = (prclDest->right >> 1) - (prclDest->left >> 1)
  198. ; if (prclDest->left & 3)
  199. ; ulLeftMask = LeftMaskTable[prclDest->left & 1]
  200. ; fl |= BLOCK_LEFT_EDGE
  201. ; ulMiddleSrc++
  202. ; ulMiddleDest++
  203. ; cjMiddle--
  204. ;
  205. ; lMiddleDelta = lDelta - cjMiddle
  206. ;
  207. ; if (prclDest->right & 1)
  208. ; ulRightMask = RightMaskTable[prclDest->right & 1]
  209. ; fl |= BLOCK_RIGHT_EDGE
  210. ; ulRightSrc = ulMiddleSrc + cjMiddle
  211. ; ulRightDest = ulMiddleDest + cjMiddle
  212. mov edx,ppdev
  213. mov eax,[edi].yBottom
  214. mov edx,[edx].pdev_lPlanarNextScan ;edx = lDelta
  215. mov ulLastDestScan,eax ;ulLastDestScan = prclDest->bottom
  216. mov ecx,[esi].ptl_y
  217. mov eax,edx
  218. mov ulCurrentSrcScan,ecx ;ulCurrentSrcScan = pptlSrc->y
  219. imul eax,ecx
  220. mov ecx,[esi].ptl_x
  221. mov ptlSrc.ptl_x,ecx ;ptlSrc.x = pptlSrc->x
  222. shr ecx,1
  223. add eax,ecx ;eax = ulLeftSrc = pptlSrc->y *
  224. ; lDelta + (pptlSrc->x >> 1)
  225. xor esi,esi ;initialize flags
  226. mov ecx,[edi].yTop
  227. mov ebx,edx
  228. mov ulCurrentDestScan,ecx ;ulCurrentDestScan = prclDest->top
  229. imul ebx,ecx
  230. mov ecx,[edi].xLeft
  231. mov rclDest.xLeft,ecx ;rclDest.left = prclDest->left
  232. shr ecx,1
  233. add ebx,ecx ;ebx = ulLeftDest = prclDest->top *
  234. ; lDelta + (prclDest->left >> 1)
  235. mov edi,[edi].xRight
  236. mov rclDest.xRight,edi
  237. shr edi,1
  238. sub edi,ecx ;cjMiddle = (prclDest->right >> 1) -
  239. ; (prclDest->left >> 1)
  240. mov ecx,rclDest.xLeft
  241. and ecx,1
  242. jz short l_t_done_left_edge ;skip if we don't need a left edge
  243. or esi,BLOCK_LEFT_EDGE
  244. mov ecx,LeftMaskTable[ecx*4]
  245. mov ulLeftMask,ecx ;ulLeftMask =
  246. ; LeftMaskTable[prclDest->left & 1]
  247. mov ulLeftSrc,eax ;ulLeftSrc
  248. mov ulLeftDest,ebx ;ulLeftDest
  249. inc eax
  250. inc ebx
  251. dec edi
  252. l_t_done_left_edge:
  253. mov ulMiddleSrc,eax ;ulMiddleSrc
  254. mov ulMiddleDest,ebx ;ulMiddleDest
  255. mov ecx,rclDest.xRight
  256. and ecx,1
  257. jz short l_t_done_right_edge ;skip if we don't need a right edge
  258. or esi,BLOCK_RIGHT_EDGE
  259. mov ecx,RightMaskTable[ecx*4]
  260. mov ulRightMask,ecx ;ulRightMask =
  261. ; RightMaskTable[prclDest->right & 1]
  262. add eax,edi
  263. add ebx,edi
  264. mov ulRightSrc,eax ;ulRightSrc = ulMiddleSrc + cjMiddle
  265. mov ulRightDest,ebx ;ulRightDest = ulMiddleDest + cjMiddle
  266. ; We special case here blits that are less than 2 pels wide and begin and end
  267. ; in the same 4-pel quadruple:
  268. cmp edi,0
  269. jge l_t_done_right_edge
  270. ; We make sure the 'middle' count of bytes is zero (we'll just let the code
  271. ; fall through the 'middle' copy code), turn off the right-edge flag, and
  272. ; give ulLeftMask the composite mask:
  273. inc edi
  274. xor esi,BLOCK_RIGHT_EDGE
  275. and ecx,ulLeftMask
  276. mov ulLeftMask,ecx
  277. l_t_done_right_edge:
  278. mov cjMiddle,edi ;cjMiddle
  279. mov lDelta,edx ;lDelta = ppdev->lPlanarNextScan
  280. sub edx,edi
  281. mov lMiddleDelta,edx ;lMiddleDelta = lDelta - cjMiddle
  282. mov ebx,ppdev
  283. mov eax,MasterBlockTable[esi*4]
  284. mov pfnCopyBlocks,eax ;copy blocks between video memory
  285. ; Branch to the appropriate top-to-bottom bank enumeration loop:
  286. mov eax,[ebx].pdev_vbtPlanarType
  287. jmp TopToBottomLoopTable[eax*4]
  288. ;-----------------------------------------------------------------------;
  289. ; Set-up code for right-to-left, top-to-bottom copies.
  290. ;
  291. ; Input:
  292. ; esi - pptlSrc
  293. ; edi - prclDest
  294. ;-----------------------------------------------------------------------;
  295. public right_to_left_top_to_bottom
  296. right_to_left_top_to_bottom::
  297. std ;copy middle blocks right-to-left
  298. mov edx,ppdev
  299. mov eax,[edi].yBottom
  300. mov edx,[edx].pdev_lPlanarNextScan ;edx = lDelta
  301. mov ulLastDestScan,eax ;ulLastDestScan = prclDest->bottom
  302. mov ecx,[esi].ptl_y
  303. mov eax,edx
  304. mov ulCurrentSrcScan,ecx ;ulCurrentSrcScan = pptlSrc->y
  305. imul eax,ecx
  306. mov ecx,[esi].ptl_x
  307. mov ptlSrc.ptl_x,ecx ;ptlSrc.x = pptlSrc->x
  308. add ecx,[edi].xRight
  309. sub ecx,[edi].xLeft
  310. shr ecx,1
  311. add eax,ecx ;eax = ulRightSrc = pptlSrc->y *
  312. ; lDelta + (pptlSrc->x +
  313. ; prclDest->right - prclDest->left) / 2
  314. mov esi,BLOCK_RIGHT_TO_LEFT ;initialize flags
  315. mov ecx,[edi].yTop
  316. mov ebx,edx
  317. mov ulCurrentDestScan,ecx ;ulCurrentDestScan = prclDest->top
  318. imul ebx,ecx
  319. mov ecx,[edi].xRight
  320. mov rclDest.xRight,ecx ;rclDest.right = prclDest->right
  321. shr ecx,1
  322. add ebx,ecx ;ebx = ulRightDest = prclDest->top *
  323. ; lDelta + prclDest->right / 2
  324. mov edi,[edi].xLeft
  325. mov rclDest.xLeft,edi
  326. shr edi,1
  327. neg edi
  328. add edi,ecx ;cjMiddle = prclDest->right / 2 -
  329. ; prclDest->left / 2
  330. mov ecx,rclDest.xRight
  331. and ecx,1
  332. jz short r_t_done_right_edge ;skip if we don't need a right edge
  333. or esi,BLOCK_RIGHT_EDGE
  334. mov ecx,RightMaskTable[ecx*4]
  335. mov ulRightMask,ecx ;ulRightMask =
  336. ; RightMaskTable[prclDest->right & 1]
  337. mov ulRightSrc,eax ;ulRightSrc
  338. mov ulRightDest,ebx ;ulRightDest
  339. r_t_done_right_edge:
  340. dec eax
  341. dec ebx
  342. mov ulMiddleSrc,eax ;ulMiddleSrc
  343. mov ulMiddleDest,ebx ;ulMiddleDest
  344. mov ecx,rclDest.xLeft
  345. and ecx,1
  346. jz short r_t_done_left_edge ;skip if we don't need a right edge
  347. or esi,BLOCK_LEFT_EDGE
  348. mov ecx,LeftMaskTable[ecx*4]
  349. mov ulLeftMask,ecx ;ulLeftMask =
  350. ; LeftMaskTable[prclDest->left & 1]
  351. dec edi ;adjust middle block length because
  352. ; we're effectively doing one less
  353. ; middle byte
  354. sub eax,edi
  355. sub ebx,edi
  356. mov ulLeftSrc,eax ;ulLeftSrc = ulMiddleSrc - cjMiddle
  357. mov ulLeftDest,ebx ;ulLeftDest = ulMiddleDest - cjMiddle
  358. ; We special case here blits that are less than 2 pels wide and begin and end
  359. ; in the same 4-pel quadruple:
  360. cmp edi,0
  361. jge r_t_done_left_edge
  362. ; We make sure the 'middle' count of bytes is zero (we'll just let the code
  363. ; fall through the 'middle' copy code), turn off the right-edge flag, and
  364. ; give ulRightMask the composite mask:
  365. inc edi
  366. xor esi,BLOCK_LEFT_EDGE
  367. and ecx,ulRightMask
  368. mov ulRightMask,ecx
  369. r_t_done_left_edge:
  370. mov cjMiddle,edi ;cjMiddle
  371. mov lDelta,edx ;lDelta = ppdev->lPlanarNextScan
  372. add edx,edi
  373. mov lMiddleDelta,edx ;lMiddleDelta = lDelta + cjMiddle
  374. mov ebx,ppdev
  375. mov eax,MasterBlockTable[esi*4]
  376. mov pfnCopyBlocks,eax ;copy blocks between video memory
  377. ; Branch to the appropriate top-to-bottom bank enumeration loop:
  378. mov eax,[ebx].pdev_vbtPlanarType
  379. jmp TopToBottomLoopTable[eax*4]
  380. ;-----------------------------------------------------------------------;
  381. ; Set-up code for left-to-right, bottom-to-top copies.
  382. ;
  383. ; Input:
  384. ; esi - pptlSrc
  385. ; edi - prclDest
  386. ;-----------------------------------------------------------------------;
  387. public left_to_right_bottom_to_top
  388. left_to_right_bottom_to_top::
  389. mov edx,ppdev
  390. mov eax,[edi].yTop
  391. mov edx,[edx].pdev_lPlanarNextScan ;edx = lDelta
  392. mov ulLastDestScan,eax ;ulLastDestScan = prclDest->top
  393. mov ecx,[esi].ptl_y
  394. add ecx,[edi].yBottom
  395. sub ecx,[edi].yTop
  396. mov eax,edx
  397. mov ulCurrentSrcScan,ecx ;ulCurrentSrcScan = pptlSrc->y +
  398. ; (prclDest->bottom - prclDest->top)
  399. dec ecx
  400. imul eax,ecx
  401. mov ecx,[esi].ptl_x
  402. mov ptlSrc.ptl_x,ecx ;ptlSrc.x = pptlSrc->x
  403. shr ecx,1
  404. add eax,ecx ;eax = ulLeftSrc = (ulCurrentSrcScan - 1)
  405. ; * lDelta + (pptlSrc->x >> 1)
  406. xor esi,esi ;initialize flags
  407. mov ecx,[edi].yBottom
  408. mov ebx,edx
  409. mov ulCurrentDestScan,ecx ;ulCurrentDestScan = prclDest->bottom
  410. dec ecx
  411. imul ebx,ecx
  412. mov ecx,[edi].xLeft
  413. mov rclDest.xLeft,ecx ;rclDest.left = prclDest->left
  414. shr ecx,1
  415. add ebx,ecx ;ebx = ulLeftDest = (prclDest->bottom - 1)
  416. ; * lDelta + (prclDest->left >> 1)
  417. mov edi,[edi].xRight
  418. mov rclDest.xRight,edi
  419. shr edi,1
  420. sub edi,ecx ;cjMiddle = (prclDest->right >> 1) -
  421. ; (prclDest->left >> 1)
  422. mov ecx,rclDest.xLeft
  423. and ecx,1
  424. jz short l_b_done_left_edge ;skip if we don't need a left edge
  425. or esi,BLOCK_LEFT_EDGE
  426. mov ecx,LeftMaskTable[ecx*4]
  427. mov ulLeftMask,ecx ;ulLeftMask =
  428. ; LeftMaskTable[prclDest->left & 3]
  429. mov ulLeftSrc,eax ;ulLeftSrc
  430. mov ulLeftDest,ebx ;ulLeftDest
  431. inc eax
  432. inc ebx
  433. dec edi
  434. l_b_done_left_edge:
  435. mov ulMiddleSrc,eax ;ulMiddleSrc
  436. mov ulMiddleDest,ebx ;ulMiddleDest
  437. mov ecx,rclDest.xRight
  438. and ecx,1
  439. jz short l_b_done_right_edge ;skip if we don't need a right edge
  440. or esi,BLOCK_RIGHT_EDGE
  441. mov ecx,RightMaskTable[ecx*4]
  442. mov ulRightMask,ecx ;ulRightMask =
  443. ; RightMaskTable[prclDest->right & 1]
  444. add eax,edi
  445. add ebx,edi
  446. mov ulRightSrc,eax ;ulRightSrc = ulMiddleSrc + cjMiddle
  447. mov ulRightDest,ebx ;ulRightDest = ulMiddleDest + cjMiddle
  448. ; We special case here blits that are less than 2 pels wide and begin and end
  449. ; in the same 4-pel quadruple:
  450. cmp edi,0
  451. jge l_b_done_right_edge
  452. ; We make sure the 'middle' count of bytes is zero (we'll just let the code
  453. ; fall through the 'middle' copy code), turn off the right-edge flag, and
  454. ; give ulLeftMask the composite mask:
  455. inc edi
  456. xor esi,BLOCK_RIGHT_EDGE
  457. and ecx,ulLeftMask
  458. mov ulLeftMask,ecx
  459. l_b_done_right_edge:
  460. mov cjMiddle,edi ;cjMiddle
  461. neg edx
  462. mov lDelta,edx ;lDelta = -ppdev->lPlanarNextScan
  463. sub edx,edi
  464. mov lMiddleDelta,edx ;lMiddleDelta = lDelta - cjMiddle
  465. mov ebx,ppdev
  466. mov eax,MasterBlockTable[esi*4]
  467. mov pfnCopyBlocks,eax ;copy blocks between video memory
  468. ; Branch to the appropriate top-to-bottom bank enumeration loop:
  469. mov eax,[ebx].pdev_vbtPlanarType
  470. jmp BottomToTopLoopTable[eax*4]
  471. ;-----------------------------------------------------------------------;
  472. ; Set-up code for right-to-left, bottom-to-top copies.
  473. ;
  474. ; Input:
  475. ; esi - pptlSrc
  476. ; edi - prclDest
  477. ;-----------------------------------------------------------------------;
  478. public right_to_left_bottom_to_top
  479. right_to_left_bottom_to_top::
  480. std ;copy middle blocks right-to-left
  481. mov edx,ppdev
  482. mov eax,[edi].yTop
  483. mov edx,[edx].pdev_lPlanarNextScan ;edx = lDelta
  484. mov ulLastDestScan,eax ;ulLastDestScan = prclDest->top
  485. mov ecx,[esi].ptl_y
  486. add ecx,[edi].yBottom
  487. sub ecx,[edi].yTop
  488. mov eax,edx
  489. mov ulCurrentSrcScan,ecx ;ulCurrentSrcScan = pptlSrc->y +
  490. ; (prclDest->bottom - prclDest->top)
  491. dec ecx
  492. imul eax,ecx
  493. mov ecx,[esi].ptl_x
  494. mov ptlSrc.ptl_x,ecx ;ptlSrc.x = pptlSrc->x
  495. add ecx,[edi].xRight
  496. sub ecx,[edi].xLeft
  497. shr ecx,1
  498. add eax,ecx ;eax = ulRightSrc = (ulCurrentSrcScan
  499. ; - 1) * lDelta + (pptlSrc->x +
  500. ; prclDest->right - prclDest->left) / 2
  501. mov esi,BLOCK_RIGHT_TO_LEFT ;initialize flags
  502. mov ecx,[edi].yBottom
  503. mov ebx,edx
  504. mov ulCurrentDestScan,ecx ;ulCurrentDestScan = prclDest->bottom
  505. dec ecx
  506. imul ebx,ecx
  507. mov ecx,[edi].xRight
  508. mov rclDest.xRight,ecx ;rclDest.right = prclDest->right
  509. shr ecx,1
  510. add ebx,ecx ;ebx = ulRightDest = (ulCurrentDestScan
  511. ; - 1) * lDelta + prclDest->right / 2
  512. mov edi,[edi].xLeft
  513. mov rclDest.xLeft,edi
  514. shr edi,1
  515. neg edi
  516. add edi,ecx ;cjMiddle = prclDest->right / 2 -
  517. ; prclDest->left / 2
  518. mov ecx,rclDest.xRight
  519. and ecx,1
  520. jz short r_b_done_right_edge ;skip if we don't need a right edge
  521. or esi,BLOCK_RIGHT_EDGE
  522. mov ecx,RightMaskTable[ecx*4]
  523. mov ulRightMask,ecx ;ulRightMask =
  524. ; RightMaskTable[prclDest->right & 1]
  525. mov ulRightSrc,eax ;ulRightSrc
  526. mov ulRightDest,ebx ;ulRightDest
  527. r_b_done_right_edge:
  528. dec eax
  529. dec ebx
  530. mov ulMiddleSrc,eax ;ulMiddleSrc
  531. mov ulMiddleDest,ebx ;ulMiddleDest
  532. mov ecx,rclDest.xLeft
  533. and ecx,1
  534. jz short r_b_done_left_edge ;skip if we don't need a right edge
  535. or esi,BLOCK_LEFT_EDGE
  536. mov ecx,LeftMaskTable[ecx*4]
  537. mov ulLeftMask,ecx ;ulLeftMask =
  538. ; LeftMaskTable[prclDest->left & 1]
  539. dec edi ;adjust middle block length because
  540. ; we're effectively doing one less
  541. ; middle byte
  542. sub eax,edi
  543. sub ebx,edi
  544. mov ulLeftSrc,eax ;ulLeftSrc = ulMiddleSrc - cjMiddle
  545. mov ulLeftDest,ebx ;ulLeftDest = ulMiddleDest - cjMiddle
  546. ; We special case here blits that are less than 2 pels wide and begin and end
  547. ; in the same 4-pel quadruple:
  548. cmp edi,0
  549. jge r_b_done_left_edge
  550. ; We make sure the 'middle' count of bytes is zero (we'll just let the code
  551. ; fall through the 'middle' copy code), turn off the right-edge flag, and
  552. ; give ulRightMask the composite mask:
  553. inc edi
  554. xor esi,BLOCK_LEFT_EDGE
  555. and ecx,ulRightMask
  556. mov ulRightMask,ecx
  557. r_b_done_left_edge:
  558. mov cjMiddle,edi ;cjMiddle
  559. neg edx
  560. mov lDelta,edx ;lDelta = -ppdev->lPlanarNextScan
  561. add edx,edi
  562. mov lMiddleDelta,edx ;lMiddleDelta = lDelta + cjMiddle
  563. mov ebx,ppdev
  564. mov eax,MasterBlockTable[esi*4]
  565. mov pfnCopyBlocks,eax ;copy blocks between video memory
  566. ; Branch to the appropriate top-to-bottom bank enumeration loop:
  567. mov eax,[ebx].pdev_vbtPlanarType
  568. jmp BottomToTopLoopTable[eax*4]
  569. ;=======================================================================;
  570. ;============================= Banking =================================;
  571. ;=======================================================================;
  572. ;-----------------------------------------------------------------------;
  573. ; Banking for 1 R/W adapters, top to bottom.
  574. ;
  575. ; Input:
  576. ; ulCurrentSrcScan
  577. ; ulCurrentDestScan
  578. ; ulLastDestScan
  579. ; Plus some other stuff for split rasters and block copiers
  580. ;-----------------------------------------------------------------------;
  581. public top_to_bottom_1RW
  582. top_to_bottom_1RW::
  583. ; LATER: Should check to see if there's any chance that the source and
  584. ; destination overlap in the same window, so that we can use planar
  585. ; copies -- otherwise, it's faster to directly call of to
  586. ; bPuntScreenToScreenCopyBits
  587. ; We're going top to bottom. Map in the source and dest, top-justified.
  588. mov ebx,ppdev
  589. mov edi,ulCurrentDestScan
  590. cmp edi,[ebx].pdev_rcl1PlanarClip.yTop
  591. jl short top_1RW_map_init_bank
  592. cmp edi,[ebx].pdev_rcl1PlanarClip.yBottom
  593. jl short top_1RW_init_bank_mapped
  594. top_1RW_map_init_bank:
  595. ; Map bank containing the top destination scan line into window.
  596. ; Note: EBX, ESI, and EDI preserved, according to C calling conventions.
  597. ptrCall <dword ptr [ebx].pdev_pfnPlanarControl>, \
  598. <ebx,edi,JustifyTop>
  599. top_1RW_init_bank_mapped:
  600. mov eax,ulCurrentSrcScan
  601. cmp eax,[ebx].pdev_rcl1PlanarClip.yBottom
  602. jl short top_1RW_do_planar_copy
  603. ; ulCurrentSrcScan >= ppdev->rcl1PlanarClip.bottom, which means that
  604. ; the window can't overlap the source and destination at all. We'll
  605. ; have to use an intermediate temporary buffer:
  606. ; ebx = ppdev
  607. ; eax = ulCurrentSrcScan
  608. ; edi = ulCurrentDestScan
  609. mov ptlSrc.ptl_y,eax ;ptlSrc.y = ulCurrentSrcScan
  610. mov rclDest.yTop,edi ;rclDest.top = ulCurrentDestScan
  611. mov esi,[ebx].pdev_rcl1PlanarClip.yBottom
  612. mov eax,ulLastDestScan
  613. sub eax,esi
  614. sbb ecx,ecx
  615. and ecx,eax
  616. add esi,ecx
  617. mov rclDest.yBottom,esi ;rclDest.bottom = min(ulLastDestScan,
  618. ; ppdev->pdev_rcl1PlanarClip.bottom)
  619. ; Enable bit mask for all bits:
  620. mov edx,VGA_BASE + GRAF_ADDR
  621. mov eax,(0ffh shl 8) + GRAF_BIT_MASK
  622. out dx,ax
  623. ; Enable writes to all planes and reset direction flag:
  624. mov edx,VGA_BASE + SEQ_DATA
  625. mov al,MM_ALL
  626. out dx,al
  627. pushfd
  628. cld
  629. ; Call our routine that copies bits the slow way, preserving EBX, ESI and EDI
  630. ; according to C calling conventions:
  631. lea ecx,rclDest
  632. lea edx,ptlSrc
  633. cCall bPuntScreenToScreenCopyBits,<ebx,0,0,ecx,edx>
  634. popfd
  635. ; Set the bit mask to disable all bits, so we can copy through latches again:
  636. mov edx,VGA_BASE + GRAF_ADDR
  637. mov eax,(000h shl 8) + GRAF_BIT_MASK
  638. out dx,ax
  639. ; Update our position variables:
  640. mov ulCurrentDestScan,esi ;ulCurrentDestScan = rclDest.bottom
  641. sub esi,edi ;ulBlockHeight = rclDest.bottom -
  642. ; rclDest.top
  643. add ulCurrentSrcScan,esi ;ulCurrentSrcScan += ulBlockHeight
  644. ; We have to adjust the offsets for all our block copiers, according to the
  645. ; number of scans we copied:
  646. mov edx,lDelta
  647. imul edx,esi ;edx = lDelta * ulBlockHeight
  648. add ulLeftSrc,edx
  649. add ulLeftDest,edx
  650. add ulMiddleSrc,edx
  651. add ulMiddleDest,edx
  652. add ulRightSrc,edx
  653. add ulRightDest,edx
  654. jmp short top_1RW_see_if_done
  655. top_1RW_do_planar_copy:
  656. ; ebx = ppdev
  657. ; eax = ulCurrentSrcScan
  658. ; edi = ulCurrentDestScan
  659. mov ebx,[ebx].pdev_rcl1PlanarClip.yBottom
  660. sub ebx,eax ;ebx = ppdev->rcl1PlanarClip.bottom -
  661. ; ulCurrentSrcScan
  662. ;ebx is the available number of scans
  663. ; we have in the source
  664. mov edx,ulLastDestScan
  665. sub edx,edi ;edx = ulLastDestScan - ulCurrentDestScan
  666. ;edx is the available number of scans
  667. ; in the destination
  668. ; (Because the source starts lower in the window than the destination,
  669. ; the bottom of the bank always limits the source number of scans before
  670. ; it does the destination.)
  671. sub ebx,edx
  672. sbb ecx,ecx
  673. and ecx,ebx
  674. add edx,ecx ;edx = min(source available,
  675. ; destination available)
  676. mov ulBlockHeight,edx
  677. add eax,edx ;We have to adjust our current scans
  678. add edi,edx
  679. mov ulCurrentSrcScan,eax
  680. mov ulCurrentDestScan,edi
  681. ; Now copy the puppy:
  682. call pfnCopyBlocks
  683. ; See if we're done:
  684. top_1RW_see_if_done:
  685. mov edi,ulCurrentDestScan
  686. cmp edi,ulLastDestScan
  687. jge all_done
  688. mov ebx,ppdev
  689. ; Map bank containing the top destination scan line into window.
  690. ; Note: EBX, ESI, and EDI preserved, according to C calling conventions.
  691. ptrCall <dword ptr [ebx].pdev_pfnPlanarControl>, \
  692. <ebx,edi,JustifyTop>
  693. jmp top_1RW_init_bank_mapped
  694. ;-----------------------------------------------------------------------;
  695. ; Banking for 1 R/W adapters, bottom to top.
  696. ;
  697. ; Input:
  698. ; ulCurrentSrcScan - Actually, 1 more current source scan
  699. ; ulCurrentDestScan - Actually, 1 more current destination scan
  700. ; ulLastDestScan
  701. ; Plus some other stuff for split rasters and block copiers
  702. ;-----------------------------------------------------------------------;
  703. public bottom_to_top_1RW
  704. bottom_to_top_1RW::
  705. ; We're going top to bottom. Map in the source and dest, top-justified.
  706. mov ebx,ppdev
  707. mov edi,ulCurrentDestScan
  708. cmp edi,[ebx].pdev_rcl1PlanarClip.yTop
  709. jle short bot_1RW_map_init_bank
  710. cmp edi,[ebx].pdev_rcl1PlanarClip.yBottom
  711. jle short bot_1RW_init_bank_mapped
  712. bot_1RW_map_init_bank:
  713. ; Map bank containing the top destination scan line into window.
  714. ; Note: EBX, ESI, and EDI preserved, according to C calling conventions.
  715. dec edi
  716. ptrCall <dword ptr [ebx].pdev_pfnPlanarControl>, \
  717. <ebx,edi,JustifyTop>
  718. inc edi
  719. bot_1RW_init_bank_mapped:
  720. mov eax,ulCurrentSrcScan
  721. cmp eax,[ebx].pdev_rcl1PlanarClip.yTop
  722. jg short bot_1RW_do_planar_copy
  723. ; ulCurrentSrcScan <= ppdev->rcl1PlanarClip.top, which means that
  724. ; the window can't overlap the source and destination at all. We'll
  725. ; have to use an intermediate temporary buffer:
  726. ; ebx = ppdev
  727. ; eax = ulCurrentSrcScan
  728. ; edi = ulCurrentDestScan
  729. mov esi,[ebx].pdev_rcl1PlanarClip.yTop
  730. mov edx,ulLastDestScan
  731. cmp esi,edx
  732. jg @F
  733. mov esi,edx
  734. @@:
  735. mov rclDest.yTop,esi ;rclDest.top = max(ulLastDestScan,
  736. ; ppdev->rcl1PlanarClip.top)
  737. mov rclDest.yBottom,edi ;rclDest.bottom = ulCurrentDestScan
  738. add eax,esi
  739. sub eax,edi
  740. mov ptlSrc.ptl_y,eax ;ptlSrc.y = ulCurrentSrcScan -
  741. ; (rclDest.bottom - rclDest.top)
  742. ; Enable bit mask for all bits:
  743. mov edx,VGA_BASE + GRAF_ADDR
  744. mov eax,(0ffh shl 8) + GRAF_BIT_MASK
  745. out dx,ax
  746. ; Enable writes to all planes and reset direction flag:
  747. mov edx,VGA_BASE + SEQ_DATA
  748. mov al,MM_ALL
  749. out dx,al
  750. pushfd
  751. cld
  752. ; Call our routine that copies bits the slow way, preserving EBX, ESI and EDI
  753. ; according to C calling conventions:
  754. lea ecx,rclDest
  755. lea edx,ptlSrc
  756. cCall bPuntScreenToScreenCopyBits,<ebx,0,0,ecx,edx>
  757. popfd
  758. ; Set the bit mask to disable all bits, so we can copy through latches again:
  759. mov edx,VGA_BASE + GRAF_ADDR
  760. mov eax,(000h shl 8) + GRAF_BIT_MASK
  761. out dx,ax
  762. ; Update our position variables:
  763. mov ulCurrentDestScan,esi ;ulCurrentDestScan = rclDest.top
  764. sub edi,esi ;ulBlockHeight = rclDest.bottom -
  765. ; rclDest.top
  766. sub ulCurrentSrcScan,edi ;ulCurrentSrcScan -= ulBlockHeight
  767. ; We have to adjust the offsets for all our block copiers, according to the
  768. ; number of scans we copied:
  769. mov edx,lDelta
  770. imul edx,edi ;edx = lDelta * ulBlockHeight
  771. add ulLeftSrc,edx
  772. add ulLeftDest,edx
  773. add ulMiddleSrc,edx
  774. add ulMiddleDest,edx
  775. add ulRightSrc,edx
  776. add ulRightDest,edx
  777. jmp short bot_1RW_see_if_done
  778. bot_1RW_do_planar_copy:
  779. ; ebx = ppdev
  780. ; eax = ulCurrentSrcScan
  781. ; edi = ulCurrentDestScan
  782. sub eax,[ebx].pdev_rcl1PlanarClip.yTop
  783. ;eax = ulCurrentSrcScan -
  784. ; ppdev->rcl1PlanarClip.top
  785. sub edi,ulLastDestScan ;edi = ulCurrentDestScan - ulLastDestScan
  786. ;edi is the available number of scans
  787. ; in the destination
  788. ; (Because the source starts higher in the window than the destination,
  789. ; the bottom of the bank always limits the source number of scans before
  790. ; it does the destination.)
  791. sub eax,edi
  792. sbb ecx,ecx
  793. and ecx,eax
  794. add edi,ecx ;edi = min(source available,
  795. ; destination available)
  796. mov ulBlockHeight,edi
  797. sub ulCurrentSrcScan,edi ;We have to adjust our current scans
  798. sub ulCurrentDestScan,edi
  799. ; Now copy the puppy:
  800. call pfnCopyBlocks
  801. ; See if we're done:
  802. bot_1RW_see_if_done:
  803. mov edi,ulCurrentDestScan
  804. cmp edi,ulLastDestScan
  805. jle all_done
  806. mov ebx,ppdev
  807. ; Map bank containing the top destination scan line into window.
  808. ; Note: EBX, ESI, and EDI preserved, according to C calling conventions.
  809. dec edi
  810. ptrCall <dword ptr [ebx].pdev_pfnPlanarControl>, \
  811. <ebx,edi,JustifyTop>
  812. inc edi
  813. jmp bot_1RW_init_bank_mapped
  814. ;-----------------------------------------------------------------------;
  815. ; Banking for 1R/1W or 2R/W adapters, top to bottom.
  816. ;
  817. ; Input:
  818. ; ulCurrentSrcScan
  819. ; ulCurrentDestScan
  820. ; ulLastDestScan
  821. ; Plus some other stuff for split rasters and block copiers
  822. ;-----------------------------------------------------------------------;
  823. public top_to_bottom_2RW
  824. top_to_bottom_2RW::
  825. ; We're going top to bottom. Map in the destination, top-justified.
  826. mov ebx,ppdev
  827. mov edi,ulCurrentDestScan
  828. mov esi,ulCurrentSrcScan
  829. cmp edi,[ebx].pdev_rcl2PlanarClipD.yTop
  830. jl short top_2RW_map_init_dest_bank
  831. cmp edi,[ebx].pdev_rcl2PlanarClipD.yBottom
  832. jl short top_2RW_init_dest_bank_mapped
  833. top_2RW_map_init_dest_bank:
  834. ; Map bank containing the top destination scan line into window.
  835. ; Note: EBX, ESI, and EDI preserved, according to C calling conventions.
  836. ptrCall <dword ptr [ebx].pdev_pfnPlanarControl2>, \
  837. <ebx,edi,JustifyTop,MapDestBank>
  838. top_2RW_init_dest_bank_mapped:
  839. cmp esi,[ebx].pdev_rcl2PlanarClipS.yTop
  840. jl short top_2RW_map_init_src_bank
  841. cmp esi,[ebx].pdev_rcl2PlanarClipS.yBottom
  842. jl short top_2RW_main_loop
  843. top_2RW_map_init_src_bank:
  844. ; Map bank containing the top source scan line into window.
  845. ; Note: EBX, ESI, and EDI preserved, according to C calling conventions.
  846. ptrCall <dword ptr [ebx].pdev_pfnPlanarControl2>, \
  847. <ebx,esi,JustifyTop,MapSourceBank>
  848. top_2RW_main_loop:
  849. mov ecx,[ebx].pdev_rcl2PlanarClipD.yBottom
  850. mov edx,ulLastDestScan
  851. sub ecx,edx
  852. sbb eax,eax
  853. and eax,ecx
  854. add edx,eax ;edx = min(ulLastDestScan,
  855. ; ppdev->rcl2PlanarClipD.bottom)
  856. mov ecx,[ebx].pdev_rcl2PlanarClipS.yBottom
  857. sub edx,edi ;edx = available scans in destination
  858. ; bank
  859. sub ecx,esi ;ecx = available scans in source bank
  860. sub ecx,edx
  861. sbb eax,eax
  862. and eax,ecx
  863. add edx,eax
  864. mov ulBlockHeight,edx ;ulBlockHeight = min(source available,
  865. ; dest available)
  866. add esi,edx ;adjust our currents scans accordingly
  867. add edi,edx
  868. mov ulCurrentSrcScan,esi
  869. mov ulCurrentDestScan,edi
  870. ; Do the actual copy:
  871. call pfnCopyBlocks
  872. mov edi,ulCurrentDestScan ;check if done
  873. cmp edi,ulLastDestScan
  874. jge all_done
  875. mov ebx,ppdev
  876. ; We'll have to map a new source bank, destination bank, or both:
  877. mov esi,ulCurrentSrcScan
  878. cmp edi,[ebx].pdev_rcl2PlanarClipD.yBottom
  879. jl short top_2RW_map_next_src_bank
  880. ; Map bank containing the top destination scan line into window.
  881. ; Note: EBX, ESI, and EDI preserved, according to C calling conventions.
  882. ptrCall <dword ptr [ebx].pdev_pfnPlanarControl2>, \
  883. <ebx,edi,JustifyTop,MapDestBank>
  884. cmp esi,[ebx].pdev_rcl2PlanarClipS.yBottom
  885. jl short top_2RW_main_loop
  886. top_2RW_map_next_src_bank:
  887. ; Map bank containing the top source scan line into window.
  888. ; Note: EBX, ESI, and EDI preserved, according to C calling conventions.
  889. ptrCall <dword ptr [ebx].pdev_pfnPlanarControl2>, \
  890. <ebx,esi,JustifyTop,MapSourceBank>
  891. jmp short top_2RW_main_loop
  892. ;-----------------------------------------------------------------------;
  893. ; Banking for 1R/1W or 2R/W adapters, bottom to top.
  894. ;
  895. ; Input:
  896. ; ulCurrentSrcScan
  897. ; ulCurrentDestScan
  898. ; ulLastDestScan
  899. ; Plus some other stuff for split rasters and block copiers
  900. ;-----------------------------------------------------------------------;
  901. public bottom_to_top_2RW
  902. bottom_to_top_2RW::
  903. ; We're going bottom to top. Map in the destination, bottom-justified.
  904. mov ebx,ppdev
  905. mov edi,ulCurrentDestScan ; 1 more than actual destination scan
  906. mov esi,ulCurrentSrcScan ; 1 more than actual source scan
  907. cmp edi,[ebx].pdev_rcl2PlanarClipD.yTop
  908. jle short bot_2RW_map_init_dest_bank
  909. cmp edi,[ebx].pdev_rcl2PlanarClipD.yBottom
  910. jle short bot_2RW_init_dest_bank_mapped
  911. bot_2RW_map_init_dest_bank:
  912. ; Map bank containing the top destination scan line into window.
  913. ; Note: EBX, ESI, and EDI preserved, according to C calling conventions.
  914. dec edi
  915. ptrCall <dword ptr [ebx].pdev_pfnPlanarControl2>, \
  916. <ebx,edi,JustifyBottom,MapDestBank>
  917. inc edi
  918. bot_2RW_init_dest_bank_mapped:
  919. cmp esi,[ebx].pdev_rcl2PlanarClipS.yTop
  920. jle short bot_2RW_map_init_src_bank
  921. cmp esi,[ebx].pdev_rcl2PlanarClipS.yBottom
  922. jle short bot_2RW_main_loop
  923. bot_2RW_map_init_src_bank:
  924. ; Map bank containing the top source scan line into window.
  925. ; Note: EBX, ESI, and EDI preserved, according to C calling conventions.
  926. dec esi
  927. ptrCall <dword ptr [ebx].pdev_pfnPlanarControl2>, \
  928. <ebx,esi,JustifyBottom,MapSourceBank>
  929. inc esi
  930. bot_2RW_main_loop:
  931. mov ecx,[ebx].pdev_rcl2PlanarClipD.yTop
  932. mov edx,ulLastDestScan
  933. cmp edx,ecx
  934. jg @F
  935. mov edx,ecx ;edx = max(ulLastDestScan,
  936. @@: ; ppdev->rcl2PlanarClipD.top)
  937. sub edi,edx ;edi = available scans in destination
  938. ; bank
  939. sub esi,[ebx].pdev_rcl2PlanarClipS.yTop
  940. ;esi = available scans in source bank
  941. sub esi,edi
  942. sbb eax,eax
  943. and eax,esi
  944. add edi,eax
  945. mov ulBlockHeight,edi ;ulBlockHeight = min(source available,
  946. ; dest available)
  947. sub ulCurrentSrcScan,edi ;adjust our current scans
  948. sub ulCurrentDestScan,edi
  949. ; Do the actual copy:
  950. call pfnCopyBlocks
  951. mov edi,ulCurrentDestScan ;check if done
  952. cmp edi,ulLastDestScan
  953. jle all_done
  954. mov ebx,ppdev
  955. ; We'll have to map a new source bank, destination bank, or both:
  956. mov esi,ulCurrentSrcScan
  957. cmp edi,[ebx].pdev_rcl2PlanarClipD.yTop
  958. jg short bot_2RW_map_next_src_bank
  959. ; Map bank containing the top destination scan line into window.
  960. ; Note: EBX, ESI, and EDI preserved, according to C calling conventions.
  961. dec edi
  962. ptrCall <dword ptr [ebx].pdev_pfnPlanarControl2>, \
  963. <ebx,edi,JustifyBottom,MapDestBank>
  964. inc edi
  965. cmp esi,[ebx].pdev_rcl2PlanarClipS.yTop
  966. jg short bot_2RW_main_loop
  967. bot_2RW_map_next_src_bank:
  968. ; Map bank containing the top source scan line into window.
  969. ; Note: EBX, ESI, and EDI preserved, according to C calling conventions.
  970. dec esi
  971. ptrCall <dword ptr [ebx].pdev_pfnPlanarControl2>, \
  972. <ebx,esi,JustifyBottom,MapSourceBank>
  973. inc esi
  974. jmp short bot_2RW_main_loop
  975. ;=======================================================================;
  976. ;=========================== Block Copiers =============================;
  977. ;=======================================================================;
  978. ;-----------------------------------------------------------------------;
  979. ; Input:
  980. ; Direction flag - set to the appropriate direction
  981. ; ulMiddleSrc - offset in bitmap to source
  982. ; ulMiddleDest - offset in bitmap to destination
  983. ; lMiddleDelta - distance from end of current scan to start of next
  984. ; ulBlockHeight - # of scans to copy
  985. ; cjMiddle - # of planar bytes to copy on every scan
  986. ;
  987. ; Output:
  988. ; Advances ulMiddleSrc and ulMiddleDest to next strip
  989. ;-----------------------------------------------------------------------;
  990. public copy_middle_block
  991. copy_middle_block::
  992. ; We only have to reset which planes are enabled if we do edges too:
  993. mov edx,VGA_BASE + SEQ_DATA
  994. mov al,MM_ALL
  995. out dx,al
  996. copy_just_middle_block::
  997. ; Calculate full start addresses:
  998. mov edi,ppdev
  999. mov eax,cjMiddle
  1000. mov ebx,ulBlockHeight
  1001. mov edx,lMiddleDelta
  1002. mov esi,[edi].pdev_pvBitmapStart2WindowS
  1003. mov edi,[edi].pdev_pvBitmapStart2WindowD
  1004. add esi,ulMiddleSrc
  1005. add edi,ulMiddleDest
  1006. SET_UP_UNROLL_VARS ebx,ecx,ebx,pfnCopyMiddleEntry, \
  1007. LOOP_UNROLL_SHIFT
  1008. jmp ecx
  1009. UNROLL_LOOP_ENTRY_TABLE pfnCopyMiddleEntry,MIDDLE, \
  1010. LOOP_UNROLL_COUNT
  1011. COPY_MIDDLE macro ENTRY_LABEL,ENTRY_INDEX
  1012. &ENTRY_LABEL&ENTRY_INDEX&:
  1013. mov ecx,eax
  1014. rep movsb
  1015. add esi,edx
  1016. add edi,edx
  1017. endm ;-----------------------------------;
  1018. ; EAX = # of bytes to copy
  1019. ; EBX = count of unrolled loop iterations
  1020. ; EDX = offset from end of one scan's fill to start of next
  1021. ; ESI = source address from which to copy
  1022. ; EDI = target address to which to copy
  1023. middle_loop:
  1024. UNROLL_LOOP COPY_MIDDLE,MIDDLE,LOOP_UNROLL_COUNT
  1025. dec ebx
  1026. jnz middle_loop
  1027. ; get ready for next time:
  1028. mov ecx,ppdev
  1029. sub esi,[ecx].pdev_pvBitmapStart2WindowS
  1030. sub edi,[ecx].pdev_pvBitmapStart2WindowD
  1031. mov ulMiddleSrc,esi
  1032. mov ulMiddleDest,edi
  1033. PLAIN_RET
  1034. ;-----------------------------------------------------------------------;
  1035. ; Input:
  1036. ; ulLeftSrc - offset in bitmap to source
  1037. ; ulLeftDest - offset in bitmap to destination
  1038. ; lDelta - distance from between planar scans
  1039. ; ulBlockHeight - # of scans to copy
  1040. ;
  1041. ; Output:
  1042. ; Advances ulLeftSrc and ulLeftDest to next strip
  1043. ;-----------------------------------------------------------------------;
  1044. public copy_left_block
  1045. copy_left_block::
  1046. ; Set left mask by disabling some planes:
  1047. mov edx,VGA_BASE + SEQ_DATA
  1048. mov eax,ulLeftMask
  1049. out dx,al
  1050. ; Calculate full start addresses:
  1051. mov ecx,ppdev
  1052. mov ebx,ulBlockHeight
  1053. mov edx,lDelta
  1054. mov esi,[ecx].pdev_pvBitmapStart2WindowS
  1055. mov edi,[ecx].pdev_pvBitmapStart2WindowD
  1056. add esi,ulLeftSrc
  1057. add edi,ulLeftDest
  1058. SET_UP_UNROLL_VARS ebx,eax,ebx,pfnCopyLeftEntry, \
  1059. LOOP_UNROLL_SHIFT
  1060. jmp eax
  1061. UNROLL_LOOP_ENTRY_TABLE pfnCopyLeftEntry,LEFT, \
  1062. LOOP_UNROLL_COUNT
  1063. COPY_LEFT macro ENTRY_LABEL,ENTRY_INDEX
  1064. &ENTRY_LABEL&ENTRY_INDEX&:
  1065. mov al,[esi]
  1066. mov [edi],al
  1067. add esi,edx
  1068. add edi,edx
  1069. endm ;-----------------------------------;
  1070. ; EBX = count of unrolled loop iterations
  1071. ; EDX = offset from one scan to next
  1072. ; ESI = source address from which to copy
  1073. ; EDI = target address to which to copy
  1074. left_loop:
  1075. UNROLL_LOOP COPY_LEFT,LEFT,LOOP_UNROLL_COUNT
  1076. dec ebx
  1077. jnz left_loop
  1078. ; get ready for next time:
  1079. sub esi,[ecx].pdev_pvBitmapStart2WindowS
  1080. sub edi,[ecx].pdev_pvBitmapStart2WindowD
  1081. mov ulLeftSrc,esi
  1082. mov ulLeftDest,edi
  1083. PLAIN_RET
  1084. ;-----------------------------------------------------------------------;
  1085. ; Input:
  1086. ; ulRightSrc - offset in bitmap to source
  1087. ; ulRightDest - offset in bitmap to destination
  1088. ; lDelta - distance from between planar scans
  1089. ; ulBlockHeight - # of scans to copy
  1090. ;
  1091. ; Output:
  1092. ; Advances ulRightSrc and ulRightDest to next strip
  1093. ;-----------------------------------------------------------------------;
  1094. public copy_right_block
  1095. copy_right_block::
  1096. ; Set right mask by disabling some planes:
  1097. mov edx,VGA_BASE + SEQ_DATA
  1098. mov eax,ulRightMask
  1099. out dx,al
  1100. ; Calculate full start addresses:
  1101. mov ecx,ppdev
  1102. mov ebx,ulBlockHeight
  1103. mov edx,lDelta
  1104. mov esi,[ecx].pdev_pvBitmapStart2WindowS
  1105. mov edi,[ecx].pdev_pvBitmapStart2WindowD
  1106. add esi,ulRightSrc
  1107. add edi,ulRightDest
  1108. SET_UP_UNROLL_VARS ebx,eax,ebx,pfnCopyRightEntry, \
  1109. LOOP_UNROLL_SHIFT
  1110. jmp eax
  1111. UNROLL_LOOP_ENTRY_TABLE pfnCopyRightEntry,RIGHT, \
  1112. LOOP_UNROLL_COUNT
  1113. COPY_RIGHT macro ENTRY_LABEL,ENTRY_INDEX
  1114. &ENTRY_LABEL&ENTRY_INDEX&:
  1115. mov al,[esi]
  1116. mov [edi],al
  1117. add esi,edx
  1118. add edi,edx
  1119. endm ;-----------------------------------;
  1120. ; EBX = count of unrolled loop iterations
  1121. ; EDX = offset from one scan to next
  1122. ; ESI = source address from which to copy
  1123. ; EDI = target address to which to copy
  1124. right_loop:
  1125. UNROLL_LOOP COPY_RIGHT,RIGHT,LOOP_UNROLL_COUNT
  1126. dec ebx
  1127. jnz right_loop
  1128. ; get ready for next time:
  1129. sub esi,[ecx].pdev_pvBitmapStart2WindowS
  1130. sub edi,[ecx].pdev_pvBitmapStart2WindowD
  1131. mov ulRightSrc,esi
  1132. mov ulRightDest,edi
  1133. PLAIN_RET
  1134. ;-----------------------------------------------------------------------;
  1135. endProc vPlanarCopyBits
  1136. end
  1137.