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.

473 lines
13 KiB

  1. TITLE lib - various C library routines
  2. ; Windows Write, Copyright 1985-1992 Microsoft Corporation
  3. ;=============================================================================
  4. ; This file contains various C library functions (and a few other
  5. ; functions) with the PL/M calling conventions. These routines
  6. ; may some day make their way into a real library of some kind, but
  7. ; until then, you'll just have to link this file in with the rest
  8. ; of your code.
  9. ;=============================================================================
  10. ?PLM = 1
  11. ?WIN = 1
  12. ;*** See note about cmacros2.inc in DOSLIB.ASM
  13. include cmacros3.inc
  14. ;
  15. ;createSeg _MMP2, code, byte, public, CODE
  16. ;
  17. sBegin CODE
  18. ; assumes CS,_MMP2
  19. assumes CS,CODE
  20. ;------------------------------------------------------------------------------
  21. ; bltbyte (pbFrom, pbTo, cb) - a block transfer of bytes from pbFrom to
  22. ; pbTo. The size of the block is cb bytes. This bltbyte() handles the
  23. ; case of overlapping source and destination. bltbyte() returns a pointer
  24. ; to the end of the destination buffer (pbTo + cb). NOTE - use this
  25. ; bltbyte to transfer within the current DS only--use the bltbx for
  26. ; FAR blts.
  27. ;-----------------------------------------------------------------------------
  28. cProc bltbyte, <FAR, PUBLIC>, <SI, DI>
  29. parmDP <pbFrom, pbTo>
  30. parmW <cb>
  31. cBegin bltbyte
  32. mov si,pbFrom ; get pointers and length of blt
  33. mov di,pbTo
  34. mov cx,cb
  35. mov ax,di ; calculate return value
  36. add ax,cx
  37. push ds ; set up segment registers
  38. pop es
  39. cmp si,di ; reverse direction of the blt if
  40. jae bltb1 ; necessary
  41. add si,cx
  42. add di,cx
  43. dec si
  44. dec di
  45. std
  46. bltb1:
  47. rep movsb
  48. cld
  49. cEnd bltbyte
  50. ;-----------------------------------------------------------------------------
  51. ; bltbx (qbFrom, qbTo, cb) - same as bltbyte above except everything is
  52. ; handled as FAR pointers.
  53. ;-----------------------------------------------------------------------------
  54. cProc bltbx, <FAR, PUBLIC>, <SI, DI, DS>
  55. parmD <qbFrom, qbTo>
  56. parmW <cb>
  57. cBegin bltbx
  58. les di,qbTo
  59. lds si,qbFrom
  60. mov cx,cb
  61. mov ax,di
  62. add ax,cx
  63. cmp si,di
  64. jae bltbx1
  65. add si,cx
  66. add di,cx
  67. dec si
  68. dec di
  69. std
  70. bltbx1:
  71. rep movsb
  72. cld
  73. mov dx,es
  74. cEnd bltbx
  75. ;------------------------------------------------------------------------------
  76. ; blt (pFrom, pTo, cw) - a block transfer of wFills from pFrom to pTo;
  77. ; The size of the block is cw wFills. This blt() handles the case of
  78. ; overlapping source and destination. blt() returns a pointer to the
  79. ; end of the destination buffer (pTo + cw). NOTE - use this blt() to
  80. ; to transfer within the current DS only--use the bltx for FAR blts.
  81. ;-----------------------------------------------------------------------------
  82. cProc blt, <FAR, PUBLIC>, <SI, DI>
  83. parmDP <pFrom, pTo>
  84. parmW <cw>
  85. cBegin blt
  86. mov si,pFrom ; get pointers and length of blt
  87. mov di,pTo
  88. mov cx,cw
  89. mov ax,di ; calculate return value
  90. mov bx,cx
  91. shl bx,1
  92. add ax,bx
  93. push ds ; set up segment registers
  94. pop es
  95. cmp si,di ; reverse direction of the blt if
  96. jae blt1 ; necessary
  97. dec bx
  98. dec bx
  99. add si,bx
  100. add di,bx
  101. std
  102. blt1:
  103. rep movsw
  104. cld
  105. cEnd blt
  106. ;-----------------------------------------------------------------------------
  107. ; bltx (qFrom, qTo, cw) - same as blt() above except everything is
  108. ; handled as FAR pointers.
  109. ;-----------------------------------------------------------------------------
  110. cProc bltx, <FAR, PUBLIC>, <si, di, ds>
  111. parmD <qFrom, qTo>
  112. parmW <cw>
  113. cBegin bltx
  114. les di,qTo
  115. lds si,qFrom
  116. mov cx,cw
  117. mov ax,di
  118. mov bx,cx
  119. shl bx,1
  120. add ax,bx
  121. cmp si,di
  122. jae bltx1
  123. dec bx
  124. dec bx
  125. add si,bx
  126. add di,bx
  127. std
  128. bltx1:
  129. rep movsw
  130. cld
  131. mov dx,es
  132. cEnd bltx
  133. ;-----------------------------------------------------------------------------
  134. ; bltc (pTo, wFill, cw) - fills cw words of memory starting at pTo with wFill.
  135. ;-----------------------------------------------------------------------------
  136. cProc bltc, <FAR, PUBLIC>, <DI>
  137. parmDP <pTo>
  138. parmW <wFill, cw>
  139. cBegin bltc
  140. mov ax,ds ; we are filling in the data segment
  141. mov es,ax
  142. mov di,pTo ; get the destination, constant, and count
  143. mov ax,wFill
  144. mov cx,cw
  145. cld ; the operation is forward
  146. rep stosw ; fill memory
  147. cEnd bltc
  148. ;-----------------------------------------------------------------------------
  149. ; bltcx (qTo, wFill, cw) - fills cw words of memory starting at FAR location
  150. ; qTo with wFill.
  151. ;-----------------------------------------------------------------------------
  152. cProc bltcx, <FAR, PUBLIC>, <DI>
  153. parmD <qTo>
  154. parmW <wFill, cw>
  155. cBegin bltcx
  156. les di,qTo ; get the destination, constant, and count
  157. mov ax,wFill
  158. mov cx,cw
  159. cld ; the operation is forward
  160. rep stosw ; fill memory
  161. cEnd bltcx
  162. ;-----------------------------------------------------------------------------
  163. ; bltbc (pTo, bFill, cb) - fills cb bytes of memory starting at pTo with
  164. ; bFill.
  165. ;-----------------------------------------------------------------------------
  166. cProc bltbc, <FAR, PUBLIC>, <DI>
  167. parmDP <pTo>
  168. parmB <bFill>
  169. parmW <cb>
  170. cBegin bltbc
  171. mov ax,ds ; we are filling in the data segment
  172. mov es,ax
  173. mov di,pTo ; get the destination, constant, and count
  174. mov al,bFill
  175. mov cx,cb
  176. cld ; the operation is forward
  177. rep stosb ; fill memory
  178. cEnd bltbc
  179. ;-----------------------------------------------------------------------------
  180. ; bltbcx (qTo, bFill, cb) - fills cb bytes of memory starting at FAR location
  181. ; qTo with bFill.
  182. ;-----------------------------------------------------------------------------
  183. cProc bltbcx, <FAR, PUBLIC>, <DI>
  184. parmD <qTo>
  185. parmB <bFill>
  186. parmW <cb>
  187. cBegin bltbcx
  188. les di,qTo ; get the destination, constant, and count
  189. mov al,bFill
  190. mov cx,cb
  191. cld ; the operation is forward
  192. rep stosb ; fill memory
  193. cEnd bltbcx
  194. ;-----------------------------------------------------------------------------
  195. ; MultDiv(w, Numer, Denom) returns (w * Numer) / Denom rounded to the nearest
  196. ; integer. A check is made so that division by zero is not attempted.
  197. ;-----------------------------------------------------------------------------
  198. cProc MultDiv, <FAR, PUBLIC>
  199. parmW <w, Numer, Denom>
  200. cBegin MultDiv
  201. mov bx,Denom ; get the demoninator
  202. mov cx,bx ; cx holds the final sign
  203. or bx,bx ; ensure the denominator is positive
  204. jns md1
  205. neg bx
  206. md1:
  207. mov ax,w ; get the word we are multiplying
  208. xor cx,ax ; make cx reflect any sign change
  209. or ax,ax ; ensure this word is positive
  210. jns md2
  211. neg ax
  212. md2:
  213. mov dx,Numer ; get the numerator
  214. xor cx,dx ; make cx reflect any sign change
  215. or dx,dx ; ensure the numerator is positive
  216. jns md3
  217. neg dx
  218. md3:
  219. mul dx ; multiply
  220. mov cl,bl ; get half of the demoninator to adjust for rounding
  221. sar bx,1
  222. add ax,bx ; adjust for possible rounding error
  223. adc dx,0 ; this is really a long addition
  224. sal bx,1 ; restore the demoninator
  225. or bl,cl
  226. cmp dx,bx ; check for overflow
  227. jae md5
  228. div bx ; divide
  229. or ax,ax ; if sign is set, then overflow occured
  230. js md5
  231. or cx,cx ; put the sign on the result
  232. jns md4
  233. neg ax
  234. md4:
  235. cEnd MultDiv
  236. md5:
  237. mov ax,7FFFh ; return the largest integer
  238. or cx,cx ; with the correct sign
  239. jns md4
  240. neg ax
  241. jmp md4
  242. ;-----------------------------------------------------------------------------
  243. ; FSzSame (szOne, szTwo) - Compare strings, return 1=Same, 0=different
  244. ; Both strings in DS
  245. ;-----------------------------------------------------------------------------
  246. cProc FSzSame, <FAR, PUBLIC>, <SI>
  247. parmDP <szOne>
  248. parmDP <szTwo>
  249. cBegin FszSame
  250. mov bx,szOne
  251. mov si,szTwo
  252. fszloop:
  253. mov al,[bx]
  254. cmp al,[si]
  255. jnz notequal ; found inequality - return FALSE
  256. inc bx
  257. inc si
  258. test al,al
  259. jnz fszloop ; didn't reach a zero-terminator compare next char
  260. mov ax,1
  261. jmp fszend
  262. notequal:
  263. xor ax,ax
  264. fszend:
  265. cEnd FszSame
  266. ;-----------------------------------------------------------------------------
  267. ; CchDiffer (rgch1,rgch2,cch) - compare 2 strings, returning cch of
  268. ; shortest prefix leaving a common remainder
  269. ; implementation of the following C code
  270. ; note rather odd return values: 0 if =, # of unmatched chars +1 otherwise.
  271. ; note comparison is from end of string
  272. ;** int CchDiffer(rgch1, rgch2, cch)
  273. ;** register CHAR *rgch1, *rgch2;
  274. ;** int cch;
  275. ;** {{ /* Return cch of shortest prefix leaving a common remainder */
  276. ;** int ich;
  277. ;** for (ich = cch - 1; ich >= 0; ich--)
  278. ;** if (rgch1[ich] != rgch2[ich])
  279. ;** break;
  280. ;** return ich + 1;
  281. ;** }}
  282. ;-----------------------------------------------------------------------------
  283. cProc CchDiffer, <FAR, PUBLIC>, <SI,DI>
  284. parmDP <rgch1>
  285. parmDP <rgch2>
  286. parmW <cch>
  287. cBegin CchDiffer
  288. mov ax,ds ; set es=ds for string ops
  289. mov es,ax
  290. mov si,rgch1
  291. mov di,rgch2
  292. mov cx,cch ; loop count in cx
  293. mov ax,cx ; compare from end of string down
  294. dec ax
  295. add si,ax
  296. add di,ax
  297. std
  298. repz cmpsb ; compare strings
  299. jz DiffRet ; return 0 if strings =
  300. inc cx ; else increment return value
  301. DiffRet:
  302. mov ax,cx ; return # of unmatched chars
  303. cld ; restore to be nice
  304. cEnd CchDiffer
  305. ifdef DEBUG
  306. ;-----------------------------------------------------------------------------
  307. ; toggleProf () - toggles winprof (windows profiler) profiling on or off.
  308. ; this calls to hard coded locations that both symdeb and winprof know
  309. ; about - see Lyle Kline for an actual explanation.
  310. ;-----------------------------------------------------------------------------
  311. cProc toggleProf, <FAR, PUBLIC>
  312. cBegin toggleProf
  313. ; ** the following strings are stored by the profiler starting at
  314. ; ** 100h of the loaded segment. This routine checks that the 1st
  315. ; ** 3 letters of each string are in the proper location to determine
  316. ; ** whether the profiler is already loaded.
  317. ; **** segname db "SEGDEBUG",0
  318. ; **** db "PROFILER",0
  319. push es
  320. push di
  321. push si
  322. xor ax,ax
  323. mov es,ax
  324. mov ax,es:[14] ;Get segment down there.
  325. mov es,ax
  326. mov di,0100h ;See if Profiler in memory.
  327. cmp Byte Ptr es:[di],'S'
  328. jnz $0001
  329. cmp Byte Ptr es:[di+1],'E'
  330. jnz $0001
  331. cmp Byte Ptr es:[di+2],'G'
  332. jnz $0001
  333. cmp Byte Ptr es:[di+9],'P'
  334. jnz $0001
  335. cmp Byte Ptr es:[di+10],'R'
  336. jnz $0001
  337. mov ax,30 ;Type of call.
  338. push ax
  339. mov di,00FCh
  340. call Dword Ptr es:[di] ; call to profiler toggle routine.
  341. add sp,2 ; winprof uses normal c conventions
  342. $0001:
  343. pop si
  344. pop di
  345. pop es
  346. cEnd toggleProf
  347. endif
  348. ;-----------------------------------------------------------------------------
  349. ; void OsTime( pTime )
  350. ;
  351. ; pTime is a pointer to a structure of the form:
  352. ; struct {
  353. ; char min; Minutes (0-59)
  354. ; char hour; Hours (0-23)
  355. ; char hsec; Hundredths of seconds (0-99)
  356. ; char sec; Seconds (0-59)
  357. ;
  358. ; Get current time into structure
  359. ; DOS-specific
  360. ;-----------------------------------------------------------------------------
  361. cProc OsTime, <FAR, PUBLIC>
  362. parmDP <pTime>
  363. cBegin OsTime
  364. mov ah,2ch
  365. int 21h
  366. mov bx,pTime
  367. mov WORD PTR [bx], cx
  368. mov WORD PTR [bx+2], dx
  369. cEnd OsTime
  370. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  371. ; Added by PaulT 3/23/89, borrowed from PC Word 5:
  372. ;
  373. ; IchIndexLp(lpsz, ch)
  374. ; char far *lpsz;
  375. ; int ch;
  376. ; Searches for ch in lpsz and returns the index (-1 if not found)
  377. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  378. cProc IchIndexLp,<FAR, PUBLIC>
  379. parmD lpsz
  380. parmB chT
  381. cBegin
  382. mov dx, di ; Save di
  383. les di, lpsz
  384. mov ah, chT
  385. xor al,al
  386. mov bx, di ; Save initial pointer
  387. ; **** Can't access parms anymore
  388. mov cx,-1
  389. repnz scasb ; Must have '\0'
  390. or ax, ax
  391. jz LDoneILI
  392. mov al, ah ; al = chT
  393. not cx
  394. dec cx
  395. mov di, bx
  396. repnz scasb
  397. jz LDoneILI
  398. mov di, bx
  399. LDoneILI:
  400. mov ax, di
  401. sub ax, bx
  402. dec ax ; ax = return value
  403. mov di, dx ; Restore di
  404. cEnd IchIndexLp
  405. sEnd CODE
  406. END
  407.