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.

805 lines
17 KiB

  1. PAGE ,132
  2. TITLE DXROM.ASM -- Dos Extender ROM Specific Code
  3. ; Copyright (c) Microsoft Corporation 1990-1991. All Rights Reserved.
  4. ;***********************************************************************
  5. ;
  6. ; DXROM.ASM -- Dos Extender ROM Specific Code
  7. ;
  8. ;-----------------------------------------------------------------------
  9. ;
  10. ; This module contains code specific to the ROM version of the DOS
  11. ; Extender.
  12. ;
  13. ;-----------------------------------------------------------------------
  14. ;
  15. ; 11/05/90 jimmat Created.
  16. ;
  17. ;***********************************************************************
  18. .286p
  19. IFDEF ROM
  20. ; -------------------------------------------------------
  21. ; INCLUDE FILE DEFINITIONS
  22. ; -------------------------------------------------------
  23. .xlist
  24. .sall
  25. include segdefs.inc
  26. include gendefs.inc
  27. include pmdefs.inc
  28. include dxrom.inc
  29. .list
  30. ; -------------------------------------------------------
  31. ; GENERAL SYMBOL DEFINITIONS
  32. ; -------------------------------------------------------
  33. ; Define some pubilc symbols to be exported for the ROM Image Builder
  34. public __selDXCODE, __selDXDGROUP, __selDXPMCODE
  35. __selDXCODE = SEL_DXCODE
  36. __selDXDGROUP = SEL_DXDATA
  37. __selDXPMCODE = SEL_DXPMCODE
  38. public __selFirstLDT, __selLDTAlias
  39. __selFirstLDT = SEL_USER
  40. __selLDTAlias = SEL_LDT_ALIAS
  41. ; -------------------------------------------------------
  42. ; EXTERNAL SYMBOL DEFINITIONS
  43. ; -------------------------------------------------------
  44. extrn ParaToLinear:NEAR
  45. extrn AllocateLDTSelector:NEAR
  46. extrn ChildTerminationHandler:NEAR
  47. externFP NSetSegmentDscr
  48. ; -------------------------------------------------------
  49. ; DATA SEGMENT DEFINITIONS
  50. ; -------------------------------------------------------
  51. DXDATA segment
  52. extrn selGDTFree:WORD
  53. extrn segDXData:WORD
  54. extrn ExitCode:BYTE
  55. SaveROMVector dw ?
  56. cparChildMem dw ? ; size of child DOS mem block in para's
  57. regOurSSSP dd ? ; SS:SP save location
  58. DXDATA ends
  59. ; -------------------------------------------------------
  60. ; CODE SEGMENT VARIABLES
  61. ; -------------------------------------------------------
  62. DXCODE segment
  63. ; For the ROM version, the following items locate (and size) the
  64. ; DGROUP and DXPMCODE segments. These items are 'imported' from
  65. ; the ROM Image Builder which sets the values when the ROM image
  66. ; is created.
  67. extrn lmaDXDGROUP:DWORD, cparDXDGROUP:ABS, lmaDXPMCODE:DWORD
  68. public lmaRomDXPMCode
  69. cparDgroup dw cparDXDGROUP
  70. lmaDGroup dd lmaDXDGROUP
  71. lmaRomDXPMCode dd lmaDXPMCODE
  72. DXCODE ends
  73. DXPMCODE segment
  74. extrn selDgroupPM:WORD
  75. extrn lmaROMTOC:DWORD
  76. MyLmaROMTOC dd lmaROMTOC
  77. DXPMCODE ends
  78. ; -------------------------------------------------------
  79. subttl ROM Real Mode ROM Specific Routines
  80. page
  81. ; -------------------------------------------------------
  82. ; ROM REAL MODE ROM SPECIFIC ROUTINES
  83. ; -------------------------------------------------------
  84. DXCODE segment
  85. assume cs:DXCODE
  86. ; -------------------------------------------------------
  87. ; ROMEntry -- Setup the special ROM environment needed
  88. ; immediately by DOSX.
  89. ;
  90. ; Note: This routine runs in real mode only!
  91. ;
  92. ; Input: ES -> PSP for use by DOSX
  93. ; Output: CY clear if successful, set if init failed
  94. ; DS -> DOSX RAM DGROUP
  95. ; DX:AX = far return address to app that invoked DOSX
  96. ; Errors: none
  97. ; Uses: All except ES
  98. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  99. public ROMEntry
  100. ROMEntry proc near
  101. ; Allocate a data segment in RAM and copy down the ROM version
  102. mov ah,48h ;allocate RAM for DGROUP
  103. mov bx,cparDgroup
  104. int 21h
  105. jc REAllocFailed ;big trouble if this happens
  106. push ax ;save RAM DGROUP
  107. mov dx, word ptr lmaDGroup[0]
  108. mov bx, word ptr lmaDGroup[2]
  109. mov cx, 4
  110. xor si, si
  111. @@:
  112. shr bx, 1 ;determine if its in conventional
  113. rcr dx, 1 ;memory and if so the canonical
  114. rcr si, 1 ;segment:offset in dx:si
  115. loop @B
  116. or bx, bx
  117. jnz RECopyFromExtended
  118. RECopyFromConventional:
  119. push es ;save es
  120. mov es,ax
  121. mov ds,dx
  122. mov cx,cparDgroup ; (CS variable)
  123. shl cx,3 ;DGROUP size in words
  124. xor di,di
  125. cld
  126. rep movsw
  127. pop es ;restore es
  128. pop ds ;point to RAM dgroup
  129. assume ds:DGROUP, es:NOTHING
  130. clc ;worked!
  131. REAllocFailed:
  132. ret
  133. RECopyFromExtended:
  134. sub sp, 30h
  135. mov si, sp
  136. push ss
  137. pop es
  138. mov di, si
  139. push ax
  140. xor ax,ax
  141. mov cx, 18h
  142. rep stosw
  143. dec ax
  144. mov es:[si+10h], ax ; Limits to FFFF
  145. mov es:[si+18h], ax
  146. mov al, 93h
  147. mov es:[si+15h], al ; access to data rw
  148. mov es:[si+1Dh], al
  149. pop ax
  150. mov cx, 4
  151. sub dx, dx
  152. @@:
  153. shl ax, 1 ;compute new DGROUP lma
  154. rcl dx, 1
  155. loop @B
  156. mov es:[si+1Ah], ax ;stuff into dest descr
  157. mov es:[si+1Ch], dl
  158. mov ax, word ptr lmaDGroup[0]
  159. mov dx, word ptr lmaDGroup[2]
  160. mov es:[si+12h], ax
  161. mov es:[si+14h], dl ;put ROM lma in source descr
  162. mov cx, cparDGroup
  163. shl cx, 3 ;length of dgroup ***in words ***
  164. mov ah, 87h ;fn 87h = copy extended memory
  165. int 15h
  166. jc REExtCopyFailed
  167. add sp, 30h
  168. pop ds ;get ram address in ds
  169. clc
  170. ret
  171. REExtCopyFailed:
  172. add sp, 32h ;remove stuff from stack
  173. stc
  174. ret
  175. ROMEntry endp
  176. ; -------------------------------------------------------
  177. ; InvokeROMChild -- ROM specific method of invoking the
  178. ; child application.
  179. ;
  180. ; Note: This routine must be called in real mode!
  181. ; It returns to the caller after the child returns. Control
  182. ; passes directly to ChildTerminationHandler if child does a
  183. ; DOS exit call.
  184. ;
  185. ; Input: none
  186. ; Output: CY clear if child executed successfully, set if failed
  187. ; AX = error code if failure (8 = insufficient DOS memory)
  188. ; Errors: none
  189. ; Uses: All except DS
  190. assume ds:DGROUP,es:NOTHING,ss:NOTHING
  191. public InvokeROMChild
  192. InvokeROMChild proc near
  193. ; Setup the environment for the ROM child app. First, allocate
  194. ; the largest conventional memory block available and build a PSP
  195. ; at the start of it.
  196. mov bx,-1 ; how big is the largest avail block?
  197. dossvc 48h
  198. cmp bx,64 SHL 6 ; is there at least 64k available?
  199. jae @f
  200. mov ax,8 ; DOS insufficient memory error
  201. jmp short IRCFail
  202. @@:
  203. mov cparChildMem,bx ; save block size
  204. dossvc 48h ; allocate block
  205. IF DEBUG
  206. jnc @f ; shouldn't fail, but...
  207. int 3
  208. @@:
  209. ENDIF
  210. ; Got conventional memory, now build a PSP at the start of it.
  211. mov dx,ax ; new PSP here
  212. mov si,10h ; use this as mem length for now
  213. dossvc 55h ; duplicate PSP call
  214. ; Set up the termination vector in the child's PSP to point to
  215. ; the Dos Extender termination code.
  216. mov es,dx
  217. assume es:PSPSEG
  218. mov word ptr [lpfnParent],offset ChildTerminationHandler
  219. mov word ptr [lpfnParent+2],cs
  220. ; Switch to protected mode to complete initialization of child environment
  221. SwitchToProtectedMode
  222. assume ds:DGROUP,es:DGROUP
  223. sti
  224. ; Allocate/init a selector mapping first 64k of child memory block & PSP
  225. call AllocateLDTSelector ; get new selector in AX
  226. ; DX still has PSP segment,
  227. call ParaToLinear ; convert to linear memory address
  228. push bx ; save lma for later
  229. push dx
  230. push ax ; save mem/PSP selector too
  231. cCall NSetSegmentDscr,<ax,bx,dx,0,0FFFFh,STD_DATA>
  232. ; Allocate/init a zero length selector pointing to just past the end of
  233. ; the child's memory block and plug the selector into the PSP.
  234. call AllocateLDTSelector ; get another selector
  235. pop es
  236. assume es:PSPSEG
  237. mov segMemEnd,ax ; store in child's PSP
  238. mov dx,cparChildMem ; get size of memory block in bytes
  239. call ParaToLinear ; in BX:DX
  240. pop ax ; recover lma of block start
  241. pop cx ; in CX:AX
  242. add dx,ax
  243. adc bx,cx ; BX:DX = lma of block end
  244. cCall NSetSegmentDscr,<segMemEnd,bx,dx,0,0,STD_DATA>
  245. ; Allocate/init a selector pointin to our DOS environment block--plug this
  246. ; into the child's PSP so it can party on the same env block.
  247. call AllocateLDTSelector
  248. mov dx,segEnviron ; segment from PSP
  249. call ParaToLinear
  250. cCall NSetSegmentDscr,<ax,bx,dx,0,7FFFH,STD_DATA>
  251. mov segEnviron,ax ; selector to PSP
  252. ; The child environment is now build, invoke the child with DS = ES =
  253. ; memory/PSP block. Set the stack 64k (less one word) into the block,
  254. ; push our far return address on the stack.
  255. mov word ptr [regOurSSSP],sp ;save DOSX stack location
  256. mov word ptr [regOurSSSP+2],ss
  257. mov ax,es ; switch to child stack
  258. mov ss,ax
  259. mov sp,0FFFEh
  260. push cs ; far return address to us
  261. push offset IRCReturn
  262. call GetROMTOCPointer ; push the kernel entry CS:IP on stack
  263. assume es:ROMTOC
  264. push word ptr [KRNL_CSIP+2]
  265. push word ptr [KRNL_CSIP]
  266. mov ds,ax
  267. mov es,ax
  268. assume ds:NOTHING,es:NOTHING
  269. xor cx, cx ; tell KRNL386 linear == physical
  270. xor dx, dx
  271. retf ; invoke the kernel
  272. public IRCReturn ;public for debugging
  273. IRCReturn:
  274. mov ds,selDgroupPM ; restore our DS
  275. assume ds:DGROUP
  276. mov ss,word ptr [regOurSSSP+2] ; and our stack
  277. mov sp,word ptr [regOurSSSP]
  278. mov ExitCode,al ; save the child exit code
  279. SwitchToRealMode
  280. sti
  281. clc
  282. ret
  283. IRCFail:
  284. stc
  285. ret
  286. InvokeROMChild endp
  287. ; -------------------------------------------------------
  288. ; ROMInitialization -- This routine performs the initial ROM
  289. ; specific DOS Extender initialization.
  290. ;
  291. ; Note: This routine runs in real mode only!
  292. ;
  293. ; Input: none
  294. ; Output: CY clear if successful, set if init failed
  295. ; Errors: none
  296. ; Uses: AX
  297. assume ds:DGROUP,es:NOTHING,ss:NOTHING
  298. public ROMInitialization
  299. ROMInitialization proc near
  300. ; Point 2nd word of DOSX ROM Int vector to the data segment.
  301. push es
  302. xor ax,ax
  303. mov es,ax
  304. mov ax, word ptr es:[ROMIntVector*4][2] ;save current vector
  305. mov SaveROMVector,ax ; contents
  306. mov word ptr es:[ROMIntVector*4][2],ds ;point vector to data
  307. pop es
  308. clc
  309. ROMInitFailed:
  310. ret
  311. ROMInitialization endp
  312. ; -------------------------------------------------------
  313. ; ROMCleanUp -- This routine performs the ROM specific
  314. ; DOS Extender termination clean up.
  315. ;
  316. ; Note: This routine runs in real mode only!
  317. ;
  318. ; Input: none
  319. ; Output: none
  320. ; Errors: none
  321. ; Uses: none
  322. assume ds:DGROUP,es:NOTHING,ss:NOTHING
  323. public ROMCleanUp
  324. ROMCleanUp proc near
  325. ; Remove DOSX Int vector pointer to the data segment.
  326. push es
  327. xor ax,ax
  328. mov es,ax
  329. mov ax,SaveROMVector ;restore prior contents
  330. mov word ptr es:[ROMIntVector*4][2],ax
  331. pop es
  332. ret
  333. ROMCleanUp endp
  334. ; -------------------------------------------------------
  335. subttl ROM Real Mode Utility Routines
  336. page
  337. ; -------------------------------------------------------
  338. ; ROM REAL MODE UTILITY ROUTINES
  339. ; -------------------------------------------------------
  340. ; GetDXDataRM -- This routine returns the paragraph address of
  341. ; the DOS Extender data segment. It should only be called
  342. ; by real mode code.
  343. ;
  344. ; Input: none
  345. ; Output: AX = DOSX data segment paragraph address
  346. ; Errors: none
  347. ; Uses: none
  348. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  349. public GetDXDataRM
  350. GetDXDataRM proc near
  351. ; Get data segment value from 2nd word of DOSX Int vector
  352. push ds
  353. xor ax,ax
  354. mov ds,ax
  355. mov ax,word ptr ds:[ROMIntVector*4][2]
  356. IF DEBUG
  357. mov ds,ax
  358. cmp ax,ds:[segDXData] ; Make sure ax points to the
  359. jz @f ; right place
  360. int 3
  361. @@:
  362. ENDIF
  363. pop ds
  364. ret
  365. GetDXDataRM endp
  366. ; -------------------------------------------------------
  367. ; SetDXDataRM -- This routine sets DS equal to the DOS Extender
  368. ; data segment address. It should only be called by real
  369. ; mode code.
  370. ;
  371. ; Input: none
  372. ; Output: DS -> DOSX data segment
  373. ; Errors: none
  374. ; Uses: none
  375. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  376. public SetDXDataRM
  377. SetDXDataRM proc near
  378. ; Get data segment value from 2nd word of DOSX Int vector
  379. push ax
  380. xor ax,ax
  381. mov ds,ax
  382. mov ds,word ptr ds:[ROMIntVector*4][2]
  383. IF DEBUG
  384. mov ax,ds ; Make sure DS points to the
  385. cmp ax,ds:[segDXData] ; right place
  386. jz @f
  387. int 3
  388. @@:
  389. ENDIF
  390. pop ax
  391. ret
  392. SetDXDataRM endp
  393. DXCODE ends
  394. ;****************************************************************
  395. DXPMCODE SEGMENT
  396. assume cs:DXPMCODE
  397. ; -------------------------------------------------------
  398. subttl ROM Protect Mode Utility Routines
  399. page
  400. ; -------------------------------------------------------
  401. ; ROM PROTECT MODE UTILITY ROUTINES
  402. ; -------------------------------------------------------
  403. ; ROMInitLDT -- This routine initializes the LDT descriptors
  404. ; defined in the ROM prototype LDT.
  405. ;
  406. ; Input: none
  407. ; Output: none
  408. ; Errors: none
  409. ; Uses: none
  410. assume ds:DGROUP,es:NOTHING,ss:NOTHING
  411. public ROMInitLDT
  412. ROMInitLDT proc near
  413. ; Access the ROM Table of Contents to find out where the proto LDT
  414. ; is, and how many descriptors it contains.
  415. pusha
  416. push ds
  417. push es
  418. call GetROMTOCPointer ; Note: uses SEL_SCR0
  419. assume es:ROMTOC
  420. mov cx,cROMsels ; # descriptors defined in proto LDT
  421. mov bx,word ptr [lmaROMLDT+2]
  422. mov dx,word ptr [lmaROMLDT] ; bx:dx = lma of proto LDT
  423. mov ax,FirstROMSel
  424. mov di, ax
  425. ; Do a quick (and dirty?) allocation of the correct number of LDT selectors.
  426. ; DANGER: this code has intimate knowledge of how the LDT free list is kept!
  427. ; We could make CX calls to AllocateLDTSelector, but that is slow and would
  428. ; do zillions and zillions of segment loads.
  429. ;
  430. cmp ax,selGDTFree ; next free descriptor in LDT
  431. jne alloc_in_chain
  432. IF DEBUG
  433. cmp ax,__selFirstLDT ; first one free better be the one
  434. jz @f ; the ROM Image Builder used.
  435. int 3
  436. @@:
  437. ENDIF
  438. shl cx,3 ; 'allocate' all these by setting
  439. add ax,cx ; the next free to be beyond them
  440. mov selGDTFree,ax
  441. push SEL_LDT_ALIAS OR STD_RING
  442. pop es
  443. jmp short sels_alloced
  444. alloc_in_chain:
  445. mov si, ax
  446. sub si, 8
  447. push SEL_LDT_ALIAS OR STD_RING
  448. pop es
  449. shl cx, 3
  450. add ax, cx
  451. mov es:[si], ax
  452. sels_alloced:
  453. ; Copy the prototype descriptors into the actual LDT
  454. cCall NSetSegmentDscr,<SEL_SCR0,bx,dx,0,-1,STD_DATA>
  455. push SEL_SCR0 OR STD_TBL_RING
  456. pop ds ; ds -> proto LDT descriptors
  457. assume ds:NOTHING
  458. xor si,si
  459. shr cx,1 ; # words of descriptors to copy
  460. cld
  461. rep movsw ; move'm into the LDT
  462. pop es
  463. pop ds
  464. assume ds:DGROUP,es:NOTHING
  465. popa
  466. ret
  467. ROMInitLDT endp
  468. ; -------------------------------------------------------
  469. ; GetROMTOCPointer -- return ES:0 pointing to the ROM Table of
  470. ; Contents.
  471. ;
  472. ; Note: modifies the SEL_SCR0 descriptor!
  473. ;
  474. ; Input: none
  475. ; Output: ES:0 -> ROM TOC
  476. ; Errors: none
  477. ; Uses: none
  478. assume ds:DGROUP,es:NOTHING,ss:NOTHING
  479. public GetROMTOCPointer
  480. GetROMTOCPointer proc near
  481. push bx
  482. push dx
  483. mov bx,word ptr [MyLmaROMTOC+2]
  484. mov dx,word ptr [MyLmaROMTOC] ;bx:dx = lma of ROMTOC
  485. cCall NSetSegmentDscr,<SEL_SCR0,bx,dx,0,-1,STD_DATA>
  486. push SEL_SCR0 OR STD_TBL_RING
  487. pop es
  488. pop dx
  489. pop bx
  490. ret
  491. GetROMTOCPointer endp
  492. ; -------------------------------------------------------
  493. ; GetDXDataPM -- This routine returns the paragraph address of
  494. ; the DOS Extender data segment. It should only be called
  495. ; by protected mode code.
  496. ;
  497. ; Input: none
  498. ; Output: AX = DOSX data segment paragraph address
  499. ; Errors: none
  500. ; Uses: none
  501. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  502. public GetDXDataPM
  503. GetDXDataPM proc near
  504. ; Get data segment value from 1st word of DOSX Int vector
  505. push ds
  506. mov ax,SEL_RMIVT or STD_RING
  507. mov ds,ax
  508. mov ax,word ptr ds:[ROMIntVector*4][2]
  509. pop ds
  510. ret
  511. GetDXDataPM endp
  512. if 0 ;***************************************************************
  513. ; -------------------------------------------------------
  514. ; SetDXDataPM -- This routine sets DS equal to the DOS Extender
  515. ; data segment address. It should only be called by protected
  516. ; mode code.
  517. ;
  518. ; Input: none
  519. ; Output: DS -> DOSX data segment
  520. ; Errors: none
  521. ; Uses: none
  522. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  523. public SetDXDataPM
  524. SetDXDataPM proc near
  525. ; Set DS = data segment selector.
  526. push SEL_DXDATA OR STD_RING
  527. pop ds
  528. ret
  529. SetDXDataPM endp
  530. endif ;***************************************************************
  531. DXPMCODE ends
  532. ;****************************************************************
  533. ifdef ROMSTUB ;--------------------------------------------------------
  534. *********************************************
  535. *********************************************
  536. ***** *****
  537. ***** THIS CODE IS NO LONGER USED *****
  538. ***** *****
  539. *********************************************
  540. *********************************************
  541. DXSTUB SEGMENT
  542. assume cs:DXSTUB
  543. ; -------------------------------------------------------
  544. subttl Real Mode RAM Stub Segment
  545. page
  546. ; -------------------------------------------------------
  547. ; REAL MODE RAM STUB SEGMENT
  548. ; -------------------------------------------------------
  549. ; This segment contains code and data that is moved to conventional
  550. ; RAM during initialization. The code is only executed from RAM
  551. ; mode and exists for those few cases where it is most convenient
  552. ; to have code segement variables.
  553. ;
  554. ; Note: Since this code is moved to RAM, be very carefull of the
  555. ; instructions it contains. In particular, realize the the code segment
  556. ; value is going to be different from the copy in ROM.
  557. ; -------------------------------------------------------
  558. ; CODE SEGMENT VARIABLES
  559. ; -------------------------------------------------------
  560. public PrevInt2FHandler
  561. PrevInt2FHandler dd ?
  562. ; -------------------------------------------------------
  563. ; StubInt2FHook -- This code is used by the DOS Extender real mode
  564. ; Int 2Fh hook to chain the interrupt to the previous Int 2Fh
  565. ; handler.
  566. ;
  567. ; Note: This code executes in real mode only!
  568. ;
  569. ; Input: stack = [DS] [IP] [CS] [FL]
  570. ; Output: none
  571. ; Errors: none
  572. ; Uses: none
  573. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  574. public StubInt2FHook
  575. StubInt2FHook proc far
  576. pop ds
  577. jmp [PrevInt2FHandler]
  578. StubInt2FHook endp
  579. ; -------------------------------------------------------
  580. DXSTUB ends
  581. endif ;----------------------------------------------------------------
  582. ;****************************************************************
  583. ENDIF ;ROM
  584. end