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.

745 lines
14 KiB

  1. page ,132
  2. subttl emwin.asm - Initialization and Termination for Windows
  3. ;***
  4. ;emwin.asm - Initialization and Termination for Windows
  5. ;
  6. ; Copyright (c) 1987-89, Microsoft Corporation
  7. ;
  8. ;Purpose:
  9. ; Initialization and Termination for Windows
  10. ;
  11. ; This Module contains Proprietary Information of Microsoft
  12. ; Corporation and should be treated as Confidential.
  13. ;
  14. ;Revision History:
  15. ; See emulator.hst
  16. ;
  17. ;*******************************************************************************
  18. comment !
  19. Windows/DOS interfaces to emulator/8087 functions
  20. Certain emulator/8087 functions are performed by calling __fpmath
  21. with an function code and arguments.
  22. __fpmath general floating point math package interface used
  23. by the emulator/8087 and float calls interfaces. This
  24. is a far routine and must be far called.
  25. entry:
  26. bx = 0 initialize floating point math (program startup)
  27. dx, ax, si input values ignored in WINDOWS emulator
  28. returns:
  29. ax = 0 if successful and using software floating point
  30. 1 if successful and using 8087
  31. just terminates process if error
  32. bx = 1 reset (FINIT) - finit ok even under WINDOWS;
  33. typical usage will load control word afterward
  34. so other tasks won't be hindered (as with _fpreset() call)
  35. bx = 2 terminate floating point math (program termination)
  36. bx = 3 set error signal address
  37. dx:ax = segment:offset of user error handler
  38. bx = 4 load user control word
  39. (user should not use FLDCW instruction directly)
  40. ax = user control word value
  41. bx = 5 store user control word
  42. returns:
  43. ax = user control word value
  44. bx = 6 truncate TOS to integer TOS
  45. ax = user control word (only use round mode)
  46. bx = 7 truncate TOS to 32-bit integer in DX:AX
  47. ax = user control word (only use round mode)
  48. bx = 8 store user status word
  49. returns:
  50. ax = user status word value
  51. bx = 9 clear exceptions
  52. bx = 10 return number of stack elements in ax
  53. bx = 11 returns 1 if using 80x87, 0 if not
  54. bx = 12 if ax = 0, turn off extended stack. if ax = 1, turn on e.s.
  55. !
  56. glb <functab>
  57. functab label word
  58. dw initialization ; 0 - initialize emulator/8087
  59. dw reset ; 1 - reset emulator/8087 stack
  60. dw termination ; 2 - terminate emulator/8087
  61. dw setsignal ; 3 - set error signal address
  62. dw loadcontrolword ; 4 - load user control word
  63. dw storecontrolword ; 5 - store user control word
  64. dw truncateTOS ; 6 - truncate TOS to integer TOS
  65. dw truncateTOSto32int ; 7 - truncate TOS to integer in DX:AX
  66. dw storestatusword ; 8 - store user status word
  67. dw clearexceptions ; 9 - clear execeptions
  68. dw NumStack ; 10 - report number of elements in stack
  69. dw ReturnHave8087 ; 11 - report if using coprocessor
  70. dw SetExtendedStack ; 12 - turn on or off extended stack
  71. endfunc label word
  72. SizeJmpTab equ 12
  73. sEnd ecode
  74. sBegin ecode
  75. assumes cs, ecode
  76. assumes ds, edata
  77. public __fpmath
  78. __fpmath proc far
  79. cmp bx, SizeJmpTab
  80. ja RetFPErr
  81. shl bx, 1
  82. push ds ; save DS
  83. mov cx, EMULATOR_DATA
  84. mov ds, cx
  85. call functab[bx]
  86. pop ds ; restore DS
  87. EmuRet:
  88. ret
  89. RetFPErr:
  90. or ax, -1
  91. cwd
  92. jmp EmuRet
  93. __fpmath endp
  94. subttl emwin.asm - Initialization and Termination
  95. page
  96. ;*********************************************************************;
  97. ; ;
  98. ; Initialization and Termination ;
  99. ; ;
  100. ;*********************************************************************;
  101. wastetime macro
  102. push cx
  103. mov cx,20 ;; wait for a short time
  104. loop $
  105. pop cx
  106. endm
  107. ; program initialization
  108. ;
  109. ; entry dx:ax = task data area (segment and size) for standalone
  110. ; si = DOS environment segment for NO87 lookup ???
  111. ; DX,AX,SI - ignored in WINDOWS case
  112. ; these register inputs are ignored for Windows app
  113. ; program-time initialization
  114. pub initialization ; all initialization is done when loaded
  115. ifdef WF
  116. cmp [Installed],0
  117. jnz @F
  118. .286p
  119. push 0
  120. call AllocSelector
  121. mov [wfSel], ax ; Error checking??
  122. mov ax, __WINFLAGS
  123. ; int 3
  124. test ax, WF_WIN386
  125. jz wfSlow1
  126. cmp [Have8087], 0
  127. je wfSlow1
  128. or [wfGoFast], 1 ; We can use fast if Enh Mode & FPU
  129. wfSlow1:
  130. @@:
  131. endif
  132. inc [Installed] ; Installed will count number of apps
  133. ; using the emulator.
  134. cmp [Have8087], 0 ; check for 8087/80287
  135. je NoInstall87
  136. extrn __FPINSTALL87:near
  137. call __FPINSTALL87 ; set NMI (int 2) for this instance
  138. NoInstall87:
  139. call reset
  140. xor ax, ax
  141. ret
  142. ifdef standalone
  143. mov di,offset BEGstk ; di = base of register stack
  144. mov [BASstk],di ; initialize stack base
  145. mov cx,Reg87Len ; cx = register length
  146. xchg ax,dx ; ax = task data segment size
  147. sub ax,di ; ax = number bytes for stack
  148. cwd ; dx:ax = number of bytes
  149. div cx ; ax = number of entries
  150. mul cx ; ax = number of bytes
  151. add ax,di ; ax = top of stack
  152. sub ax,cx ; Leave room for one on overflow
  153. mov [LIMstk],ax ; set top of stack
  154. endif ;standalone
  155. ; check if floating point emulator/8087 already installed (device driver)
  156. ; load time initialization
  157. pub LoadTimeInit
  158. push di
  159. push si
  160. push ds
  161. mov ax,EMULATOR_DATA
  162. mov ds,ax
  163. mov ax, __WINFLAGS
  164. and ax, WF_80x87
  165. cmp ax, WF_80x87
  166. jz WinHave87
  167. ifdef only87
  168. jmp loadiniterrorret
  169. endif
  170. jmp WinSet87
  171. pub WinHave87
  172. mov al,1
  173. pub WinSet87
  174. mov [Have8087],al
  175. ; real mode emulation and fixup on the fly vector setup
  176. pub initvec
  177. call SaveVectors
  178. call SetVectors
  179. pub loadinitfinish
  180. ; finish initialization
  181. pub initfinish
  182. mov [Installed], 0 ; Installed will count number of apps
  183. call reset ; reset (0), FINIT if 8087 present and
  184. ; set up default control word
  185. mov ax, 1 ; return non zero result
  186. pub loadiniterrorret
  187. pop ds
  188. pop si
  189. pop di
  190. retf ; far return for dynalink lib entry pt.
  191. ;*
  192. ;* DLL termination routine.
  193. ;*
  194. public WEP
  195. WEP label far
  196. push ds
  197. push ax
  198. push si
  199. push di
  200. mov ax,EMULATOR_DATA
  201. mov ds,ax
  202. call reset
  203. call RestoreVectors
  204. pop di
  205. pop si
  206. pop ax
  207. pop ds
  208. retf 2 ; WEP functions are called with a word paramater.
  209. ;------ program termination ----------------------------------------------------
  210. pub termination
  211. call reset ; reset chip for other apps
  212. dec [Installed] ; if Installed is not 0, someone is
  213. jnz termrealdone ; still using the emulator.
  214. ifdef WF
  215. xor ax, ax
  216. xchg ax, [wfSel]
  217. or ax, ax
  218. jz @F
  219. push ax
  220. call FreeSelector
  221. @@:
  222. endif
  223. ifndef only87
  224. cmp [Have8087],0 ; Non zero if 8087 chip exists
  225. je termrealdone
  226. endif ;only87
  227. extrn __FPTERMINATE87:near ; reset NMI (int 2) for this instance
  228. call __FPTERMINATE87
  229. pub termrealdone
  230. ret
  231. subttl emwin.asm - reset and clearexceptions
  232. page
  233. ;*********************************************************************;
  234. ; ;
  235. ; Reset and Clearexceptions ;
  236. ; ;
  237. ;*********************************************************************;
  238. pub reset
  239. ifndef only87
  240. cmp [Have8087],0 ; Nonzero if 8087 chip exists
  241. je NoFINIT
  242. endif ;only87
  243. fninit
  244. fwait ; Workaround for 80387 bug.
  245. fninit
  246. pub NoFINIT
  247. mov ax, [BASstk]
  248. mov [CURstk], ax ; reset stack to bottom
  249. mov ax, InitControlWord ; setup initial control word
  250. call loadcontrolword
  251. ; fall into clearexceptions
  252. pub clearexceptions
  253. xor ax, ax
  254. ifndef only87
  255. cmp al, [Have8087] ; Nonzero if 8087 chip exists
  256. je NoFCLEX
  257. endif ;only87
  258. fclex ; clear exceptions
  259. pub NoFCLEX
  260. ifndef only87
  261. mov [StatusWord], ax ; clear status word
  262. endif ;only87
  263. mov [UserStatusWord], ax ; clear exception status word
  264. ret
  265. subttl emwin.asm - setsignal ---------------------------------
  266. page
  267. ;*********************************************************************;
  268. ; ;
  269. ; Setsignal ;
  270. ; ;
  271. ;*********************************************************************;
  272. pub setsignal
  273. push ds
  274. mov ds, dx ; set TSKINT to SignalAddress
  275. mov dx, ax
  276. mov ax, 25h*256 + TSKINT
  277. IntDOS
  278. pop ds
  279. ret
  280. pub SaveVectors
  281. mov cx, NUMVEC ; save old vectors under DOS 3
  282. mov ax, 35h*256 + BEGINT ; get vector
  283. mov di, offset oldvec ; di = old vector table
  284. pub getvecs
  285. IntDOS
  286. inc ax
  287. mov [di], bx ; save old vector
  288. mov [di+2], es
  289. add di, 4
  290. loop getvecs
  291. ret
  292. pub SetVectors
  293. ifndef only87
  294. mov dx, offset DStrap ; assume emulator
  295. mov si, offset SOtrap
  296. mov di, offset FWtrap
  297. ifdef WINDOWS
  298. mov ax, __WINFLAGS ; if we are in PMODE & win386 increment all of
  299. and ax, WF_PMODE or WF_WIN386 ; the handler address past the "sti".
  300. cmp ax, WF_PMODE or WF_WIN386
  301. jne NotPmode1
  302. inc dx
  303. inc si
  304. inc di
  305. lab NotPmode1
  306. endif ;WINDOWS
  307. cmp [Have8087], 0 ; are we using 8087 ?
  308. jz SetEmVecs ; no - go ahead and set them
  309. endif ;only87
  310. mov dx, offset DSFixUpOnFly ; set up for fixup-on-the-fly
  311. mov si, offset SOFixUpOnFly
  312. mov di, offset FWFixUpOnFly
  313. ifdef WINDOWS
  314. mov ax, __WINFLAGS ; if we are in PMODE & win386 increment all of
  315. and ax, WF_PMODE or WF_WIN386 ; the handler address past the "sti".
  316. cmp ax, WF_PMODE or WF_WIN386
  317. jne NotPmode2
  318. inc dx
  319. inc si
  320. inc di
  321. lab NotPmode2
  322. endif ;WINDOWS
  323. pub SetEmVecs
  324. push ds
  325. push cs
  326. pop ds
  327. mov ax, 25h*256 + BEGINT
  328. mov cx, 8 ; 8 vectors for DStrap
  329. pub SetDSLoop
  330. IntDOS ; set vector
  331. inc ax ; bump to next one
  332. loop SetDSLoop
  333. mov dx, si ; set Segtrap
  334. IntDOS
  335. inc ax
  336. mov dx, di ; set FWtrap
  337. IntDOS
  338. pop ds ; restore task data area
  339. ret
  340. pub RestoreVectors
  341. mov cx, NUMVEC
  342. mov ax, 25h*256 + BEGINT ; Dos set vector.
  343. mov di, offset oldvec ; di = old vector table
  344. pub ResetVecLoop
  345. push ds
  346. lds dx, [di] ; get old vector value
  347. IntDOS
  348. pop ds
  349. inc ax
  350. add di,4
  351. loop ResetVecLoop
  352. ret
  353. pub NumStack ; returns the number of stack elements in ax
  354. xor dx, dx ; dx will count nonzero elements
  355. ifndef only87
  356. cmp Have8087, 0
  357. je CountEmulatorStack
  358. endif ;only87
  359. sub sp, 14 ; need 14 bytes for fstenv
  360. mov bx, sp
  361. fstenv ss:[bx]
  362. fldcw ss:[bx] ; reset control word
  363. mov ax, ss:[bx+4] ; put tag word in ax
  364. add sp, 14 ; reset stack
  365. mov cx, 8
  366. pub NotEmptyLoop
  367. mov bx, ax
  368. shr ax, 1
  369. shr ax, 1
  370. and bx, 3
  371. cmp bx, 3
  372. je StackEntryEmpty
  373. inc dx ; stack element was not empty
  374. pub StackEntryEmpty
  375. loop NotEmptyLoop
  376. pub CountEmulatorStack
  377. mov ax, CURstk
  378. sub ax, BASstk
  379. mov bl, Reg87Len
  380. div bl
  381. add ax, dx ; add elements on 80x87 stack
  382. ret
  383. ReturnHave8087 proc near
  384. mov al, [Have8087]
  385. cbw
  386. ret
  387. ReturnHave8087 endp
  388. SetExtendedStack proc near
  389. mov [ExtendStack], ax
  390. ret
  391. SetExtendedStack endp
  392. ;***
  393. ;int far pascal __Win87EmInfo( WinInfoStruct far * p, int cb );
  394. ;
  395. ;Purpose:
  396. ; returns information about win87em.exe to CodeView
  397. ;
  398. ;Entry:
  399. ; WinInfoStruct far * p
  400. ; int cb - size of WinInfoStruct
  401. ;
  402. ;Exit:
  403. ; returns non zero if error.
  404. ;
  405. ;
  406. ;Uses:
  407. ;
  408. ;Exceptions:
  409. ;
  410. ;*******************************************************************************
  411. cProc __WIN87EMINFO,<PUBLIC,FAR,PLM>,<ds>
  412. parmD p
  413. parmW cb
  414. cBegin
  415. or ax, -1
  416. cmp [cb], size WinInfoStruct
  417. jb WIDone
  418. mov ax, edataBASE
  419. mov es, ax
  420. assumes es, edata
  421. lds bx, [p]
  422. assumes ds, nothing
  423. mov [bx.WI_Version], (major_ver shl 8) + minor_ver
  424. mov [bx.WI_SizeSaveArea], Size80x87Area + edataOFFSET __fptaskdata
  425. mov [bx.WI_WinDataSeg], es
  426. mov [bx.WI_WinCodeSeg], cs
  427. mov al, [Have8087]
  428. cbw
  429. mov [bx.WI_Have80x87], ax
  430. assumes es, nothing
  431. xor ax, ax ; return 0 if no error
  432. mov [bx.WI_Unused], ax
  433. WIDone:
  434. cEnd
  435. ;***
  436. ;int far pascal __Win87EmSave( void far * p, int cb );
  437. ;
  438. ;Purpose:
  439. ; saves win87em.exe info in p
  440. ;
  441. ;Entry:
  442. ; void far * p - pointer to save area.
  443. ; int cb - size of save area.
  444. ;
  445. ;Exit:
  446. ; returns non zero if error.
  447. ;
  448. ;Uses:
  449. ;
  450. ;Exceptions:
  451. ;
  452. ;*******************************************************************************
  453. cProc __WIN87EMSAVE,<PUBLIC,FAR,PLM>,<ds,si,di>
  454. parmD p
  455. parmW cb
  456. cBegin
  457. or ax, -1
  458. cmp [cb], Size80x87Area + edataOFFSET __fptaskdata
  459. jb WSDone
  460. mov ax, edataBASE
  461. mov ds, ax
  462. assumes ds, edata
  463. les di, [p]
  464. assumes es, nothing
  465. cmp [Have8087], 0
  466. je NoSave80x87
  467. fsave es:[di.WSA_Save80x87]
  468. NoSave80x87:
  469. add di, (WSA_SaveEm - WSA_Save80x87)
  470. xor si, si
  471. mov cx, edataOFFSET __fptaskdata
  472. shr cx, 1
  473. rep movsw
  474. jnc NoSaveLastByte
  475. movsb
  476. NoSaveLastByte:
  477. xor ax, ax ; return 0 if no error.
  478. WSDone:
  479. cEnd
  480. ;***
  481. ;int far pascal __Win87EmRestore( void far * p, int cb );
  482. ;
  483. ;Purpose:
  484. ; retores win87em.exe info from p
  485. ;
  486. ;Entry:
  487. ; void far * p - pointer to save area.
  488. ; int cb - size of save area.
  489. ;
  490. ;Exit:
  491. ; returns non zero if error.
  492. ;
  493. ;Uses:
  494. ;
  495. ;Exceptions:
  496. ;
  497. ;*******************************************************************************
  498. cProc __WIN87EMRESTORE,<PUBLIC,FAR,PLM>,<ds,si,di>
  499. parmD p
  500. parmW cb
  501. cBegin
  502. or ax, -1
  503. cmp [cb], Size80x87Area + edataOFFSET __fptaskdata
  504. jb WRDone
  505. mov ax, edataBASE
  506. mov es, ax
  507. assumes es, edata
  508. lds si, [p]
  509. assumes ds, nothing
  510. add si, (WSA_SaveEm - WSA_Save80x87)
  511. xor di, di
  512. mov cx, edataOFFSET __fptaskdata
  513. shr cx, 1
  514. rep movsw
  515. jnc NoRestoreLastByte
  516. movsb
  517. NoRestoreLastByte:
  518. mov si, [OFF_p] ; reset source pointer.
  519. cmp [Have8087], 0
  520. je NoRestore80x87
  521. frstor [si.WSA_Save80x87]
  522. NoRestore80x87:
  523. xor ax, ax ; return 0 if no error.
  524. WRDone:
  525. cEnd
  526. assumes ds, edata
  527. assumes es, nothing