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.

715 lines
17 KiB

  1. page ,132
  2. title emulator - 8087/287 emulator for MS-DOS, XENIX, OS/2, Windows
  3. ;***
  4. ;emulator.asm - 8087/287 emulator for MS-DOS, XENIX, OS/2, Windows
  5. ;
  6. ; Copyright (c) 1984-89, Microsoft Corporation
  7. ;
  8. ;Purpose:
  9. ; 8087/287 emulator for MS-DOS, XENIX, OS/2, 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. include emulator.hst ; Emulator history file.
  19. major_ver equ 6
  20. minor_ver equ 0
  21. fastSP = 0 ; default to no fast single precision
  22. ;*******************************************************************************
  23. ;
  24. ; Print out emulator version.
  25. ;
  26. ;*******************************************************************************
  27. OutMsg macro text
  28. ifndef ?QUIET
  29. %out text
  30. endif
  31. endm
  32. outver macro maj,tens,hunds
  33. OutMsg <Emulator Version maj&.&tens&hunds>
  34. endm
  35. if1
  36. outver %major_ver,%(minor_ver/10),%(minor_ver mod 10)
  37. ifdef WINDOWS
  38. OutMsg <Windows 2.00 Emulator>
  39. endif
  40. ifdef QB3
  41. OutMsg <QuickBASIC 3.00 Emulator>
  42. endif
  43. ifdef _NOSTKEXCHLR ; formerly called QB4
  44. OutMsg <No stack overflow/underflow hadler.>
  45. endif
  46. ifdef PCDOS
  47. OutMsg <IBM PC-DOS version - Uses int 11h BIOS equipment check.>
  48. endif
  49. ifdef MTHREAD
  50. ifdef DOS5only
  51. OutMsg <Reentrant multithread OS/2 emulator.>
  52. else
  53. %out *** Error: MTHREAD supported only if DOS5only defined.
  54. endif
  55. endif
  56. ifdef SQL_EMMT
  57. ifdef MTHREAD
  58. OutMsg <Special SQL version.>
  59. else
  60. %out *** Error: SQL supported only if MTHREAD is defined.
  61. endif
  62. endif
  63. ifdef _COM_
  64. OutMsg <COM files supported.>
  65. endif ;_COM_
  66. ifdef XENIX
  67. OutMsg <XENIX emulator.>
  68. PROTECT = 1 ; XENIX is always protect mode
  69. else ;not XENIX
  70. ifdef DOS5only
  71. OutMsg <DOS 5 only emulator.>
  72. DOS5 = 1
  73. PROTECT = 1 ; DOS 5 is always protect mode
  74. else ;not DOS5only
  75. DOS3= 1 ; DOS 3 support is default
  76. ifdef DOS5
  77. OutMsg <DOS 3 & 5 emulator.>
  78. DOS3and5= 1
  79. PROTECT = 1 ; DOS 5 is always protect mode
  80. else ;not DOS5
  81. OutMsg <DOS 3 only emulator.>
  82. endif ;not DOS5
  83. endif ;not DOS5only
  84. ifdef standalone
  85. OutMsg <Stand-alone version (uses task vector for DS).>
  86. ifdef DOS5
  87. %out *** Error: DOS 5 support not allowed.
  88. .error
  89. endif ;DOS5
  90. endif ;standalone
  91. ifdef frontend
  92. OutMsg <Front-end version - No hardware and limited instructions.>
  93. endif ;frontend
  94. ifdef SMALL_EMULATOR
  95. OutMsg <Small Emulator - Limited instructions.>
  96. endif ;SMALL_EMULATOR
  97. ifdef only87
  98. OutMsg <8087 only version - No emulation.>
  99. endif ;only87
  100. ifdef POLLING
  101. OutMsg <Exception handling uses polling FWAITs.>
  102. endif
  103. endif ;not XENIX
  104. ifdef i386
  105. OutMsg <386 version>
  106. endif
  107. if fastSP
  108. %out Fast Single Precision version - Not supported.
  109. endif ;fastSP
  110. ifdef DEBUG
  111. OutMsg <+++ Debug Version +++>
  112. endif ;DEBUG
  113. ifdef PROFILE
  114. OutMsg <Profiling version.>
  115. endif ;PROFILE
  116. endif ;if1
  117. ;*******************************************************************************
  118. ;
  119. ; Include cmacros.inc
  120. ;
  121. ;*******************************************************************************
  122. ?PLM = 1
  123. ?WIN = 0
  124. ?DF = 1
  125. ?NOGLOBAL = 1
  126. ?NOSTATIC = 1
  127. ?NOEXTERN = 1
  128. ?NODEF = 1
  129. ?NOPTR = 1
  130. include cmac_mrt.inc ; old, customized masm510 cmacros
  131. include mrt386.inc
  132. ifdef MTHREAD
  133. include os2supp.inc
  134. endif
  135. ;*******************************************************************************
  136. ;
  137. ; Include emulator macros.
  138. ;
  139. ;*******************************************************************************
  140. include emulator.inc
  141. ;*******************************************************************************
  142. ;
  143. ; Processor setup.
  144. ;
  145. ;*******************************************************************************
  146. ifdef i386
  147. .386p
  148. .287
  149. elseifdef XENIX
  150. .286c ; allow 286 instructions if XENIX
  151. .287
  152. elseifdef DOS5only
  153. .286c ; allow 286 instructions if DOS 5 only
  154. .287
  155. else ;Default
  156. .8086 ; otherwise only 8086 instructions
  157. .8087 ; make sure there are fwaits before all instruction
  158. endif
  159. ;*******************************************************************************
  160. ;
  161. ; Define segments.
  162. ;
  163. ;*******************************************************************************
  164. ifdef QB3
  165. createSeg EMULATOR_DATA, edata, para, public, CODE, <>
  166. createSeg EMULATOR_TEXT, ecode, para, public, CODE, <>
  167. elseifdef QP
  168. createSeg DATA, edata, word, public,, <>
  169. createSeg CODE, ecode, word, public,, <>
  170. else ;DEFAULT
  171. createSeg EMULATOR_DATA, edata, para, public, FAR_DATA, <>
  172. createSeg EMULATOR_TEXT, ecode, para, public, CODE, <>
  173. endif ;DEFAULT
  174. ;*******************************************************************************
  175. ;
  176. ; Define Number of stack elements, BEGINT and TSKINT
  177. ;
  178. ;*******************************************************************************
  179. ifdef XENIX
  180. Numlev equ 10 ; 10 levels minimum for floating point
  181. else ;not XENIX
  182. ifdef QB3
  183. extrn $EM_INT:far ; QB3 emulator error entry
  184. BEGINT equ 084h ; MSDOS beginning interrupt
  185. Numlev equ 10 ; 10 levels minimum for floating point
  186. else ;not QB3
  187. BEGINT equ 034h ; MSDOS beginning interrupt
  188. ifdef _NOSTKEXCHLR
  189. Numlev equ 10 ; 10 levels minimum for floating point
  190. elseifdef MTHREAD
  191. Numlev equ 16 ; 16 levels minimum for floating-point
  192. else ;Default
  193. Numlev equ 16 ; 16 levels minimum for floating point
  194. endif ;Default
  195. ifdef standalone
  196. TSKINT equ BEGINT + 10 ; Task data pointer
  197. endif
  198. ifdef WINDOWS
  199. TSKINT equ BEGINT + 10 ; SignalAddress pointer
  200. endif
  201. endif ;not QB3
  202. ifdef WINDOWS
  203. FIDRQQ equ (fINT + 256*(BEGINT + 0)) - (fFWAIT + 256*fESCAPE)
  204. FIERQQ equ (fINT + 256*(BEGINT + 8)) - (fFWAIT + 256*fES)
  205. FIWRQQ equ (fINT + 256*(BEGINT + 9)) - (iNOP + 256*fFWAIT)
  206. FIARQQ equ (fINT + 256*(BEGINT + 8)) - (fFWAIT + 256*fDS)
  207. FJARQQ equ 256*(((0 shl 6) or (fESCAPE and 03Fh)) - fESCAPE)
  208. FISRQQ equ (fINT + 256*(BEGINT + 8)) - (fFWAIT + 256*fSS)
  209. FJSRQQ equ 256*(((1 shl 6) or (fESCAPE and 03Fh)) - fESCAPE)
  210. FICRQQ equ (fINT + 256*(BEGINT + 8)) - (fFWAIT + 256*fCS)
  211. FJCRQQ equ 256*(((2 shl 6) or (fESCAPE and 03Fh)) - fESCAPE)
  212. elseifdef QP ; QuickPascal can't do absolutes
  213. FIDRQQ equ (fINT + 256*(BEGINT + 0)) - (fFWAIT + 256*fESCAPE)
  214. FIERQQ equ (fINT + 256*(BEGINT + 8)) - (fFWAIT + 256*fES)
  215. FIWRQQ equ (fINT + 256*(BEGINT + 9)) - (iNOP + 256*fFWAIT)
  216. FIARQQ equ (fINT + 256*(BEGINT + 8)) - (fFWAIT + 256*fDS)
  217. FJARQQ equ 256*(((0 shl 6) or (fESCAPE and 03Fh)) - fESCAPE)
  218. FISRQQ equ (fINT + 256*(BEGINT + 8)) - (fFWAIT + 256*fSS)
  219. FJSRQQ equ 256*(((1 shl 6) or (fESCAPE and 03Fh)) - fESCAPE)
  220. FICRQQ equ (fINT + 256*(BEGINT + 8)) - (fFWAIT + 256*fCS)
  221. FJCRQQ equ 256*(((2 shl 6) or (fESCAPE and 03Fh)) - fESCAPE)
  222. else ;not WINDOWS or QuickPascal
  223. extrn FIWRQQ:abs, FIERQQ:abs, FIDRQQ:abs
  224. extrn FISRQQ:abs, FJSRQQ:abs
  225. extrn FIARQQ:abs, FJARQQ:abs
  226. extrn FICRQQ:abs, FJCRQQ:abs
  227. endif ;not WINDOWS or QuickPascal
  228. endif ;not XENIX
  229. ;*******************************************************************************
  230. ;
  231. ; List external functions.
  232. ;
  233. ;*******************************************************************************
  234. ifdef WINDOWSP
  235. extrn DOS3CALL:far
  236. endif
  237. ifdef WINDOWS
  238. extrn __WINFLAGS:abs
  239. extrn ALLOCDSTOCSALIAS:far
  240. extrn FREESELECTOR:far
  241. ifdef WF
  242. extrn ALLOCSELECTOR:far
  243. ;if we are linking to LIBW from Win 3.0, CS isn't found, use PCS
  244. CHANGESELECTOR equ <PRESTOCHANGOSELECTOR>
  245. extrn CHANGESELECTOR:far
  246. endif
  247. endif
  248. ifdef DOS3and5
  249. os2extrn DOSGETMACHINEMODE
  250. endif ;DOS3and5
  251. ifdef DOS5
  252. ifndef frontend
  253. ifndef only87
  254. os2extrn DOSWRITE ; only needed to print out "NO87="
  255. endif ;only87
  256. os2extrn DOSCREATECSALIAS
  257. os2extrn DOSFREESEG
  258. os2extrn DOSDEVCONFIG
  259. endif ;not frontend
  260. os2extrn DOSSETVEC
  261. ifdef MTHREAD
  262. os2extrn DOSALLOCSEG
  263. os2extrn DOSEXIT
  264. extrn __FarGetTidTab:far
  265. endif ;MTHREAD
  266. endif ;DOS5
  267. ;*******************************************************************************
  268. ;
  269. ; Include some more macros and constants.
  270. ;
  271. ;*******************************************************************************
  272. include emdoc.asm
  273. include emintern.asm
  274. ifdef MTHREAD
  275. include emthread.asm
  276. endif ;MTHREAD
  277. subttl emulator.asm - Emulator Task DATA Segment
  278. page
  279. ;*********************************************************************;
  280. ; ;
  281. ; Emulator Task DATA Segment ;
  282. ; ;
  283. ;*********************************************************************;
  284. sBegin edata
  285. ; eventually this needs to be a big struct
  286. glb <REMLSW,InitControlWord,CURerr>
  287. glb <UserControlWord,UserStatusWord,Have8087>
  288. glb <ControlWord,CWcntl,StatusWord,SWcc>
  289. glb <BASstk,CURstk,LIMstk>
  290. ;*******************************************************************************
  291. ;
  292. ; Order of information here must not change (for CodeView debugging).
  293. ; Check with CodeView guys before changing.
  294. ;
  295. ;*******************************************************************************
  296. ifndef i386
  297. glb <SignalAddress>
  298. nedd SignalAddress,<1 dup (?)> ; Error signal address
  299. endif
  300. Have8087 db 0 ; Is a real 8087 present (0 = no 8087)
  301. Einstall db 0 ; Emulator installed flag (XENIX sets to 1)
  302. UserControlWord dw ? ; User level control word
  303. UserStatusWord dw ? ; User level exception status word
  304. ControlWord label word
  305. CWmask db ? ; exception masks
  306. CWcntl db ? ; arithmetic control flags
  307. StatusWord label word
  308. SWerr db ? ; Initially no exceptions (sticky flags)
  309. SWcc db ? ; Condition codes from various operations
  310. ifdef XENIX
  311. nedw BASstk,<?> ; init to BEGstk + 8*Have8087*Reg87Len
  312. ; = start of memory (+ 8 regs if 8087)
  313. nedw CURstk,<?> ; init to BASstk = start of stack
  314. nedw LIMstk,<?> ; ENDstk - 1 reg = end of memory
  315. else ;not XENIX
  316. nedw BASstk,<offset BEGstk> ; init to BEGstk + 8*Have8087*Reg87Len
  317. ; = start of memory (+ 8 regs if 8087)
  318. nedw CURstk,<?> ; init to BASstk = start of stack
  319. nedw LIMstk,<offset ENDstk-(2*Reg87Len)> ; ENDstk - 1 reg = end of memory
  320. endif ;not XENIX
  321. ;*******************************************************************************
  322. ;
  323. ; End of fixed area
  324. ;
  325. ;*******************************************************************************
  326. ifdef DOS3and5
  327. glb <protmode>
  328. protmode dw ? ; Protect mode flag (0 = real)
  329. endif ;DOS3and5
  330. ifdef POLLING ; used by new POLLING exception code
  331. ifdef DOS3
  332. glb <errorcode>
  333. errorcode db 0 ; error code
  334. db 0
  335. endif ;DOS3
  336. endif ;POLLING
  337. ifdef QB3
  338. initCW dw ? ; QB3 initial control word
  339. endif
  340. InitControlWord equ 1332H ; Default - Affine, Round near,
  341. ; 64 bits, all exceptions unmasked
  342. NewStatusWord label word ; space for status after reexecution
  343. CURerr dw ? ; initially 8087 exception flags clear
  344. ; this is the internal flag reset after
  345. ; each operation to detect per instruction
  346. ; errors
  347. ifndef XENIX
  348. glb <env_seg>
  349. env_seg dw ? ; environment segment
  350. endif
  351. REMLSW dw ? ; sometimes used as a temp
  352. dw ? ; (2 or 4 bytes)
  353. ifndef XENIX
  354. ifdef DOS5only
  355. NUMVEC= 2 ; coprocesser no present + exception
  356. else
  357. NUMVEC= 11 ; 8 DS + 1 segovr + 1 fwait + 1 task
  358. endif ;DOS5only
  359. glb <oldvec>
  360. oldvec dd NUMVEC dup (0) ; old interrupt vector values
  361. endif
  362. ;Transcendental working variables
  363. glb <Reg8087ST0,TEMP1>
  364. Reg8087ST0 label word
  365. TEMP1 dw Reg87Len/2 DUP (?)
  366. ifndef frontend
  367. ifdef DOS5
  368. SSalias dw ? ; SSalias for exception handler
  369. endif ;DOS5
  370. endif ;frontend
  371. ifdef DOS3
  372. ifndef frontend
  373. glb <statwd>
  374. statwd dw 0 ; Location for 8087 status/control word
  375. endif ;frontend
  376. endif ;DOS3
  377. ifndef only87
  378. glb <TEMP2,TEMP3,ARG2,DENORX,COEFFICIENT,RESULT,DAC>
  379. TEMP2 dw Reg87Len/2 DUP (?)
  380. TEMP3 dw Reg87Len/2 DUP (?)
  381. ARG2 dw Reg87Len/2 DUP (?)
  382. DENORX dw Reg87Len/2 DUP (?)
  383. COEFFICIENT dw Reg87Len/2 DUP (?)
  384. nedw RESULT,<?>
  385. DAC dw MantissaByteCnt/2 DUP (?)
  386. endif ;only87
  387. ifndef frontend
  388. ifndef SMALL_EMULATOR
  389. loopct dw 0 ; data for FPREM emulation
  390. bigquot dw 0 ; quotient > 65535 ?
  391. endif ;not SMALL_EMULATOR
  392. endif ;not frontend
  393. ExtendStack dw 1 ; 1 => extend 80x87 stack
  394. ifdef WINDOWS
  395. Installed dw 0 ; Installation flag
  396. ExceptFlag db 0 ; 80x87 exception flag for polling.
  397. db 0
  398. ifdef WF
  399. wfInsn dw 0 ; instruction we overwrote with INT 3d
  400. wfSel dw 0 ; selector to use for alias
  401. wfErr dw 0 ; FP error code (YAEC)
  402. wfGoFast dw 0 ; 1 if we are Enhanced with coproc
  403. endif
  404. public OldNMIVec
  405. OldNMIVec dd 0 ; Old value in 8087 exception interrupt vector
  406. endif ;WINDOWS
  407. ifdef LOOK_AHEAD
  408. NextOpCode db 0 ; first byte of next instruction
  409. LookAheadRoutine dw 0
  410. endif
  411. ; Emulator stack area
  412. glb <BEGstk,ENDstk>
  413. BEGstk db Numlev*Reg87Len dup (?) ; emulator stack area
  414. ENDstk label byte
  415. ifdef MTHREAD
  416. cvtbufsize= 349 ; see \clib\include\cvt.h
  417. cvtbuf db cvtbufsize dup (?) ; used by ecvt/fcvt
  418. ; routines
  419. endif ;MTHREAD
  420. public __fptaskdata
  421. __fptaskdata label byte ; task data pointer and size
  422. ; (if linked with user program)
  423. sEnd edata
  424. subttl emulator.asm
  425. page
  426. ;*********************************************************************;
  427. ; ;
  428. ; Start of Code Segment ;
  429. ; ;
  430. ;*********************************************************************;
  431. sBegin ecode
  432. assumes cs, ecode
  433. assumes ds, edata
  434. public __fpemulatorbegin
  435. __fpemulatorbegin: ; emulator really starts here
  436. reservedspace: ; IMPORTANT: Must be EMULATOR_TEXT:0000
  437. EMver ; IMPORTANT: Emulator version number
  438. ; IMPORTANT: EBASIC needs this here!
  439. db 'gfw...GW'
  440. ifdef _COM_
  441. extrn __EmDataSeg:word
  442. endif ;_COM_
  443. page
  444. ifdef XENIX
  445. include emxenix.asm ; XENIX initialization
  446. elseifdef WINDOWS
  447. include emwin.asm ; WINDOWS initialization
  448. else ;not XENIX or WINDOWS
  449. include emdos.asm ; DOS initialization
  450. endif ;not XENIX or WINDOWS
  451. include emstack.asm ; stack management macros
  452. ifndef QB3 ; no exception handling for QB3
  453. ifndef XENIX ; UNDONE - no exception handling for XENIX
  454. ifndef frontend
  455. include emexcept.asm ; oem independent 8087 exception handling
  456. endif ;frontend
  457. endif ;XENIX ; UNDONE - at this time
  458. endif ;QB3
  459. include emerror.asm ; error handler
  460. ifndef XENIX ; not used with XENIX
  461. include emspec.asm ; special emulator/8087 functions
  462. ifndef frontend
  463. include emfixfly.asm ; fixup on the fly
  464. endif ;not frontend
  465. endif ;not XENIX
  466. ifndef only87
  467. public __fpemulator
  468. __fpemulator: ; emulator starts here
  469. include emdisp.asm ; dispatch tables
  470. include emconst.asm ; constants
  471. ifdef i386
  472. include em386.asm ; 386 emulation/initialization entry
  473. else
  474. include emmain.asm ; main entry and address calculation
  475. endif
  476. include emdecode.asm ; instruction decoder
  477. include emarith.asm ; arithmetic dispatcher
  478. include emfadd.asm ; add and subtract
  479. include emfmul.asm ; multiply
  480. include emfdiv.asm ; division
  481. include emnormal.asm ; normalize and round
  482. include emlssng.asm ; load and store single
  483. include emlsdbl.asm ; load and store double
  484. include emlsint.asm ; load and store integer
  485. include emlsquad.asm ; load and store quadword integer
  486. include emfrndi.asm ; round to integer
  487. include emlstmp.asm ; load and store temp real
  488. include emfmisc.asm ; miscellaneous instructions
  489. include emfcom.asm ; compare
  490. include emfconst.asm ; constant loading
  491. include emnew.asm ; new instructions: f<op> ST(i)
  492. ifndef frontend
  493. ifndef SMALL_EMULATOR
  494. include emfprem.asm ; partial remainder
  495. include emfsqrt.asm ; square root
  496. include emftran.asm ; transcendentals
  497. endif ;not SMALL_EMULATOR
  498. endif ;not frontend
  499. endif ;not only87
  500. public __fpemulatorend
  501. __fpemulatorend: ; emulator ends here
  502. sEnd ecode
  503. ifdef WINDOWS
  504. EM_END equ <end LoadTimeInit>
  505. else
  506. EM_END equ <end>
  507. endif
  508. EM_END