Source code of Windows XP (NT5)
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.

842 lines
20 KiB

  1. TITLE - Converted Winrect.c to Assembler
  2. .286p
  3. .xlist
  4. include wow.inc
  5. include wowusr.inc
  6. include cmacros.inc
  7. NOEXTERNS=1 ; to suppress including most of the stuff in user.inc
  8. include user.inc
  9. .list
  10. sBegin CODE
  11. assumes cs, CODE
  12. assumes ds, DATA
  13. ;******************************************************************************
  14. ; ORIGINAL C SOURCE
  15. ;
  16. ;*void FAR SetRect(pRect,left,top,right,bottom)
  17. ;*LPRECT pRect;
  18. ;*int top,left,bottom,right;
  19. ;*{
  20. ;* pRect->top = top;
  21. ;* pRect->left = left;
  22. ;* pRect->bottom = bottom;
  23. ;* pRect->right = right;
  24. ;*}
  25. ;******************************************************************************
  26. cProcVDO SetRect,<FAR, PUBLIC, NODATA>
  27. ;ParmD lprc
  28. ;ParmW left
  29. ;ParmW top
  30. ;ParmW right
  31. ;ParmW bottom
  32. cBegin nogen
  33. mov bx,sp
  34. mov cx,di
  35. beg_fault_trap sr_trap
  36. cld
  37. les di,ss:[bx]+4+2+2+2+2
  38. mov ax,ss:[bx]+4+2+2+2
  39. stosw
  40. mov ax,ss:[bx]+4+2+2
  41. stosw
  42. mov ax,ss:[bx]+4+2
  43. stosw
  44. mov ax,ss:[bx]+4
  45. stosw
  46. end_fault_trap
  47. sr_cont:
  48. mov di,cx
  49. retf 4+2+2+2+2
  50. cEnd nogen
  51. sr_trap:
  52. fault_fix_stack
  53. jmp short sr_cont
  54. ;******************************************************************************
  55. ;* ORIGINAL C SOURCE
  56. ;*
  57. ;*int FAR SetRectEmpty(pRect)
  58. ;*LPRECT pRect;
  59. ;*{
  60. ;* LFillStruct(pRect,sizeof(RECT),0);
  61. ;*}
  62. ;*
  63. ;******************************************************************************
  64. LabelVDO SetRectEmpty
  65. pop ax
  66. pop dx
  67. pop bx
  68. pop cx
  69. push dx
  70. push ax
  71. xchg di,bx
  72. beg_fault_trap sre_trap
  73. mov es,cx
  74. xor ax,ax
  75. cld
  76. stosw
  77. stosw
  78. stosw
  79. stosw
  80. end_fault_trap
  81. sre_cont:
  82. mov di,bx
  83. retf
  84. sre_trap:
  85. fault_fix_stack
  86. jmp short sre_cont
  87. ;******************************************************************************
  88. ;* ORIGINAL C SOURCE
  89. ;*
  90. ;*int FAR CopyRect(pDstRect,pSrcRect)
  91. ;*LPRECT pSrcRect; /*ptr to source rect */
  92. ;*LPRECT pDstRect; /*Ptr to dest rect */
  93. ;*{
  94. ;* LCopyStruct(pSrcRect,pDstRect,sizeof(RECT));
  95. ;* /*copy from source to dest */
  96. ;*}
  97. ;*
  98. ;******************************************************************************
  99. cProcVDO CopyRect, <FAR, PUBLIC, NODATA>, <ds, si, di>
  100. parmD lpDstRect ;long pointer to DstRect
  101. parmD lpSrcRect ;long pointer to SrcRect
  102. cBegin
  103. beg_fault_trap cr_trap
  104. lds si, lpSrcRect ;mov into ds:si a far pointer to SrcRect
  105. les di, lpDstRect ;mov into es:di far pointer to DstRect
  106. cld ;clear direction flag for increment stuff
  107. movsw
  108. movsw
  109. movsw
  110. movsw
  111. end_fault_trap
  112. cr_cont:
  113. cEnd
  114. cr_trap:
  115. fault_fix_stack
  116. jmp short cr_cont
  117. ;******************************************************************************
  118. ;* ORIGINAL C SOURCE
  119. ;*
  120. ;*BOOL FAR IsRectEmpty(pRect)
  121. ;*LPRECT pRect;
  122. ;*{
  123. ;* return(((pRect->right-pRect->left<=0)||(pRect->bottom-pRect->top<=0)) ? TRUE : FALSE);
  124. ;*}
  125. ;*
  126. ;******************************************************************************
  127. LabelVDO IsRectEmpty
  128. pop ax
  129. pop dx
  130. pop bx ; get lprc
  131. pop cx
  132. push dx
  133. push ax
  134. beg_fault_trap ire_trap
  135. mov es,cx
  136. mov ax,TRUE
  137. mov cx,es:[bx].rcRight
  138. cmp cx,es:[bx].rcLeft
  139. jle empty0
  140. mov cx,es:[bx].rcBottom
  141. cmp cx,es:[bx].rcTop
  142. jle empty0
  143. xor ax,ax
  144. end_fault_trap
  145. empty0:
  146. retf
  147. ire_trap:
  148. fault_fix_stack
  149. jmp short empty0
  150. ;******************************************************************************
  151. ;* ORIGINAL C SOURCE
  152. ;*
  153. ;*BOOL FAR PtInRect(lprc, pt)
  154. ;*LPRECT lprc;
  155. ;*POINT pt;
  156. ;*{
  157. ;* return(pt.x >= lprc->left && pt.x < lprc->right &&
  158. ;* pt.y >= lprc->top && pt.y < lprc->bottom);
  159. ;*}
  160. ;*
  161. ;******************************************************************************
  162. cProcVDO PtInRect,<PUBLIC,FAR,NODATA>,<DS,SI>
  163. ; parmD lpRect
  164. ; parmD lpPoint
  165. cBegin nogen
  166. mov bx,sp
  167. push ds
  168. push si
  169. mov cx,ss:[bx+4] ; cx = pt.x
  170. mov dx,ss:[bx+6] ; dx = pt.y
  171. beg_fault_trap pir_trap
  172. lds si,ss:[bx+8] ; lpRect
  173. cld
  174. xor bx,bx ; Result = FALSE
  175. lodsw ; AX = lpRect->left
  176. cmp cx,ax ; xcoord < left?
  177. jl PtNotInRect ; Yes, not in rectangle
  178. lodsw ; AX = lpRect->top
  179. cmp dx,ax ; ycoord < top?
  180. jl PtNotInRect ; Yes, not in rectangle
  181. lodsw ; AX = lpRect->right
  182. cmp cx,ax ; xcoord >= right?
  183. jge PtNotInRect ; Yes, not in rectangle
  184. lodsw ; AX = lpRect->bottom
  185. cmp dx,ax ; ycoord >= bottom?
  186. jge PtNotInRect ; Yes, not in rectangle
  187. inc bx ; Point in rectangle, result = TRUE
  188. end_fault_trap
  189. PtNotInRect:
  190. mov ax,bx
  191. pop si
  192. pop ds
  193. retf 8
  194. cEnd nogen
  195. pir_trap:
  196. fault_fix_stack
  197. jmp short PtNotInRect
  198. ;******************************************************************************
  199. ;* ORIGINAL C SOURCE
  200. ;*
  201. ;*int FAR OffsetRect(pRect, x, y)
  202. ;*LPRECT pRect;
  203. ;*int x;
  204. ;*int y;
  205. ;*{
  206. ;* pRect->left += x;
  207. ;* pRect->right += x;
  208. ;* pRect->top += y;
  209. ;* pRect->bottom += y;
  210. ;*}
  211. ;*
  212. ;******************************************************************************
  213. cProcVDO OffsetRect,<FAR, PUBLIC, NODATA>,<DS>
  214. ; parmD lpRect ;far pointer to struct type rect
  215. ; parmW xDelta ;X delta
  216. ; parmW yDelta ;Y Delta
  217. cBegin nogen
  218. mov bx,sp
  219. push ds
  220. beg_fault_trap or_trap
  221. mov dx,ss:[bx+6] ; dx = dx
  222. mov cx,ss:[bx+4] ; CX = dy
  223. lds bx,ss:[bx+8] ; ds:bx = lprc
  224. add [bx].rcLeft,dx
  225. add [bx].rcTop,cx
  226. add [bx].rcRight,dx
  227. add [bx].rcBottom,cx
  228. end_fault_trap
  229. or_cont:
  230. pop ds
  231. retf 8
  232. cEnd
  233. or_trap:
  234. fault_fix_stack
  235. jmp short or_cont
  236. ;******************************************************************************
  237. ;* ORIGINAL C SOURCE
  238. ;*
  239. ;*int FAR InflateRect(pRect, x, y)
  240. ;*LPRECT pRect;
  241. ;*int x;
  242. ;*int y;
  243. ;*{
  244. ;* pRect->left -= x;
  245. ;* pRect->right += x;
  246. ;* pRect->top -= y;
  247. ;* pRect->bottom += y;
  248. ;*}
  249. ;*
  250. ;******************************************************************************
  251. cProcVDO InflateRect,<FAR, PUBLIC, NODATA>,<DS>
  252. ; parmD lpRect ;far pointer to struct type rect
  253. ; parmW xOffset
  254. ; parmW yOffset
  255. cBegin nogen
  256. mov bx,sp
  257. push ds
  258. beg_fault_trap ir_trap
  259. mov dx,ss:[bx+6] ; dx = dx
  260. mov cx,ss:[bx+4] ; CX = dy
  261. lds bx,ss:[bx+8] ; ds:bx = lprc
  262. sub [bx].rcLeft,dx
  263. sub [bx].rcTop,cx
  264. add [bx].rcRight,dx
  265. add [bx].rcBottom,cx
  266. end_fault_trap
  267. ir_cont:
  268. pop ds
  269. retf 8
  270. cEnd
  271. ir_trap:
  272. fault_fix_stack
  273. jmp short ir_cont
  274. ;-----------------------------------------------------------------
  275. ;
  276. ; IntersectRect(lprcDst, lprcSrc1, lprcSrc2);
  277. ;
  278. cProcVDO IntersectRect,<PUBLIC, FAR, NODATA>,<SI, DI, DS>
  279. ParmD lprcDst
  280. ParmD lprcSrc1
  281. ParmD lprcSrc2
  282. cBegin
  283. beg_fault_trap irc_trap
  284. lds si,lprcSrc1 ; point at source rects
  285. les di,lprcSrc2
  286. mov ax,[si].rcLeft ; new left = cx = max(rc1.left, rc2.left)
  287. mov cx,es:[di].rcLeft
  288. cmp ax,cx
  289. jl ir100
  290. xchg ax,cx
  291. ir100:
  292. mov ax,[si].rcRight ; new right = dx = min(rc1.right, rc2.right)
  293. mov dx,es:[di].rcRight
  294. cmp ax,dx
  295. jg ir200
  296. xchg ax,dx
  297. ir200:
  298. cmp cx,dx ; is left >= right?
  299. jge irempty ; yes - return empty rect
  300. mov ax,[si].rcTop ; new top = cx = max(rc1.top, rc2.top)
  301. mov bx,es:[di].rcTop
  302. cmp ax,bx
  303. jl ir300
  304. xchg ax,bx
  305. ir300:
  306. mov ax,[si].rcBottom ; new bottom = dx = min(rc1.bottom, rc2.bottom)
  307. mov di,es:[di].rcBottom
  308. cmp ax,di
  309. jg ir400
  310. xchg ax,di
  311. ir400:
  312. cmp bx,di ; is top >= bottom?
  313. jge irempty ; no: store result
  314. lds si,lprcDst ; store away new right & left
  315. mov [si].rcLeft,cx
  316. mov [si].rcTop,bx
  317. mov [si].rcRight,dx
  318. mov [si].rcBottom,di
  319. mov al,TRUE ; return TRUE
  320. end_fault_trap
  321. irexit:
  322. cEnd
  323. irc_trap:
  324. fault_fix_stack
  325. irempty:
  326. les di,lprcDst ; point at dst rect
  327. xor ax,ax ; set to (0, 0, 0, 0)
  328. cld
  329. stosw
  330. stosw
  331. stosw
  332. stosw ; return FALSE
  333. jmps irexit
  334. ;=============================================================================
  335. ;
  336. ; BOOL UnionRect(lprcDest, lprcSrc1, lprcSrc2)
  337. ; LPRECT lprcDest;
  338. ; LPRECT lprcSrc1;
  339. ; LPRECT lprcSrc2;
  340. ;
  341. ; Calculates *lprcDest as the minimum rectangle that bounds both
  342. ; *lprcSrc1 and *lprcSrc2. If either rectangle is empty, lprcDest
  343. ; is set to the other rectangle. Returns TRUE if the result is a non-empty
  344. ; rectangle, FALSE otherwise.
  345. ;
  346. ;
  347. cProcVDO UnionRect,<FAR, PUBLIC, NODATA>,<SI, DI, DS>
  348. ParmD lprcDest
  349. ParmD lprcSrc1
  350. ParmD lprcSrc2
  351. LocalW wTemp
  352. cBegin
  353. beg_fault_trap ur_trap
  354. lds si,lprcSrc1
  355. les di,lprcSrc2
  356. push es
  357. push di
  358. wcall IIsRectEmpty
  359. push ax ; save result
  360. ; IsRectEmpty trashes es....
  361. push es
  362. push ds
  363. push si
  364. wcall IIsRectEmpty
  365. pop es ; restore it
  366. pop cx
  367. ;ax = IsRectEmpty(1), cx = IsRectEmpty(2)
  368. or ax,ax
  369. jnz URrc1empty
  370. mov ax,TRUE ; return true, not both empty
  371. or cx,cx
  372. jz URnormalcase
  373. jmps URrc2empty
  374. URrc1empty:
  375. lds si,lprcSrc2
  376. jcxz URrc2empty ; rc2 not empty, ax has true for return
  377. xor ax,ax ; return false, both empty
  378. URrc2empty:
  379. les di,lprcDest
  380. cld
  381. movsw
  382. movsw
  383. movsw
  384. movsw
  385. jmps URexit
  386. ; src1 and src2 not empty
  387. URnormalcase:
  388. mov ax,[si].rcLeft ; bx = min(Src1.left, Src2.left)
  389. mov cx,es:[di].rcLeft
  390. cmp ax,cx
  391. jl URleft
  392. xchg ax,cx
  393. URleft:
  394. mov bx,ax
  395. mov ax,[si].rcTop ; dx = min(Src1.top, Src2.top)
  396. mov cx,es:[di].rcTop
  397. cmp ax,cx
  398. jl URtop
  399. xchg ax,cx
  400. URtop:
  401. mov dx,ax
  402. mov ax,[si].rcRight ; wTemp = max(Src1.right, Src2.right)
  403. mov cx,es:[di].rcRight
  404. cmp ax,cx
  405. jg URright
  406. xchg ax,cx
  407. URright:
  408. mov wTemp,ax
  409. mov ax,[si].rcBottom ; ax = max(Src1.bottom, Src2.bottom)
  410. mov cx,es:[di].rcBottom
  411. cmp ax,cx
  412. jg URbottom
  413. xchg ax,cx
  414. URbottom:
  415. les di,lprcDest ; fill into lprcDest
  416. mov es:[di].rcLeft,bx
  417. mov es:[di].rcTop,dx
  418. mov es:[di].rcBottom,ax
  419. mov ax,wTemp
  420. mov es:[di].rcRight,ax
  421. end_fault_trap
  422. ur_true:
  423. mov ax,TRUE ; return true, not both empty
  424. URexit:
  425. cEnd
  426. ur_trap:
  427. fault_fix_stack
  428. jmp ur_true
  429. ;******************************************************************************
  430. ;* ORIGINAL C SOURCE
  431. ;*
  432. ;*BOOL FAR EqualRect(lpRect1, lpRect2)
  433. ;*LPRECT lpRect1;
  434. ;*LPRECT lpRect2;
  435. ;*{
  436. ;* return lpRect1->left == lpRect2->left && lpRect1->top == lpRect2->top
  437. ;* && lpRect1->right == lpRect1->right && lpRect1->bottom ==
  438. ;* lpRect2->bottom;
  439. ;*}
  440. ;*
  441. ;******************************************************************************
  442. cProcVDO EqualRect, <FAR, PUBLIC, NODATA>, <SI, DI, DS>
  443. parmD lpRect1
  444. parmD lpRect2
  445. cBegin
  446. xor ax,ax ; assume FALSE
  447. beg_fault_trap er_trap
  448. lds si,lpRect1
  449. les di,lpRect2
  450. mov cx,4
  451. cld
  452. repz cmpsw
  453. jnz er10
  454. inc al
  455. end_fault_trap
  456. er10:
  457. cEnd
  458. er_trap:
  459. fault_fix_stack
  460. jmp er10
  461. ;****************************************************************************
  462. ; The following Routine to subtract one rectangle from another is lifted
  463. ; from PM and Modified by Sankar.
  464. ;
  465. ;****************************************************************************
  466. ;** Public Routine ****************************************************-;
  467. ; BOOL far SubtractRect(lprcDest, lprc1, lprc2)
  468. ; LPRECT lprcDest;
  469. ; LPRECT lprcSrc1;
  470. ; LPRECT lprcSrc2;
  471. ;
  472. ; This function subtracts *lprc2 from *lprc1, returning the result
  473. ; in *lprcDest. Returns TRUE if *lprcDest is non-empty, FALSE otherwise.
  474. ;
  475. ; Warning: Subtracting one rectangle from another may not
  476. ; always result in a rectangular area; in this case
  477. ; WinSubtractRect will return *lprc1 in *lprcDest.
  478. ; For this reason, WinSubtractRect provides only an
  479. ; approximation of subtraction. However, the area
  480. ; described by *lprcDest will always be greater
  481. ; than or equal to the "true" result of the
  482. ; subtraction.
  483. ;
  484. ; History :
  485. ; Added by Sankar on July 27, 1988
  486. ;**********************************************************************-;
  487. cProcVDO SubtractRect, <PUBLIC, FAR, NODATA>, <SI, DI, DS>
  488. ParmD lprcDest
  489. ParmD lprc1
  490. ParmD lprc2
  491. LocalV rc,%size RECT
  492. cBegin
  493. ;
  494. ; First copy lprc1 into lprcDest.
  495. ;
  496. beg_fault_trap sbr_trap
  497. lds si,lprc1
  498. les di,lprcDest
  499. cld
  500. movsw
  501. movsw
  502. movsw
  503. movsw
  504. lds si,lprcDest ; ds:[si] = lprcDest.
  505. lea di,rc ; ss:[di] = &rc
  506. ;
  507. ; We're subtracting lprc2 from lprc1. Make sure they at least
  508. ; intersect each other. If not, return TRUE.
  509. ;
  510. push ss ; pushd &rc
  511. push di
  512. push ds ; pushd lprcDest
  513. push si
  514. push seg_lprc2 ; pushd lprc2
  515. push off_lprc2
  516. wcall IIntersectRect
  517. or ax,ax ; Did we intersect?
  518. jz sr700 ; If no, skip to check empty rect
  519. ;
  520. ; Now make sure that we can subtract lprc2 from lprc1 and get a rect.
  521. ;
  522. errnz <rcLeft - 0>
  523. errnz <rcTop - 2>
  524. errnz <rcRight - 4>
  525. errnz <rcBottom - 6>
  526. ;
  527. ; We make a loop that iterates twice - once for the x's and once for the
  528. ; y's. We want at least 3 sides of lprc2 to be outside of 3 sides of lprc1.
  529. ;
  530. xor cx,cx
  531. xor dx,dx
  532. dec cx
  533. ;
  534. ; ds:si points to lprc1 (actually lprcDest)
  535. ; ss:di points to rc on stack
  536. ;
  537. sr100:
  538. inc cx
  539. mov bx,cx
  540. shl bx,1 ; bx is a Word pointer
  541. mov ax,ss:[di+bx].rcLeft ; if lprc2 left/top is > lprc1 l/t,
  542. cmp ax,ds:[si+bx].rcLeft
  543. jg sr200 ; then inside the rect.
  544. inc dx
  545. sr200:
  546. mov ax,ss:[di+bx].rcRight ; if lprc2 right/bottom is > lprc1 r/b,
  547. cmp ax,ds:[si+bx].rcRight
  548. jl sr300 ; then inside the rect.
  549. inc dx
  550. sr300:
  551. jcxz sr100 ; loop one more time...
  552. cmp dx,3 ; Are 3 sides outside? If not,
  553. jb sr700 ; skip to check empty rect code
  554. cmp dx,4 ; Is rc1 completely inside rc2? If so,
  555. jne sr350 ; empty lprcDest and return TRUE
  556. pushd lprcDest ; empty that puppy
  557. wcall ISetRectEmpty
  558. xor ax,ax ; Go return FALSE.
  559. jmps srExit
  560. sr350:
  561. ;
  562. ; Now we know that we can take lprc2 from lprc1 and leave a rect, so
  563. ; now we perform the 'subtract rect'. Interate twice, again once for the
  564. ; x's and once for the y's.
  565. ;
  566. xor cx,cx
  567. dec cx
  568. sr400:
  569. inc cx
  570. mov bx,cx
  571. shl bx,1 ; Make bx a Word pointer
  572. mov dx,ss:[di+bx].rcLeft ; New right/Bottom border?
  573. cmp dx,ds:[si+bx].rcLeft
  574. jle sr500
  575. mov ds:[si+bx].rcRight,dx
  576. jmps sr600
  577. sr500:
  578. mov dx,ss:[di+bx].rcRight ; New left/top border?
  579. cmp dx,ds:[si+bx].rcRight
  580. jge sr600
  581. mov ds:[si+bx].rcLeft,dx
  582. sr600:
  583. jcxz sr400
  584. sr700:
  585. xor ax,ax ; Assume it is empty: FALSE
  586. mov cx,ds:[si].rcRight
  587. cmp cx,ds:[si].rcLeft
  588. jle SrExit
  589. mov cx,ds:[si].rcBottom
  590. cmp cx,ds:[si].rcTop
  591. jle SrExit
  592. inc al ; Non-empty: return TRUE.
  593. end_fault_trap
  594. srExit:
  595. cEnd
  596. sbr_trap:
  597. fault_fix_stack
  598. xor ax,ax ; return FALSE
  599. jmp srExit
  600. ;****************************************************************************
  601. ;
  602. ; void FAR SplitRectangle(lprcRect, lprcRectArray, wcx, wcy)
  603. ; LPRECT lprcRect
  604. ; RECT lprcRectArray[4]
  605. ;
  606. ; This splits the given rectangular frame into four segments and stores
  607. ; them in the given array
  608. ;
  609. ; Pseudo code:
  610. ; -----------
  611. ;
  612. ; cxWidth = lprcRect -> rcRight - lprcRect -> rcLeft - wcx;
  613. ; cyWidth = lprcRect -> rcBottom - lprcRect -> rcTop - wcy;
  614. ;
  615. ; A = -cyWidth;
  616. ; B = -cxWidth;
  617. ;
  618. ; for (i = 0; i < 4; i++)
  619. ; {
  620. ; lprcRectArray[i][i] = lprcRect[i];
  621. ; lprcRectArray[i][(i+1)&3] = lprcRect[(i+3)&3] + A;
  622. ; lprcRectArray[i][(i+2)&3] = lprcRect[(i+2)&3] + B;
  623. ; lprcRectArray[i][(i+3)&3] = lprcRect[(i+3)];
  624. ;
  625. ; TMP = A;
  626. ; A = -B;
  627. ; B = TMP;
  628. ; }
  629. ;
  630. ; Note:
  631. ; Value of i Value of A Value of B
  632. ; ---------- ---------- ----------
  633. ; 0 -cyWidth -cxWidth
  634. ; 1 +cxWidth -cyWidth
  635. ; 2 +cyWidth +cxWidth
  636. ; 3 -cxWidth +cyWidth
  637. ;
  638. ;
  639. ;***************************************************************************
  640. cProc SplitRectangle, <FAR, PUBLIC, NODATA>, <SI, DI, DS>
  641. ParmD <lprcRect, lprcRectArray> ; Rect and Array
  642. Parmw <wcx, wcy> ; Border widths
  643. cBegin
  644. les di, lprcRectArray ; es:di => lprcRectArray
  645. lds si, lprcRect ; ds:si => given rectangle
  646. ; Calculate the value of -cxWidth
  647. mov ax, [si].rcLeft
  648. sub ax, [si].rcRight
  649. add ax, wcx
  650. push ax ; Save B on stack.
  651. ; Calculate the value of -cyWidth
  652. mov ax, [si].rcTop
  653. sub ax, [si].rcBottom
  654. add ax, wcy
  655. push ax ; Save A on stack
  656. ; Initialise the loop related variables
  657. xor cx, cx ; Loop count
  658. xor bx, bx ; Index into Rect Structure.
  659. LoopSt:
  660. ; lprcRectArray[i][i] = lprcRect[i];
  661. mov ax, [si+bx]
  662. mov es:[di+bx], ax
  663. ; lprcRectArray[i][(i+1)&3] = lprcRect[(i+3)&3] + A;
  664. inc bx
  665. inc bx ; Make it a word pointer
  666. and bx, 6
  667. push bx ; Save (i+1) tempoarily
  668. add bx, 4 ; Calculate (i+3)
  669. and bx, 6
  670. mov ax, [si+bx] ; lprcRect[(i+3)] is taken
  671. pop bx ; (i+1) is returned to bx
  672. pop dx ; Value "A" is taken from stack
  673. add ax, dx
  674. mov es:[di+bx], ax
  675. ; Swap A and B on stack. A is in DX
  676. pop ax ; Value B from Stack.
  677. push dx ; B = A;
  678. Push ax ; A = B;
  679. ; Now B is on top of stack and A is below it.
  680. ; lprcRectArray[i][(i+2)&3] = lprcRect[(i+2)&3] + B;
  681. inc bx
  682. inc bx ; (i+2) is calculated
  683. and bx, 6
  684. mov ax, [si+bx]
  685. pop dx ; pop B
  686. add ax, dx
  687. mov es:[di+bx], ax
  688. neg dx ; make -B
  689. push dx
  690. ; lprcRectArray[i][(i+3)&3] = lprcRect[(i+3)];
  691. inc bx
  692. inc bx
  693. and bx, 6 ; make [(i+3)&3]
  694. mov ax, [si+bx]
  695. mov es:[di+bx], ax
  696. inc cx
  697. cmp cx, 4
  698. jge exit
  699. mov bx, cx
  700. shl bx, 1 ; Make it a word pointer
  701. add di, size RECT ; Make it point to next rect in the array
  702. jmp LoopSt
  703. exit:
  704. ; A and B exist on stack. So,Pop them
  705. add sp, 4
  706. cEnd
  707. sEnd TEXT
  708. end