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.

474 lines
12 KiB

  1. ; Copyright (c) 1998 Microsoft Corporation
  2. ;
  3. ; @Doc DMusic16
  4. ;
  5. ; @Module DMHelp.asm - Helper functions |
  6. ;
  7. ; Thunk helpers for DMusic16.DLL
  8. ;
  9. page ,132
  10. TITLE $dos\usa\dmhelp.asm
  11. .386
  12. OPTION READONLY
  13. OPTION OLDSTRUCTS
  14. OPTION SEGMENT:USE16
  15. .model LARGE,PASCAL
  16. ;?MEDIUM=1
  17. ;?QUIET=1
  18. externDef TileBuffer:far16
  19. externDef UntileBuffer:far16
  20. externDef OutputDebugString:far16
  21. ;===========================================================================
  22. ;
  23. ; 64-bit integer struct as passed in from C routines
  24. ;
  25. ; This must match the definition in dmusic16.h
  26. ;
  27. ;
  28. ;===========================================================================
  29. QUADWORD struc
  30. qwLow dd ?
  31. qwHigh dd ?
  32. QUADWORD ends
  33. .code dmhelp
  34. ;===========================================================================
  35. EAXtoDXAX macro
  36. shld edx, eax, 16 ; move HIWORD(eax) to dx
  37. endm
  38. DXAXtoEAX macro
  39. ror eax, 16 ; xchg HIWORD(eax) and LOWORD(eax)
  40. shrd eax, edx, 16 ; move LOWORD(edx) to HIWORD(eax)
  41. endm
  42. ;===========================================================================
  43. public dmTileBuffer
  44. public dmUntileBuffer
  45. public QuadwordDiv
  46. externDef __FLATDS:abs
  47. _DATA SEGMENT WORD USE16 PUBLIC 'DATA'
  48. FlatData dw __FLATDS
  49. ifdef DEBUG
  50. szNotOwner db 'Critical section released by other than owner', 0
  51. endif
  52. _DATA ENDS
  53. ;===========================================================================
  54. ;
  55. ; @func DWORD | dmTileBuffer | Tile a 32-bit linear address as selectors
  56. ;
  57. ; @comm
  58. ;
  59. ; Take the 32-bit virtual address in <p dwFlatMemory> of length <p dwLength> and create
  60. ; tiled selectors for it. This is used to pass a region of memory to a 16 bit thunk
  61. ; as a huge pointer.
  62. ;
  63. ; @rdesc
  64. ;
  65. ; Returns a DWORD of tiling information, or 0 if the tiling could not be completed.
  66. ; The tiling information consists of a 16 bit selector in the high word and the
  67. ; number of tiled selectors in the low word. To make a 16:16 pointer to the
  68. ; block of memory, mask the low 16 bits of the tiling information to zero.
  69. ;
  70. ; @parm DWORD | dwFlatMemory | The linear address of the memory to tile
  71. ;
  72. ; @parm DWORD | dwLength | The length in bytes of the region to tile
  73. ;
  74. align
  75. dmTileBuffer proc far16 public,
  76. dwFlatMemory:dword, dwLength:dword
  77. push edi
  78. push esi
  79. mov eax, dwFlatMemory
  80. mov ecx, dwLength
  81. call TileBuffer
  82. mov eax, ecx
  83. EAXtoDXAX
  84. pop esi
  85. pop edi
  86. ret
  87. dmTileBuffer endp
  88. ;===========================================================================
  89. ;
  90. ; @func VOID | dmUntileBuffer | Untile a buffer
  91. ;
  92. ; @comm
  93. ;
  94. ; Free the tiled selectors allocated by dmTileBuffer. The buffer must have
  95. ; been previously tiles with <f dmTileBuffer>.
  96. ;
  97. ; @parm DWORD | dwTilingInfo | The tiling info returned by a previous call
  98. ; to <f dmTileBuffer>.
  99. ;
  100. align
  101. dmUntileBuffer proc far16 public,
  102. dwTilingInfo:dword
  103. push esi
  104. push edi
  105. mov ecx, dwTilingInfo
  106. call UntileBuffer
  107. pop edi
  108. pop esi
  109. ret
  110. dmUntileBuffer endp
  111. ;===========================================================================
  112. ;
  113. ; @func VOID PASCAL | InitializeCriticalSection | Initialize a critical section
  114. ;
  115. ; @comm
  116. ;
  117. ; Initialize the critical section to not-in.
  118. ;
  119. ; @parm LPWORD | lpwCritSect | The critical section to initialize.
  120. ;
  121. align
  122. InitializeCriticalSection proc far16 public,
  123. lpwCritSect:dword
  124. push es
  125. push di
  126. les di, [lpwCritSect]
  127. mov word ptr es:[di], 1
  128. pop di
  129. pop es
  130. ret
  131. InitializeCriticalSection endp
  132. ;===========================================================================
  133. ;
  134. ; @func WORD PASCAL | EnterCriticalSection | Enter a critical section
  135. ;
  136. ; @comm
  137. ;
  138. ; If fBlocking is set, then spin until we can get the critical section.
  139. ; Otherwise, return failure if we could not get it.
  140. ;
  141. ; @rdesc
  142. ; Returns
  143. ; 0 if we did not get the critical section
  144. ; A non-zero ID if we did get the critical section
  145. ;
  146. ; @parm LPWORD | lpwCritSect | A pointer to the critical section to enter
  147. ; @parm WORD | fBlocking | A flag to indicate that the function should block if the
  148. ; critical section is not immediately available
  149. ;
  150. align
  151. EnterCriticalSection proc far16 public,
  152. lpwCritSect:dword,
  153. fBlocking:word
  154. push es
  155. push di
  156. les di, [lpwCritSect] ; -> critical section
  157. mov cx, [fBlocking]
  158. ecs_check:
  159. dec word ptr es:[di] ; 1 -> 0 means we got it
  160. ; atomic on non-MP
  161. jz short ecs_success
  162. inc word ptr es:[di] ; Return to previous state
  163. or cx, cx ; Blocking?
  164. jnz short ecs_check ; Yes
  165. xor ax, ax ; Non-blocking and failed
  166. jmp ecs_done
  167. ecs_success:
  168. mov ax, 1
  169. ecs_done:
  170. pop di
  171. pop es
  172. ret
  173. EnterCriticalSection endp
  174. ;===========================================================================
  175. ;
  176. ; @func VOID PASCAL | LeaveCriticalSection | Leave a critical section
  177. ;
  178. ; @comm
  179. ;
  180. ; Leave the critical section. wCritSectID must be the critical section ID returned
  181. ; by the matching call to <f EnterCriticalSection> (used to verify nesting in debug
  182. ; versions).
  183. ;
  184. ; @parm LPWORD | lpwCritSect | The critical section to leave
  185. ;
  186. align
  187. LeaveCriticalSection proc far16 public,
  188. lpwCritSect:dword
  189. push es
  190. push di
  191. les di, [lpwCritSect] ; -> critical section
  192. inc word ptr es:[di] ; Reset to default value of 1
  193. pop di
  194. pop es
  195. ret
  196. LeaveCriticalSection endp
  197. ;===========================================================================
  198. ;
  199. ; @func WORD PASCAL | DisableInterrupts | Disable interrupts
  200. ;
  201. ; @comm
  202. ;
  203. ; Disable interrupts and return the previous status for a call to
  204. ; <f RestoreInterrupts>
  205. ;
  206. ; @rdesc
  207. ;
  208. ; Returns the previous state of the interrupt flag
  209. ;
  210. ;
  211. DisableInterrupts proc far16 public
  212. pushf
  213. pop ax ; Get state
  214. and ax, 0200h ; Already disabled?
  215. jz short @F ; Don't do it again
  216. cli
  217. @@:
  218. ret
  219. DisableInterrupts endp
  220. ;===========================================================================
  221. ;
  222. ; @func VOID PASCAL | RestoreInterrupts | Restore the interrupt state
  223. ;
  224. ; @comm
  225. ;
  226. ; Restore interrupts if they were enabled when <f DisableInterrupts> was
  227. ; called.
  228. ;
  229. ; @parm WORD | wIntStat | The previous interrupt state as returned from a
  230. ; call to <f DisableInterrupts>
  231. ;
  232. RestoreInterrupts proc far16 public,
  233. wIntStat : word
  234. mov ax, [wIntStat] ; Previous state
  235. test ax, 0200h ; Enabled before?
  236. jz short @F ; No, don't re-enable now
  237. sti
  238. @@:
  239. ret
  240. RestoreInterrupts endp
  241. ;===========================================================================
  242. ;
  243. ; @func WORD PASCAL | InterlockedIncrement | Increment the given word
  244. ; atomically and return the result.
  245. ;
  246. ; @comm
  247. ;
  248. ; Disable interrupts to guarantee increment-and-read as an atomic
  249. ; operation.
  250. ;
  251. ; @parm LPWORD | lpw | The word to increment.
  252. ;
  253. InterlockedIncrement proc far16 public,
  254. lpw : dword
  255. pushf
  256. pop cx
  257. test cx, 0200h ; Were interrupts enabled?
  258. jz @F ; No
  259. cli ; Yes, disable
  260. @@:
  261. les bx, [lpw]
  262. inc word ptr es:[bx]
  263. mov ax, word ptr es:[bx]
  264. test cx, 0200h ; Were interrupts enabled?
  265. jz @F ; No
  266. sti ; Yes, reenable
  267. @@:
  268. ret
  269. InterlockedIncrement endp
  270. ;===========================================================================
  271. ;
  272. ; @func WORD PASCAL | InterlockedDecrement | Decrement the given word
  273. ; atomically and return the result.
  274. ;
  275. ; @comm
  276. ;
  277. ; Disable interrupts to guarantee decrement-and-read as an atomic
  278. ; operation.
  279. ;
  280. ; @parm LPWORD | lpw | The word to decrement.
  281. ;
  282. InterlockedDecrement proc far16 public,
  283. lpw : dword
  284. pushf
  285. pop cx
  286. test cx, 0200h ; Were interrupts enabled?
  287. jz @F ; No
  288. cli ; Yes, disable
  289. @@:
  290. les bx, [lpw]
  291. dec word ptr es:[bx]
  292. mov ax, word ptr es:[bx]
  293. test cx, 0200h ; Were interrupts enabled?
  294. jz @F ; No
  295. sti ; Yes, reenable
  296. @@:
  297. ret
  298. InterlockedDecrement endp
  299. ;===========================================================================
  300. ;
  301. ; @func void PASCAL | QuadwordMul | Multiply using 64-bit precision
  302. ;
  303. ; @comm
  304. ;
  305. ; Multiply the two 32-bit numbers in <p m1> and <p m2> giving a 64-bit result
  306. ; in <p lpqwResult>.
  307. ;
  308. ; @rdesc
  309. ; Returns m1 * m2
  310. ;
  311. ; @parm DWORD | m1 | First multiplicand
  312. ; @parm DWORD | m2 | Second multiplicand
  313. ; @parm LPQUADWORD | lpqwResult | 64-bit result
  314. ;
  315. QuadwordMul proc far16 public,
  316. m1 : dword,
  317. m2 : dword,
  318. lpqwResult : dword
  319. mov edx, [m1]
  320. mov eax, [m2]
  321. mul edx
  322. les bx, [lpqwResult]
  323. mov es:[bx.qwLow], eax
  324. mov es:[bx.qwHigh], edx
  325. ret
  326. QuadwordMul endp
  327. ;===========================================================================
  328. ;
  329. ; @func DWORD PASCAL | QuadwordDiv | Divide using 64-bit precision
  330. ;
  331. ; @comm
  332. ;
  333. ; Divide the 64-bit number in <p ull> by the 32-bit number in <p dwDivisor> and
  334. ; return the result. May throw a divide by zero exception.
  335. ;
  336. ; @rdesc
  337. ; Returns ull / dwDivisor
  338. ;
  339. ; @parm QUADWORD | ull | The unsigned long dividend
  340. ; @parm DWORD | dwDivisor | The divisor
  341. ;
  342. ;
  343. QuadwordDiv proc far16 public,
  344. qwDividend : QUADWORD,
  345. dwDivisor : dword
  346. mov edx, [qwDividend.qwHigh]
  347. mov eax, [qwDividend.qwLow]
  348. mov ebx, [dwDivisor]
  349. div ebx
  350. ; Result in eax, needs to be dx:ax for 16-bit code
  351. ror eax, 16
  352. mov dx, ax
  353. ror eax, 16
  354. ret
  355. QuadwordDiv endp
  356. ;===========================================================================
  357. ;
  358. ; @func DWORD PASCAL | QuadwordLT | Compare two quadwords for less than (unsigned)
  359. ;
  360. ; @rdesc
  361. ; Returns TRUE if qwLValue < qwRValue
  362. ;
  363. ; @parm QUADWORD | qwLValue | The first operand of less-than
  364. ; @parm QUADWORD | qwRValue | The second operand of less-than
  365. ;
  366. ;
  367. QuadwordLT proc far16 public,
  368. qwLValue : QUADWORD,
  369. qwRValue : QUADWORD
  370. mov ebx, [qwLValue.qwHigh]
  371. sub ebx, [qwRValue.qwHigh]
  372. jz short @F
  373. sbb eax, eax
  374. ret
  375. @@: mov ebx, [qwLValue.qwLow]
  376. sub ebx, [qwRValue.qwLow]
  377. sbb eax, eax
  378. ret
  379. QuadwordLT endp
  380. ;===========================================================================
  381. ;
  382. ; @func DWORD PASCAL | QuadwordAdd | Add two unsigned quadwords
  383. ;
  384. ; @parm QUADWORD | qwOp1 | The first operand
  385. ; @parm QUADWORD | qwOp2 | The second operand
  386. ; @parm LPQUADWORD | lpwqResult | The result
  387. ;
  388. ;
  389. QuadwordAdd proc far16 public,
  390. qwOp1 : QUADWORD,
  391. qwOp2 : QUADWORD,
  392. lpdwResult : DWORD
  393. mov eax, [qwOp1.qwLow]
  394. add eax, [qwOp2.qwLow]
  395. mov edx, [qwOp1.qwHigh]
  396. adc edx, [qwOp2.qwHigh]
  397. les bx, [lpdwResult]
  398. mov es:[bx.qwLow], eax
  399. mov es:[bx.qwHigh], edx
  400. ret
  401. QuadwordAdd endp
  402. end