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.

4141 lines
116 KiB

  1. PAGE ,132
  2. TITLE Windows Protect Mode Routines
  3. .list
  4. include kernel.inc
  5. include protect.inc
  6. include pdb.inc
  7. include newexe.inc
  8. .list
  9. .286p
  10. ifdef WOW
  11. ;
  12. ; the dpmi func 04f1h is idential to function 00h, except that
  13. ; the descriptor base and limit are not initialized to zero.
  14. ;
  15. ;
  16. ; the dpmi func 04f2h is identical to 0ch except that it
  17. ; sets 'count' (in cx) LDTs at one time. The first selector is in
  18. ; register bx. The descriptor data is in gdtdsc[bx], gdtdsc[bx+8]
  19. ; etc. This data is shared between dpmi (dosx.exe) and us and thus
  20. ; need not be passed in es:di
  21. WOW_DPMIFUNC_00 equ 04f1h
  22. WOW_DPMIFUNC_0C equ 04f2h
  23. endif
  24. MovsDsc Macro ;Move (copy) a descriptor (4 words)
  25. cld
  26. rept 4
  27. movsw
  28. endm
  29. endm
  30. CheckDS Macro
  31. local okDS
  32. push ax
  33. mov ax, ds
  34. cmp ax, pGlobalHeap
  35. je okDS
  36. int 3
  37. okDS:
  38. pop ax
  39. endm
  40. CheckLDT Macro selector
  41. if KDEBUG
  42. test selector,SEL_LDT
  43. jnz @F
  44. int 3
  45. @@:
  46. endif
  47. Endm
  48. DPMICALL MACRO callno
  49. mov ax, callno
  50. call DPMIProc
  51. ENDM
  52. CHECKSEL MACRO selector
  53. ENDM
  54. extrn GlobalHandle:FAR
  55. extrn GlobalRealloc:FAR
  56. extrn GlobalFix:FAR
  57. extrn GlobalUnFix:FAR
  58. extrn IGlobalFix:FAR ;Far calls in this segment
  59. extrn IGlobalFlags:FAR
  60. IF KDEBUG
  61. extrn GlobalHandleNorip:FAR
  62. ELSE
  63. extrn IGlobalHandle:FAR
  64. ENDIF
  65. DataBegin
  66. ifdef WOW
  67. externW SelectorFreeBlock
  68. externW UserSelArray
  69. endif
  70. externW WinFlags
  71. extrn kr1dsc:WORD
  72. extrn kr2dsc:WORD
  73. extrn blotdsc:WORD
  74. extrn DemandLoadSel:WORD
  75. extrn temp_sel:WORD
  76. externW MyCSSeg
  77. externW selWoaPdb
  78. externW cpLowHeap
  79. externW selLowHeap
  80. externW pGlobalHeap
  81. externW SelTableLen
  82. externW MyCSAlias
  83. extrn SelTableStart:DWORD
  84. extrn sel_alias_array:WORD
  85. if ROM
  86. externW selROMTOC
  87. externW selROMLDT
  88. externW sel1stAvail
  89. endif
  90. if ROM
  91. externD lmaHiROM
  92. externD cbHiROM
  93. endif
  94. globalD lpProc,0
  95. DataEnd
  96. DataBegin INIT
  97. RModeCallStructure STRUC
  98. RMCS_DI dw 0
  99. dw 0
  100. RMCS_ESI dd 0
  101. RMCS_EBP dd 0
  102. RMCS_Res dd 0
  103. RMCS_EBX dd 0
  104. RMCS_EDX dd 0
  105. RMCS_ECX dd 0
  106. RMCS_EAX dd 0
  107. RMCS_Flags dw 0
  108. RMCS_ES dw 0
  109. RMCS_DS dw 0
  110. RMCS_FS dw 0
  111. RMCS_GS dw 0
  112. RMCS_IP dw 0
  113. RMCS_CS dw 0
  114. RMCS_SP dw 0
  115. RMCS_SS dw 0
  116. RModeCallStructure ENDS
  117. MyCallStruc RModeCallStructure <>
  118. public MS_DOS_Name_String
  119. MS_DOS_Name_String db "MS-DOS", 0
  120. DataEnd INIT
  121. sBegin CODE
  122. externW MyCSDS
  123. externW gdtdsc
  124. ifdef WOW
  125. externD prevInt31proc
  126. endif
  127. sEnd CODE
  128. sBegin INITCODE
  129. assumes cs,CODE
  130. ;-----------------------------------------------------------------------;
  131. ; SwitchToPMODE ;
  132. ; ;
  133. ; Entry: ;
  134. ; In Real or Virtual Mode ;
  135. ; DS -> Data Segment ;
  136. ; ES -> PSP ;
  137. ; ;
  138. ; Returns: ;
  139. ; In Protect Mode ;
  140. ; BX -> LDT selector ;
  141. ; SI -> Segment of start of available memory ;
  142. ; ES -> PSP ;
  143. ; ;
  144. ; Error Returns: ;
  145. ; Exits via DOS call 4Ch ;
  146. ; ;
  147. ; Registers Preserved: ;
  148. ; ;
  149. ; ;
  150. ; Registers Destroyed: ;
  151. ; ;
  152. ; Calls: ;
  153. ; ;
  154. ; History: ;
  155. ; ;
  156. ;-----------------------------------------------------------------------;
  157. assumes ds,DATA
  158. assumes es,nothing
  159. ife ROM
  160. cProc SwitchToPMODE,<PUBLIC,NEAR>
  161. cBegin nogen
  162. push cx
  163. push es ; Current PSP
  164. mov ax, 1687h
  165. int 2Fh ; Get PMODE switch entry
  166. or ax, ax ; Can we do it?
  167. jz @F
  168. NoPMODEj:
  169. jmp NoPMODE
  170. @@:
  171. xor bh, bh ; Set CPU type now
  172. mov bl,WF_CPU286
  173. cmp cl, 2 ; At least a 286?
  174. jb NoPMODEj ; No, Fail
  175. je @F ; It is a 286?
  176. mov bl,WF_CPU386
  177. cmp cl,3 ; No, 386?
  178. je @F
  179. mov bl,WF_CPU486 ; No, assume 486 for now
  180. @@:
  181. mov WinFlags, bx ; Save away CPU type
  182. mov word ptr [lpProc][0], di
  183. mov word ptr [lpProc][2], es
  184. pop ax ; PSP
  185. add ax, 10h ; Skip the PSP
  186. mov es, ax ; Give this to the DOS extender
  187. add si, ax ; Start of memory available to us
  188. mov selWoaPdb, si ; PDB for WOA
  189. add si, 10h ; Move start on another 256 bytes
  190. xor ax, ax ; 16-bit app
  191. call [lpProc] ; Switch to PROTECTED mode
  192. jc short NoPMODEj ; No, still Real/Virtual mode
  193. mov ax, cs
  194. and al, 7 ; LDT, Ring 3
  195. cmp al, 7
  196. je @F
  197. jmp BadDPMI ; Insist on Ring 3!
  198. @@:
  199. mov bx, cs ; Allocate CS Alias
  200. DPMICALL 000Ah
  201. mov MyCSAlias, ax ; Save CS Alias in DS
  202. mov bx, ds ; Use alias to update code seg var
  203. mov ds, ax
  204. assumes ds, CODE
  205. mov MyCSDS, bx ; The DS selector
  206. mov ds, bx
  207. ReSetKernelDS
  208. push si ; Unlock all of our memory
  209. mov bx, si ; Segment address of start of our memory
  210. mov di, es:[PDB_block_len] ; End of our memory
  211. sub di, bx ; Size of our block in paragraphs
  212. mov cpLowHeap, di ; (MAY NEED INCREMENTING!!!)
  213. xor si, si ; Calculate # bytes in SI:DI
  214. REPT 4
  215. shl di, 1
  216. rcl si, 1
  217. ENDM
  218. mov cx, bx ; Convert start of block to linear
  219. xor bx, bx ; address
  220. REPT 4
  221. shl cx, 1
  222. rcl bx, 1
  223. ENDM
  224. mov ax, 0602h
  225. ;BUGBUGBUGBUG
  226. int 31h ; Mark region as pageable.
  227. pop bx
  228. DPMICALL 0002h ; Convert start of memory to selector
  229. mov si, ax
  230. mov selLowHeap, ax ; Save for WOA (MAY NEED PARA LESS!!!)
  231. mov bx, selWoaPdb ; Convert WOA PDB segment to selector
  232. DPMICALL 0002h
  233. mov selWoaPdb, ax
  234. push si
  235. push es
  236. mov ax, 168Ah ; See if we have MS-DOS extensions
  237. mov si, dataOffset MS_DOS_Name_String
  238. int 2Fh
  239. cmp al, 8Ah
  240. je short BadDPMI ; No extensions, screwed
  241. mov word ptr [lpProc][0], di ; Save CallBack address
  242. mov word ptr [lpProc][2], es
  243. mov ax, 0100h ; Get base of LDT
  244. call [lpProc]
  245. jc short NoLDTParty
  246. ifndef WOW
  247. verw ax ; Writeable?
  248. else
  249. verr ax ; for WOW we can use read access
  250. endif
  251. jnz short NoLDTParty ; nope, don't bother with it
  252. mov es, MyCSAlias
  253. assumes es,CODE
  254. mov gdtdsc, ax
  255. assumes es,nothing
  256. NoLDTParty: ; Well, we'll just have to use DPMI!
  257. pop es
  258. pop si
  259. xor bx, bx
  260. pop cx
  261. ret
  262. BadDPMI:
  263. ;
  264. ; Call real/virtual mode to whine
  265. ;
  266. xor cx, cx ; Nothing on stack to copy
  267. xor bh, bh ; Flags to DPMI
  268. mov ax, MyCSSeg
  269. mov MyCallStruc.RMCS_DS, ax ; Real mode DS will be parent PDB
  270. mov MyCallStruc.RMCS_ES, cx ; Real mode ES will be 0
  271. mov MyCallStruc.RMCS_CS, ax ; Real mode CS
  272. mov MyCallStruc.RMCS_IP, codeoffset RModeCode ; Real mode IP
  273. smov es, ds
  274. mov di, dataoffset MyCallStruc ; ES:DI points to call structure
  275. mov ax, 0301h ; Call Real Mode Procedure
  276. int 31h
  277. jmps GoodBye
  278. RModeCode:
  279. mov dx, codeoffset szInadequate
  280. mov ah, 9
  281. int 21h
  282. retf
  283. ;szInadequate:
  284. ; DB 'KRNL286: Inadequate DPMI Server',13,10,'$'
  285. externB <szNoPMode, szInadequate>
  286. NoPMODE: ; NOTE: stack trashed...
  287. ifdef WOW
  288. ;** Put Up a Dialog Box If we fail to Enter Protect Mode
  289. ;** Prepare the dialog box
  290. push cs ;In our DS
  291. push codeOFFSET szNoPMode ; -> unable to enter Prot Mode
  292. push ds
  293. externB <syserr>
  294. push dataOffset syserr ;Caption
  295. push 0 ;No left button
  296. push SEB_CLOSE + SEB_DEFBUTTON ;Button 1 style
  297. push 0 ;No right button
  298. externFP kSYSERRORBOX
  299. call kSYSERRORBOX ;Put up the system error message
  300. externNP ExitKernel
  301. jmp ExitKernel
  302. else ; Not WOW
  303. mov dx, codeoffset szNoPMode
  304. ; call complain
  305. ; DB 'KRNL286: Unable to enter Protected Mode',7,7,7,13,10,'$'
  306. ;complain:
  307. ; pop dx
  308. push cs
  309. pop ds ; DS:DX -> error message
  310. mov ah,9 ; Print error message
  311. int 21h
  312. endif ; WOW
  313. GoodBye:
  314. mov ax, 4CFFh
  315. int 21h
  316. cEnd nogen
  317. endif ;ROM
  318. ;-----------------------------------------------------------------------;
  319. ; LDT_Init ;
  320. ; ;
  321. ; Entry: ;
  322. ; ;
  323. ; Returns: ;
  324. ; ;
  325. ; Error Returns: ;
  326. ; ;
  327. ; Registers Preserved: ;
  328. ; AX,BX,CX,DX,DI,SI,DS,ES ;
  329. ; ;
  330. ; Registers Destroyed: ;
  331. ; ;
  332. ; Calls: ;
  333. ; ;
  334. ; History: ;
  335. ; ;
  336. ;-----------------------------------------------------------------------;
  337. assumes ds,nothing
  338. assumes es,nothing
  339. cProc LDT_Init,<PUBLIC,NEAR>,<ax,bx,cx,di,es>
  340. cBegin
  341. ReSetKernelDS
  342. mov es, bx ; Selector for LDT if any
  343. push es ; Get random selectors
  344. smov es, ds
  345. ReSetKernelDS es
  346. assumes ds,nothing
  347. mov cx, 1 ; Argument to get_sel
  348. call get_sel
  349. mov kr1dsc, si
  350. call get_sel
  351. mov blotdsc, si
  352. call get_sel
  353. or si, SEG_RING
  354. mov DemandLoadSel, si
  355. mov ax, DSC_DATA+DSC_PRESENT; Get an array of 16 selectors
  356. cCall alloc_sel,<0000h,0BADh,0FFFFh> ; This covers 1Mb.
  357. mov kr2dsc, ax
  358. smov ds, es
  359. pop es
  360. assumes es,nothing
  361. cEnd
  362. sEnd INITCODE
  363. sBegin CODE
  364. assumes cs,CODE
  365. ;-----------------------------------------------------------------------;
  366. ; AllocSelector
  367. ;
  368. ;
  369. ; Entry:
  370. ;
  371. ; Returns:
  372. ; AX = New selector
  373. ; = 0 if out of selectors
  374. ;
  375. ; Registers Destroyed:
  376. ;
  377. ; History:
  378. ; Thu 08-Dec-1988 14:17:38 -by- David N. Weise [davidw]
  379. ; Wrote it!
  380. ;-----------------------------------------------------------------------;
  381. assumes ds,nothing
  382. assumes es,nothing
  383. cProc AllocSelectorWOW,<PUBLIC,FAR>
  384. parmW selector
  385. cBegin
  386. ; same as allocselector but doesn't set the descriptor
  387. cCall inner_alloc_selector,<selector,0ffffh>
  388. cEnd
  389. cProc AllocSelector,<PUBLIC,FAR>
  390. parmW selector
  391. cBegin
  392. cCall inner_alloc_selector,<selector,0>
  393. cEnd
  394. labelFP <PUBLIC, IAllocCStoDSAlias>
  395. ;-----------------------------------------------------------------------;
  396. ; AllocAlias
  397. ;
  398. ; This allocates a data alias for the passed in selector, which
  399. ; can be either code or data. The alias will track segment
  400. ; motion.
  401. ;
  402. ; Entry:
  403. ; parmW selector selector to get an alias for
  404. ;
  405. ; Returns:
  406. ; AX = selector
  407. ; = 0 failure
  408. ;
  409. ; Registers Destroyed:
  410. ;
  411. ; History:
  412. ; Sat 20-Jan-1990 23:40:32 -by- David N. Weise [davidw]
  413. ; Cleaning up.
  414. ;
  415. ; Fri 02-Dec-1988 11:04:58 -by- David N. Weise [davidw]
  416. ; Wrote it!
  417. ;-----------------------------------------------------------------------;
  418. assumes ds,nothing
  419. assumes es,nothing
  420. cProc AllocAlias,<FAR,PUBLIC>
  421. parmW selector
  422. cBegin
  423. ifdef WOW
  424. push bx ; Whitewater tool ObjDraw needs this too
  425. endif
  426. cCall inner_alloc_selector,<selector,1>
  427. ; WhiteWater Resource Toolkit (shipped with Borland's Turbo
  428. ; Pascal) depends on dx being the data selector which was true
  429. ; in 3.0 but in 3.1 validation layer destroys it.
  430. mov dx,selector
  431. ifdef WOW
  432. pop bx
  433. endif
  434. cEnd
  435. ;-----------------------------------------------------------------------;
  436. ; AllocDStoCSAlias
  437. ;
  438. ; This allocates a code alias for the passed in selector, which
  439. ; should be data. The alias will track segment motion. The
  440. ; passed in selector must be less than 64K.
  441. ;
  442. ; Entry:
  443. ; parmW selector selector to get an alias for
  444. ;
  445. ; Returns:
  446. ; AX = selector
  447. ; = 0 failure
  448. ;
  449. ; Registers Destroyed:
  450. ;
  451. ; History:
  452. ; Sat 20-Jan-1990 23:40:32 -by- David N. Weise [davidw]
  453. ; Cleaning up.
  454. ;
  455. ; Fri 02-Dec-1988 11:04:58 -by- David N. Weise [davidw]
  456. ; Wrote it!
  457. ;-----------------------------------------------------------------------;
  458. assumes ds,nothing
  459. assumes es,nothing
  460. cProc IAllocDStoCSAlias,<FAR,PUBLIC>, <cx,si,di>
  461. parmW data_selector
  462. cBegin
  463. ;** AllocDStoCSAlias has an interesting hack. A fix was made to
  464. ;** not allow apps to GlobalAlloc fixed memory. This was done
  465. ;** for performance reasons. The only reason we can ascertain
  466. ;** for an app needing fixed GlobalAlloc'ed memory is in the case
  467. ;** of alias selectors. We assume that all apps needing alias
  468. ;** selectors will use this function to make the alias. So, if
  469. ;** we see a DStoCS alias being made, we make sure the DS is fixed.
  470. mov ax, data_selector ;Get handle
  471. push ax
  472. IF KDEBUG
  473. call GlobalHandleNorip ;Make sure it's really a handle
  474. ELSE
  475. call IGlobalHandle ;Make sure it's really a handle
  476. ENDIF
  477. test ax, 1 ;Fixed blocks have low bit set
  478. jnz ADCA_Already_Fixed ;It's already a fixed block!
  479. ;** If the block is not fixed, it may be locked so we must check this.
  480. push ax ;Save returned selector
  481. push ax ;Use as parameter
  482. call IGlobalFlags ;Returns lock count if any
  483. or al, al ;Non-zero lock count?
  484. pop ax ;Get selector back
  485. jnz ADCA_Already_Fixed ;Yes, don't mess with it
  486. ;** Fix the memory. Note that we're only doing this for
  487. ;** apps that are calling this on non-fixed or -locked memory.
  488. ;** This will cause them to rip on the GlobalFree call to this
  489. ;** memory, but at least it won't move on them!
  490. push ax ;Fix it
  491. call IGlobalFix
  492. ADCA_Already_Fixed:
  493. cCall inner_alloc_selector,<data_selector,2>
  494. if ALIASES
  495. or ax,ax
  496. jz ada_nope
  497. mov bx,data_selector
  498. call add_alias
  499. ada_nope:
  500. endif
  501. smov es,0
  502. ; WhiteWater Resource Toolkit (shipped with Borland's Turbo
  503. ; Pascal) depends on dx being the data selector which was
  504. ; true in 3.0 but in 3.1 validation layer destroys it.
  505. mov dx,data_selector
  506. cEnd
  507. ;-----------------------------------------------------------------------;
  508. ; inner_alloc_selector
  509. ;
  510. ;
  511. ; Entry:
  512. ;
  513. ; Returns:
  514. ;
  515. ; Registers Destroyed:
  516. ;
  517. ; History:
  518. ; Sat 20-Jan-1990 23:40:32 -by- David N. Weise [davidw]
  519. ;
  520. ;-----------------------------------------------------------------------;
  521. assumes ds,nothing
  522. assumes es,nothing
  523. cProc inner_alloc_selector,<PUBLIC,NEAR>,<di,si>
  524. parmW selector
  525. parmW sel_type
  526. localV DscBuf,DSC_LEN
  527. cBegin
  528. mov cx, 1
  529. mov di, selector
  530. and di, not SEG_RING_MASK
  531. jnz as1
  532. call get_sel
  533. jnz short as_exit ; We got it
  534. jmps as_exit1
  535. as1:
  536. mov bx, selector
  537. lea di, DscBuf
  538. smov es, ss
  539. ifdef WOW
  540. DPMICALL 000Bh ; Get existing descriptor
  541. else
  542. push ds
  543. mov ds, gdtdsc
  544. push si ; Get Descriptor
  545. mov si, bx
  546. and si, not 7
  547. MovsDsc
  548. lea di, [di-DSC_LEN] ; Restore DI
  549. pop si
  550. pop ds
  551. endif
  552. mov cl, DscBuf.dsc_hlimit
  553. and cl, 0Fh
  554. inc cl ; # selectors
  555. call get_sel
  556. jz short as_exit1
  557. ifdef WOW
  558. cmp sel_type, 0ffffh ; called from AllocSelectorWOW ?
  559. jz as_exit ; yes . dont set descriptor
  560. endif
  561. cmp sel_type,0 ; called from AllocSelector?
  562. jz as_fill ; done if so
  563. mov al,DSC_PRESENT+DSC_DATA
  564. cmp sel_type,1 ; called from AllocAlias?
  565. jz @F
  566. or al,DSC_CODE_BIT ; called from AllocDStoCSAlias
  567. @@:
  568. mov DscBuf.dsc_access,al
  569. as_fill:
  570. mov bx, si
  571. or bl, SEG_RING
  572. call fill_in_selector_array
  573. as_exit:
  574. or si, SEG_RING
  575. as_exit1:
  576. mov ax,si
  577. smov es, 0
  578. cEnd
  579. ;-----------------------------------------------------------------------;
  580. ; get_sel ;
  581. ; ;
  582. ; Entry: ;
  583. ; CX = # of selectors required ;
  584. ; ;
  585. ; Returns: ;
  586. ; SI = First Selector ;
  587. ; DS = LDT ;
  588. ; ZF = 0 ;
  589. ; ;
  590. ; Error Returns: ;
  591. ; SI = 0 ;
  592. ; ZF = 1 ;
  593. ; ;
  594. ; Registers Preserved: ;
  595. ; AX,BX,CX,DX,DI,ES ;
  596. ; ;
  597. ; Registers Destroyed: ;
  598. ; ;
  599. ; Calls: ;
  600. ; ;
  601. ; History: ;
  602. ; ;
  603. ;-----------------------------------------------------------------------;
  604. cProc AllocSelectorArray,<PUBLIC,FAR>,<si>
  605. parmW nSels
  606. cBegin
  607. mov cx, nSels
  608. call get_sel
  609. mov ax, si
  610. jz asa_fail
  611. or si, SEG_RING
  612. mov bx, si
  613. mov dx, cx
  614. mov cx, DSC_DATA+DSC_PRESENT ; Mark all as Data and Present
  615. ifdef WOW
  616. fill_in_access:
  617. DPMICALL 0009h
  618. lea bx, [bx+DSC_LEN]
  619. dec dx
  620. jnz fill_in_access
  621. else
  622. push ds
  623. mov ds, gdtdsc
  624. push bx
  625. and bl, not 7
  626. fill_in_access:
  627. mov word ptr ds:[bx].dsc_access, cx
  628. if 0 ;;ROM and KDEBUG
  629. call CheckROMSelector
  630. endif
  631. lea bx, [bx+DSC_LEN]
  632. dec dx
  633. jnz fill_in_access
  634. pop bx
  635. pop ds
  636. endif; WOW
  637. mov ax, si
  638. asa_fail:
  639. cEnd
  640. cProc get_sel,<PUBLIC,NEAR>
  641. cBegin nogen
  642. call SetKernelDSProc ; Must call procedure here
  643. ReSetKernelDS
  644. push ax
  645. push cx
  646. xor ax, ax
  647. cmp cx, 1 ; One selector only?
  648. jne gs_int31
  649. cmp temp_sel, ax ; Have one waiting?
  650. je gs_int31 ; no, get one
  651. xchg temp_sel, ax ; Use the waiting selector
  652. jmps gs_got_sel
  653. gs_int31:
  654. DPMICALL 0000h
  655. CHECKSEL ax
  656. gs_got_sel:
  657. mov si, ax
  658. and si, not SEG_RING_MASK
  659. if KDEBUG
  660. jnz got_sel
  661. push es
  662. pusha
  663. kerror 0,<Out of selectors>
  664. popa
  665. pop es
  666. jmps gs_exit
  667. got_sel:
  668. endif
  669. mov ax, si
  670. shr ax, 2
  671. cmp ax, SelTableLen ; Make sure we can associate it
  672. jae gs_free_sels
  673. gs_exit:
  674. mov ds, gdtdsc ; SIDE EFFECT...
  675. UnSetKernelDS
  676. gs_exit_2:
  677. pop cx
  678. pop ax
  679. or si, si
  680. ret
  681. gs_free_sels:
  682. ReSetKernelDS
  683. cmp SelTableLen, 0
  684. je gs_exit ; Not set yet, so we are ok
  685. mov ds, gdtdsc
  686. UnSetKernelDS
  687. push bx
  688. mov bx, si ; Could not associate, so free them
  689. xor si, si
  690. or bl, SEG_RING
  691. as_free:
  692. DPMICALL 0001h
  693. lea bx, [bx+DSC_LEN]
  694. loop as_free
  695. pop bx
  696. jmps gs_exit_2
  697. cEnd nogen
  698. ;-----------------------------------------------------------------------;
  699. ; FreeSelector ;
  700. ; free_sel ;
  701. ; FreeSelArray
  702. ; ;
  703. ; Entry: ;
  704. ; ;
  705. ; Returns: ;
  706. ; ;
  707. ; Error Returns: ;
  708. ; ;
  709. ; Registers Preserved: ;
  710. ; BX,CX,DX,DI,SI,DS,ES ;
  711. ; ;
  712. ; Registers Destroyed: ;
  713. ; ;
  714. ; Calls: ;
  715. ; ;
  716. ; History: ;
  717. ; ;
  718. ;-----------------------------------------------------------------------;
  719. assumes ds,nothing
  720. assumes es,nothing
  721. cProc IFreeSelector,<FAR,PUBLIC>,<di,si>
  722. parmW selector
  723. cBegin
  724. CheckLDT selector
  725. if ALIASES
  726. mov ax,selector
  727. call delete_alias
  728. endif
  729. xor ax, ax
  730. mov es, ax ; GRRRRRRRR!
  731. cCall FreeSelArray,<selector>
  732. cEnd
  733. assumes ds,nothing
  734. assumes es,nothing
  735. cProc free_sel,<PUBLIC,NEAR>,<ax,bx>
  736. parmW selector
  737. cBegin
  738. pushf ; !! for the nonce
  739. mov bx,selector ; must be careful in gcompact
  740. ; to ignore error return
  741. if KDEBUG
  742. or bx, SEG_RING ; Ensure Table bit correct
  743. endif
  744. DPMICALL 0001h
  745. popf
  746. cEnd
  747. assumes ds,nothing
  748. assumes es,nothing
  749. cProc FreeSelArray,<PUBLIC,NEAR>,<ax,bx,cx>
  750. parmW selector
  751. cBegin
  752. mov bx,selector ; to ignore error return
  753. cCall GetSelectorCount
  754. mov cx, ax
  755. fsa_loop:
  756. DPMICALL 0001h
  757. lea bx, [bx+DSC_LEN]
  758. loop fsa_loop ; Any left to free
  759. cEnd
  760. ;-----------------------------------------------------------------------;
  761. ; GrowSelArray ;
  762. ; ;
  763. ; This is called from within grealloc. The point is to grow the ;
  764. ; number of contiguous selectors to tile the memory object. ;
  765. ; If we can't get a contiguous set then we attempt to find a set ;
  766. ; anywhere. ;
  767. ; ;
  768. ; Entry: ;
  769. ; ES => arena header ;
  770. ; ;
  771. ; Returns: ;
  772. ; AX => new selector array ;
  773. ; CX => new number of selectors ;
  774. ; ;
  775. ; Error Returns: ;
  776. ; ;
  777. ; Registers Preserved: ;
  778. ; BX,DX,DI,SI,DS,ES ;
  779. ; ;
  780. ; Registers Destroyed: ;
  781. ; ;
  782. ; Calls: ;
  783. ; ;
  784. ; History: ;
  785. ; ;
  786. ;-----------------------------------------------------------------------;
  787. assumes ds,nothing
  788. assumes es,nothing
  789. cProc GrowSelArray,<PUBLIC,NEAR>,<bx,si,di,ds>
  790. localV DscBuf,DSC_LEN
  791. localW oldCount
  792. cBegin
  793. mov bx, es:[ga_handle]
  794. mov di, bx
  795. cCall GetSelectorCount
  796. mov word ptr oldCount, ax
  797. mov cx, si ; New size
  798. dec cx ; Paragraph limit
  799. shr cx, 12
  800. inc cx ; new # selectors
  801. cmp al, cl ; Same # of selectors required?
  802. je gsa_done ; yes, just return!
  803. call get_sel ; get a new selector array
  804. jz short gsa_nosels
  805. xchg si, di ; DI now new array, SI old array
  806. push es
  807. push cx
  808. and bx, SEG_RING_MASK ; Ring bits
  809. or bx, di ; New handle
  810. mov cx, word ptr oldCount
  811. push ds ; Copy Descriptor(s)
  812. push si
  813. mov es, gdtdsc
  814. mov ds, gdtdsc
  815. and si, not 7
  816. shl cx, 2 ; CX = 4 * Descriptors = words to copy
  817. rep movsw
  818. pop si
  819. pop ds
  820. ifdef WOW
  821. ; set the descriptors
  822. push bx
  823. mov cx, word ptr oldCount
  824. or bx, SEG_RING_MASK ; start selector
  825. DPMICALL WOW_DPMIFUNC_0C
  826. pop bx
  827. endif; WOW
  828. pop cx
  829. pop es
  830. SetKernelDS
  831. mov ds, pGlobalHeap
  832. UnSetKernelDS
  833. cCall AssociateSelector,<si,0>
  834. mov es:[ga_handle], bx
  835. cCall AssociateSelector,<bx,es>
  836. jmps gsa_done
  837. gsa_nosels:
  838. xor bx, bx ; Indicate failure
  839. gsa_done:
  840. mov ax, bx
  841. or ax, ax ; Indicate success
  842. gsa_ret:
  843. cEnd
  844. assumes ds, nothing
  845. assumes es, nothing
  846. cProc PreallocSel,<PUBLIC,NEAR>
  847. cBegin nogen
  848. push ds
  849. push cx
  850. push si
  851. mov cx, 1
  852. call get_sel
  853. call SetKernelDSProc
  854. ReSetKernelDS
  855. mov temp_sel, si
  856. or si, si ; Set flags for caller
  857. pop si
  858. pop cx
  859. pop ds
  860. UnSetKernelDS
  861. ret
  862. cEnd nogen
  863. ;-----------------------------------------------------------------------;
  864. ; alloc_sel ;
  865. ; alloc_data_sel
  866. ; ;
  867. ; Entry: ;
  868. ; parmD Address 32 bit address ;
  869. ; parmW Limit limit in paragraphs (limit of 1 meg) ;
  870. ; AX = flags alloc_sel only ;
  871. ; ;
  872. ; Returns: ;
  873. ; AX = new selector ;
  874. ; ;
  875. ; Error Returns: ;
  876. ; AX = 0 ;
  877. ; ;
  878. ; Registers Preserved: ;
  879. ; AX,BX,CX,DX,DI,SI,DS,ES ;
  880. ; ;
  881. ; Registers Destroyed: ;
  882. ; ;
  883. ; Calls: ;
  884. ; ;
  885. ; History: ;
  886. ; ;
  887. ; Thu 07-Apr-1988 21:33:27 -by- David N. Weise [davidw] ;
  888. ; Added the GlobalNotify check. ;
  889. ; ;
  890. ; Sun Feb 01, 1987 07:48:39p -by- David N. Weise [davidw] ;
  891. ; Added this nifty comment block. ;
  892. ;-----------------------------------------------------------------------;
  893. assumes ds, nothing
  894. assumes es, nothing
  895. if ROM
  896. public far_alloc_data_sel16
  897. far_alloc_data_sel16 equ this far
  898. endif
  899. cProc far_alloc_data_sel,<PUBLIC,FAR>
  900. parmD Address
  901. parmW Limit
  902. cBegin
  903. cCall alloc_data_sel,<Address,Limit>
  904. cEnd
  905. if ROM
  906. public alloc_data_sel16
  907. alloc_data_sel16 equ this near
  908. endif
  909. cProc alloc_data_sel,<PUBLIC,NEAR>
  910. ; parmD Address
  911. ; parmW Limit
  912. cBegin nogen
  913. mov ax, DSC_DATA+DSC_PRESENT
  914. errn$ alloc_sel
  915. cEnd nogen
  916. cProc alloc_sel,<PUBLIC,NEAR>,<bx,cx,dx,si,di,ds,es>
  917. parmD Address
  918. parmW Limit
  919. localV DscBuf,DSC_LEN
  920. cBegin
  921. mov cx, 1
  922. test al, DSC_PRESENT
  923. jz as_oneonly
  924. mov cx, Limit ; Calculate how many selectors required
  925. add cx, 0FFFh
  926. rcr cx, 1 ; 17 bitdom
  927. shr cx, 11
  928. as_oneonly:
  929. call get_sel
  930. jz short a_s_exit
  931. mov bx, si ; Selector in bx for DPMI
  932. or bl, SEL_LDT
  933. lea di, DscBuf
  934. smov es, ss ; es:di points to descriptor buffer
  935. push ax ; Save access word
  936. mov ax, Address.lo ; Set descriptor base
  937. mov DscBuf.dsc_lbase, ax
  938. mov ax, Address.hi
  939. mov DscBuf.dsc_mbase, al
  940. mov DscBuf.dsc_hbase, ah
  941. pop ax ; Access word
  942. test al, DSC_PRESENT ; If selector not present, limit is
  943. jnz short set_everything ; as passed, not a paragraph count
  944. mov word ptr DscBuf.dsc_access, ax
  945. mov ax, word ptr Limit
  946. mov DscBuf.dsc_limit, ax
  947. ifdef WOW
  948. DPMICALL 000Ch ; Fill in our stuff in the descriptor
  949. else
  950. push ds
  951. push bx ; Set Descriptor
  952. mov ds, gdtdsc
  953. and bl, not 7
  954. mov ax, es:[di] ; This looks slow but it isn't...
  955. mov ds:[bx], ax
  956. mov ax, es:[di][2]
  957. mov ds:[bx][2], ax
  958. mov ax, es:[di][4]
  959. mov ds:[bx][4], ax
  960. mov ax, es:[di][6]
  961. mov ds:[bx][6], ax
  962. if 0 ;;ROM and KDEBUG
  963. call CheckROMSelector
  964. endif
  965. pop bx
  966. pop ds
  967. endif; WOW
  968. jmps as_done
  969. set_everything:
  970. dec cl
  971. and ah, not 0Fh ; Zero limit 19:16
  972. or ah, cl ; Fill in limit 19:16
  973. inc cl
  974. mov word ptr DscBuf.dsc_access, ax
  975. mov ax, Limit
  976. shl ax, 4 ; Convert paragraphs to byte limit
  977. dec ax
  978. mov DscBuf.dsc_limit, ax
  979. call fill_in_selector_array
  980. as_done:
  981. or si, SEG_RING
  982. a_s_exit:
  983. mov ax, si
  984. cEnd
  985. ;-----------------------------------------------------------------------;
  986. ; fill_in_selector_array ;
  987. ; ;
  988. ; Entry: ;
  989. ; AX = size of object in paragraphs ;
  990. ; DH = Discard bit for descriptors ;
  991. ; DL = Access bits ;
  992. ; CX:BX = 32 bit base address of object ;
  993. ; SI = index into LDT ;
  994. ; Returns: ;
  995. ; ;
  996. ; Error Returns: ;
  997. ; ;
  998. ; Registers Preserved: ;
  999. ; SI, DI, DS, ES ;
  1000. ; ;
  1001. ; Registers Destroyed: ;
  1002. ; AX,BX,CX,DX ;
  1003. ; ;
  1004. ; Calls: ;
  1005. ; ;
  1006. ; History: ;
  1007. ; ;
  1008. ;-----------------------------------------------------------------------;
  1009. assumes ds, nothing
  1010. assumes es, nothing
  1011. cProc fill_in_selector_array,<PUBLIC,NEAR>
  1012. cBegin nogen
  1013. CheckLDT bl
  1014. push ds
  1015. push es:[di].dsc_limit ; Save limit for last selector
  1016. SetKernelDS
  1017. test WinFlags, WF_CPU286 ; protect mode on a 286?
  1018. jz next_sel
  1019. mov es:[di].dsc_limit, 0FFFFh ; Others get 64k limit on 286
  1020. next_sel:
  1021. cmp cx, 1 ; Last selector?
  1022. jne fsa_not_last
  1023. pop es:[di].dsc_limit ; yes, get its limit
  1024. fsa_not_last:
  1025. DPMICALL 000Ch ; Set this descriptor
  1026. lea bx, [bx+DSC_LEN] ; On to next selector
  1027. add es:[di].dsc_mbase, 1 ; Add 64kb to address
  1028. adc es:[di].dsc_hbase, 0
  1029. dec es:[di].dsc_hlimit ; subtract 64kb from limit
  1030. loop next_sel
  1031. pop ds
  1032. ret
  1033. cEnd nogen
  1034. ;-----------------------------------------------------------------------;
  1035. ; GetSelectorBase
  1036. ; get_physical_address
  1037. ;
  1038. ;
  1039. ; Entry:
  1040. ;
  1041. ; Returns:
  1042. ; DX:AX 32 bit physical address
  1043. ; Registers Destroyed:
  1044. ; none
  1045. ;
  1046. ; History:
  1047. ; Sat 09-Jul-1988 16:40:59 -by- David N. Weise [davidw]
  1048. ;
  1049. ;-----------------------------------------------------------------------;
  1050. assumes ds,nothing
  1051. assumes es,nothing
  1052. cProc GetSelectorBase,<PUBLIC,FAR>
  1053. parmW selector
  1054. cBegin
  1055. cCall get_physical_address,<selector>
  1056. cEnd
  1057. cProc get_physical_address,<PUBLIC,NEAR>
  1058. parmW selector
  1059. cBegin
  1060. push bx
  1061. push cx
  1062. mov bx, selector
  1063. CheckLDT bl
  1064. ifdef WOWJUNK
  1065. DPMICALL 0006h
  1066. mov ax, dx
  1067. mov dx, cx
  1068. else
  1069. push ds ; Get Segment Base Address
  1070. mov ds, gdtdsc
  1071. and bl, not 7
  1072. mov ax, ds:[bx].dsc_lbase
  1073. mov dl, ds:[bx].dsc_mbase
  1074. mov dh, ds:[bx].dsc_hbase
  1075. pop ds
  1076. endif; WOW
  1077. pop cx
  1078. pop bx
  1079. cEnd
  1080. ;-----------------------------------------------------------------------;
  1081. ; set_physical_address
  1082. ;
  1083. ;
  1084. ; Entry:
  1085. ; DX:AX 32 bit physical address
  1086. ; Returns:
  1087. ;
  1088. ; Registers Destroyed:
  1089. ;
  1090. ; History:
  1091. ; Sat 09-Jul-1988 16:40:59 -by- David N. Weise [davidw]
  1092. ;
  1093. ;-----------------------------------------------------------------------;
  1094. assumes ds,nothing
  1095. assumes es,nothing
  1096. cProc set_physical_address,<PUBLIC,NEAR>,<ax,bx,cx,dx>
  1097. parmW selector
  1098. cBegin
  1099. CheckLDT selector
  1100. push di
  1101. push ax ; save low bits of address
  1102. mov bx, selector
  1103. call GetSelectorCount
  1104. mov di, ax
  1105. mov cx, dx ; CX:DX has new address
  1106. pop dx
  1107. set_bases:
  1108. DPMICALL 0007h ; Set selector base
  1109. lea bx, [bx+DSC_LEN] ; On to next selector
  1110. inc cx ; Add 64k to base
  1111. dec di
  1112. jnz set_bases
  1113. pop di
  1114. cEnd
  1115. ;-----------------------------------------------------------------------;
  1116. ; get_selector_length16
  1117. ;
  1118. ;
  1119. ; Entry:
  1120. ;
  1121. ; Returns:
  1122. ; AX 16 bit segment length
  1123. ; Registers Destroyed:
  1124. ;
  1125. ; History:
  1126. ; Sat 09-Jul-1988 16:40:59 -by- David N. Weise [davidw]
  1127. ;
  1128. ;-----------------------------------------------------------------------;
  1129. assumes ds,nothing
  1130. assumes es,nothing
  1131. cProc get_selector_length16,<PUBLIC,NEAR>
  1132. parmW selector
  1133. cBegin
  1134. mov ax, -1
  1135. lsl ax, selector
  1136. inc ax ; length is one bigger!
  1137. cEnd
  1138. ;-----------------------------------------------------------------------;
  1139. ; set_sel_limit
  1140. ; SIDE EFFECT: descriptor bases and access are set based
  1141. ; on the first in the array
  1142. ;
  1143. ; Entry:
  1144. ; CX:BX = length of segment
  1145. ; Returns:
  1146. ;
  1147. ; Registers Destroyed:
  1148. ; CX
  1149. ;
  1150. ; History:
  1151. ; Fri 15-Jul-1988 19:41:44 -by- David N. Weise [davidw]
  1152. ;
  1153. ;-----------------------------------------------------------------------;
  1154. assumes ds,nothing
  1155. assumes es,nothing
  1156. cProc set_sel_limit,<PUBLIC,NEAR>,<ax,bx,dx>
  1157. parmW selector
  1158. localV DscBuf,DSC_LEN
  1159. cBegin
  1160. push es
  1161. push di
  1162. push bx ; Get existing descriptor
  1163. smov es, ss
  1164. lea di, DscBuf
  1165. mov bx, selector
  1166. CheckLDT bl
  1167. ifdef WOW
  1168. DPMICALL 000Bh
  1169. else
  1170. push ds ; Get Descriptor
  1171. mov ds, gdtdsc
  1172. push si
  1173. mov si, bx
  1174. and si, not 7
  1175. MovsDsc
  1176. lea di, [di-DSC_LEN] ; Restore DI
  1177. pop si
  1178. pop ds
  1179. endif; WOW
  1180. pop bx
  1181. mov dx, word ptr [DscBuf.dsc_access]
  1182. and dh, 0F0h ; Zap old hlimit bits
  1183. sub bx, 1 ; Turn length into linit
  1184. sbb cx, 0
  1185. and cx, 0Fh ; Get bits 19:16 of new limit
  1186. or dh, cl ; Set new hlimit bits
  1187. mov word ptr DscBuf.dsc_access, dx
  1188. mov DscBuf.dsc_limit, bx
  1189. mov bx, Selector
  1190. jcxz ssl_set_limit1 ; Only one, fast out
  1191. inc cx ; Turn CX into selector count
  1192. call fill_in_selector_array
  1193. jmps ssl_done
  1194. ssl_set_limit1: ; Fast out for one only
  1195. ifdef WOW
  1196. DPMICALL 000Ch
  1197. else
  1198. push ds
  1199. push bx ; Set Descriptor
  1200. mov ds, gdtdsc
  1201. and bl, not 7
  1202. mov ax, es:[di] ; This looks slow but it isn't...
  1203. mov ds:[bx], ax
  1204. mov ax, es:[di][2]
  1205. mov ds:[bx][2], ax
  1206. mov ax, es:[di][4]
  1207. mov ds:[bx][4], ax
  1208. mov ax, es:[di][6]
  1209. mov ds:[bx][6], ax
  1210. if 0 ;;ROM and KDEBUG
  1211. call CheckROMSelector
  1212. endif
  1213. pop bx
  1214. pop ds
  1215. endif; WOW
  1216. ssl_done:
  1217. pop di
  1218. pop es
  1219. smov ss,ss ; It might be SS we're changing
  1220. cEnd
  1221. ;-----------------------------------------------------------------------;
  1222. ; mark_sel_NP
  1223. ;
  1224. ;
  1225. ; Entry:
  1226. ;
  1227. ; Returns:
  1228. ;
  1229. ; Registers Destroyed:
  1230. ;
  1231. ; History:
  1232. ; Fri 15-Jul-1988 21:37:22 -by- David N. Weise [davidw]
  1233. ;
  1234. ;-----------------------------------------------------------------------;
  1235. assumes ds,nothing
  1236. assumes es,nothing
  1237. cProc mark_sel_NP,<PUBLIC,NEAR>
  1238. parmW selector
  1239. parmW owner
  1240. localV DscBuf,DSC_LEN
  1241. cBegin
  1242. push es
  1243. push ax
  1244. push bx
  1245. push di
  1246. ifdef WOW
  1247. lea di, DscBuf
  1248. smov es, ss
  1249. mov bx, selector
  1250. DPMICALL 000Bh
  1251. and DscBuf.dsc_access, not DSC_PRESENT
  1252. or DscBuf.dsc_hlimit, DSC_DISCARDABLE
  1253. mov ax, owner
  1254. mov DscBuf.dsc_owner, ax
  1255. DPMICALL 000Ch
  1256. else
  1257. push ds ; Get Descriptor
  1258. mov ds, gdtdsc
  1259. mov bx, selector
  1260. and bl, not 7
  1261. and [bx].dsc_access, not DSC_PRESENT
  1262. or [bx].dsc_hlimit, DSC_DISCARDABLE
  1263. mov ax, owner
  1264. mov [bx].dsc_owner, ax
  1265. pop ds
  1266. endif; WOW
  1267. SetKernelDS
  1268. mov ds, pGlobalHeap
  1269. UnSetKernelDS
  1270. cCall AssociateSelector,<bx,owner>
  1271. pop di
  1272. pop bx
  1273. pop ax
  1274. pop es
  1275. cEnd
  1276. ;-----------------------------------------------------------------------;
  1277. ; mark_sel_PRESENT
  1278. ;
  1279. ; This little routine is called from grealloc, specifically
  1280. ; racreate.
  1281. ;
  1282. ; Entry:
  1283. ; parmW arena_sel
  1284. ; parmW selector
  1285. ;
  1286. ; Returns:
  1287. ; SI = selector to client area (may have changed)
  1288. ;
  1289. ; Registers Destroyed:
  1290. ;
  1291. ; History:
  1292. ; Tue 06-Feb-1990 00:29:56 -by- David N. Weise [davidw]
  1293. ; Cleaning up tony's int 1's way too late.
  1294. ;
  1295. ; Fri 15-Jul-1988 21:37:22 -by- David N. Weise [davidw]
  1296. ;-----------------------------------------------------------------------;
  1297. assumes ds,nothing
  1298. assumes es,nothing
  1299. cProc mark_sel_PRESENT,<PUBLIC,NEAR>,<ax,bx,cx,dx,di,ds>
  1300. parmW arena_sel
  1301. parmW selector
  1302. localV DscBuf,DSC_LEN
  1303. cBegin
  1304. push es
  1305. smov es, ss
  1306. lea di, DscBuf ; ES:DI -> descriptor buffer
  1307. mov bx, selector
  1308. ifdef WOW
  1309. DPMICALL 000Bh ; Get old descriptor
  1310. else
  1311. push ds ; Get Descriptor
  1312. mov ds, gdtdsc
  1313. push si
  1314. mov si, bx
  1315. and si, not 7
  1316. MovsDsc
  1317. lea di, [di-DSC_LEN] ; Restore DI
  1318. pop si
  1319. pop ds
  1320. endif; WOW
  1321. or DscBuf.dsc_access, DSC_PRESENT
  1322. mov ds, arena_sel
  1323. mov bl, DscBuf.dsc_hlimit
  1324. and bl, 0Fh ; Current number of selectors - 1
  1325. inc bl
  1326. mov ax, ds:[ga_size]
  1327. mov cx, ax
  1328. dec cx
  1329. shr cx, 12 ; New number of selectors - 1
  1330. inc cl
  1331. sub bl, cl
  1332. jz go_ahead ; Same number, just fill in array
  1333. jb get_big ; More, must get more
  1334. ; here to get small
  1335. and DscBuf.dsc_hlimit, NOT 0Fh
  1336. dec cl
  1337. or DscBuf.dsc_hlimit, cl ; Put new number of selectors in limit
  1338. inc cl
  1339. push cx
  1340. xor bh,bh ; BX = number of selectors to free
  1341. shl cx,3
  1342. .errnz DSC_LEN - 8
  1343. add cx,selector ; CX = selector to start to free
  1344. xchg bx,cx
  1345. @@: cCall free_sel,<bx>
  1346. lea bx, [bx+DSC_LEN]
  1347. loop @B
  1348. pop cx
  1349. jmps go_ahead ; And fill in remaining selectors
  1350. get_big:
  1351. push ax ; # paragraphs
  1352. mov bx, ds
  1353. DPMICALL 0006h ; Get base address of arena
  1354. add dx, 10h ; Move on to block
  1355. adc cx, 0
  1356. pop bx ; # paragraphs
  1357. mov ax, word ptr DscBuf.dsc_access ; Access bits in ax
  1358. cCall alloc_sel,<cx,dx,bx>
  1359. mov si, ax
  1360. or ax,ax ; did we get a set?
  1361. jz return_new_handle
  1362. or si, SEG_RING
  1363. test selector, IS_SELECTOR
  1364. jnz @F
  1365. StoH si
  1366. HtoS selector
  1367. @@:
  1368. SetKernelDS
  1369. mov ds, pGlobalHeap
  1370. UnSetKernelDS
  1371. cCall AssociateSelector,<selector,0>
  1372. cCall FreeSelArray,<selector> ; Zap old handle
  1373. jmps return_new_handle
  1374. go_ahead:
  1375. shl ax, 4 ; AX had length in paras
  1376. dec ax ; now limit in bytes
  1377. mov DscBuf.dsc_limit, ax ; Put in descriptor
  1378. push cx
  1379. mov bx, ds
  1380. DPMICALL 0006h ; Get base address of arena
  1381. add dx, 10h ; Move on to block
  1382. adc cx, 0
  1383. mov DscBuf.dsc_lbase, dx
  1384. mov DscBuf.dsc_mbase, cl
  1385. mov DscBuf.dsc_hbase, ch
  1386. pop cx ; # selectors
  1387. mov bx, selector
  1388. call fill_in_selector_array
  1389. mov si, selector ; return old selector in SI
  1390. return_new_handle:
  1391. pop es
  1392. cEnd
  1393. ;-----------------------------------------------------------------------;
  1394. ; alloc_data_sel_below
  1395. ;
  1396. ;
  1397. ; Entry:
  1398. ;
  1399. ; Returns:
  1400. ;
  1401. ; Registers Destroyed:
  1402. ;
  1403. ; History:
  1404. ; Sat 09-Jul-1988 19:10:14 -by- David N. Weise [davidw]
  1405. ;
  1406. ;-----------------------------------------------------------------------;
  1407. assumes ds,nothing
  1408. assumes es,nothing
  1409. cProc alloc_data_sel_below,<PUBLIC,NEAR>,<bx,cx,dx>
  1410. parmW selector
  1411. parmW paras
  1412. cBegin
  1413. mov bx, paras
  1414. xor cx, cx
  1415. rept 4
  1416. shl bx, 1
  1417. rcl cx, 1
  1418. endm
  1419. cCall get_physical_address,<selector>
  1420. sub ax, bx
  1421. sbb dx, cx
  1422. cCall alloc_data_sel,<dx, ax, 1>
  1423. cEnd
  1424. ;-----------------------------------------------------------------------;
  1425. ; alloc_data_sel_above
  1426. ;
  1427. ;
  1428. ; Entry:
  1429. ;
  1430. ; Returns:
  1431. ;
  1432. ; Registers Destroyed:
  1433. ;
  1434. ; History:
  1435. ; Sat 09-Jul-1988 19:10:14 -by- David N. Weise [davidw]
  1436. ;
  1437. ;-----------------------------------------------------------------------;
  1438. assumes ds,nothing
  1439. assumes es,nothing
  1440. cProc alloc_data_sel_above,<PUBLIC,NEAR>,<bx,cx,dx>
  1441. parmW selector
  1442. parmW paras
  1443. cBegin
  1444. mov bx, paras
  1445. xor cx, cx
  1446. rept 4
  1447. shl bx, 1
  1448. rcl cx, 1
  1449. endm
  1450. cCall get_physical_address,<selector>
  1451. add ax, bx
  1452. adc dx, cx
  1453. cCall alloc_data_sel,<dx, ax, 1>
  1454. cEnd
  1455. ;-----------------------------------------------------------------------;
  1456. ; cmp_sel_address
  1457. ;
  1458. ; Compares the physical addresses corresponding to two selectors
  1459. ;
  1460. ; Entry:
  1461. ;
  1462. ; Returns:
  1463. ;
  1464. ; Registers Destroyed:
  1465. ;
  1466. ; History:
  1467. ; Sat 09-Jul-1988 19:10:14 -by- David N. Weise [davidw]
  1468. ;
  1469. ;-----------------------------------------------------------------------;
  1470. assumes ds,nothing
  1471. assumes es,nothing
  1472. cProc cmp_sel_address,<PUBLIC,NEAR>,<ax,bx,cx,dx>
  1473. parmW sel1
  1474. parmW sel2
  1475. cBegin
  1476. cCall get_physical_address,<sel1>
  1477. mov cx, dx
  1478. mov bx, ax
  1479. cCall get_physical_address,<sel2>
  1480. cmp cx, dx
  1481. jne csa_done
  1482. cmp bx, ax
  1483. csa_done:
  1484. cEnd
  1485. ;-----------------------------------------------------------------------;
  1486. ; get_arena_pointer
  1487. ;
  1488. ;
  1489. ; Entry:
  1490. ;
  1491. ; Returns:
  1492. ;
  1493. ; Registers Destroyed:
  1494. ;
  1495. ; History:
  1496. ; Sat 09-Jul-1988 20:11:27 -by- David N. Weise [davidw]
  1497. ;
  1498. ;-----------------------------------------------------------------------;
  1499. assumes ds,nothing
  1500. assumes es,nothing
  1501. cProc far_get_arena_pointer,<FAR,PUBLIC>
  1502. parmW selector
  1503. cBegin
  1504. cCall get_arena_pointer,<selector>
  1505. cEnd
  1506. cProc get_arena_pointer,<PUBLIC,NEAR>
  1507. parmW selector
  1508. cBegin
  1509. push bx
  1510. push ds
  1511. push es
  1512. mov bx, selector
  1513. cCall get_selector_association
  1514. ReSetKernelDS es
  1515. if ROM
  1516. test al,1 ; If the low bit isn't set
  1517. jnz @f ; then it's either 0 or the
  1518. xor ax,ax ; special ROM owner selector
  1519. jmps gap_exit ; (see Get/SetROMOwner)
  1520. @@:
  1521. endif
  1522. if KDEBUG
  1523. or ax, ax
  1524. jz gap_exit
  1525. mov ds, ax ; Sanity checks:
  1526. cmp ds:[ne_magic], NEMAGIC
  1527. je gap_exit
  1528. cmp ds:[0], 020CDh ; PSP - not a very good check,
  1529. je gap_exit ; but OK for DEBUG
  1530. push si
  1531. mov si, ds:[ga_handle] ; Make sure handle matches
  1532. sel_check si
  1533. or si, si
  1534. jz short gap_match ; Boot time...
  1535. sub bx, word ptr SelTableStart
  1536. shl bx, 2
  1537. cmp bx, si
  1538. je short gap_match
  1539. xor ax, ax ; put back in 5 feb 90, alias avoided
  1540. ;;; xor ax, ax ; Removed - may be an alias!
  1541. gap_match:
  1542. pop si
  1543. endif ; KDEBUG
  1544. gap_exit:
  1545. pop es
  1546. pop ds
  1547. pop bx
  1548. cEnd
  1549. ;-----------------------------------------------------------------------;
  1550. ; AssociateSelector
  1551. ;
  1552. ; Put the arena pointer or owner in the selector table slot
  1553. ; corresponding to the given selector.
  1554. ;
  1555. ;
  1556. ; Entry:
  1557. ;
  1558. ; Returns:
  1559. ;
  1560. ; Registers Destroyed:
  1561. ; flags
  1562. ;
  1563. ; History:
  1564. ;
  1565. ;-----------------------------------------------------------------------;
  1566. assumes ds,nothing
  1567. assumes es,nothing
  1568. cProc FarAssociateSelector,<PUBLIC,FAR>
  1569. parmW Selector
  1570. parmW ArenaSel
  1571. cBegin
  1572. cCall AssociateSelector,<Selector,ArenaSel>
  1573. cEnd
  1574. cProc AssociateSelector,<PUBLIC,NEAR>,<ax,bx,es>
  1575. parmW selector
  1576. parmW ArenaSel
  1577. cBegin
  1578. SetKernelDS es
  1579. CheckDS ; DS must bp pGlobalHeap
  1580. mov bx, selector
  1581. and bl, NOT SEG_RING_MASK
  1582. shr bx, 2 ; 2 bytes per selector: divide by 4
  1583. if KDEBUG
  1584. cmp bx, SelTableLen ; More sanity
  1585. jb @F
  1586. INT3_WARN
  1587. jmps bad
  1588. @@:
  1589. endif
  1590. add bx, word ptr SelTableStart
  1591. mov ax, ArenaSel
  1592. if KDEBUG
  1593. or ax, ax ; Zero means deleting entry
  1594. jz okay
  1595. CheckLDT al ; Ensure we won't GP fault later
  1596. okay:
  1597. endif
  1598. mov ds:[bx], ax ; Finally fill in table entry
  1599. bad:
  1600. cEnd
  1601. ;-----------------------------------------------------------------------;
  1602. ; get_selector_association
  1603. ;
  1604. ; Returns the arena pointer or owner field from the selector table that
  1605. ; was set by AssociateSelector.
  1606. ;
  1607. ;
  1608. ; Entry:
  1609. ; BX = selector to get associated arena pointer/owner
  1610. ;
  1611. ; Returns:
  1612. ; AX = arena pointer/owner or 0
  1613. ; DS = pGlobalHeap
  1614. ; ES = Kernel DS
  1615. ;
  1616. ; Registers Destroyed:
  1617. ; BX, flags
  1618. ;
  1619. ; History:
  1620. ;
  1621. ;-----------------------------------------------------------------------;
  1622. assumes ds,nothing
  1623. assumes es,nothing
  1624. cProc get_selector_association,<PUBLIC,NEAR>
  1625. cBegin nogen
  1626. SetKernelDS es
  1627. mov ds, pGlobalHeap
  1628. and bl, NOT SEG_RING_MASK
  1629. shr bx, 2 ; 2 bytes per selector: divide by 4
  1630. if ROM ;-------------------------------
  1631. cmp bx, SelTableLen ; Selector in range? Make this check
  1632. jb gsa_in_range ; even if not debug kernel.
  1633. xor ax,ax ; No, just fail
  1634. jmps gsa_exit
  1635. gsa_in_range:
  1636. else ;ROM ------------------------
  1637. if KDEBUG
  1638. cmp bx, SelTableLen ; Selector in range?
  1639. jb @F
  1640. INT3_WARN
  1641. xor ax, ax ; No, just fail
  1642. jmps gsa_exit
  1643. @@:
  1644. endif
  1645. endif ;ROM ------------------------
  1646. add bx, word ptr SelTableStart
  1647. mov ax, ds:[bx] ; Get associated value
  1648. gsa_exit:
  1649. ret
  1650. cEnd nogen
  1651. ;-----------------------------------------------------------------------;
  1652. ; pdref ;
  1653. ; ;
  1654. ; Dereferences the given global handle, i.e. gives back abs. address. ;
  1655. ; ;
  1656. ; Arguments: ;
  1657. ; DX = selector ;
  1658. ; DS:DI = BURGERMASTER ;
  1659. ; ;
  1660. ; Returns: ;
  1661. ; ES:DI = address of arena header ;
  1662. ; AX = address of client data ;
  1663. ; CH = lock count or 0 for fixed objects ;
  1664. ; CL = flags ;
  1665. ; SI = handle, 0 for fixed objects ;
  1666. ; ;
  1667. ; Error Returns: ;
  1668. ; ZF = 1 if invalid or discarded ;
  1669. ; AX = 0 ;
  1670. ; BX = owner of discarded object ;
  1671. ; ;
  1672. ; Registers Preserved: ;
  1673. ; ;
  1674. ; Registers Destroyed: ;
  1675. ; ;
  1676. ; Calls: ;
  1677. ; ghdref ;
  1678. ; ;
  1679. ; History: ;
  1680. ; ;
  1681. ;-----------------------------------------------------------------------;
  1682. assumes ds,nothing
  1683. assumes es,nothing
  1684. cProc pdref,<PUBLIC,NEAR>
  1685. cBegin nogen
  1686. mov si, dx
  1687. sel_check si
  1688. or si, si ; Null handle?
  1689. mov ax, si
  1690. jz pd_exit ; yes, return 0
  1691. cCall GetAccessWord,<dx> ; Get the access bits
  1692. or ax, ax
  1693. jz pd_totally_bogus
  1694. ; We should beef up the check for a valid discarded sel.
  1695. xor cx,cx
  1696. test ah, DSC_DISCARDABLE
  1697. jz pd_not_discardable
  1698. or cl,GA_DISCARDABLE
  1699. ; Discardable, is it code?
  1700. test al,DSC_CODE_BIT
  1701. jz pd_not_code
  1702. or cl,GA_DISCCODE
  1703. pd_not_code:
  1704. pd_not_discardable:
  1705. test al,DSC_PRESENT
  1706. jnz pd_not_discarded
  1707. ; object discarded
  1708. or cl,HE_DISCARDED
  1709. ife RING-1
  1710. or si, SEG_RING+1 ; Handles are RING 2
  1711. else
  1712. or si, SEG_RING-1 ; Handles are RING 2
  1713. endif
  1714. cCall get_arena_pointer,<si> ; get the owner
  1715. mov bx, ax
  1716. xor ax,ax
  1717. jmps pd_exit
  1718. pd_not_discarded:
  1719. if KDEBUG
  1720. or si, SEG_RING ; For the sel_check later
  1721. endif
  1722. cCall get_arena_pointer,<si>
  1723. or ax, ax
  1724. jz pd_nomatch
  1725. mov es, ax
  1726. mov ax, es:[ga_handle] ; The real thing
  1727. mov si, ax
  1728. cmp ax, dx ; Quick check - handle in header
  1729. je pd_match ; matches what we were given?
  1730. test dl, IS_SELECTOR ; NOW, we MUST have been given
  1731. jz pd_totally_bogus ; a selector!!
  1732. test al, GA_FIXED ; Fixed segment?
  1733. jnz pd_nomatch ; Doesn't match arena header...
  1734. push ax
  1735. HtoS al
  1736. cmp ax, dx ; Selector must match
  1737. pop ax
  1738. jne pd_nomatch
  1739. pd_match:
  1740. or cl, es:[ga_flags]
  1741. and cl, NOT HE_DISCARDED ; same as GA_NOTIFY!!
  1742. test al, GA_FIXED
  1743. jnz pd_fixed
  1744. mov ch, es:[ga_count]
  1745. HtoS al ; Back to ring 1
  1746. pd_exit:
  1747. or ax,ax
  1748. ret
  1749. pd_totally_bogus:
  1750. if KDEBUG
  1751. or dx,dx
  1752. jnz dref_invalid
  1753. pd_null_passed:
  1754. endif
  1755. xor dx,dx
  1756. pd_nomatch: ; Handle did not match...
  1757. mov ax, dx ; Must be an alias...
  1758. pd_fixed:
  1759. xor si, si
  1760. xor dx, dx
  1761. jmps pd_exit
  1762. if KDEBUG
  1763. dref_invalid:
  1764. push ax
  1765. kerror ERR_GMEMHANDLE,<gdref: invalid handle>,0,dx
  1766. pop ax
  1767. jmps pd_null_passed
  1768. endif
  1769. cEnd nogen
  1770. ;-----------------------------------------------------------------------;
  1771. ; get_rover_2 ;
  1772. ; ;
  1773. ; Entry: ;
  1774. ; ;
  1775. ; Returns: ;
  1776. ; ;
  1777. ; Error Returns: ;
  1778. ; ;
  1779. ; Registers Preserved: ;
  1780. ; AX,BX,CX,DX,DI,SI,DS ;
  1781. ; ;
  1782. ; Registers Destroyed: ;
  1783. ; ;
  1784. ; Calls: ;
  1785. ; ;
  1786. ; History: ;
  1787. ; ;
  1788. ;-----------------------------------------------------------------------;
  1789. assumes ds,nothing
  1790. assumes es,nothing
  1791. cProc get_rover_2,<PUBLIC,NEAR>,<ax,bx,di>
  1792. localV DscBuf,DSC_LEN
  1793. cBegin
  1794. mov bx, es
  1795. lea di, DscBuf
  1796. smov es, ss
  1797. ifdef WOW
  1798. DPMICALL 000Bh ; Get source descriptor
  1799. else
  1800. push ds ; Get Descriptor
  1801. mov ds, gdtdsc
  1802. push si
  1803. mov si, bx
  1804. and si, not 7
  1805. MovsDsc
  1806. lea di, [di-DSC_LEN] ; Restore DI
  1807. pop si
  1808. pop ds
  1809. endif; WOW
  1810. SetKernelDS es
  1811. mov bx, kr2dsc ; Will set kr2 to point there
  1812. or bl, SEG_RING
  1813. mov word ptr DscBuf.dsc_access, DSC_PRESENT+DSC_DATA
  1814. mov DscBuf.dsc_limit, 0FFFFh
  1815. smov es, ss
  1816. UnSetKernelDS es
  1817. ifdef WOW
  1818. DPMICALL 000Ch
  1819. else
  1820. push ds
  1821. mov ds, gdtdsc
  1822. push bx ; Set Descriptor
  1823. and bl, not 7
  1824. mov ax, es:[di] ; This looks slow but it isn't...
  1825. mov ds:[bx], ax
  1826. mov ax, es:[di][2]
  1827. mov ds:[bx][2], ax
  1828. mov ax, es:[di][4]
  1829. mov ds:[bx][4], ax
  1830. mov ax, es:[di][6]
  1831. mov ds:[bx][6], ax
  1832. if 0 ;;ROM and KDEBUG
  1833. call CheckROMSelector
  1834. endif
  1835. pop bx
  1836. pop ds
  1837. endif; WOW
  1838. mov es, bx
  1839. cEnd
  1840. ;-----------------------------------------------------------------------;
  1841. ; get_blotto
  1842. ;
  1843. ;
  1844. ; Entry:
  1845. ; AX = arena header
  1846. ;
  1847. ; Returns:
  1848. ;
  1849. ; Registers Destroyed:
  1850. ;
  1851. ; History:
  1852. ; Sun 31-Jul-1988 16:20:53 -by- David N. Weise [davidw]
  1853. ;
  1854. ;-----------------------------------------------------------------------;
  1855. assumes ds,nothing
  1856. assumes es,nothing
  1857. cProc get_blotto,<PUBLIC,NEAR>,<bx,di,es>
  1858. localV DscBuf,DSC_LEN
  1859. cBegin
  1860. mov bx, ax
  1861. lea di, DscBuf
  1862. smov es, ss
  1863. ifdef WOW
  1864. DPMICALL 000Bh ; Get source descriptor
  1865. else
  1866. push ds ; Get Descriptor
  1867. mov ds, gdtdsc
  1868. push si
  1869. mov si, bx
  1870. and si, not 7
  1871. MovsDsc
  1872. lea di, [di-DSC_LEN] ; Restore DI
  1873. pop si
  1874. pop ds
  1875. endif
  1876. SetKernelDS es
  1877. mov bx, blotdsc ; Will set kr2 to point there
  1878. or bl, SEG_RING
  1879. mov word ptr DscBuf.dsc_access, DSC_PRESENT+DSC_DATA
  1880. mov DscBuf.dsc_limit, 0FFFFh
  1881. mov DscBuf.dsc_hlimit, 0Fh
  1882. add DscBuf.dsc_lbase, 10h ; Move on to object from arena
  1883. adc DscBuf.dsc_mbase, 0
  1884. adc DscBuf.dsc_hbase, 0
  1885. smov es, ss
  1886. UnSetKernelDS es
  1887. ifdef WOW
  1888. DPMICALL 000Ch ; Set new descriptor
  1889. else
  1890. push ds
  1891. mov ds, gdtdsc
  1892. push bx ; Set Descriptor
  1893. and bl, not 7
  1894. mov ax, es:[di] ; This looks slow but it isn't...
  1895. mov ds:[bx], ax
  1896. mov ax, es:[di][2]
  1897. mov ds:[bx][2], ax
  1898. mov ax, es:[di][4]
  1899. mov ds:[bx][4], ax
  1900. mov ax, es:[di][6]
  1901. mov ds:[bx][6], ax
  1902. if 0 ;;ROM and KDEBUG
  1903. call CheckROMSelector
  1904. endif
  1905. pop bx
  1906. pop ds
  1907. endif ;WOW
  1908. mov ax, bx ; Return new selector
  1909. cEnd
  1910. ;-----------------------------------------------------------------------;
  1911. ; get_temp_sel
  1912. ; far_get_temp_sel
  1913. ;
  1914. ;
  1915. ; Entry:
  1916. ;
  1917. ; Returns:
  1918. ;
  1919. ; Registers Destroyed:
  1920. ;
  1921. ; History:
  1922. ; Mon 08-Aug-1988 19:14:45 -by- David N. Weise [davidw]
  1923. ;
  1924. ;-----------------------------------------------------------------------;
  1925. assumes ds,nothing
  1926. assumes es,nothing
  1927. cProc far_get_temp_sel,<FAR,PUBLIC>
  1928. cBegin nogen
  1929. cCall get_temp_sel
  1930. ret
  1931. cEnd nogen
  1932. cProc get_temp_sel,<PUBLIC,NEAR>,<ax,bx,cx,di,si,ds>
  1933. localV DscBuf,DSC_LEN
  1934. cBegin
  1935. mov cx, 1
  1936. call get_sel
  1937. mov ax, si
  1938. jz gts_exit
  1939. mov bx, es
  1940. smov es, ss
  1941. lea di, DscBuf
  1942. ifdef WOW
  1943. DPMICALL 000Bh ; Get existing descriptor
  1944. else
  1945. push ds ; Get Descriptor
  1946. mov ds, gdtdsc
  1947. push si
  1948. mov si, bx
  1949. and si, not 7
  1950. MovsDsc
  1951. lea di, [di-DSC_LEN] ; Restore DI
  1952. pop si
  1953. pop ds
  1954. endif ; WOW
  1955. mov DscBuf.dsc_access,DSC_PRESENT+DSC_DATA
  1956. mov DscBuf.dsc_limit,0ffffh
  1957. IFNDEF WOW
  1958. or DscBuf.dsc_hlimit, 0Fh ; Max length ; bugbug daveh
  1959. ENDIF
  1960. mov bx, si
  1961. or bl, SEG_RING
  1962. ifdef WOW
  1963. DPMICALL 000Ch ; Set new descriptor
  1964. else
  1965. push ds
  1966. mov ds, gdtdsc
  1967. push bx ; Set Descriptor
  1968. and bl, not 7
  1969. mov ax, es:[di] ; This looks slow but it isn't...
  1970. mov ds:[bx], ax
  1971. mov ax, es:[di][2]
  1972. mov ds:[bx][2], ax
  1973. mov ax, es:[di][4]
  1974. mov ds:[bx][4], ax
  1975. mov ax, es:[di][6]
  1976. mov ds:[bx][6], ax
  1977. if 0 ;;ROM and KDEBUG
  1978. call CheckROMSelector
  1979. endif
  1980. pop bx
  1981. pop ds
  1982. endif ; WOW
  1983. mov es, bx ; and return selector in ES
  1984. gts_exit:
  1985. cEnd
  1986. cProc far_free_temp_sel,<FAR,PUBLIC>
  1987. parmW selector
  1988. cBegin
  1989. cCall free_sel,<selector>
  1990. cEnd
  1991. ;-----------------------------------------------------------------------;
  1992. ; PrestoChangoSel
  1993. ;
  1994. ;
  1995. ; Entry:
  1996. ;
  1997. ; Returns:
  1998. ;
  1999. ; Registers Destroyed:
  2000. ;
  2001. ; History:
  2002. ; Thu 08-Dec-1988 14:17:38 -by- David N. Weise [davidw]
  2003. ; Wrote it!
  2004. ;-----------------------------------------------------------------------;
  2005. assumes ds,nothing
  2006. assumes es,nothing
  2007. cProc IPrestoChangoSelector,<PUBLIC,FAR>,<di,si>
  2008. parmW sourcesel
  2009. parmW destsel
  2010. localV DscBuf,DSC_LEN
  2011. cBegin
  2012. smov es, ss
  2013. lea di, DscBuf
  2014. mov bx, sourcesel
  2015. ifdef WOW
  2016. DPMICALL 000Bh
  2017. else
  2018. push ds ; Get Descriptor
  2019. mov ds, gdtdsc
  2020. push si
  2021. mov si, bx
  2022. and si, not 7
  2023. MovsDsc
  2024. lea di, [di-DSC_LEN] ; Restore DI
  2025. pop si
  2026. pop ds
  2027. endif ; WOW
  2028. xor DscBuf.dsc_access, DSC_CODE_BIT
  2029. mov bx, destsel
  2030. ifdef WOW
  2031. DPMICALL 000Ch
  2032. else
  2033. push ds
  2034. mov ds, gdtdsc
  2035. push bx ; Set Descriptor
  2036. and bl, not 7
  2037. mov ax, es:[di] ; This looks slow but it isn't...
  2038. mov ds:[bx], ax
  2039. mov ax, es:[di][2]
  2040. mov ds:[bx][2], ax
  2041. mov ax, es:[di][4]
  2042. mov ds:[bx][4], ax
  2043. mov ax, es:[di][6]
  2044. mov ds:[bx][6], ax
  2045. if 0 ;;ROM and KDEBUG
  2046. call CheckROMSelector
  2047. endif
  2048. pop bx
  2049. pop ds
  2050. endif; WOW
  2051. mov ax, bx
  2052. smov es, 0
  2053. cEnd
  2054. if 0
  2055. ;-----------------------------------------------------------------------;
  2056. ; pmnum ;
  2057. ; ;
  2058. ; Enumerates the allocated selectors in the GDT with the ;
  2059. ; specified discard level. ;
  2060. ; ;
  2061. ; Arguments: ;
  2062. ; SI = zero first time called. Otherwise contains a pointer ;
  2063. ; to the last handle returned. ;
  2064. ; CX = #handles remaining. Zero first time called. ;
  2065. ; DI = address of local arena information structure. ;
  2066. ; ;
  2067. ; Returns: ;
  2068. ; SI = address of handle table entry ;
  2069. ; CX = #handles remaining, including the one returned. ;
  2070. ; ZF = 1 if SI = 0 and no more handle table entries. ;
  2071. ; ;
  2072. ; Error Returns: ;
  2073. ; ;
  2074. ; Registers Preserved: ;
  2075. ; ;
  2076. ; Registers Destroyed: ;
  2077. ; AX ;
  2078. ; ;
  2079. ; Calls: ;
  2080. ; nothing ;
  2081. ; ;
  2082. ; History: ;
  2083. ; ;
  2084. ; Tue Oct 14, 1986 04:19:15p -by- David N. Weise [davidw] ;
  2085. ; Added this nifty comment block. ;
  2086. ;-----------------------------------------------------------------------;
  2087. cProc pmnum,<PUBLIC,NEAR>
  2088. cBegin nogen
  2089. or si,si ; Beginning of enumeration?
  2090. jnz lcdhenext ; No, return next handle
  2091. mov ax,[di].hi_htable ; Yes, start with last handle table block
  2092. lcdhtloop:
  2093. mov si,ax ; SI = address of handle table block
  2094. or si,si ; Any more handle table blocks?
  2095. jz lcdheall ; No, return zero
  2096. lodsw ; Get # handles in this block
  2097. errnz ht_count
  2098. mov cx,ax ; into CX
  2099. lcdheloop: ; Loop to process each handle table entry
  2100. mov ax,word ptr [si].lhe_flags
  2101. errnz <lhe_flags - he_flags>
  2102. errnz <2-lhe_flags>
  2103. errnz <3-lhe_count>
  2104. inc ax ; Free handle?
  2105. jz lcdhenext ; Yes, skip this handle
  2106. errnz <LHE_FREEHANDLE - 0FFFFh>
  2107. errnz <LHE_FREEHANDLE - HE_FREEHANDLE >
  2108. dec ax
  2109. cmp [di].hi_dislevel,0 ; Enumerating all allocated handles?
  2110. je lcdheall ; Yes, return this handle
  2111. test al,LHE_DISCARDED ; No, handle already discarded?
  2112. jnz lcdhenext ; Yes, skip this handle
  2113. and al,LHE_DISCARDABLE ; Test if DISCARDABLE
  2114. cmp [di].hi_dislevel,al ; at the current discard level
  2115. jne lcdhenext ; No, skip this handle
  2116. or ah,ah ; Is handle locked?
  2117. jnz lcdhenext ; Yes, skip this handle
  2118. lcdheall:
  2119. or si,si ; No, then return handle to caller
  2120. ret ; with Z flag clear
  2121. lcdhenext:
  2122. lea si,[si].SIZE LocalHandleEntry ; Point to next handle table entry
  2123. errnz <LocalHandleEntry - HandleEntry>
  2124. loop lcdheloop ; Process next handle table entry
  2125. lodsw ; end of this block, go to next
  2126. jmp lcdhtloop
  2127. cEnd nogen
  2128. endif
  2129. ;-----------------------------------------------------------------------;
  2130. ; LongPtrAdd
  2131. ;
  2132. ; Performs segment arithmetic on a long pointer and a DWORD offset
  2133. ; The resulting pointer is normalized to a paragraph boundary.
  2134. ; The offset cannot be greater than a megabyte.
  2135. ;
  2136. ; Entry:
  2137. ;
  2138. ; Returns:
  2139. ; DX:AX new segment:offset
  2140. ;
  2141. ; Error returns:
  2142. ; DX:AX = 0
  2143. ;
  2144. ; Registers Destroyed:
  2145. ; BX,CX
  2146. ;
  2147. ; History:
  2148. ; Mon 19-Dec-1988 18:37:23 -by- David N. Weise [davidw]
  2149. ; Wrote it!
  2150. ;-----------------------------------------------------------------------;
  2151. assumes ds,nothing
  2152. assumes es,nothing
  2153. ifdef WOW
  2154. LPTRADDWOW_SETBASE equ 01h
  2155. ;cProc LongPtrAddWOW,<PUBLIC,FAR>,<si,di>
  2156. ; parmD long_ptr
  2157. ; parmD delta
  2158. ; parmW RefSelector
  2159. ; parmW flBaseSetting
  2160. ;
  2161. ; effectively pops RefSelector and flBaseSetting into dx and ax.
  2162. ; and jumps to longptrAddWorker.
  2163. ;
  2164. ; RefSelector is used only if the descriptor needs to be set.
  2165. ;
  2166. labelFP <PUBLIC,LongPtrAddWOW>
  2167. pop ax
  2168. pop dx ; far return address
  2169. mov bx,sp
  2170. xchg ax, ss:[bx] ; replace the 'dword' with the return address
  2171. xchg dx, ss:[bx+2]
  2172. jmps LongPtrAddWorker ; ax = flags; dx = reference selector
  2173. labelFP <PUBLIC,LongPtrAdd>
  2174. mov ax, LPTRADDWOW_SETBASE
  2175. xor dx, dx
  2176. ; fall through
  2177. cProc LongPtrAddWorker,<PUBLIC,FAR>,<si,di>
  2178. parmD long_ptr
  2179. parmD delta
  2180. localV DscBuf,DSC_LEN
  2181. localW flBaseSetting
  2182. localW RefSelector
  2183. cBegin
  2184. mov flBaseSetting, ax ; save in localvariables
  2185. mov RefSelector, dx
  2186. or dx, dx ; if RefSelector is nonzero
  2187. jz @F ; use it for querying descriptor info.
  2188. xchg dx, word ptr long_ptr[2] ; and store the selector to be set in
  2189. mov RefSelector, dx ; the localvariable
  2190. @@:
  2191. else
  2192. cProc LongPtrAdd,<PUBLIC,FAR>,<si,di>
  2193. parmD long_ptr
  2194. parmD delta
  2195. localV DscBuf,DSC_LEN
  2196. cBegin
  2197. endif
  2198. mov bx,word ptr long_ptr[2]
  2199. lea di, DscBuf
  2200. smov es, ss
  2201. ifdef WOW
  2202. DPMICALL 000Bh ; Pick up old descriptor
  2203. else
  2204. push ds ; Get Descriptor
  2205. mov ds, gdtdsc
  2206. push si
  2207. mov si, bx
  2208. and si, not 7
  2209. MovsDsc
  2210. lea di, [di-DSC_LEN] ; Restore DI
  2211. pop si
  2212. pop ds
  2213. endif ; WOW
  2214. mov ax,word ptr long_ptr[0] ; get the pointer into SI:AX
  2215. and ax,0FFF0h
  2216. mov si, DscBuf.dsc_lbase ; DX:SI gets old base
  2217. mov dl, DscBuf.dsc_mbase
  2218. mov dh, DscBuf.dsc_hbase
  2219. add si, ax ; Add in old pointer offset
  2220. adc dx, 0
  2221. mov cx, word ptr delta[2] ; add the segment and MSW
  2222. test cx, 0FFF0h
  2223. ifdef WOW
  2224. jz @F
  2225. test flBaseSetting, LPTRADDWOW_SETBASE
  2226. jnz lptr_mustset
  2227. jmp short lpa_too_big
  2228. @@:
  2229. else
  2230. jnz short lpa_too_big
  2231. endif
  2232. add si, word ptr delta[0]
  2233. adc dx, cx
  2234. ifdef WOW
  2235. lptr_mustset:
  2236. endif
  2237. mov cl, DscBuf.dsc_hlimit ; Calculate # selectors now in array
  2238. and cl, 0Fh
  2239. xor ch, ch
  2240. inc cx
  2241. ifdef WOW
  2242. test flBaseSetting, LPTRADDWOW_SETBASE
  2243. jz lptr_dontset
  2244. cmp RefSelector, 0
  2245. jz @F
  2246. mov bx, RefSelector
  2247. mov word ptr long_ptr[2], bx
  2248. @@:
  2249. endif
  2250. mov DscBuf.dsc_lbase, si ; Put new base back in descriptor
  2251. mov DscBuf.dsc_mbase, dl
  2252. mov DscBuf.dsc_hbase, dh
  2253. call fill_in_selector_array
  2254. ifdef WOW
  2255. lptr_dontset:
  2256. test word ptr delta[2], 0fff0h
  2257. jz @F
  2258. mov cx, word ptr delta[2]
  2259. jmps lpa_too_big
  2260. @@:
  2261. endif
  2262. mov dx,word ptr long_ptr[2]
  2263. mov ax,word ptr long_ptr[0]
  2264. and ax, 0Fh
  2265. jmps lpa_exit
  2266. lpa_too_big:
  2267. xor ax,ax
  2268. xor dx,dx
  2269. lpa_exit:
  2270. smov es,0
  2271. cEnd
  2272. ;-----------------------------------------------------------------------;
  2273. ; SetSelectorBase
  2274. ;
  2275. ; Sets the base and limit of the given selector.
  2276. ;
  2277. ; Entry:
  2278. ; parmW selector
  2279. ; parmD selbase
  2280. ;
  2281. ; Returns:
  2282. ; AX = selector
  2283. ;
  2284. ; Error Returns:
  2285. ; AX = 0
  2286. ;
  2287. ; History:
  2288. ; Tue 23-May-1989 21:10:29 -by- David N. Weise [davidw]
  2289. ; Wrote it!
  2290. ;-----------------------------------------------------------------------;
  2291. assumes ds,nothing
  2292. assumes es,nothing
  2293. cProc SetSelectorBase,<PUBLIC,FAR>
  2294. parmW selector
  2295. parmD selbase
  2296. cBegin
  2297. mov bx, selector
  2298. mov dx, selbase.lo
  2299. mov cx, selbase.hi
  2300. ifdef WOW
  2301. DPMICALL 0007h
  2302. else
  2303. push ds
  2304. mov ds, gdtdsc
  2305. push bx
  2306. and bl, not 7
  2307. mov ds:[bx].dsc_lbase, dx
  2308. mov ds:[bx].dsc_mbase, cl
  2309. mov ds:[bx].dsc_hbase, ch
  2310. pop bx
  2311. pop ds
  2312. endif ; WOW
  2313. mov ax, 0
  2314. jc ssb_exit
  2315. mov ax, selector ; Return selector
  2316. ssb_exit:
  2317. cEnd
  2318. ;-----------------------------------------------------------------------;
  2319. ; GetSelectorLimit
  2320. ;
  2321. ; Gets the limit of the given selector.
  2322. ;
  2323. ; Entry:
  2324. ; parmW selector
  2325. ;
  2326. ; Returns:
  2327. ; DX:AX = limit of selector
  2328. ;
  2329. ; Registers Destroyed:
  2330. ;
  2331. ; History:
  2332. ; Tue 23-May-1989 21:10:29 -by- David N. Weise [davidw]
  2333. ; Wrote it!
  2334. ;-----------------------------------------------------------------------;
  2335. assumes ds,nothing
  2336. assumes es,nothing
  2337. cProc GetSelectorLimit,<PUBLIC,FAR>
  2338. parmW selector
  2339. localV DscBuf,DSC_LEN
  2340. cBegin
  2341. mov bx, selector
  2342. ifdef WOW
  2343. lea di, DscBuf
  2344. smov es, ss
  2345. DPMICALL 000Bh
  2346. xor dx, dx
  2347. mov ax, DscBuf.dsc_limit
  2348. mov dl, DscBuf.dsc_hlimit
  2349. and dx, 0Fh ; AND out flags
  2350. else
  2351. push ds ; Get Descriptor
  2352. mov ds, gdtdsc
  2353. and bl, not 7
  2354. mov ax, [bx].dsc_limit
  2355. mov dl, [bx].dsc_hlimit
  2356. and dx, 0Fh ; AND out flags
  2357. pop ds
  2358. endif ; WOW
  2359. cEnd
  2360. ;-----------------------------------------------------------------------;
  2361. ; SetSelectorLimit
  2362. ;
  2363. ; Sets the limit of the given selector.
  2364. ;
  2365. ; Entry:
  2366. ; parmW selector
  2367. ; parmD sellimit
  2368. ;
  2369. ; Returns:
  2370. ; AX = 0 success
  2371. ;
  2372. ; Registers Destroyed:
  2373. ;
  2374. ; History:
  2375. ; Tue 23-May-1989 21:10:29 -by- David N. Weise [davidw]
  2376. ; Wrote it!
  2377. ;-----------------------------------------------------------------------;
  2378. assumes ds,nothing
  2379. assumes es,nothing
  2380. cProc SetSelectorLimit,<PUBLIC,FAR>
  2381. parmW selector
  2382. parmD sellimit
  2383. localV DscBuf,DSC_LEN
  2384. cBegin
  2385. mov bx, selector
  2386. ifdef WOW
  2387. push di
  2388. lea di, DscBuf
  2389. smov es, ss
  2390. DPMICALL 000Bh
  2391. mov ax, word ptr sellimit[0]
  2392. mov DscBuf.dsc_limit, ax
  2393. mov al, byte ptr sellimit[2]
  2394. and al, 0Fh
  2395. and DscBuf.dsc_hlimit, 0F0h
  2396. or DscBuf.dsc_hlimit, al
  2397. DPMICALL 000Ch
  2398. pop di
  2399. else
  2400. push ds ; Get Descriptor
  2401. mov ds, gdtdsc
  2402. push si
  2403. mov si, bx
  2404. and si, not 7
  2405. mov ax, sellimit.lo
  2406. mov [si].dsc_limit, ax
  2407. mov ax, sellimit.hi
  2408. and al, 0Fh
  2409. and [si].dsc_hlimit, 0F0h
  2410. or [si].dsc_hlimit, al
  2411. pop si
  2412. pop ds
  2413. endif ;WOW
  2414. xor ax,ax ; for now always return success
  2415. cEnd
  2416. ;-----------------------------------------------------------------------;
  2417. ; SelectorAccessRights
  2418. ;
  2419. ; Sets the access and other bytes of the given selector.
  2420. ;
  2421. ; Entry:
  2422. ; parmW selector
  2423. ; parmW getsetflag
  2424. ; parmD selrights
  2425. ;
  2426. ; Returns:
  2427. ; AX = 0 success
  2428. ;
  2429. ; Registers Destroyed:
  2430. ;
  2431. ; History:
  2432. ; Tue 23-May-1989 21:10:29 -by- David N. Weise [davidw]
  2433. ; Wrote it!
  2434. ;-----------------------------------------------------------------------;
  2435. assumes ds,nothing
  2436. assumes es,nothing
  2437. cProc SelectorAccessRights,<PUBLIC,FAR>
  2438. parmW selector
  2439. parmW getsetflag
  2440. parmW selrights
  2441. localV DscBuf,DSC_LEN
  2442. cBegin
  2443. cCall GetAccessWord,<selector>
  2444. cmp getsetflag,0
  2445. jnz short sar_set
  2446. and ax, 0D01Eh ; Hide bits they can't play with
  2447. jmps sar_exit
  2448. sar_set:
  2449. mov cx, selrights
  2450. and cx, 0D01Eh ; Zap bits they can't set and
  2451. and ax, NOT 0D01Eh ; get them from existing access rights
  2452. or cx, ax
  2453. mov bx, selector
  2454. ifdef WOW
  2455. push di
  2456. lea di, DscBuf
  2457. smov es, ss
  2458. DPMICALL 000Bh ; Set new access rights
  2459. mov word ptr DscBuf.dsc_access, cx
  2460. DPMICALL 000Ch
  2461. pop di
  2462. else
  2463. push ds ; Get Descriptor
  2464. mov ds, gdtdsc
  2465. and bx, not 7
  2466. mov word ptr [bx].dsc_access, cx
  2467. pop ds
  2468. endif ;WOW
  2469. xor ax,ax ; for now always return success
  2470. sar_exit:
  2471. cEnd
  2472. ;
  2473. ; Direct GDT access is really helpful here - you are supposed
  2474. ; to use LAR to get the high access bits, but this
  2475. ; cannot be done on a 286 where we are STILL using
  2476. ; these bits in a 386 compatible manner
  2477. ;
  2478. cProc GetAccessWord,<PUBLIC,NEAR>
  2479. parmW selector
  2480. localV DscBuf,DSC_LEN
  2481. cBegin
  2482. push bx
  2483. push es
  2484. cmp gdtdsc, 0 ; Do we have LDT access?
  2485. je do_it_the_really_slow_way ; no, must make DPMI call
  2486. mov es, gdtdsc ; Go grab it out of the LDT
  2487. mov bx, selector
  2488. sel_check bl
  2489. mov ax, word ptr es:[bx].dsc_access
  2490. jmps gaw_exit
  2491. do_it_the_really_slow_way:
  2492. push di
  2493. lea di, DscBuf
  2494. smov es, ss
  2495. mov bx, selector
  2496. DPMICALL 000Bh
  2497. mov ax, word ptr DscBuf.dsc_access
  2498. pop di
  2499. gaw_exit:
  2500. pop es
  2501. pop bx
  2502. gaw_exit1:
  2503. cEnd
  2504. ;
  2505. ; Setting it is WORSE....
  2506. ;
  2507. cProc SetAccessWord,<PUBLIC,NEAR>,<ax,bx,es>
  2508. parmW selector
  2509. parmW access
  2510. localV DscBuf,DSC_LEN
  2511. cBegin
  2512. mov bx, selector
  2513. ifndef WOW ; For WOW we have to call DMPI, LATER for mips this should party directly
  2514. cmp gdtdsc, 0
  2515. je slow_again
  2516. mov es, gdtdsc ; Go stuff it in the LDT
  2517. sel_check bl
  2518. mov ax, access
  2519. mov word ptr es:[bx].dsc_access, ax
  2520. jmps saw_exit
  2521. endif ; WOW
  2522. slow_again:
  2523. ;
  2524. ; The DPMI guys changed their mind, NOW call 9h
  2525. ; WILL set the AVL bit in the descriptor on
  2526. ; all implementations.
  2527. ;
  2528. sel_check bl
  2529. push cx
  2530. mov cx, access
  2531. DPMICALL 0009h
  2532. pop cx
  2533. saw_exit:
  2534. cEnd
  2535. ;
  2536. ; Selector in BX
  2537. ;
  2538. cProc GetSelectorCount,<PUBLIC,NEAR>
  2539. cBegin nogen
  2540. cmp gdtdsc, 0
  2541. je @F
  2542. push ds
  2543. push bx
  2544. mov ds, gdtdsc
  2545. sel_check bl
  2546. mov al, ds:[bx].dsc_hlimit
  2547. pop bx
  2548. pop ds
  2549. and ax, 0Fh
  2550. inc al
  2551. ret
  2552. @@:
  2553. push es
  2554. push di
  2555. sub sp, DSC_LEN
  2556. mov di, sp
  2557. smov es, ss
  2558. DPMICALL 000Bh
  2559. mov al, es:[di].dsc_hlimit
  2560. add sp, DSC_LEN
  2561. pop di
  2562. pop es
  2563. and ax, 0Fh
  2564. inc al
  2565. ret
  2566. cEnd nogen
  2567. ;-----------------------------------------------------------------------;
  2568. ; GlobalPageLock
  2569. ;
  2570. ; Page locks the memory associated with the Handle.
  2571. ;
  2572. ; Entry:
  2573. ; parmW handle
  2574. ;
  2575. ; Returns:
  2576. ; AX = new lock count
  2577. ;
  2578. ; History:
  2579. ; Fri 16-Feb-1990 02:13:09 -by- David N. Weise [davidw]
  2580. ; Should it or shouldn't it? At the very least it must lock
  2581. ; the object to be consitent with 386pmode.
  2582. ;
  2583. ; Wed 31-May-1989 22:14:21 -by- David N. Weise [davidw]
  2584. ; Wrote it!
  2585. ;-----------------------------------------------------------------------;
  2586. assumes ds,nothing
  2587. assumes es,nothing
  2588. cProc IGlobalPageLock,<PUBLIC,FAR>,<si,di>
  2589. parmW handle
  2590. cBegin
  2591. cCall GlobalFix,<handle>
  2592. cCall GetSelectorLimit,<handle>
  2593. mov si, dx
  2594. mov di, ax
  2595. cCall get_physical_address,<handle>
  2596. mov bx, dx
  2597. mov cx, ax
  2598. DPMICALL 0600h
  2599. mov ax, 1
  2600. cEnd
  2601. ;-----------------------------------------------------------------------;
  2602. ; GlobalPageUnlock
  2603. ;
  2604. ; Page unlocks the memory associated with the Handle.
  2605. ;
  2606. ; Entry:
  2607. ; parmW handle
  2608. ;
  2609. ; Returns:
  2610. ; AX = new lock count
  2611. ;
  2612. ; History:
  2613. ; Fri 16-Feb-1990 02:13:09 -by- David N. Weise [davidw]
  2614. ; Should it or shouldn't it? At the very least it must unlock
  2615. ; the object to be consitent with 386pmode.
  2616. ;
  2617. ; Wed 31-May-1989 22:14:21 -by- David N. Weise [davidw]
  2618. ; Wrote it!
  2619. ;-----------------------------------------------------------------------;
  2620. assumes ds,nothing
  2621. assumes es,nothing
  2622. cProc IGlobalPageUnlock,<PUBLIC,FAR>,<si,di>
  2623. parmW handle
  2624. cBegin
  2625. cCall GlobalUnFix,<handle>
  2626. cCall GetSelectorLimit,<handle>
  2627. mov si, dx
  2628. mov di, ax
  2629. cCall get_physical_address,<handle>
  2630. mov bx, dx
  2631. mov cx, ax
  2632. DPMICALL 0601h
  2633. xor ax,ax ; page lock count is zero
  2634. cEnd
  2635. if ROM ;----------------------------------------------------------------
  2636. ;-----------------------------------------------------------------------
  2637. ; ChangeROMHandle
  2638. ;
  2639. ; Changes the handle of an allocated memory block. Used when loading
  2640. ; segments from ROM to RAM so RAM copy can use the handle expected by
  2641. ; other ROM code.
  2642. ;
  2643. ; Entry:
  2644. ; parmW hOld
  2645. ; parmW hNew
  2646. ;
  2647. ; Returns:
  2648. ; AX = hNew if successful, 0 if not
  2649. ;
  2650. ; History:
  2651. ;
  2652. ;-----------------------------------------------------------------------
  2653. assumes ds,nothing
  2654. assumes es,nothing
  2655. cProc ChangeROMHandle,<PUBLIC,FAR>,<bx,si,di,ds,es>
  2656. parmW hOld
  2657. parmW hNew
  2658. localV DscBuf,DSC_LEN
  2659. cBegin
  2660. mov bx,hOld ; Get arena pointer for old handle
  2661. cCall get_arena_pointer,<bx>
  2662. or ax,ax
  2663. if KDEBUG
  2664. jnz @f
  2665. INT3_WARN
  2666. jmps ch_ret
  2667. @@:
  2668. else
  2669. jz ch_ret
  2670. endif
  2671. push ax
  2672. mov si, bx
  2673. and bx, SEG_RING_MASK ; Ring bits
  2674. or bx, hNew ; New handle
  2675. smov es, ss
  2676. lea di, DscBuf
  2677. xchg bx ,si
  2678. DPMICALL 000Bh ; Get old descriptor
  2679. xchg bx, si
  2680. DPMICALL 000Ch ; Set new descriptor
  2681. pop es ; es -> arena (or owner)
  2682. SetKernelDS
  2683. mov ds, pGlobalHeap
  2684. UnSetKernelDS
  2685. cCall AssociateSelector,<si,0> ; Old sel has not association
  2686. test DscBuf.dsc_access,DSC_PRESENT ; Change handle in arena
  2687. jz crh_np ; if selector is present
  2688. mov es:[ga_handle], bx
  2689. crh_np:
  2690. cCall AssociateSelector,<bx,es> ; New sel associated with this
  2691. ; arena or owner
  2692. cCall FreeSelArray,<hOld> ; Free old selector
  2693. mov ax,bx
  2694. ch_ret:
  2695. cEnd
  2696. ;-----------------------------------------------------------------------
  2697. ; CloneROMSelector
  2698. ;
  2699. ; Changes the base and limit of the clone selector to point to the
  2700. ; ROM selector's original ROM segment. ROM segment selectors may be
  2701. ; changed when loading a ROM segment to RAM.
  2702. ;
  2703. ; Entry:
  2704. ; parmW selROM
  2705. ; parmW selClone
  2706. ;
  2707. ; Returns:
  2708. ;
  2709. ; History:
  2710. ;
  2711. ;-----------------------------------------------------------------------
  2712. assumes ds,nothing
  2713. assumes es,nothing
  2714. cProc CloneROMSelector,<PUBLIC,NEAR>,<bx, si, di, ds, es>
  2715. parmW selROM
  2716. parmW selClone
  2717. localV DscBuf,DSC_LEN
  2718. cBegin
  2719. SetKernelDS es
  2720. mov ax,selROMLDT
  2721. mov es,selROMToc
  2722. assumes es,nothing
  2723. mov bx,selROM
  2724. if KDEBUG
  2725. cmp bx,es:[FirstROMsel] ; sanity checks to make sure
  2726. jae @f ; selector is within ROM range
  2727. INT3_WARN
  2728. @@:
  2729. push bx
  2730. and bl,not SEG_RING_MASK
  2731. sub bx,es:[FirstROMsel]
  2732. shr bx,3
  2733. cmp bx,es:[cROMsels]
  2734. jbe @f
  2735. INT3_WARN
  2736. @@:
  2737. pop bx
  2738. endif
  2739. mov si, bx
  2740. and si, NOT SEG_RING_MASK
  2741. sub si, es:[FirstROMsel] ; si = offset in ROM LDT of descriptor
  2742. mov ds, ax ; copy ROM desciptor to stack buffer
  2743. smov es, ss
  2744. lea di, DscBuf
  2745. errnz <8 - DSC_LEN>
  2746. movsw
  2747. movsw
  2748. movsw
  2749. movsw
  2750. mov bx, selClone ; clone descriptor to orig ROM contents
  2751. lea di, DscBuf
  2752. DPMICALL 000Ch
  2753. SetKernelDS
  2754. mov ds, pGlobalHeap
  2755. UnSetKernelDS
  2756. cCall AssociateSelector,<bx,0> ; no arena/owner currently
  2757. mov ax,bx ; return with selClone in AX
  2758. cEnd
  2759. endif ;ROM ---------------------------------------------------------
  2760. cProc SetKernelCSDwordProc,<PUBLIC,NEAR>,<ax,bx,ds>
  2761. parmw addr
  2762. parmw hiword
  2763. parmw loword
  2764. cBegin
  2765. SetKernelDS
  2766. mov ds, MyCSAlias
  2767. UnSetKernelDS
  2768. mov bx, addr
  2769. mov ax, loword
  2770. mov [bx], ax
  2771. mov ax, hiword
  2772. mov [bx+2], ax
  2773. cEnd
  2774. cProc GetKernelDataSeg,<PUBLIC,NEAR>
  2775. cBegin nogen
  2776. mov ax, cs:MyCSDS
  2777. ret
  2778. cEnd nogen
  2779. cProc SetKernelDSProc,<PUBLIC,NEAR>
  2780. cBegin nogen
  2781. mov ds, cs:MyCSDS
  2782. ret
  2783. cEnd nogen
  2784. cProc SetKernelESProc,<PUBLIC,NEAR>
  2785. cBegin nogen
  2786. mov es, cs:MyCSDS
  2787. ret
  2788. cEnd nogen
  2789. cProc CheckKernelDSProc,<PUBLIC,NEAR>
  2790. cBegin nogen
  2791. if KDEBUG
  2792. cmp ax, cs:MyCSDS
  2793. je dsok
  2794. INT3_WARN
  2795. dsok:
  2796. endif
  2797. ret
  2798. cEnd nogen
  2799. assumes ds, nothing
  2800. assumes es, nothing
  2801. cProc FarGetOwner,<PUBLIC,FAR>,<bx>
  2802. parmW Selector
  2803. cBegin
  2804. cCall GetOwner,<Selector>
  2805. cEnd
  2806. cProc GetOwner,<PUBLIC,NEAR>,<es>
  2807. parmW Selector
  2808. cBegin
  2809. cCall get_arena_pointer,<Selector>
  2810. if ROM
  2811. or ax,ax ; get_arena_pointer fails on
  2812. jnz go_got_it ; ROM segments so give it
  2813. cCall GetROMOwner,<Selector> ; another try
  2814. jmps go_end
  2815. go_got_it:
  2816. else
  2817. or ax, ax
  2818. jz go_end
  2819. endif
  2820. mov es, ax
  2821. mov ax, es:[ga_owner]
  2822. go_end:
  2823. cEnd
  2824. assumes ds, nothing
  2825. assumes es, nothing
  2826. cProc FarSetOwner,<PUBLIC,FAR>
  2827. parmW Selector
  2828. parmW owner
  2829. cBegin
  2830. cCall SetOwner,<Selector,owner>
  2831. cEnd
  2832. assumes ds, nothing
  2833. assumes es, nothing
  2834. cProc SetOwner,<PUBLIC,NEAR>,<ax,es>
  2835. parmW Selector
  2836. parmW owner
  2837. cBegin
  2838. cCall get_arena_pointer,<Selector>
  2839. mov es, ax
  2840. push owner
  2841. pop es:[ga_owner]
  2842. cEnd
  2843. if ROM ;----------------------------------------------------------------
  2844. ;-----------------------------------------------------------------------
  2845. ; Set/GetROMOwner
  2846. ;
  2847. ; The Get/SetROMOwner routines use AssociateSelector and the inverse
  2848. ; get_selector_association routines to track the owner of an object
  2849. ; in ROM. ROM objects (like code segments and resources) don't have
  2850. ; a global heap arena to store the owner's ID in.
  2851. ;
  2852. ; NOTE: THIS CODE DEPENDS ON WINDOWS RUNNING IN RING 1 OR 3!! The low
  2853. ; bit of the associated value is set to zero to indicate the object is
  2854. ; in ROM. SetROMOwner expects the owner selector to have the low bit
  2855. ; set, and GetROMOwner returns the owner field with the low bit set.
  2856. ;
  2857. ;-----------------------------------------------------------------------
  2858. assumes ds, nothing
  2859. assumes es, nothing
  2860. cProc FarSetROMOwner,<PUBLIC,FAR>
  2861. parmW Selector
  2862. parmW Owner
  2863. cBegin
  2864. cCall SetROMOwner,<Selector,Owner>
  2865. cEnd
  2866. cProc SetROMOwner,<PUBLIC,NEAR>,<ds>
  2867. parmW Selector
  2868. parmW Owner
  2869. cBegin
  2870. mov ax,Owner
  2871. and al,NOT 1 ; mark this as a ROM selector
  2872. SetKernelDS
  2873. mov ds,pGlobalHeap
  2874. UnSetKernelDS
  2875. cCall AssociateSelector,<Selector,ax>
  2876. cEnd
  2877. cProc GetROMOwner,<PUBLIC,NEAR>,<bx,es,ds>
  2878. parmW Selector
  2879. cBegin
  2880. mov bx,Selector
  2881. cCall get_selector_association
  2882. or ax,ax
  2883. jz gro_exit
  2884. test al,1 ; low bit off if ROM owner
  2885. jnz gro_not_rom_owner
  2886. or al,1 ; restore bit cleared by SetROMOwner
  2887. jmps gro_exit
  2888. gro_not_rom_owner:
  2889. xor ax,ax
  2890. gro_exit:
  2891. cEnd
  2892. ;-----------------------------------------------------------------------;
  2893. ; IsROMObject
  2894. ;
  2895. ; Determines if a given selector points into the ROM area.
  2896. ;
  2897. ; Entry:
  2898. ; selector selector to check
  2899. ;
  2900. ; Returns:
  2901. ; AX != 0 & CY set if selector points to ROM
  2902. ; AX = 0 & CY clr if selector does not point to ROM
  2903. ;
  2904. ; Registers Destroyed:
  2905. ; none
  2906. ;
  2907. ; History:
  2908. ;-----------------------------------------------------------------------;
  2909. assumes ds,nothing
  2910. assumes es,nothing
  2911. cProc FarIsROMObject, <PUBLIC, FAR>
  2912. parmW selector
  2913. cBegin
  2914. cCall IsROMObject, <selector>
  2915. cEnd
  2916. cProc IsROMObject,<PUBLIC,NEAR>,<bx,di,es>
  2917. parmW selector
  2918. localV DscBuf,DSC_LEN
  2919. cBegin
  2920. push ds
  2921. SetKernelDS
  2922. if KDEBUG
  2923. mov ax,selector
  2924. sel_check ax
  2925. endif
  2926. mov bx,selector
  2927. smov es,ss
  2928. lea di,DscBuf
  2929. DPMICALL 000Bh ; Get current descriptor
  2930. mov bh,DscBuf.dsc_hbase ; is descriptor base at or
  2931. mov bl,DscBuf.dsc_mbase ; above start of ROM?
  2932. mov ax,DscBuf.dsc_lbase
  2933. sub ax,lmaHiROM.off
  2934. sbb bx,lmaHiROM.sel
  2935. jc iro_not_rom
  2936. sub ax,cbHiROM.off ; make sure it's not above
  2937. sbb bx,cbHiROM.sel ; the end of the ROM
  2938. jnc iro_not_rom
  2939. mov al,1 ; in ROM range, ret AX != 0 & CY set
  2940. jmps iro_exit
  2941. iro_not_rom:
  2942. xor ax,ax ; not in ROM, AX = 0 & CY clear
  2943. iro_exit:
  2944. pop ds
  2945. assumes ds,nothing
  2946. cEnd
  2947. endif ;ROM ---------------------------------------------------------
  2948. assumes ds, nothing
  2949. assumes es, nothing
  2950. cProc FarValidatePointer,<PUBLIC,FAR>
  2951. parmD p
  2952. cBegin
  2953. cCall ValidatePointer,<p>
  2954. cEnd
  2955. cProc ValidatePointer,<PUBLIC,NEAR>
  2956. parmD p
  2957. cBegin
  2958. lsl ax, seg_p
  2959. jnz short bad_p ; can we access this selector?
  2960. cmp ax, off_p ; yes, is the offset valid?
  2961. jae short good_p
  2962. bad_p:
  2963. xor ax, ax
  2964. jmps vp_done
  2965. good_p:
  2966. mov ax, 1
  2967. vp_done:
  2968. cEnd
  2969. assumes ds, nothing
  2970. assumes es, nothing
  2971. OneParaBytes dw 10h
  2972. cProc SelToSeg,<PUBLIC,NEAR>,<dx>
  2973. parmW selector
  2974. cBegin
  2975. cCall get_physical_address,<selector>
  2976. div OneParaBytes ; Smaller than rotates
  2977. cEnd
  2978. cProc SegToSelector,<PUBLIC,NEAR>,<bx>
  2979. parmW smegma
  2980. cBegin
  2981. mov bx, smegma
  2982. DPMICALL 0002h
  2983. cEnd
  2984. ;-----------------------------------------------------------------------;
  2985. ; set_discarded_sel_owner
  2986. ;
  2987. ; Sets the owner of a selector that points to a discarded object,
  2988. ; which lives in the limit field.
  2989. ;
  2990. ; Entry:
  2991. ; BX = selector to mark
  2992. ; ES = owner
  2993. ;
  2994. ; Returns:
  2995. ; nothing
  2996. ;
  2997. ; Registers Destroyed:
  2998. ; BX
  2999. ;
  3000. ; History:
  3001. ; Sun 03-Dec-1989 21:02:24 -by- David N. Weise [davidw]
  3002. ; Wrote it!
  3003. ;-----------------------------------------------------------------------;
  3004. assumes ds,nothing
  3005. assumes es,nothing
  3006. cProc set_discarded_sel_owner,<PUBLIC,FAR>,<ds,di>
  3007. localV DscBuf,DSC_LEN
  3008. cBegin
  3009. mov cx, es
  3010. ifdef WOW
  3011. push ax
  3012. lea di, DscBuf
  3013. smov es, ss
  3014. DPMICALL 000Bh
  3015. mov DscBuf.dsc_owner, cx
  3016. DPMICALL 000Ch
  3017. pop ax
  3018. else
  3019. push ds ; Get Descriptor
  3020. mov ds, gdtdsc
  3021. push di
  3022. mov di, bx
  3023. and di, not 7
  3024. mov [di].dsc_owner, cx
  3025. pop di
  3026. pop ds
  3027. endif ; WOW
  3028. SetKernelDS
  3029. mov ds, pGlobalHeap
  3030. UnSetKernelDS
  3031. cCall AssociateSelector,<bx,cx>
  3032. mov es, cx ; Restore ES
  3033. cEnd
  3034. ;-----------------------------------------------------------------------;
  3035. ; SetResourceOwner
  3036. ;
  3037. ; Sets the owner of a selector that points to a not present resource
  3038. ;
  3039. ; Entry:
  3040. ;
  3041. ; Returns:
  3042. ; nothing
  3043. ;
  3044. ; Registers Destroyed:
  3045. ;
  3046. ; History:
  3047. ;-----------------------------------------------------------------------;
  3048. assumes ds,nothing
  3049. assumes es,nothing
  3050. cProc SetResourceOwner,<PUBLIC,NEAR>,<ax,bx,cx,di,ds,es>
  3051. parmW selector
  3052. parmW owner
  3053. parmW selCount
  3054. localV DscBuf,DSC_LEN
  3055. cBegin
  3056. mov bx, selector
  3057. mov cx, owner
  3058. ifdef WOW
  3059. smov es, ss
  3060. lea di, DscBuf
  3061. DPMICALL 000Bh ; Get current descriptor
  3062. mov DscBuf.dsc_owner, cx
  3063. mov DscBuf.dsc_access, DSC_DATA
  3064. mov cx,selCount
  3065. dec cl
  3066. and cl,00001111b
  3067. or cl,DSC_DISCARDABLE
  3068. mov DscBuf.dsc_hlimit, cl ; Save number of selectors here
  3069. DPMICALL 000Ch ; Set it with new owner
  3070. else
  3071. push ds ; Get Descriptor
  3072. mov ds, gdtdsc
  3073. push bx
  3074. and bx, not 7
  3075. mov [bx].dsc_owner, cx
  3076. mov [bx].dsc_access, DSC_DATA
  3077. mov cx,selCount
  3078. dec cl
  3079. and cl,00001111b
  3080. or cl,DSC_DISCARDABLE
  3081. mov [bx].dsc_hlimit, cl ; Save number of selectors here
  3082. pop bx
  3083. pop ds
  3084. endif ; WOW
  3085. SetKernelDS
  3086. mov ds, pGlobalHeap
  3087. UnSetKernelDS
  3088. cCall AssociateSelector,<bx,owner> ; And save in selector table
  3089. cEnd
  3090. ;-----------------------------------------------------------------------;
  3091. ;
  3092. ; Alias stuff moved out due to gross bloating of this file
  3093. ;
  3094. ;-----------------------------------------------------------------------;
  3095. if ALIASES
  3096. include aliases.asm
  3097. endif
  3098. ;-----------------------------------------------------------------------;
  3099. ; DPMIProc
  3100. ;
  3101. ; Called NEAR by the DPMICALL macro -
  3102. ; this is better than intercepting int 31h
  3103. ;
  3104. ; By sheer fluke, all intercepts return with
  3105. ; Carry clear ie no error.
  3106. ;
  3107. ;-----------------------------------------------------------------------;
  3108. cProc DPMIProc,<PUBLIC,NEAR>
  3109. cBegin nogen
  3110. or ah, ah
  3111. jz @F
  3112. CallServer:
  3113. ifndef WOW
  3114. int 31h ; Nope, call DPMI server
  3115. ret
  3116. else
  3117. test word ptr [prevInt31Proc + 2],0FFFFh
  3118. jz dp30
  3119. dp20: pushf
  3120. call [prevInt31Proc]
  3121. ret
  3122. endif
  3123. @@:
  3124. if ROM
  3125. cmp al, 01h ; Free selector?
  3126. jne @f
  3127. push ds
  3128. SetKernelDS
  3129. cmp bx,sel1stAvail ; Yes, don't free selectors in
  3130. pop ds ; the preallocated ROM range
  3131. UnSetKernelDS
  3132. jae CallServer
  3133. ret
  3134. @@:
  3135. endif ;ROM
  3136. ifdef WOW
  3137. cmp gdtdsc, 0 ; Can we party?
  3138. jz CallServer ; Nope
  3139. endif
  3140. push ds
  3141. mov ds, gdtdsc
  3142. ifdef WOW
  3143. or al, al
  3144. jnz @F
  3145. mov ax, WOW_DPMIFUNC_00
  3146. pop ds
  3147. jmps CallServer
  3148. @@:
  3149. endif
  3150. cmp al, 0Bh
  3151. jne @F
  3152. test bx,4
  3153. jnz xx1
  3154. ; On MIPS if Win87EM is processing an NPX exception the selector
  3155. ; to Dosx's stack is being looked up here. Since it is a global
  3156. ; selector the normal lookup will not find it and Win87EM will
  3157. ; fault. This is solved by calling Dosx since it knows about the
  3158. ; global selectors that we don't. - MarkRi [6/93]
  3159. ;
  3160. pop ds
  3161. jmps CallServer
  3162. xx1: push si ; Get Descriptor - used very often!
  3163. mov si, bx
  3164. and si, not 7
  3165. MovsDsc
  3166. lea di, [di-DSC_LEN] ; Restore DI
  3167. pop si
  3168. pop ds
  3169. ret
  3170. ifndef WOW
  3171. @@:
  3172. cmp al, 0Ch
  3173. jne @F
  3174. push bx ; Set Descriptor
  3175. and bl, not 7
  3176. mov ax, es:[di] ; This looks slow but it isn't...
  3177. mov ds:[bx], ax
  3178. mov ax, es:[di][2]
  3179. mov ds:[bx][2], ax
  3180. mov ax, es:[di][4]
  3181. mov ds:[bx][4], ax
  3182. mov ax, es:[di][6]
  3183. mov ds:[bx][6], ax
  3184. if 0 ;;ROM and KDEBUG
  3185. call CheckROMSelector
  3186. endif
  3187. pop bx
  3188. pop ds
  3189. ret
  3190. @@:
  3191. cmp al, 07h ; Set Segment Base Address
  3192. jne @F
  3193. push bx
  3194. and bl, not 7
  3195. mov ds:[bx].dsc_lbase, dx
  3196. mov ds:[bx].dsc_mbase, cl
  3197. mov ds:[bx].dsc_hbase, ch
  3198. pop bx
  3199. pop ds
  3200. ret
  3201. endif
  3202. @@:
  3203. cmp al, 06h ; Get Segment Base Address
  3204. jne @F
  3205. push bx
  3206. and bl, not 7
  3207. mov dx, ds:[bx].dsc_lbase
  3208. mov cl, ds:[bx].dsc_mbase
  3209. mov ch, ds:[bx].dsc_hbase
  3210. pop bx
  3211. pop ds
  3212. ret
  3213. ifndef WOW
  3214. @@:
  3215. cmp al, 09h ; Set Descriptor Access Rights
  3216. jne @F
  3217. push bx
  3218. and bl, not 7
  3219. mov word ptr ds:[bx].dsc_access, cx
  3220. if 0 ;;ROM and KDEBUG
  3221. call CheckROMSelector
  3222. endif
  3223. pop bx
  3224. pop ds
  3225. ret
  3226. endif
  3227. @@:
  3228. pop ds
  3229. jmp CallServer
  3230. ifdef WOW
  3231. dp30: int 31h
  3232. ret
  3233. endif
  3234. cEnd nogen
  3235. if ROM
  3236. if1
  3237. %out CheckROMSelector -- fix me!! (what exactly is wrong?)
  3238. endif
  3239. endif
  3240. if 0 ;;ROM and KDEBUG
  3241. ;------------------------------------------------------------------------
  3242. ; CheckROMSelector
  3243. ;
  3244. ; ROM Windows debug hack to ensure that Windows code doesn't try writing
  3245. ; to the ROM image. It does this by making any data selector to the
  3246. ; ROM read only.
  3247. ;
  3248. ; Entry:
  3249. ; DS:BX -> descriptor to check
  3250. ;
  3251. ; Returns:
  3252. ; nothing
  3253. ;
  3254. ; Registers Destroyed:
  3255. ; none
  3256. ;
  3257. ;------------------------------------------------------------------------
  3258. assumes ds,nothing
  3259. assumes es,nothing
  3260. cProc CheckROMSelector,<PUBLIC,NEAR>
  3261. cBegin nogen
  3262. test ds:[bx].dsc_access,DSC_CODEDATA ; code or data dsc?
  3263. jz crs_exit ; no, skip it
  3264. test ds:[bx].dsc_access,DSC_CODE_BIT ; code?
  3265. jnz crs_exit ; yes, skip it
  3266. push ax
  3267. push dx
  3268. mov dh,ds:[bx].dsc_hbase ; is descriptor base at or
  3269. mov dl,ds:[bx].dsc_mbase ; above start of ROM?
  3270. mov ax,ds:[bx].dsc_lbase
  3271. sub ax,lmaHiROM.off
  3272. sbb dx,lmaHiROM.sel
  3273. jc crs_exit1
  3274. sub ax,cbHiROM.off ; make sure it's not above
  3275. sbb dx,cbHiROM.sel ; the end of the ROM
  3276. jnc crs_exit1
  3277. and ds:[bx].dsc_access,NOT DSC_RW_BIT ; make it read only
  3278. crs_exit1:
  3279. pop dx
  3280. pop ax
  3281. crs_exit:
  3282. ret
  3283. cEnd nogen
  3284. endif ;ROM and KDEBUG
  3285. ifdef WOW
  3286. cProc alloc_special_sel,<PUBLIC,NEAR>,<bx,cx,dx,si,di,ds>
  3287. parmW AllocFlags
  3288. parmW SelFreeBlock
  3289. parmW SizeFreeBlock
  3290. parmW SizeNewFreeBlock
  3291. parmW AdjustedSize
  3292. parmB fBaseAddressToUse
  3293. localD AddressNewFreeBlock
  3294. localD Address
  3295. localW Limit
  3296. localW cFreeBlock
  3297. localW cTotalSelectors
  3298. localW EachSelectorLimit
  3299. cBegin
  3300. ;
  3301. ; this will be our ds
  3302. ;
  3303. mov ds, gdtdsc
  3304. ;
  3305. ; replace allocflags with accessword
  3306. ;
  3307. mov bx, AllocFlags
  3308. and bx, ((GA_CODE_DATA+GA_DISCARDABLE) shl 8) + GA_DGROUP
  3309. or bl, bh
  3310. xor bh, bh
  3311. shl bx, 1
  3312. mov ax, cs:SelAccessWord[bx] ; Pick up access rights for selector
  3313. mov AllocFlags, ax ; allocflags = access rights
  3314. ;
  3315. ; Limit for data selectors
  3316. ;
  3317. mov ax, AdjustedSize
  3318. dec ax
  3319. mov Limit, ax
  3320. ;
  3321. ; compute base address for new freeblock and the first selector
  3322. ; the base address is dependent on fBaseAddressToUse flag
  3323. ;
  3324. cCall get_physical_address,<SelFreeBlock>
  3325. cmp fBaseAddressToUse, ga_prev
  3326. jne @F
  3327. mov bx, SizeNewFreeBlock
  3328. xor cx,cx
  3329. REPT 4
  3330. shl bx,1
  3331. rcl cx,1
  3332. ENDM
  3333. add ax, bx
  3334. adc dx, cx
  3335. mov AddressNewFreeBlock.lo, ax
  3336. mov AddressNewFreeBlock.hi, dx
  3337. ;
  3338. ; compute base address for first selector
  3339. ;
  3340. add ax, 10h
  3341. adc dx, 00h
  3342. mov Address.lo, ax
  3343. mov Address.hi, dx
  3344. jmps alloc_checkforfreeblock
  3345. @@:
  3346. push ax ; save base address of freeblock
  3347. push dx
  3348. add ax, 10h
  3349. adc dx, 00h
  3350. mov Address.lo, ax ; address of first selector
  3351. mov Address.hi, dx
  3352. pop dx
  3353. pop ax
  3354. mov bx, AdjustedSize
  3355. xor cx,cx
  3356. REPT 4
  3357. shl bx,1
  3358. rcl cx,1
  3359. ENDM
  3360. add ax, bx
  3361. adc dx, cx
  3362. mov AddressNewFreeBlock.lo, ax
  3363. mov AddressNewFreeBlock.hi, dx
  3364. alloc_checkforfreeblock:
  3365. ;
  3366. ; check if a 'new' free block needs to be created.
  3367. ; cFreeBlock = (SizeNewFreeBlock) ? 1 : 0;
  3368. ;
  3369. mov cFreeBlock, 0
  3370. mov cx, SizeNewFreeBlock
  3371. jcxz alloc_nofreeblock
  3372. mov cFreeBlock, 1
  3373. alloc_nofreeblock:
  3374. ;
  3375. ; start of processing
  3376. ;
  3377. mov cx, 1
  3378. mov ax, AllocFlags
  3379. test al, DSC_PRESENT
  3380. jz allocspecial_oneonly
  3381. ; limit in paras
  3382. mov cx, Limit ; Calculate how many selectors required
  3383. add cx, 0FFFh
  3384. rcr cx, 1 ; 17 bitdom
  3385. shr cx, 11
  3386. allocspecial_oneonly:
  3387. push cx
  3388. add cx, cFreeBlock ; cFreeBlock is zero or one
  3389. mov cTotalSelectors, cx
  3390. ;
  3391. ; the dpmi func is 04f1h. This is idential to function 00h, except that
  3392. ; the descriptor base and limit are not initialized to zero.
  3393. ;
  3394. DPMICALL WOW_DPMIFUNC_00
  3395. pop cx
  3396. jnz allocspecial_continue
  3397. jmp allocspecial_exit
  3398. allocspecial_continue:
  3399. push ax ; save the first selector
  3400. and ax, not SEG_RING
  3401. mov bx, ax ; Selector in bx for DPMI
  3402. mov ax, Address.lo ; Set descriptor base
  3403. mov [bx].dsc_lbase, ax
  3404. mov di, ax ; used later
  3405. mov ax, Address.hi
  3406. mov [bx].dsc_mbase, al
  3407. mov [bx].dsc_hbase, ah
  3408. mov ax, AllocFlags
  3409. test al, DSC_PRESENT ; If selector not present, limit is
  3410. jnz short allocspecial_present ; as passed, not a paragraph count
  3411. allocspecial_not_present:
  3412. mov word ptr [bx].dsc_access, ax
  3413. mov ax, word ptr Limit
  3414. mov [bx].dsc_limit, ax
  3415. jmps allocspecial_done
  3416. allocspecial_present:
  3417. dec cl
  3418. and ah, not 0Fh ; Zero limit 19:16
  3419. or ah, cl ; Fill in limit 19:16
  3420. inc cl
  3421. mov word ptr [bx].dsc_access, ax
  3422. mov si, ax ; save for later use
  3423. mov ax, Limit
  3424. shl ax, 4 ; Convert paragraphs to byte limit
  3425. dec ax
  3426. mov [bx].dsc_limit, ax
  3427. dec cx
  3428. jcxz allocspecial_done ; if sel=1 done.
  3429. mov EachSelectorLimit, ax ; ax the limit from above
  3430. mov al, [bx].dsc_mbase ;
  3431. mov ah, [bx].dsc_hbase
  3432. mov dl, [bx].dsc_hlimit
  3433. push ds
  3434. SetKernelDS
  3435. test WinFlags, WF_CPU286 ; protect mode on a 286?
  3436. pop ds
  3437. push [bx].dsc_limit ; Save limit for last selector
  3438. jz allocspecial_next_sel ; the result of the test above
  3439. mov EachSelectorLimit, 0FFFFh ; Others get 64k limit on 286
  3440. allocspecial_next_sel:
  3441. push ax
  3442. mov ax, EachSelectorLimit
  3443. mov [bx].dsc_limit, ax ; limit for current selector
  3444. pop ax
  3445. lea bx, [bx+DSC_LEN] ; On to next selector
  3446. cmp cx, 1 ; Last selector?
  3447. jne allocspecial_fsa_not_last
  3448. pop [bx].dsc_limit ; yes, get its limit
  3449. allocspecial_fsa_not_last:
  3450. mov [bx].dsc_lbase, di
  3451. mov word ptr [bx].dsc_access, si
  3452. inc ax
  3453. mov [bx].dsc_mbase, al ; Add 64kb to address
  3454. mov [bx].dsc_hbase, ah
  3455. dec dl
  3456. mov [bx].dsc_hlimit, dl ; subtract 64kb from limit
  3457. loop allocspecial_next_sel
  3458. allocspecial_done:
  3459. cmp cFreeBlock, 1
  3460. jne allocspecial_nofreeblock
  3461. allocspecial_freeblock:
  3462. mov ax, AddressNewFreeBlock.lo ; the base for freeblock
  3463. mov dx, AddressNewFreeBlock.hi
  3464. lea bx, [bx+DSC_LEN] ; On to next selector
  3465. mov [bx].dsc_limit, 0fh ; = 1 para
  3466. mov [bx].dsc_lbase, ax
  3467. mov [bx].dsc_mbase, dl
  3468. mov [bx].dsc_hbase, dh
  3469. mov ax, DSC_DATA+DSC_PRESENT
  3470. and ah, not 0Fh ; Zero limit 19:16
  3471. mov word ptr [bx].dsc_access, ax
  3472. allocspecial_nofreeblock:
  3473. pop si ; restore the first selector
  3474. push bx
  3475. mov cx, cTotalSelectors
  3476. mov bx, si
  3477. ;
  3478. ; the dpmi func is 04f2h. This is identical to 0ch except that it
  3479. ; sets 'count' (in cx) LDTs at one time. The first selector is in
  3480. ; register bx. The descriptor data is in gdtdsc[bx], gdtdsc[bx+8]
  3481. ; etc. This data is shared between dpmi (dosx.exe) and us and thus
  3482. ; need not be passed in es:di
  3483. DPMICALL WOW_DPMIFUNC_0C
  3484. pop bx
  3485. SetKernelDS
  3486. ;
  3487. ; sanity check. done so late because if this check was done
  3488. ; somewhere eariler, we would have had to Save and Restor DS. Since
  3489. ; this check would be successful most of the time, it is quite Ok
  3490. ; to do it now and we would avoid unneccessary loading of DS.
  3491. mov ax, bx
  3492. shr ax, 2
  3493. cmp ax, SelTableLen ; Make sure we can associate it
  3494. jb @F
  3495. xor ax, ax ; set zero flag
  3496. jmps allocspecial_exit
  3497. @@:
  3498. mov UserSelArray, si ; the selector for user data
  3499. mov ax, bx
  3500. or ax, SEG_RING ; selector of new freeblock, if one is
  3501. ; created. sets nz flag.
  3502. mov SelectorFreeBlock, ax ;
  3503. allocspecial_exit:
  3504. cEnd
  3505. ;----------------------------------------------------------------------------
  3506. ; grabbed from 2gmem.asm
  3507. ;
  3508. ;----------------------------------------------------------------------------
  3509. SelAccessWord dw DSC_DATA+DSC_PRESENT
  3510. dw (DSC_DISCARDABLE SHL 8) + DSC_DATA+DSC_PRESENT
  3511. dw DSC_CODE+DSC_PRESENT
  3512. dw (DSC_DISCARDABLE SHL 8) + DSC_CODE+DSC_PRESENT
  3513. dw DSC_DATA+DSC_PRESENT
  3514. dw (DSC_DISCARDABLE SHL 8) + DSC_DATA+DSC_PRESENT
  3515. dw DSC_DATA+DSC_PRESENT
  3516. dw (DSC_DISCARDABLE SHL 8) + DSC_DATA+DSC_PRESENT
  3517. ;-----------------------------------------------------------------------------
  3518. ; Grab the selector 0x47 so that we dont need to special case the biosdata
  3519. ; selector (0x40) while converting seg:off address to flat 32bit address
  3520. ;
  3521. ; This, however should not be part of Krnl286 heap.
  3522. ;
  3523. ; - Nanduri Ramakrishna
  3524. ;-----------------------------------------------------------------------------
  3525. cProc AllocSelector_0x47,<PUBLIC,FAR>, <ax, bx, cx, ds>
  3526. cBegin
  3527. ; alloc the specific selector
  3528. mov bx, 047h
  3529. DPMICALL 0dh
  3530. jc as47_exit
  3531. ; initialize the LDT
  3532. and bx, not SEG_RING
  3533. mov ds, gdtdsc
  3534. mov [bx].dsc_limit, 00h ; = 1 byte
  3535. mov [bx].dsc_lbase, 0400h
  3536. mov [bx].dsc_mbase, 00h
  3537. mov [bx].dsc_hbase, 00h
  3538. mov ax, DSC_DATA+DSC_PRESENT
  3539. and ah, not 0Fh ; Zero limit 19:16
  3540. mov word ptr [bx].dsc_access, ax
  3541. ; set the LDT
  3542. mov cx,1
  3543. mov bx, 047h
  3544. DPMICALL WOW_DPMIFUNC_0C
  3545. as47_exit:
  3546. cEnd
  3547. sEnd CODE
  3548. sBegin NRESCODE
  3549. assumes CS,NRESCODE
  3550. assumes DS,NOTHING
  3551. assumes ES,NOTHING
  3552. cProc get_sel_flags,<PUBLIC,NEAR>
  3553. parmW selector
  3554. cBegin
  3555. ; Not used in krnl286
  3556. xor ax,ax
  3557. xor dx,dx
  3558. cEnd
  3559. cProc set_sel_for_dib,<PUBLIC,NEAR>
  3560. parmW selector
  3561. parmW flags
  3562. parmD address
  3563. parmW csel
  3564. cBegin
  3565. ; Not used in krnl286
  3566. xor ax,ax
  3567. xor dx,dx
  3568. cEnd
  3569. cProc RestoreDib,<PUBLIC,NEAR>
  3570. parmW selector
  3571. parmW flags
  3572. parmD address
  3573. cBegin
  3574. ; Not used in krnl286
  3575. xor ax,ax
  3576. xor dx,dx
  3577. cEnd
  3578. cProc DibRealloc,<PUBLIC,FAR>
  3579. parmW Selector
  3580. parmW NewSize
  3581. cBegin
  3582. cEnd
  3583. endif
  3584. sEnd NRESCODE
  3585. end