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.

618 lines
13 KiB

  1. ;++
  2. ;
  3. ; WOW v1.0
  4. ;
  5. ; Copyright (c) 1991, Microsoft Corporation
  6. ;
  7. ; WINUTIL.ASM
  8. ; Win16 general utility routines
  9. ;
  10. ; History:
  11. ;
  12. ; Created 28-May-1991 by Jeff Parsons (jeffpar)
  13. ; Copied from WIN31 and edited (as little as possible) for WOW16.
  14. ; At this time, all we want is MultDiv() and LCopyStruct(), which the
  15. ; edit controls use.
  16. ;--
  17. ;****************************************************************************
  18. ;* *
  19. ;* WINUTIL.ASM - *
  20. ;* *
  21. ;* General Utility Routines *
  22. ;* *
  23. ;****************************************************************************
  24. title WINUTIL.ASM - General Utility routines
  25. ifdef WOW
  26. NOEXTERNS equ 1
  27. SEGNAME equ <TEXT>
  28. endif
  29. .xlist
  30. include user.inc
  31. .list
  32. ;*==========================================================================*
  33. ;* *
  34. ;* FFFE Segment Definition - *
  35. ;* *
  36. ;*==========================================================================*
  37. createSeg _%SEGNAME, %SEGNAME, WORD, PUBLIC, CODE
  38. assumes cs,%SEGNAME
  39. assumes ds,DATA
  40. ExternFP <GetStockObject>
  41. ExternFP <GetTextExtent>
  42. ExternFP <TextOut>
  43. ExternA <__WinFlags>
  44. ifdef FE_SB ; **** April,26,1990 by KenjiK ****
  45. ExternFP IsDBCSLeadByte
  46. endif
  47. sBegin DATA
  48. sEnd DATA
  49. sBegin %SEGNAME
  50. ;*--------------------------------------------------------------------------*
  51. ;* *
  52. ;* MultDiv() - *
  53. ;* *
  54. ;*--------------------------------------------------------------------------*
  55. ; Calc a * b / c, with 32-bit intermediate result
  56. cProc MultDiv, <PUBLIC, FAR>
  57. ;ParmW a
  58. ;ParmW b
  59. ;ParmW c
  60. cBegin nogen
  61. mov bx,sp
  62. ; calc (a * b + c/2) / c
  63. mov ax,ss:[bx+8] ; ax = a
  64. mov cx,ss:[bx+4] ; cx = c
  65. or cx,cx
  66. jz mdexit ; just return A if we'll get divide by 0
  67. mov dx,ss:[bx+6] ; dx=b
  68. imul dx
  69. mov bx,cx ; save a copy of c in bx for later
  70. shr cx,1 ; add in cx/2 for rounding
  71. add ax,cx
  72. adc dx,0 ; add in carry if needed
  73. ; get c from bx register since idev mem
  74. idiv bx ; doesn't work on tandy 2000's
  75. mdexit:
  76. retf 6
  77. cEnd nogen
  78. ifdef DISABLE
  79. ;*--------------------------------------------------------------------------*
  80. ;* *
  81. ;* min() - *
  82. ;* *
  83. ;*--------------------------------------------------------------------------*
  84. cProc min, <FAR, PUBLIC>
  85. ;ParmW a
  86. ;ParmW b
  87. cBegin nogen
  88. mov bx,sp
  89. mov ax,ss:[bx+6] ;ax = a
  90. mov cx,ss:[bx+4] ;cx = b
  91. cmp ax,cx
  92. jl min10
  93. mov ax,cx
  94. min10:
  95. retf 4
  96. cEnd nogen
  97. ;*--------------------------------------------------------------------------*
  98. ;* *
  99. ;* max() - *
  100. ;* *
  101. ;*--------------------------------------------------------------------------*
  102. cProc max, <FAR, PUBLIC>
  103. ;ParmW a
  104. ;ParmW b
  105. cBegin nogen
  106. mov bx,sp
  107. mov ax,ss:[bx+6] ;ax = a
  108. mov cx,ss:[bx+4] ;cx = b
  109. cmp ax,cx
  110. jg max10
  111. mov ax,cx
  112. max10:
  113. retf 4
  114. cEnd nogen
  115. ;*--------------------------------------------------------------------------*
  116. ;* *
  117. ;* umin() - *
  118. ;* *
  119. ;*--------------------------------------------------------------------------*
  120. cProc umin, <FAR, PUBLIC>
  121. ;ParmW a
  122. ;ParmW b
  123. cBegin nogen
  124. mov bx,sp
  125. mov ax,ss:[bx+6] ;ax = a
  126. mov cx,ss:[bx+4] ;cx = b
  127. cmp ax,cx
  128. jb umin10
  129. mov ax,cx
  130. umin10:
  131. retf 4
  132. cEnd nogen
  133. ;*--------------------------------------------------------------------------*
  134. ;* *
  135. ;* umax() - *
  136. ;* *
  137. ;*--------------------------------------------------------------------------*
  138. cProc umax, <FAR, PUBLIC>
  139. ;ParmW a
  140. ;ParmW b
  141. cBegin nogen
  142. mov bx,sp
  143. mov ax,ss:[bx+6] ;ax = a
  144. mov cx,ss:[bx+4] ;cx = b
  145. cmp ax,cx
  146. ja umax10
  147. mov ax,cx
  148. umax10:
  149. retf 4
  150. cEnd nogen
  151. endif ; DISABLE
  152. ;*--------------------------------------------------------------------------*
  153. ;* *
  154. ;* LFillStruct() - *
  155. ;* *
  156. ;*--------------------------------------------------------------------------*
  157. cProc LFillStruct, <PUBLIC, FAR, NODATA, ATOMIC>, <di>
  158. parmD lpStruct
  159. parmW cb
  160. parmW fillChar
  161. cBegin
  162. les di,lpStruct
  163. mov cx,cb
  164. mov ax,fillChar
  165. cld
  166. rep stosb
  167. cEnd LFillStruct
  168. ;*--------------------------------------------------------------------------*
  169. ;* *
  170. ;* LCopyStruct() - *
  171. ;* *
  172. ;*--------------------------------------------------------------------------*
  173. ; LCopyStruct(pbSrc, pbDst, cb)
  174. cProc LCopyStruct, <FAR, PUBLIC>
  175. ;ParmD pSrc
  176. ;ParmD pDest
  177. ;ParmW cb
  178. cBegin nogen
  179. mov bx,sp
  180. mov cx,ss:[bx+4] ; cx = cb
  181. jcxz lcopynone ; Nothing to do if count == 0
  182. push si
  183. push di
  184. mov dx,ds ; save ds
  185. lds si,ss:[bx+4+2+4] ; ds:si = pSrc
  186. les di,ss:[bx+4+2] ; es:di = pDst
  187. cmp si,di ; Could they overlap?
  188. jae lcopyok
  189. mov ax,cx ; Yes: copy from the top down
  190. dec ax
  191. dec ax
  192. add si,ax
  193. add di,ax
  194. std
  195. shr cx,1
  196. rep movsw
  197. jnc @F ; an odd byte to blt?
  198. inc si ; went one too far: back up.
  199. inc di
  200. movsb
  201. @@:
  202. cld
  203. jmps lcopydone
  204. lcopyok:
  205. cld
  206. shr cx,1
  207. rep movsw
  208. jnc @F ; an odd byte to blt?
  209. movsb
  210. @@:
  211. lcopydone:
  212. mov ds,dx
  213. pop di
  214. pop si
  215. lcopynone:
  216. retf 4+4+2
  217. cEnd nogen
  218. ifndef WOW
  219. ;*--------------------------------------------------------------------------*
  220. ;* *
  221. ;* The following routines are "Movable DS" equivalents of their normal *
  222. ;* counterparts. The PS stands for "Pointer Safe." They prevent problems *
  223. ;* which occur when an app passes in a pointer to an object in its DS *
  224. ;* which we somehow cause to move. To prevent this problem, we copy what *
  225. ;* the pointer points to into USER's DS and use a pointer to our copy *
  226. ;* instead. *
  227. ;* *
  228. ;*--------------------------------------------------------------------------*
  229. ;*--------------------------------------------------------------------------*
  230. ;* *
  231. ;* PSGetTextExtent() - *
  232. ;* *
  233. ;*--------------------------------------------------------------------------*
  234. ifndef PMODE
  235. cProc PSGetTextExtent, <PUBLIC, FAR, NODATA>, <si,di>
  236. ParmW hdc
  237. ParmD lpch
  238. ParmW cch
  239. LocalV rgch, 128 ; max 128 chars
  240. cBegin
  241. mov ax,__WinFlags
  242. test al,WF_PMODE
  243. errnz high(WF_PMODE)
  244. jz PSGTE_RealMode
  245. push hdc
  246. pushd lpch
  247. push cch
  248. jmp short PSGTE_GetExtent
  249. PSGTE_RealMode:
  250. lea di,rgch ; es:di = dest
  251. push ss
  252. pop es
  253. lds si,lpch ; ds:si = src
  254. mov cx,cch ; count = min(cch, 128)
  255. mov ax,128
  256. cmp cx,ax
  257. jbe gte100
  258. xchg ax,cx
  259. gte100: push hdc ; Push args before rep movsb destroys
  260. push ss ; cx and di
  261. push di
  262. push cx
  263. cld
  264. rep movsb ; Copy string to local storage
  265. PSGTE_GetExtent:
  266. call GetTextExtent
  267. cEnd PSGetTextExtent
  268. ;*--------------------------------------------------------------------------*
  269. ;* *
  270. ;* PSTextOut() - *
  271. ;* *
  272. ;*--------------------------------------------------------------------------*
  273. ; void PSTextOut(hdc, lpch, cch)
  274. cProc PSTextOut,<PUBLIC, FAR, NODATA>, <si, di>
  275. ParmW hdc
  276. ParmW x
  277. ParmW y
  278. ParmD lpch
  279. ParmW cch
  280. LocalV rgch, 255 ; max 255 chars
  281. cBegin
  282. mov ax,__WinFlags
  283. test al,WF_PMODE
  284. errnz high(WF_PMODE)
  285. jz PSTO_RealMode
  286. push hdc
  287. push x
  288. push y
  289. pushd lpch
  290. push cch
  291. jmp short PSTO_TextOut
  292. PSTO_RealMode:
  293. lea di,rgch ; es:di = dest
  294. push ss
  295. pop es
  296. lds si,lpch ; ds:si = src
  297. mov cx,cch ; count = min(cch, 255)
  298. mov ax,255
  299. cmp cx,ax
  300. jbe to100
  301. xchg ax,cx
  302. to100: push hdc ; Push args before rep movsb destroys
  303. push x ; cx and di
  304. push y
  305. push ss ; Push &rgch[0]
  306. push di
  307. push cx
  308. cld
  309. rep movsb ; copy string before we go
  310. PSTO_TextOut:
  311. call TextOut
  312. cEnd PSTextOut
  313. endif ; ifndef PMODE
  314. ;*--------------------------------------------------------------------------*
  315. ;* *
  316. ;* FindCharPosition() - *
  317. ;* *
  318. ;*--------------------------------------------------------------------------*
  319. ; Finds position of char ch in string psz. If none, returns the length of
  320. ; the string.
  321. cProc FindCharPosition, <FAR, PUBLIC, NODATA>, <si, ds>
  322. ParmD psz
  323. ParmB char
  324. cBegin
  325. lds si,psz
  326. fcp100: lodsb ; get a byte
  327. or al,al
  328. jz fcp200
  329. ifdef FE_SB ; **** April,26,1990 by KenjiK ****
  330. sub ah,ah
  331. push ax
  332. cCall IsDBCSLeadByte,<ax> ; first byte of double byte?
  333. test ax,ax
  334. pop ax
  335. jz fcp150 ; no just do normal stuff
  336. lodsb ; skip second byte of double byte
  337. jmps fcp100 ; and do again
  338. fcp150:
  339. endif
  340. cmp al,char
  341. jnz fcp100
  342. fcp200: xchg ax,si ; calc char index: pch - 1 - psz
  343. dec ax
  344. sub ax,off_psz
  345. cEnd FindCharPosition
  346. endif ;WOW
  347. sEnd %SEGNAME
  348. ifndef WOW
  349. ;*==========================================================================*
  350. ;* *
  351. ;* RUNAPP Segment Definition - *
  352. ;* *
  353. ;*==========================================================================*
  354. createSeg _RUNAPP, RUNAPP, BYTE, PUBLIC, CODE
  355. sBegin RUNAPP
  356. assumes cs,RUNAPP
  357. assumes ds,DATA
  358. ;*--------------------------------------------------------------------------*
  359. ;* *
  360. ;* CrunchX2() - *
  361. ;* *
  362. ;*--------------------------------------------------------------------------*
  363. ; This routine copies the pile of bits from the source pointer
  364. ; to the dest pointer doing the integer crunch as it goes
  365. ; it will favor black (0) to white (1) and will keep the destinations
  366. ; widthbytes even.
  367. ;
  368. ; Assumptions: Neither source nor destination are greater than 64K
  369. ; Either the two bitmaps, lpSrc and lpDst are disjoint
  370. ; or lpDst <= lpSrc (i.e. we fill from the front)
  371. ; WidthBytes is even
  372. cProc CrunchX2, <FAR, PUBLIC, NODATA>, <ds, si, di>
  373. parmD lpSrc
  374. parmD lpDst
  375. parmW WidthBytes
  376. parmW Height
  377. LocalW dwb ; destination width if not corrected
  378. LocalW destinc ; used to force dest width even each scan
  379. cBegin
  380. cld
  381. lds si,lpSrc
  382. les di,lpDst
  383. mov bx,Height
  384. ; Compute destination widthbytes
  385. mov ax,WidthBytes ; must be even
  386. shr ax,1 ; widthbytes for the destination
  387. mov dwb,ax
  388. and ax,1 ; iff odd must inc dest pointer
  389. mov destinc,ax ; at the end of each scan
  390. sub di,ax
  391. NextSX: dec bx
  392. jl exitX
  393. mov cx,dwb
  394. add di,destinc
  395. CrunchBX:
  396. lodsw
  397. mov dx,ax
  398. rol ax,1
  399. and dx,ax ; this and selects 0 in favor of 1
  400. mov al,dl
  401. shl ax,1
  402. shl al,1
  403. shl ax,1
  404. shl al,1
  405. shl ax,1
  406. shl al,1
  407. shl ax,1
  408. mov al,dh
  409. shl ax,1
  410. shl al,1
  411. shl ax,1
  412. shl al,1
  413. shl ax,1
  414. shl al,1
  415. shl ax,1
  416. mov al,ah
  417. stosb
  418. loop CrunchBX
  419. jmp NextSX
  420. exitX:
  421. cEnd CrunchX2
  422. ;*--------------------------------------------------------------------------*
  423. ;* *
  424. ;* CrunchY() - *
  425. ;* *
  426. ;*--------------------------------------------------------------------------*
  427. cProc CrunchY, <FAR, PUBLIC, NODATA>, <ds, si, di>
  428. parmD lpSrc
  429. parmD lpDst
  430. parmW WidthBytes
  431. parmW Height
  432. parmW scale
  433. LocalW groupcount ;Height/scale
  434. LocalW groupinc ;WidthBytes * Height/Scale
  435. LocalW scancount ;counter of bytes in scan reset each group
  436. LocalW bytecount ;number of bytes joined = scale - 1
  437. cBegin
  438. cld
  439. lds si,lpSrc
  440. les di,lpDst
  441. ; Compute group count
  442. mov bx,scale ; only scale positive
  443. cmp bx,1
  444. jle CopyBitmap
  445. mov ax,Height
  446. xor dx,dx
  447. div bx
  448. mov groupcount,ax ; Height/scale
  449. mov cx,WidthBytes ; must be even
  450. dec bx
  451. mov bytecount,bx
  452. mov ax,bx
  453. mul cx
  454. mov groupinc,ax ; WidthBytes * (scale - 1)
  455. mov dx,cx
  456. mov bx,si
  457. sub bx,groupinc
  458. dec bx
  459. dec bx
  460. NextGroup:
  461. dec groupcount
  462. jl exitY
  463. add bx,groupinc
  464. mov ax,dx
  465. shr ax,1
  466. mov scancount,ax
  467. NextByte:
  468. dec scancount
  469. jl NextGroup
  470. inc bx
  471. inc bx
  472. mov si,bx
  473. mov ax,[si]
  474. mov cx,bytecount
  475. CrunchBY:
  476. add si,dx
  477. and ax,[si]
  478. loop CrunchBY
  479. stosw
  480. jmp NextByte
  481. CopyBitmap:
  482. mov ax,Height
  483. mul WidthBytes
  484. shr ax,1
  485. mov cx,ax
  486. rep movsw
  487. exitY:
  488. cEnd CrunchY
  489. sEnd RUNAPP
  490. endif ;WOW
  491. end