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.

932 lines
45 KiB

  1. ;---------------------------Module-Header------------------------------;
  2. ; Module Name: stretch.asm
  3. ;
  4. ; Copyright (c) 1992 Microsoft Corporation
  5. ;-----------------------------------------------------------------------;
  6. ;-----------------------------------------------------------------------;
  7. ; INT vStretchBlt8bpp(PPDEV ppdev, PBYTE pSrc, LONG lSrcNext,
  8. ; PRECTL prclSrc, PRECTL prclDest, PRECTL prclDestClip,
  9. ; PULONG pulXlatVector)
  10. ; Input:
  11. ;
  12. ; Performs accelerated stretch blts from 8-bit DIBs to 256-color VGA
  13. ; display memory.
  14. ;-----------------------------------------------------------------------;
  15. ; Note: Does not handle source clipping.
  16. ;
  17. ; Note: Does not yet handle expansion, only shrinking.
  18. ;-----------------------------------------------------------------------;
  19. comment $
  20. ***
  21. Note: in the noxlat loop, EBX isn't altered, so it could be used for
  22. something else, like the scan line count. This isn't done currently
  23. because the scan-line loop is shared by the xlat and noxlat cases, and
  24. the xlat cases do alter EBX; separate loops would be needed in order
  25. to perform this optimization.
  26. commend $
  27. ;-----------------------------------------------------------------------;
  28. .386
  29. ifndef DOS_PLATFORM
  30. .model small,c
  31. else
  32. ifdef STD_CALL
  33. .model small,c
  34. else
  35. .model small,pascal
  36. endif; STD_CALL
  37. endif; DOS_PLATFORM
  38. assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
  39. assume fs:nothing,gs:nothing
  40. .xlist
  41. include stdcall.inc ;calling convention cmacros
  42. include i386\strucs.inc
  43. include i386\driver.inc
  44. .list
  45. ;-----------------------------------------------------------------------;
  46. .data
  47. ;-----------------------------------------------------------------------;
  48. .code
  49. ;-----------------------------------------------------------------------;
  50. cProc vStretchBlt8bpp,28,< \
  51. uses esi edi ebx, \
  52. ppdev:ptr, \
  53. pSrc:ptr, \
  54. lSrcNext:dword, \
  55. prclSrc:ptr, \
  56. prclDest:ptr, \
  57. prclDestClip:ptr, \
  58. pulXlatVector:dword >
  59. local pulDDAArray:dword ;pointer to array of n and n+1
  60. ; values generated by DDA, used to
  61. ; advance across source
  62. local ulXStretchCount:dword ;# of pixels or pixel pair to copy to
  63. ; (pixel pairs except in narrow
  64. ; cases; doesn't include leading or
  65. ; trailing single pixels in pixel
  66. ; pair cases)
  67. local ulDestNext:dword ;offset from last dest pixel on one
  68. ; scan to first on next
  69. local ulSrcMinNext:dword ;offset from start of one source scan
  70. ; to start of next scan that's skipped
  71. ; to by minimum DDA advance (basically,
  72. ; skips over n scans when DDA advances
  73. ; either n or n+1 scans)
  74. local lYErrorTerm:dword ;current error term for the DDA in Y
  75. local ulYAdjUp:dword ;error term adjust up for advancing
  76. ; DDA in Y
  77. local ulYAdjDown:dword ;error term adjust down for advancing
  78. ; DDA in Y
  79. local ulDstTopScan:dword ;top scan of dest text rect in
  80. ; current bank
  81. local ulDstBottomScan :dword ;bottom scan line of dest rectangle
  82. local ulScanCount:dword ;# of scans to stretch in current
  83. ; bank
  84. local pfnRowVector:dword ;pointer to routine to be used to
  85. ; stretch each row
  86. local pfnStretchFn:dword ;pointer to routine to do a bank's
  87. ; worth of stretching
  88. local ulSrcTopScan:dword ;top scan line of source from which
  89. ; to copy (after clipping, if needed)
  90. local ulYMinStep:dword ;minimum # of scans to skip in source
  91. ; when advancing dest one scan
  92. local lXDstRight:dword ;right edge of dest area to which to
  93. ; stretch, accounting for clipping
  94. local lXDstLeft:dword ;left edge of dest area to which to
  95. ; stretch, accounting for clipping
  96. local ulXAdjUp:dword ;X error term adjust up
  97. local ulXMinStep:dword ;X minimum step per dest 1-pixel step
  98. local ulXAdjDown:dword ;X error term adjust down
  99. local lXSrcRight:dword ;right edge of source area from which
  100. ; to stretch, accounting for clipping
  101. local lXSrcLeft:dword ;left edge of source area from which to
  102. ; stretch, accounting for clipping
  103. local pvBuf:dword ;local copy of ppdev->pvTmpBuf ptr
  104. ;-----------------------------------------------------------------------;
  105. mov esi,ppdev
  106. mov edi,[esi].pdev_pvTmpBuf
  107. mov pvBuf,edi
  108. mov esi,prclSrc
  109. mov edi,prclDest
  110. mov eax,[esi].xRight
  111. mov edx,[esi].xLeft
  112. mov lXSrcLeft,edx
  113. sub eax,edx ;EAX = source width
  114. mov ecx,[edi].xRight
  115. mov lXDstRight,ecx
  116. mov edx,[edi].xLeft
  117. mov lXDstLeft,edx
  118. sub ecx,edx ;ECX = dest width
  119. cmp eax,ecx ;shrink or stretch in X?
  120. jge short x_shrink ;shrink
  121. ;stretch
  122. ;@@@
  123. DoneFailed::
  124. sub eax,eax ;@@@shouldn't have to return a value
  125. jmp done
  126. ;The destination is narrower than the source
  127. x_shrink::
  128. mov pfnStretchFn,offset shrink_8bpp_loop
  129. ;-----------------------------------------------------------------------;
  130. ; Precalculate the DDA steps for X and store them in the temp buffer. We know
  131. ; these will fit in the temp buffer, because there are only, say, 2K steps
  132. ; max across the screen, and the temp buffer is guaranteed to be more than
  133. ; 2K*4 = 8K bytes long.
  134. ;
  135. ; At this point, EAX = source width, ECX = destination width
  136. ;-----------------------------------------------------------------------;
  137. sub edx,edx ;prepare for division
  138. div ecx ;SourceDeltaX / DestDeltaX
  139. mov ulXMinStep,eax ;EAX = minimum step in source for 1 dest step
  140. mov esi,edx ;set aside SourceDeltaX % DestDeltaX
  141. add edx,edx ;scale up ulXAdjUp by 2 so we can handle a
  142. ; half-pixel advance
  143. mov ulXAdjUp,edx ;ulXAdjUp = (SourceDeltaX % DestDeltaX)*2
  144. ;prestep source X coord and error term by 1/2
  145. ; a destination pixel, so we pick the source
  146. ; pixel that most closely matches the center
  147. ; of each destination pixel
  148. ;step by 1/2 the whole source pixel advance
  149. ; per destination step
  150. shr eax,1 ;minimum step/2
  151. jnc short @F ;odd
  152. ;even
  153. add esi,ecx ;advance error term for 1/2 of the source
  154. ; pixel we just split (by DestDeltaX)
  155. @@:
  156. add lXSrcLeft,eax ;advance 1/2 minimum step in source
  157. add ecx,ecx ;scale up DestDeltaX by 2 so we can handle a
  158. ; half-pixel advance
  159. mov ulXAdjDown,ecx ;ulXAdjDown = DestDeltaX*2
  160. sub esi,ecx ;initial error term = -(DestDeltaX*2) + 1/2
  161. ; normal error term step (for 1/2 pixel dest
  162. ; advance effect on error term; note that 1/2
  163. ; effect on whole source pixels has already
  164. ; been accounted for)
  165. ;-----------------------------------------------------------------------;
  166. ; Clip to the dest in X, if necessary.
  167. ;-----------------------------------------------------------------------;
  168. mov ebx,prclDestClip
  169. and ebx,ebx ;any clipping?
  170. jz short x_clip_done ;no, all set
  171. mov eax,[ebx].xRight ;right clip edge
  172. cmp eax,lXDstRight ;is the right edge clipped?
  173. jge short check_x_left_clip ;no
  174. ;right edge is clipped
  175. mov lXDstRight,eax ;set the clipped right edge
  176. check_x_left_clip:
  177. mov eax,[ebx].xLeft ;left clip edge
  178. cmp eax,lXDstLeft ;is the left edge clipped?
  179. jle short check_x_not_fully_clipped ;no
  180. ;left edge is clipped
  181. mov edx,lXDstLeft ;get the unclipped dest left edge
  182. mov lXDstLeft,eax ;set the clipped dest left edge
  183. ;now figure out how many source pixels
  184. ; were clipped, and advance the error
  185. ; term appropriately
  186. sub eax,edx ;# of dest pixels clipped
  187. mov ecx,eax ;set aside # of dest pixels to skip
  188. mul ulXAdjUp ;# of adjust ups in the course of the
  189. ; skipped pixels
  190. add esi,eax ;EDX:ESI = error term after skipping
  191. adc edx,-1 ;(the initial error term is negative;
  192. ; this stretches it to 64 bits)
  193. jnc short check_x_not_fully_clipped ;didn't turn over even once
  194. mov eax,esi ;EDX:EAX = error term after skipping
  195. div ulXAdjDown ;EAX = # of times to adjust down
  196. ; while skipping pixels, minus 1
  197. sub edx,ulXAdjDown ;do the last adjust down, to cross
  198. ; back into negative territory where
  199. ; the error term belongs
  200. mov esi,edx ;error term at new, clipped dest left
  201. ; edge
  202. inc eax ;count the last adjust down (# of times
  203. ; source error turned over while
  204. ; advancing to the clipped left edge)
  205. imul ecx,ulXMinStep ;# of whole pixels skipped in source
  206. ; while advancing to dest clip left
  207. ; edge
  208. add eax,ecx ;total # of pixels skipped in source
  209. ; while advancing to dest clip left
  210. ; edge
  211. add lXSrcLeft,eax ;advance the source left edge to match
  212. ; advancing the destination left edge
  213. ; to the left edge of the clip
  214. ; rectangle
  215. check_x_not_fully_clipped:
  216. mov eax,lXDstLeft
  217. cmp lXDstRight,eax ;is the destination fully x-clipped?
  218. jle done ;yes, nothing to draw
  219. x_clip_done:
  220. ;-----------------------------------------------------------------------;
  221. ; Now actually generate the (possibly clipped) X DDA skip array
  222. ;
  223. ; At this point, ESI = X error term for left edge (accounting for any
  224. ; X clipping that has occurred)
  225. ;-----------------------------------------------------------------------;
  226. mov eax,ulXMinStep
  227. mov edi,pvBuf ;we'll store the DDA steps in the temp
  228. mov pulDDAArray,edi ; buffer
  229. mov edx,ulXAdjUp
  230. mov ebx,ulXAdjDown
  231. mov ecx,lXDstRight
  232. sub ecx,lXDstLeft ;ECX = # of pixels per dest scan
  233. push ecx ;remember # of dest pixels across
  234. push ebp ;preserve stack frame pointer
  235. lea ebp,[eax+1] ;maximum step
  236. ;***stack frame unavailable***
  237. x_shrink_set_dda_loop::
  238. add esi,edx ;adjust the error term up
  239. jnc short x_shrink_set_dda_min ;didn't turn over, so advance
  240. ; minimum step
  241. x_shrink_set_dda_max::
  242. sub esi,ebx ;turned over; adjust error term back down
  243. mov [edi],ebp ;advance by maximum step
  244. add edi,4 ;point to next DDA array storage location
  245. dec ecx ;count down steps
  246. jz short x_shrink_set_dda_done ;no more steps
  247. add esi,edx ;adjust the error term up
  248. jc x_shrink_set_dda_max ;did turn over, so advance maximum step
  249. x_shrink_set_dda_min::
  250. mov [edi],eax ;advance by minimum step
  251. add edi,4 ;point to next DDA array storage location
  252. dec ecx ;count down steps
  253. jnz x_shrink_set_dda_loop
  254. x_shrink_set_dda_done::
  255. mov dword ptr [edi],0 ;mark the end of the DDA
  256. pop ebp ;restore stack frame pointer
  257. ;***stack frame available***
  258. pop ecx ;retrieve # of dest pixels across
  259. mov edi,prclDest
  260. cmp pulXlatVector,0 ;translation?
  261. jz short x_shrink_noxlat ;no
  262. ;yes
  263. cmp ecx,3 ;narrow case?
  264. ja short @F ;no
  265. mov pfnRowVector,offset shrink_xlat_8bpp_narrow ;narrow case
  266. mov ulXStretchCount,ecx ;do all dest pixels one at a time
  267. jmp check_y_shrink
  268. @@: ;not narrow case; figure out which wide case,
  269. ; based on the need to perform as many word-
  270. ; aligned writes to display memory as possible
  271. mov edx,ecx
  272. test [edi].xLeft,1 ;starting at an odd destination address?
  273. jnz short x_shrink_xlat_leading ;yes, need leading pixel
  274. mov pfnRowVector,offset shrink_xlat_8bpp_nl_nt
  275. ;assume no leading or trailing pixels
  276. shr edx,1 ;destination width in pixel pairs
  277. mov ulXStretchCount,edx ;count of pixel pairs to draw
  278. jnc short check_y_shrink ;no leading or trailing pixels
  279. mov pfnRowVector,offset shrink_xlat_8bpp_nl_t
  280. ;no leading pixel, is a trailing pixel
  281. jmp short check_y_shrink
  282. x_shrink_xlat_leading: ;there is a leading pixel
  283. mov pfnRowVector,offset shrink_xlat_8bpp_l_nt
  284. ;assume no trailing pixel
  285. shr edx,1 ;destination width in pixel pairs
  286. mov ulXStretchCount,edx ;count of pixel pairs to draw
  287. jc short check_y_shrink ;no trailing pixel
  288. mov pfnRowVector,offset shrink_xlat_8bpp_l_t
  289. ;both leading and trailing pixels
  290. dec edx ;we'll do one pixel pair in the form
  291. ; of the leading/trailing pixel pair
  292. mov ulXStretchCount,edx ;count of pixel pairs to draw
  293. jmp short check_y_shrink
  294. x_shrink_noxlat: ;no translation
  295. cmp ecx,3 ;narrow case?
  296. ja short @F ;no
  297. mov pfnRowVector,offset shrink_noxlat_8bpp_narrow ;narrow case
  298. mov ulXStretchCount,ecx ;do all dest pixels one at a time
  299. jmp short check_y_shrink
  300. @@: ;not narrow case; figure out which wide case,
  301. ; based on the need to perform as many word-
  302. ; aligned writes to display memory as possible
  303. mov edx,ecx
  304. test [edi].xLeft,1 ;starting at an odd destination address?
  305. jnz short x_shrink_noxlat_leading ;yes, need leading pixel
  306. mov pfnRowVector,offset shrink_noxlat_8bpp_nl_nt
  307. ;assume no leading or trailing pixels
  308. shr edx,1 ;destination width in pixel pairs
  309. mov ulXStretchCount,edx ;count of pixel pairs to draw
  310. jnc short check_y_shrink ;no leading or trailing pixels
  311. mov pfnRowVector,offset shrink_noxlat_8bpp_nl_t
  312. ;no leading pixel, is a trailing pixel
  313. jmp short check_y_shrink
  314. x_shrink_noxlat_leading: ;there is a leading pixel
  315. mov pfnRowVector,offset shrink_noxlat_8bpp_l_nt
  316. ;assume no trailing pixel
  317. shr edx,1 ;destination width in pixel pairs
  318. mov ulXStretchCount,edx ;count of pixel pairs to draw
  319. jc short check_y_shrink ;no trailing pixel
  320. mov pfnRowVector,offset shrink_noxlat_8bpp_l_t
  321. ;both leading and trailing pixels
  322. dec edx ;we'll do one pixel pair in the form
  323. ; of the leading/trailing pixel pair
  324. mov ulXStretchCount,edx ;count of pixel pairs to draw
  325. check_y_shrink::
  326. mov esi,edi ;ESI->prclDest
  327. mov edi,prclSrc ;EDI->prclSrc
  328. mov eax,[edi].yBottom
  329. mov ecx,[edi].yTop
  330. mov ulSrcTopScan,ecx
  331. sub eax,ecx ;EAX = source height
  332. mov ecx,[esi].yBottom
  333. mov ulDstBottomScan,ecx
  334. mov edx,[esi].yTop
  335. mov ulDstTopScan,edx
  336. sub ecx,edx ;ECX = dest height
  337. cmp eax,ecx ;shrink or stretch in Y?
  338. jge short y_shrink ;shrink
  339. ;stretch
  340. ;@@@
  341. sub eax,eax ;@@@shouldn't have to return a value
  342. jmp done
  343. ;The destination is shorter than the source; calculate the error term values
  344. ; for advancing through the source on a per-dest-scan-line basis.
  345. y_shrink::
  346. sub edx,edx ;prepare for division
  347. div ecx ;SourceDeltaY/DestDeltaY
  348. mov ulYMinStep,eax ;EAX = minimum step in source for 1 dest step
  349. mov ebx,edx ;set aside SourceDeltaY % DestDeltaY
  350. add edx,edx ;scale up ulYAdjUp by 2 so we can handle a
  351. ; half-pixel advance
  352. mov ulYAdjUp,edx ;ulYAdjUp = (SourceDeltaY % DestDeltaY)*2
  353. imul lSrcNext ;(minimum step * source scan width in bytes)
  354. mov ulSrcMinNext,eax ; = minimum offset by which to advance from
  355. ; one scan to the next
  356. ;prestep source X coord and error term by 1/2
  357. ; a destination pixel, so we pick the source
  358. ; pixel that most closely matches the center
  359. ; of each destination pixel
  360. ;step by 1/2 the whole source pixel advance
  361. ; per destination step
  362. mov eax,ulYMinStep ;retrieve minimum step
  363. shr eax,1 ;minimum step/2
  364. jnc short @F ;odd
  365. ;even
  366. add ebx,ecx ;advance error term for 1/2 of the source
  367. ; pixel we just split
  368. @@:
  369. add ulSrcTopScan,eax ;advance 1/2 minimum step in source
  370. add ecx,ecx ;scale up DestDeltaY by 2 so we can handle a
  371. ; half-pixel advance
  372. mov ulYAdjDown,ecx ;ulYAdjDown = DestDeltaY*2
  373. sub ebx,ecx ;initial error term = -(DestDeltaY*2) + 1/2
  374. ; normal error term step (for 1/2 pixel dest
  375. ; advance effect on error term; note that 1/2
  376. ; effect on whole source pixels has already
  377. ; been accounted for)
  378. mov lYErrorTerm,ebx
  379. ;-----------------------------------------------------------------------;
  380. ; Clip in Y, if necessary.
  381. ;-----------------------------------------------------------------------;
  382. mov ebx,prclDestClip
  383. and ebx,ebx ;any clipping?
  384. jz short y_clip_done ;no, all set
  385. mov eax,[ebx].yBottom ;yes, clipping
  386. ;see if the dest is clipped off the
  387. ; bottom
  388. cmp ulDstBottomScan,eax ;is the bottom clipped?
  389. jle short check_y_top_clip ;no, check the top
  390. mov ulDstBottomScan,eax ;yes, set the new bottom
  391. check_y_top_clip:
  392. ;see if the dest is clipped off the
  393. ; top
  394. mov eax,[ebx].yTop
  395. cmp ulDstTopScan,eax ;is the top clipped?
  396. jge short check_y_not_fully_clipped ;no
  397. ;yes, so advance the top scan and the
  398. ; error term accordingly
  399. mov ulDstTopScan,eax ;top of clipped destination rectangle
  400. sub eax,[esi].yTop ;# of destination scans to skip
  401. mov ecx,eax ;set aside # of dest scans to skip
  402. mul ulYAdjUp ;# of adjust ups in the course of the
  403. ; skipped scans
  404. add eax,lYErrorTerm ;EDX:EAX = error term after skipping
  405. adc edx,-1 ;(the initial error term is negative;
  406. ; this stretches it to 64 bits)
  407. jnc short check_y_not_fully_clipped ;didn't turn over even once
  408. div ulYAdjDown ;EAX = # of times to adjust down
  409. ; while skipping scans, minus 1
  410. sub edx,ulYAdjDown ;do the last adjust down, to cross
  411. ; back into negative territory where
  412. ; the error term belongs
  413. mov lYErrorTerm,edx ;error term at new, clipped dest top
  414. inc eax ;count the last adjust down (# of
  415. ; times source error has turned over)
  416. imul ecx,ulYMinStep ;# of whole steps in source while
  417. ; advancing to dest clip top
  418. add eax,ecx ;total # of scans skipped in source
  419. ; while advancing to dest clip top
  420. add ulSrcTopScan,eax ;advance the source top edge to match
  421. ; advancing the destination top edge to
  422. ; the top of the clip rectangle
  423. check_y_not_fully_clipped:
  424. mov eax,ulDstTopScan
  425. cmp ulDstBottomScan,eax ;is the destination fully y-clipped?
  426. jle done ;yes, nothing to draw
  427. y_clip_done:
  428. ;-----------------------------------------------------------------------;
  429. ; Calculate the offset of the initial destination pixel.
  430. ;-----------------------------------------------------------------------;
  431. mov ebx,ppdev
  432. mov eax,ulDstTopScan ;top scan line of text
  433. mov esi,[ebx].pdev_lDeltaScreen
  434. mul esi
  435. mov edi,lXDstLeft
  436. mov ecx,lXDstRight
  437. sub ecx,edi ;dest width
  438. sub esi,ecx ;dest width - width of a dest scan to stretch
  439. mov ulDestNext,esi ;offset from end of one dest stretched
  440. ; scan to start of next
  441. add edi,eax
  442. ;-----------------------------------------------------------------------;
  443. ; Map in the bank containing the top scan of the text, if it's not
  444. ; mapped in already.
  445. ;-----------------------------------------------------------------------;
  446. mov eax,ulDstTopScan ;top scan line of text
  447. cmp eax,[ebx].pdev_rcl1WindowClip.yTop ;is text top less than
  448. ; current bank?
  449. jl short map_init_bank ;yes, map in proper bank
  450. cmp eax,[ebx].pdev_rcl1WindowClip.yBottom ;text top greater than
  451. ; current bank?
  452. jl short init_bank_mapped ;no, proper bank already mapped
  453. map_init_bank::
  454. ; Map in the bank containing the top scan line of the destination.
  455. ; Preserves EBX, ESI, and EDI.
  456. ptrCall <dword ptr [ebx].pdev_pfnBankControl>,<ebx,eax,JustifyTop>
  457. init_bank_mapped::
  458. add edi,[ebx].pdev_pvBitmapStart ;initial destination address
  459. ;-----------------------------------------------------------------------;
  460. ; Calculate the offset of the initial source pixel.
  461. ;-----------------------------------------------------------------------;
  462. mov esi,prclSrc
  463. mov eax,lSrcNext
  464. imul ulSrcTopScan
  465. mov esi,lXSrcLeft
  466. add esi,eax
  467. add esi,pSrc
  468. ;-----------------------------------------------------------------------;
  469. ; Main loop for processing stretch blt in each bank.
  470. ;
  471. ; At start of loop, EBX->ppdev, ESI->current src, EDI->current dst
  472. ;-----------------------------------------------------------------------;
  473. bank_loop::
  474. mov edx,ulDstBottomScan ;bottom of destination rectangle
  475. cmp edx,[ebx].pdev_rcl1WindowClip.yBottom
  476. ;which comes first, the bottom of the
  477. ; text rect or the bottom of the
  478. ; current bank?
  479. jl short @F ;text bottom comes first, so draw to
  480. ; that; this is the last bank in text
  481. mov edx,[ebx].pdev_rcl1WindowClip.yBottom
  482. ;bank bottom comes first; draw to
  483. ; bottom of bank
  484. @@:
  485. sub edx,ulDstTopScan ;# of scans to draw in bank
  486. mov ulScanCount,edx
  487. call pfnStretchFn ;stretch the bitmap block that's in this bank
  488. ;-----------------------------------------------------------------------;
  489. ; See if there are more banks to draw.
  490. ;-----------------------------------------------------------------------;
  491. mov ebx,ppdev
  492. mov eax,[ebx].pdev_rcl1WindowClip.yBottom ;is the text bottom in
  493. cmp ulDstBottomScan,eax ; the current bank?
  494. jnle short do_next_bank ;no, map in the next bank and draw
  495. mov eax,1 ;success
  496. ;@@@shouldn't return a value
  497. done::
  498. cRet vStretchBlt8bpp ;yes, so we're done
  499. do_next_bank::
  500. mov ulDstTopScan,eax
  501. sub edi,[ebx].pdev_pvBitmapStart ;convert from address to offset
  502. ; within bitmap
  503. ptrCall <dword ptr [ebx].pdev_pfnBankControl>,<ebx,eax,JustifyTop>
  504. ;map in the bank (call preserves
  505. ; EBX, ESI, and EDI)
  506. add edi,[ebx].pdev_pvBitmapStart ;convert from offset within bitmap
  507. ; to address (bitmap start just
  508. ; moved)
  509. jmp bank_loop ;we're ready to draw to the new
  510. ; bank
  511. ;-----------------------------------------------------------------------;
  512. ; Shrink in X and Y, xlat or noxlat, 8-bpp source, VGA dest
  513. ;
  514. ; On entry: ESI->first source pixel to copy from
  515. ; EDI->first dest pixel to copy to
  516. ; pulXlatVector = pointer to color translation array (xlat cases
  517. ; only)
  518. ; ulSrcMinNext = minimum offset from end of current source scan to
  519. ; start of next source scan to stretch
  520. ; lSrcNext = offset from start of one source scan to start of next
  521. ; ulDestNext = offset from end of current dest scan to start of
  522. ; next dest scan to stretch to
  523. ; pfnRowVector = pointer to routine to call to stretch one scan
  524. ; ulScanCount = # of scans to stretch
  525. ; lYErrorTerm, ulYAdjUp, ulYAdjDown = Y DDA error term components
  526. ;
  527. ; On exit: ESI->next source pixel to copy from
  528. ; EDI->next dest pixel to copy to
  529. ; lYErrorTerm advanced for next scan
  530. ;-----------------------------------------------------------------------;
  531. shrink_8bpp_loop::
  532. sub ebx,ebx ;prepare EBX=0 for xlat-case row-drawing
  533. ; routines
  534. shrink_block_8bpp_loop::
  535. mov edx,pulDDAArray ;point to array of skip values to use to scan
  536. ; across the source
  537. mov ecx,ulXStretchCount ;# of pixels or pixel pairs to copy to
  538. push esi ;preserve source pointer
  539. call pfnRowVector ;stretch/shrink this row
  540. pop esi ;restore source pointer
  541. add esi,ulSrcMinNext ;point to start of next source row, assuming
  542. ; no extra row for error term turnover
  543. mov eax,lYErrorTerm
  544. add eax,ulYAdjUp ;advance the error term
  545. jnc short @F ; didn't turn over (minimum step)
  546. sub eax,ulYAdjDown ;turned over, adjust down and...
  547. add esi,lSrcNext ; advance an extra scan (maximum step)
  548. @@:
  549. mov lYErrorTerm,eax ;remember the new error term
  550. add edi,ulDestNext ;point to start of next destination row
  551. dec ulScanCount ;count down scans
  552. jnz shrink_block_8bpp_loop
  553. retn
  554. ;-----------------------------------------------------------------------;
  555. ; Single-row optimizations, called out of main stretch loops.
  556. ;-----------------------------------------------------------------------;
  557. ;-----------------------------------------------------------------------;
  558. ; Shrink in X
  559. ; No xlat
  560. ; 8-bit source
  561. ; Writes a word at a time
  562. ;
  563. ; Input: ECX = number of pixel pairs to do, not counting leading and trailing
  564. ; single pixels (except in narrow case, where ECX = number of
  565. ; pixels, not pixel pairs)
  566. ; EDX = pointer to pre-computed skip array
  567. ; ESI = pointer to initial source pixel
  568. ; EDI = pointer to initial destination pixel
  569. ;
  570. ; Output: ESI = pointer after last source pixel processed
  571. ; EDI = pointer after last source pixel processed
  572. ;
  573. ; EBX and EBP are preserved
  574. ; The contents of EAX, ECX, and EDX may be destroyed
  575. ;-----------------------------------------------------------------------;
  576. ; No leading byte, no trailing byte.
  577. shrink_noxlat_8bpp_nl_nt::
  578. shrink_noxlat_8bpp_nl_nt_pixel_loop::
  579. mov al,[esi] ;get first source pixel
  580. add esi,[edx] ;point to next source pixel
  581. mov ah,[esi] ;get second source pixel
  582. add esi,[edx+4] ;point to next source pixel
  583. add edx,8 ;point to next skip entry
  584. mov [edi],ax ;write both pixels to the destination
  585. add edi,2 ;point to next destination pixel
  586. dec ecx ;count down pixel pairs
  587. jnz shrink_noxlat_8bpp_nl_nt_pixel_loop
  588. retn
  589. ; Leading byte, no trailing byte.
  590. shrink_noxlat_8bpp_l_nt::
  591. ;do the leading pixel
  592. mov al,[esi] ;get the current source pixel
  593. add esi,[edx] ;point to next source pixel
  594. add edx,4 ;point to next skip entry
  595. mov [edi],al ;write the pixel to the destination
  596. inc edi ;point to next destination pixel
  597. ;now do pixel pairs across the middle
  598. shrink_noxlat_8bpp_l_nt_pixel_loop::
  599. mov al,[esi] ;get first source pixel
  600. add esi,[edx] ;point to next source pixel
  601. mov ah,[esi] ;get second source pixel
  602. add esi,[edx+4] ;point to next source pixel
  603. add edx,8 ;point to next skip entry
  604. mov [edi],ax ;write both pixels to the destination
  605. add edi,2 ;point to next destination pixel
  606. dec ecx ;count down pixel pairs
  607. jnz shrink_noxlat_8bpp_l_nt_pixel_loop
  608. retn
  609. ; Leading byte, trailing byte.
  610. shrink_noxlat_8bpp_l_t::
  611. ;do the leading pixel
  612. mov al,[esi] ;get current source pixel
  613. add esi,[edx] ;point to next source pixel
  614. add edx,4 ;point to next skip entry
  615. mov [edi],al ;write the pixel to the destination
  616. inc edi ;point to next destination pixel
  617. ;now do pixel pairs across the middle
  618. shrink_noxlat_8bpp_l_t_pixel_loop::
  619. mov al,[esi] ;get first source pixel
  620. add esi,[edx] ;point to next source pixel
  621. mov ah,[esi] ;get second source pixel
  622. add esi,[edx+4] ;point to next source pixel
  623. add edx,8 ;point to next skip entry
  624. mov [edi],ax ;write both pixels to the destination
  625. add edi,2 ;point to next destination pixel
  626. dec ecx ;count down pixel pairs
  627. jnz shrink_noxlat_8bpp_l_t_pixel_loop
  628. ;do the trailing pixel
  629. mov al,[esi] ;get current source pixel
  630. add esi,[edx] ;point to next source pixel
  631. add edx,4 ;point to next skip entry
  632. mov [edi],al ;write the pixel to the destination
  633. inc edi ;point to next destination pixel
  634. retn
  635. ; No leading byte, trailing byte.
  636. shrink_noxlat_8bpp_nl_t::
  637. shrink_noxlat_8bpp_nl_t_pixel_loop::
  638. mov al,[esi] ;get first source pixel
  639. add esi,[edx] ;point to next source pixel
  640. mov ah,[esi] ;get second source pixel
  641. add esi,[edx+4] ;point to next source pixel
  642. add edx,8 ;point to next skip entry
  643. mov [edi],ax ;write both pixels to the destination
  644. add edi,2 ;point to next destination pixel
  645. dec ecx ;count down pixel pairs
  646. jnz shrink_noxlat_8bpp_nl_t_pixel_loop
  647. ;do the trailing pixel
  648. mov al,[esi] ;get current source pixel
  649. add esi,[edx] ;point to next source pixel
  650. add edx,4 ;point to next skip entry
  651. mov [edi],al ;write the pixel to the destination
  652. inc edi ;point to next destination pixel
  653. retn
  654. ; Narrow case, a byte at a time.
  655. shrink_noxlat_8bpp_narrow::
  656. shrink_noxlat_8bpp_narrow_pixel_loop::
  657. mov al,[esi] ;get current source pixel
  658. add esi,[edx] ;point to next source pixel
  659. add edx,4 ;point to next skip entry
  660. mov [edi],al ;write the pixel to the destination
  661. inc edi ;point to next destination pixel
  662. dec ecx ;count down pixels
  663. jnz shrink_noxlat_8bpp_narrow_pixel_loop
  664. retn
  665. ;-----------------------------------------------------------------------;
  666. ; Shrink in X
  667. ; Xlat
  668. ; 8-bit source
  669. ; Writes a word at a time
  670. ;
  671. ; Input: EBX upper three bytes = zero (0)
  672. ; ECX = number of pixel pairs to do, not counting leading and trailing
  673. ; single pixels (except in narrow case, where ECX = number of
  674. ; pixels, not pixel pairs)
  675. ; EDX = pointer to pre-computed skip array
  676. ; ESI = pointer to initial source pixel
  677. ; EDI = pointer to initial destination pixel
  678. ; pulXlatVector = pointer to color translation array
  679. ;
  680. ; Output: ESI = pointer after last source pixel processed
  681. ; EDI = pointer after last source pixel processed
  682. ;
  683. ; EBP is preserved
  684. ; The upper three bytes of EBX are preserved
  685. ; The contents of EAX, BL, ECX, and EDX may be destroyed
  686. ;-----------------------------------------------------------------------;
  687. ; No leading byte, no trailing byte.
  688. shrink_xlat_8bpp_nl_nt::
  689. push ebp ;***stack frame not available***
  690. mov ebp,pulXlatVector ;point EBP to the translation table
  691. shrink_xlat_8bpp_nl_nt_pixel_loop::
  692. mov bl,[esi] ;get first source pixel
  693. add esi,[edx] ;point to next source pixel
  694. mov eax,[ebp+ebx*4] ;translate the pixel color
  695. mov bl,[esi] ;get second source pixel
  696. add esi,[edx+4] ;point to next source pixel
  697. mov ah,[ebp+ebx*4] ;translate the pixel color
  698. add edx,8 ;point to next skip entry
  699. mov [edi],ax ;write both pixels to the destination
  700. add edi,2 ;point to next destination pixel
  701. dec ecx ;count down pixel pairs
  702. jnz shrink_xlat_8bpp_nl_nt_pixel_loop
  703. pop ebp ;***stack frame available***
  704. retn
  705. ; Leading byte, no trailing byte.
  706. shrink_xlat_8bpp_l_nt::
  707. push ebp ;***stack frame not available***
  708. mov ebp,pulXlatVector ;point EBP to the translation table
  709. ;do the leading pixel
  710. mov bl,[esi] ;get first source pixel
  711. add esi,[edx] ;point to next source pixel
  712. mov eax,[ebp+ebx*4] ;translate the pixel color
  713. add edx,4 ;point to next skip entry
  714. mov [edi],al ;write the pixel to the destination
  715. inc edi ;point to next destination pixel
  716. ;now do pixel pairs across the middle
  717. shrink_xlat_8bpp_l_nt_pixel_loop::
  718. mov bl,[esi] ;get first source pixel
  719. add esi,[edx] ;point to next source pixel
  720. mov eax,[ebp+ebx*4] ;translate the pixel color
  721. mov bl,[esi] ;get second source pixel
  722. add esi,[edx+4] ;point to next source pixel
  723. mov ah,[ebp+ebx*4] ;translate the pixel color
  724. add edx,8 ;point to next skip entry
  725. mov [edi],ax ;write both pixels to the destination
  726. add edi,2 ;point to next destination pixel
  727. dec ecx ;count down pixel pairs
  728. jnz shrink_xlat_8bpp_l_nt_pixel_loop
  729. pop ebp ;***stack frame available***
  730. retn
  731. ; Leading byte, trailing byte.
  732. shrink_xlat_8bpp_l_t::
  733. push ebp ;***stack frame not available***
  734. mov ebp,pulXlatVector ;point EBP to the translation table
  735. ;do the leading pixel
  736. mov bl,[esi] ;get first source pixel
  737. add esi,[edx] ;point to next source pixel
  738. mov eax,[ebp+ebx*4] ;translate the pixel color
  739. add edx,4 ;point to next skip entry
  740. mov [edi],al ;write the pixel to the destination
  741. inc edi ;point to next destination pixel
  742. ;now do pixel pairs across the middle
  743. shrink_xlat_8bpp_l_t_pixel_loop::
  744. mov bl,[esi] ;get first source pixel
  745. add esi,[edx] ;point to next source pixel
  746. mov eax,[ebp+ebx*4] ;translate the pixel color
  747. mov bl,[esi] ;get second source pixel
  748. add esi,[edx+4] ;point to next source pixel
  749. mov ah,[ebp+ebx*4] ;translate the pixel color
  750. add edx,8 ;point to next skip entry
  751. mov [edi],ax ;write both pixels to the destination
  752. add edi,2 ;point to next destination pixel
  753. dec ecx ;count down pixel pairs
  754. jnz shrink_xlat_8bpp_l_t_pixel_loop
  755. ;do the trailing pixel
  756. mov bl,[esi] ;get first source pixel
  757. add esi,[edx] ;point to next source pixel
  758. mov eax,[ebp+ebx*4] ;translate the pixel color
  759. add edx,4 ;point to next skip entry
  760. mov [edi],al ;write the pixel to the destination
  761. inc edi ;point to next destination pixel
  762. pop ebp ;***stack frame available***
  763. retn
  764. ; No leading byte, trailing byte.
  765. shrink_xlat_8bpp_nl_t::
  766. push ebp ;***stack frame not available***
  767. mov ebp,pulXlatVector ;point EBP to the translation table
  768. shrink_xlat_8bpp_nl_t_pixel_loop::
  769. mov bl,[esi] ;get first source pixel
  770. add esi,[edx] ;point to next source pixel
  771. mov eax,[ebp+ebx*4] ;translate the pixel color
  772. mov bl,[esi] ;get second source pixel
  773. add esi,[edx+4] ;point to next source pixel
  774. mov ah,[ebp+ebx*4] ;translate the pixel color
  775. add edx,8 ;point to next skip entry
  776. mov [edi],ax ;write both pixels to the destination
  777. add edi,2 ;point to next destination pixel
  778. dec ecx ;count down pixel pairs
  779. jnz shrink_xlat_8bpp_nl_t_pixel_loop
  780. ;do the trailing pixel
  781. mov bl,[esi] ;get first source pixel
  782. add esi,[edx] ;point to next source pixel
  783. mov eax,[ebp+ebx*4] ;translate the pixel color
  784. add edx,4 ;point to next skip entry
  785. mov [edi],al ;write the pixel to the destination
  786. inc edi ;point to next destination pixel
  787. pop ebp ;***stack frame available***
  788. retn
  789. ; Narrow case, a byte at a time.
  790. shrink_xlat_8bpp_narrow::
  791. push ebp ;***stack frame not available***
  792. mov ebp,pulXlatVector ;point EBP to the translation table
  793. shrink_xlat_8bpp_narrow_loop::
  794. mov bl,[esi] ;get first source pixel
  795. add esi,[edx] ;point to next source pixel
  796. mov eax,[ebp+ebx*4] ;translate the pixel color
  797. add edx,4 ;point to next skip entry
  798. mov [edi],al ;write the pixel to the destination
  799. inc edi ;point to next destination pixel
  800. dec ecx ;count down pixels
  801. jnz shrink_xlat_8bpp_narrow_loop
  802. pop ebp ;***stack frame available***
  803. retn
  804. endProc vStretchBlt8bpp
  805. public DoneFailed
  806. public x_shrink
  807. public check_y_shrink
  808. public x_shrink_set_dda_loop
  809. public x_shrink_set_dda_max
  810. public x_shrink_set_dda_min
  811. public x_shrink_set_dda_done
  812. public y_shrink
  813. public map_init_bank
  814. public init_bank_mapped
  815. public bank_loop
  816. public done
  817. public do_next_bank
  818. public shrink_8bpp_loop
  819. public shrink_block_8bpp_loop
  820. public shrink_noxlat_8bpp_nl_nt
  821. public shrink_noxlat_8bpp_nl_nt_pixel_loop
  822. public shrink_noxlat_8bpp_l_nt
  823. public shrink_noxlat_8bpp_l_nt_pixel_loop
  824. public shrink_noxlat_8bpp_l_t
  825. public shrink_noxlat_8bpp_l_t_pixel_loop
  826. public shrink_noxlat_8bpp_nl_t
  827. public shrink_noxlat_8bpp_nl_t_pixel_loop
  828. public shrink_noxlat_8bpp_narrow
  829. public shrink_noxlat_8bpp_narrow_pixel_loop
  830. public shrink_xlat_8bpp_nl_nt
  831. public shrink_xlat_8bpp_nl_nt_pixel_loop
  832. public shrink_xlat_8bpp_l_nt
  833. public shrink_xlat_8bpp_l_nt_pixel_loop
  834. public shrink_xlat_8bpp_l_t
  835. public shrink_xlat_8bpp_l_t_pixel_loop
  836. public shrink_xlat_8bpp_nl_t
  837. public shrink_xlat_8bpp_nl_t_pixel_loop
  838. public shrink_xlat_8bpp_narrow
  839. public shrink_xlat_8bpp_narrow_loop
  840. end