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.

2039 lines
52 KiB

  1. page ,132
  2. TITLE GINTERF - Global Memory Manager interface procedures
  3. .sall
  4. .xlist
  5. include kernel.inc
  6. include pdb.inc
  7. include tdb.inc
  8. include newexe.inc
  9. include protect.inc
  10. ifdef WOW
  11. include wowkrn.inc
  12. include vint.inc
  13. endif
  14. .list
  15. CheckHeap MACRO name
  16. local a
  17. if KDEBUG
  18. extrn CheckGlobalHeap :near
  19. call CheckGlobalHeap
  20. jnc a
  21. or ax,ERR_GMEM
  22. xor bx,bx
  23. kerror <>,<&name: Invalid global heap>,dx,bx
  24. a:
  25. endif
  26. endm
  27. PROFILE MACRO function
  28. pushf
  29. add word ptr ds:[di.gi_stats][c&function], 1
  30. adc word ptr ds:[di.gi_stats][c&function][2], 0
  31. popf
  32. ENDM
  33. ifdef WOW
  34. externFP WowCursorIconOp
  35. externFP WowDdeFreeHandle
  36. endif
  37. externW pStackTop
  38. externW pStackMin
  39. externW pStackBot
  40. DataBegin
  41. externB Kernel_Flags
  42. externB fBooting
  43. externW hGlobalHeap
  44. externW pGlobalHeap
  45. externW curTDB
  46. externW loadTDB
  47. externW hExeHead
  48. GSS_SI dw 0
  49. GSS_DS dw 0
  50. GSS_RET dd 0
  51. DataEnd
  52. sBegin CODE
  53. assumes CS,CODE
  54. if SDEBUG
  55. externNP DebugFreeSegment
  56. endif
  57. externNP galloc
  58. externNP grealloc
  59. externNP gfree
  60. externNP glock
  61. externNP gunlock
  62. externNP gfreeall
  63. externNP galign
  64. externNP gcompact
  65. externNP gmovebusy
  66. externNP gsearch
  67. externNP genter
  68. externNP gleave
  69. externNP gavail
  70. externNP glrutop
  71. externNP glrubot
  72. externNP glrudel
  73. externNP glruadd
  74. externNP gmarkfree
  75. ;externNP gdiscard
  76. externNP get_arena_pointer
  77. externNP pdref
  78. externNP cmp_sel_address
  79. externNP get_physical_address
  80. externNP set_physical_address
  81. externNP set_sel_limit
  82. externNP alloc_data_sel
  83. externFP FreeSelector
  84. externNP GetAccessWord
  85. externNP MyGetAppCompatFlags
  86. if ALIASES
  87. externNP add_alias
  88. externNP delete_alias
  89. externNP get_alias_from_original
  90. externNP get_original_from_alias
  91. externNP wipe_out_alias
  92. endif
  93. externNP ShrinkHeap
  94. externNP DpmiProc
  95. externNP HackCheck
  96. if KDEBUG
  97. externFP OutputDebugString
  98. ThisIsForTurboPascal:
  99. db "A program has attempted an invalid selector-to-handle conversion.",13,10,"Attempting to correct this error.",13,10,0
  100. endif
  101. if ROM
  102. externNP GetOwner
  103. endif
  104. if KDEBUG
  105. externNP xhandle_norip
  106. endif
  107. ;-----------------------------------------------------------------------;
  108. ; gbtop ;
  109. ; ;
  110. ; Converts a 32-bit byte count to a 16-bit paragraph count. ;
  111. ; ;
  112. ; Arguments: ;
  113. ; AX = allocation flags or -1 if called from GlobalCompact ;
  114. ; BX = stack address of 32-bit unsigned integer ;
  115. ; DX = handle being reallocated or zero ;
  116. ; DS:DI = address of GlobalInfo for global heap ;
  117. ; ;
  118. ; Returns: ;
  119. ; AX = updated allocation flags ;
  120. ; BX = #paragraphs needed to contain that many bytes ;
  121. ; CX = owner value to use ;
  122. ; DX = handle being reallocated or zero ;
  123. ; ;
  124. ; Error Returns: ;
  125. ; ;
  126. ; Registers Preserved: ;
  127. ; ;
  128. ; Registers Destroyed: ;
  129. ; ;
  130. ; Calls: ;
  131. ; ;
  132. ; History: ;
  133. ; ;
  134. ; Wed Dec 03, 1986 10:20:01p -by- David N. Weise [davidw] ;
  135. ; Added this nifty comment block. ;
  136. ;-----------------------------------------------------------------------;
  137. cProc gbtop,<PUBLIC,NEAR>
  138. cBegin nogen
  139. push dx
  140. mov dx,ss:[bx][2]
  141. mov bx,ss:[bx]
  142. mov cx,4
  143. add bx,15
  144. adc dx,0
  145. jnc gbtop1
  146. dec dx
  147. dec bx
  148. gbtop1:
  149. shr dx,1
  150. rcr bx,1
  151. loop gbtop1
  152. or dx,dx ; Requesting more than 1 meg?
  153. jz gbtop2
  154. mov bx,0FFFFh ; Yes, set to bogus value - this can NEVER succeed
  155. gbtop2:
  156. pop dx
  157. inc ax
  158. jnz gbtop2a
  159. ret ; All done if called from GlobalCompact
  160. gbtop2a:
  161. dec ax
  162. push ax
  163. if ROM
  164. cCall GetOwner,<[bp].savedCS>
  165. mov es,ax ; ES has owner exe hdr selector
  166. else
  167. cCall get_arena_pointer,<[bp].savedCS>
  168. mov es,ax ; ES has arena of calling CS (if known)
  169. endif
  170. pop ax
  171. push ds
  172. SetKernelDS
  173. cmp fBooting,0 ; Done booting?
  174. jne gbtop3 ; No, must be KERNEL allocating then
  175. if ROM
  176. mov cx,es
  177. cmp cx,hExeHead ; Is the KERNEL calling us?
  178. else
  179. mov cx,hExeHead ; CX = KERNEL exe header
  180. cmp cx,es:[di].ga_owner ; Is the KERNEL calling us?
  181. endif
  182. je gbtop3 ; Yes, let him party
  183. and ax,not GA_INTFLAGS ; No, then cant use these flags
  184. gbtop3:
  185. pop ds
  186. UnSetKernelDS
  187. test ah,GA_ALLOC_DOS ; Dos land allocations can never ever
  188. jz gbtop3b ; be moved once allocated--make sure
  189. and al,not GA_MOVEABLE ; caller isn't confused about this
  190. gbtop3b:
  191. mov cl,GA_SEGTYPE ; Isolate segment type bits in CL
  192. and cl,al
  193. mov [di].gi_cmpflags,al ; Save flags for gcompact
  194. and [di].gi_cmpflags,CMP_FLAGS
  195. push ds
  196. SetKernelDS
  197. test al, GA_MOVEABLE ; Is this fixed?
  198. jz gbtop4 ; yes, must go low
  199. ife ROM
  200. cmp fBooting, 1 ; Booting?
  201. je @F ; yes, allocate high
  202. endif
  203. test cl, GA_DISCCODE ; no, only discardable code goes high
  204. jz gbtop4
  205. @@:
  206. or al, GA_ALLOCHIGH
  207. gbtop4:
  208. pop ds
  209. UnSetKernelDS
  210. push ax ; Under Win1.0x ANY bit in 0Fh meant
  211. mov al,HE_DISCARDABLE ; make discardable.
  212. and ah,al ; Under Win2.0x ONLY 01h or 0Fh means
  213. cmp ah,al ; discardable.
  214. pop ax
  215. jnz gbtop4a
  216. and ah,not HE_DISCARDABLE ; Yes, convert to boolean value
  217. or ah,GA_DISCARDABLE
  218. gbtop4a:
  219. and ah,NOT GA_SEGTYPE ; Clear any bogus flags
  220. or ah,cl ; Copy segment type bits
  221. test ah,GA_SHAREABLE ; Shared memory request?
  222. jz GetDefOwner ; No, default action
  223. mov cx, es ; Arena of calling CS
  224. jcxz no_owner_yet
  225. ife ROM
  226. mov cx,es:[di].ga_owner ; owner of calling code segment
  227. endif
  228. no_owner_yet:
  229. ret
  230. cEnd nogen
  231. cProc GetDefOwner,<PUBLIC,NEAR>
  232. cBegin nogen
  233. push ds
  234. SetKernelDS
  235. mov cx,curTDB
  236. jcxz xxxx
  237. mov es,cx
  238. mov cx,loadTDB
  239. jcxz xxx
  240. mov es,cx
  241. xxx: mov cx,es:[TDB_PDB]
  242. inc cx
  243. xxxx: dec cx
  244. pop ds
  245. UnSetKernelDS
  246. ret
  247. cEnd nogen
  248. ; The remainder of this file implements the exported interface to the
  249. ; global memory manager. A summary follows:
  250. ; HANDLE far PASCAL GlobalAlloc( WORD, DWORD );
  251. ; HANDLE far PASCAL GlobalReAlloc( HANDLE, DWORD, WORD );
  252. ; HANDLE far PASCAL GlobalFree( HANDLE );
  253. ; HANDLE far PASCAL GlobalFreeAll( WORD );
  254. ; char far * far PASCAL GlobalLock( HANDLE );
  255. ; BOOL far PASCAL GlobalUnlock( HANDLE );
  256. ; DWORD far PASCAL GlobalSize( HANDLE );
  257. ; DWORD far PASCAL GlobalCompact( DWORD );
  258. ; #define GlobalDiscard( h ) GlobalReAlloc( h, 0L, GMEM_MOVEABLE )
  259. ; HANDLE far PASCAL GlobalHandle( WORD );
  260. ; HANDLE far PASCAL LockSegment( WORD );
  261. ; HANDLE far PASCAL UnlockSegment( WORD );
  262. cProc IGlobalAlloc,<PUBLIC,FAR>,<si,di>
  263. parmW flags
  264. parmD nbytes
  265. cBegin
  266. call genter ; About to modify memory arena
  267. PROFILE GLOBALALLOC
  268. cCall MyGetAppCompatFlags ; Ignore the NODISCARD flag
  269. test al, GACF_IGNORENODISCARD ; for selected modules
  270. mov ax, flags
  271. jz @f
  272. call IsKernelCalling ; needs caller's CS @ [bp+4]
  273. jz @f ; skip hack if kernel calling us
  274. and al, NOT GA_NODISCARD
  275. @@:
  276. ifdef WOW
  277. ; compatibility: amipro calls globalallocs some memory for storing one
  278. ; of its ini files and accesses the lpstring[byte after the null char].
  279. ; This happens to be harmless on most occasions because we roundoff the
  280. ; allocation to next 16byte boundary. However if the allocation request
  281. ; is for exactly 0x10 bytes we allocate a selector of exactly 0x10 bytes
  282. ; and thus amipro GPs when it access the byte seg:0x10
  283. ;
  284. ; So here is a cheap fix.
  285. ; - nanduri
  286. cmp word ptr nbytes+2, 0
  287. jnz @F
  288. cmp word ptr nbytes, 010h
  289. jne @F
  290. inc word ptr nbytes
  291. @@:
  292. endif
  293. xor dx,dx ; No handle
  294. lea bx,nbytes ; Convert requested bytes to paragraphs
  295. call gbtop ; ... into BX
  296. call galloc
  297. CheckHeap GlobalAlloc
  298. call gleave
  299. mov es,di
  300. cEnd
  301. cProc IGlobalReAlloc,<PUBLIC,FAR>,<si,di>
  302. parmW handle
  303. parmD nbytes
  304. parmW rflags
  305. cBegin
  306. ;
  307. ; Does this thing have any ring bits or LDT bit? If not, then it
  308. ; could be a selector incorrectly converted to a handle.
  309. ;
  310. test byte ptr handle,7
  311. jnz @F
  312. if KDEBUG
  313. Trace_Out "GlobalReAlloc:"
  314. push seg ThisIsForTurboPascal
  315. push offset ThisIsForTurboPascal
  316. cCall OutputDebugString
  317. INT3_WARN
  318. endif
  319. dec handle
  320. @@:
  321. call genter ; About to modify memory arena
  322. PROFILE GLOBALREALLOC
  323. cCall MyGetAppCompatFlags ; Ignore the NODISCARD flag
  324. test al, GACF_IGNORENODISCARD ; for selected modules
  325. mov ax, rflags
  326. jz @f
  327. call IsKernelCalling ; needs caller's CS @ [bp+4]
  328. jz @f ; skip hack if kernel calling us
  329. and al, NOT GA_NODISCARD
  330. @@:
  331. mov dx,handle
  332. ;mov ax,rflags
  333. lea bx,nbytes ; Convert requested bytes to paragraphs
  334. call gbtop ; ... into BX
  335. call grealloc
  336. gr_done:
  337. CheckHeap GlobalReAlloc
  338. call gleave
  339. mov es,di
  340. cEnd
  341. cProc DiscardTheWorld,<PUBLIC,NEAR>
  342. cBegin
  343. call genter
  344. mov [di].gi_cmpflags, GA_DISCCODE
  345. mov dx, -1
  346. Trace_Out "Discarding the World."
  347. call gcompact
  348. call gleave
  349. cEnd
  350. ; Returns with Z flag set if ss:[bp+4] is a kernel code segment selector.
  351. ; Uses: DX, flags.
  352. cProc IsKernelCalling,<PUBLIC,NEAR>
  353. cBegin nogen
  354. mov dx, [bp+4] ; CS of GlobalAlloc caller
  355. cmp dx, IGROUP
  356. jz @f
  357. cmp dx, _NRESTEXT
  358. jz @f
  359. cmp dx, _MISCTEXT
  360. @@:
  361. ret
  362. cEnd nogen
  363. ;-----------------------------------------------------------------------;
  364. ; GlobalFree ;
  365. ; ;
  366. ; Frees the given object. If the object lives in someone elses banks ;
  367. ; then the argument MUST be a handle entry. ;
  368. ; ;
  369. ; Arguments: ;
  370. ; parmW handle ;
  371. ; ;
  372. ; Returns: ;
  373. ; ;
  374. ; Error Returns: ;
  375. ; ;
  376. ; Registers Preserved: ;
  377. ; ;
  378. ; Registers Destroyed: ;
  379. ; ;
  380. ; Calls: ;
  381. ; ;
  382. ; History: ;
  383. ; ;
  384. ; Wed 26-Apr-1989 15:33:18 -by- David N. Weise [davidw] ;
  385. ; Added the zero'ing of ES on exit. ;
  386. ; ;
  387. ; Sat Apr 25, 1987 10:23:13p -by- David N. Weise [davidw] ;
  388. ; Added support for EMS and added this nifty comment block. ;
  389. ;-----------------------------------------------------------------------;
  390. cProc IGlobalFree,<PUBLIC,FAR>,<si,di>
  391. parmW handle
  392. ifdef WOW
  393. DsOnStack equ [bp][-2]
  394. endif
  395. ; if you add any local params or make this nogen or something similar,
  396. ; the references to [bp][-2] to access DS on stack will need to change!
  397. cBegin
  398. call genter ; About to modify memory arena
  399. PROFILE GLOBALFREE
  400. xor ax,ax ; In case handle = 0.
  401. mov dx,handle
  402. or dx,dx
  403. jnz @F
  404. jmp nothing_to_free
  405. @@:
  406. ;
  407. ; Does this thing have any ring bits or LDT bit? If not, then it
  408. ; could be a selector incorrectly converted to a handle.
  409. ;
  410. test dl,7
  411. jnz @F
  412. if KDEBUG
  413. Trace_Out "GlobalFree:"
  414. push seg ThisIsForTurboPascal
  415. push offset ThisIsForTurboPascal
  416. cCall OutputDebugString
  417. INT3_WARN
  418. endif
  419. dec dx
  420. mov handle,dx
  421. @@:
  422. if ALIASES
  423. call wipe_out_alias
  424. endif
  425. push dx
  426. call pdref ; returns dx=handle, ax=selector
  427. pushf ; save pdref Z flag return
  428. ifdef WOW
  429. ;
  430. ; [bp][-2] has been changed to DsOnStack
  431. ;
  432. endif
  433. cmp ax,DsOnStack ; Are we about to free the DS on
  434. jz short yup ; the stack and GP?
  435. cmp dx,DsOnStack
  436. jnz short nope
  437. yup: xor dx,dx ; Yup, zero DS image on stack...
  438. mov DsOnStack,dx
  439. nope:
  440. popf ; flags from pdref, Z set if discarded
  441. pop dx
  442. jz @f ; discarded can be freed, but has
  443. ; no arena pointer
  444. mov bx, es ; Invalid handle if arena ptr = 0
  445. or bx, bx
  446. jz nothing_to_free
  447. @@:
  448. if KDEBUG
  449. or si,si
  450. jz freeo
  451. or ch,ch ; Debugging check for count underflow
  452. jz freeo
  453. pusha
  454. xor bx,bx
  455. kerror ERR_GMEMUNLOCK,<GlobalFree: freeing locked object>,bx,handle
  456. popa
  457. freeo:
  458. endif
  459. ifdef WOW
  460. test cl, GAH_CURSORICON ; call to pdref above sets cl
  461. jz gf_wowdde
  462. push ax ; save
  463. push bx
  464. push dx
  465. push es
  466. push handle
  467. push FUN_GLOBALFREE
  468. call WowCursorIconOp
  469. or ax, ax ; if TRUE 'free' else 'dont free, fake success'
  470. pop es
  471. pop dx
  472. pop bx
  473. pop ax ; restore
  474. jnz gf_notglobalicon
  475. xor ax, ax ; fake success
  476. xor cx, cx
  477. jmps nothing_to_free
  478. gf_wowdde:
  479. test cl, GAH_WOWDDEFREEHANDLE ; call to pdref above sets cl
  480. jz gf_noticon
  481. push ax ; save
  482. push bx
  483. push dx
  484. push es
  485. push handle
  486. call WowDdeFreeHandle
  487. or ax, ax ; if TRUE 'free' else 'dont free, fake success'
  488. pop es
  489. pop dx
  490. pop bx
  491. pop ax ; restore
  492. jnz gf_notglobalicon
  493. xor ax, ax ; fake success
  494. xor cx, cx
  495. jmps nothing_to_free
  496. gf_notglobalicon:
  497. gf_noticon:
  498. endif
  499. xor cx,cx ; Dont check owner field
  500. call gfree
  501. nothing_to_free:
  502. CheckHeap GlobalFree
  503. call gleave
  504. mov es,di
  505. cEnd
  506. ;-----------------------------------------------------------------------;
  507. ; GlobalFreeAll ;
  508. ; ;
  509. ; Frees all of the global objects belonging to the given owner. ;
  510. ; ;
  511. ; Arguments: ;
  512. ; parmW id ;
  513. ; ;
  514. ; Returns: ;
  515. ; ;
  516. ; Error Returns: ;
  517. ; ;
  518. ; Registers Preserved: ;
  519. ; ;
  520. ; Registers Destroyed: ;
  521. ; ;
  522. ; Calls: ;
  523. ; ;
  524. ; History: ;
  525. ; ;
  526. ; Wed 26-Apr-1989 15:33:18 -by- David N. Weise [davidw] ;
  527. ; Added the zero'ing of ES on exit. ;
  528. ; ;
  529. ; Sat Apr 25, 1987 10:23:13p -by- David N. Weise [davidw] ;
  530. ; Added support for EMS and added this nifty comment block. ;
  531. ;-----------------------------------------------------------------------;
  532. cProc GlobalFreeAll,<PUBLIC,FAR>,<si,di>
  533. parmW id
  534. cBegin
  535. call genter ; About to modify memory arena
  536. PROFILE GLOBALFREEALL
  537. mov cx,1
  538. push cx
  539. mov dx,id ; Get id to match with
  540. or dx,dx ; Is it zero?
  541. jnz all1 ; No, continue
  542. call GetDefOwner ; Yes, CX = default task owner to free
  543. mov dx,cx
  544. all1:
  545. if SDEBUG
  546. mov es,[di].hi_first ; ES:DI points to first arena entry
  547. mov cx,[di].hi_count ; CX = #entries in the arena
  548. all2:
  549. cmp es:[di].ga_owner,dx
  550. jne all3
  551. mov ax, es:[di].ga_handle
  552. Handle_To_Sel al
  553. push cx
  554. push dx
  555. cCall DebugFreeSegment,<ax,0>
  556. pop dx
  557. pop cx
  558. all3:
  559. mov es,es:[di].ga_next ; Move to next block
  560. loop all2 ; Back for more if there (may go extra times
  561. ; because of coalescing, but no great whoop)
  562. endif
  563. call gfreeall
  564. pop cx
  565. CheckHeap GlobalFreeAll
  566. call gleave
  567. mov es,di
  568. cEnd
  569. ;-----------------------------------------------------------------------;
  570. ; xhandle ;
  571. ; ;
  572. ; Returns the handle for a global segment. ;
  573. ; ;
  574. ; Arguments: ;
  575. ; Stack = sp -> near return return address ;
  576. ; sp+2 -> far return return address of caller ;
  577. ; sp+6 -> segment address parameter ;
  578. ; ;
  579. ; Returns: ;
  580. ; Old DS,DI have been pushed on the stack ;
  581. ; ;
  582. ; ZF= 1 if fixed segment. ;
  583. ; AX = handle ;
  584. ; ;
  585. ; ZF = 0 ;
  586. ; AX = handle ;
  587. ; BX = pointer to handle table entry ;
  588. ; CX = flags and count word from handle table ;
  589. ; DX = segment address ;
  590. ; ES:DI = arena header of object ;
  591. ; DS:DI = master object segment address ;
  592. ; ;
  593. ; Error Returns: ;
  594. ; AX = 0 if invalid segment address ;
  595. ; ZF = 1 ;
  596. ; ;
  597. ; Registers Preserved: ;
  598. ; ;
  599. ; Registers Destroyed: ;
  600. ; ;
  601. ; Calls: ;
  602. ; ;
  603. ; History: ;
  604. ; ;
  605. ; Thu Oct 16, 1986 02:40:08p -by- David N. Weise [davidw] ;
  606. ; Added this nifty comment block. ;
  607. ;-----------------------------------------------------------------------;
  608. cProc xhandle,<PUBLIC,NEAR>
  609. cBegin nogen
  610. pop dx ; Get near return address
  611. mov bx,sp ; Get seg parameter from stack
  612. mov ax,ss:[bx+4]
  613. cmp ax,-1 ; Is it -1?
  614. jnz xh1
  615. mov ax,ds ; Yes, use callers DS
  616. xh1: inc bp
  617. push bp
  618. mov bp,sp
  619. push ds ; Save DS:DI
  620. push di
  621. call genter
  622. push dx
  623. mov dx,ax
  624. push si
  625. call pdref
  626. mov dx,ax ; get seg address in DX
  627. jz xhandle_ret ; invalid or discarded handle
  628. mov bx,si
  629. or si,si
  630. jz xhandle_ret
  631. mov ax,si
  632. xhandle_ret:
  633. pop si
  634. ret
  635. cEnd nogen
  636. cProc GlobalHandleNorip,<PUBLIC,FAR>
  637. ; parmW seg
  638. cBegin nogen
  639. if KDEBUG
  640. call xhandle_norip
  641. jmp xhandlex
  642. endif
  643. cEnd nogen
  644. cProc IGlobalHandle,<PUBLIC,FAR>
  645. parmW selector
  646. cBegin
  647. cCall MyLock,<selector>
  648. xchg ax, dx
  649. cEnd
  650. cProc MyLock,<PUBLIC,NEAR>
  651. ; parmW selector
  652. cBegin nogen
  653. mov bx, sp
  654. xor ax, ax ; In case LAR fails
  655. xor dx, dx
  656. lar ax, ss:[bx+2]
  657. jnz ML_End ; LAR failed, get out
  658. test ah, DSC_PRESENT
  659. jz @F
  660. push ds ; Do quick conversion for present
  661. SetKernelDS ; selector
  662. mov ds, pGlobalHeap
  663. UnSetKernelDS
  664. cCall get_arena_pointer,<ss:[bx+2]>
  665. ;** Fix for bugs #9106 and (I think) #9102
  666. or ax,ax ;Did get_arena_pointer fail?
  667. jnz ml_got_arena ;No, skip this
  668. ife ROM
  669. ;** If we get here, it's only because get_arena_pointer failed.
  670. ;** This happens with any non-heap selector.
  671. pop ds
  672. jmps ML_End ;Return NULL instead of GP faulting
  673. else
  674. ;** get_arena_pointer fails when called with a ROM segment selector
  675. ;** so just assume that's what happened and return the selector
  676. mov ax,ss:[bx+2] ; Assume that's what happened and
  677. jmps ml_ret ; just return the selector
  678. endif
  679. ml_got_arena:
  680. mov ds, ax
  681. mov ax, ds:[ga_handle]
  682. ml_ret:
  683. pop ds
  684. mov dx, ax
  685. Handle_To_Sel al
  686. ML_End:
  687. ret 2
  688. @@:
  689. pop ax ; Convert to far call for xhandle
  690. push cs
  691. push ax
  692. call xhandle ; Go around the houses
  693. PROFILE GlobalHandle
  694. xchg ax, dx
  695. jmp xhandlex
  696. cEnd nogen
  697. cProc ILockSegment,<PUBLIC,FAR>
  698. ; parmW seg
  699. cBegin nogen
  700. call xhandle ; Get handle
  701. PROFILE LOCKSEGMENT
  702. jz @F ; Ignore invalid or discarded objects
  703. test cl,GA_DISCARDABLE
  704. jz @F
  705. call glock
  706. @@:
  707. jmp xhandlex
  708. cEnd nogen
  709. cProc IGlobalFix,<PUBLIC,FAR>
  710. ; parmW seg
  711. cBegin nogen
  712. call xhandle ; Get handle
  713. PROFILE GLOBALFIX
  714. jnz igf5
  715. jmp xhandlex ; Ignore invalid or discarded objects
  716. igf5:
  717. call glock
  718. jmp xhandlex
  719. cEnd nogen
  720. cProc IUnlockSegment,<PUBLIC,FAR>
  721. ; parmW seg
  722. cBegin nogen
  723. call xhandle ; Get handle
  724. PROFILE UNLOCKSEGMENT
  725. jz xhandlex ; Ignore invalid or discarded objects
  726. test cl,GA_DISCARDABLE
  727. jz xhandlex
  728. call gunlock
  729. jmps xhandlex
  730. cEnd nogen
  731. cProc IGlobalUnfix,<PUBLIC,FAR>
  732. ; parmW seg
  733. cBegin nogen
  734. call xhandle ; Get handle
  735. PROFILE GLOBALUNFIX
  736. jz xhandlex ; Ignore invalid or discarded objects
  737. call gunlock
  738. jmps xhandlex
  739. cEnd nogen
  740. cProc IGlobalSize,<PUBLIC,FAR>
  741. ; parmW handle
  742. cBegin nogen
  743. call xhandle ; Call ghandle with handle in DX
  744. PROFILE GLOBALSIZE
  745. jnz gs1 ; Continue if valid handle
  746. or dx,dx
  747. jnz gs1
  748. xor ax,ax ; Return zero if invalid handle
  749. jmps xhandlex
  750. gs1: mov ax, es ; Invalid handle if arena ptr = 0
  751. or ax, ax
  752. jz gs4
  753. gs2: mov ax,es:[di].ga_size ; Get size in paragraphs
  754. gs2a: push ax
  755. xor dx,dx ; Returning a long result
  756. mov cx,4
  757. gs3: shl ax,1
  758. rcl dx,1
  759. loop gs3
  760. if 0
  761. ; This hack should be enabled for Simcity when its other problems
  762. ; are fixed on RISC (aka with krnl286).
  763. push ds
  764. push dx
  765. push ax
  766. cCall hackcheck,<handle>
  767. or ax,ax
  768. jz gsN
  769. pop ax
  770. pop dx
  771. mov ax,02000h
  772. xor dx,dx
  773. push dx
  774. push ax
  775. gsN:
  776. pop ax
  777. pop dx
  778. pop ds
  779. endif
  780. pop cx ; Return number paragraphs in CX
  781. jmps xhandlex
  782. gs4: xor dx, dx
  783. jmps xhandlex
  784. cEnd nogen
  785. cProc IGlobalFlags,<PUBLIC,FAR>
  786. ; parmW handle
  787. cBegin nogen
  788. call xhandle ; Call ghandle with handle in DX
  789. PROFILE GLOBALFLAGS
  790. xchg cl,ch ; Return lock count in low half
  791. mov ax,cx ; Let caller do jcxz to test failure
  792. xhandlex:
  793. call gleave
  794. mov es,di ; don't return arbitrary selector
  795. pop di
  796. pop ds
  797. pop bp
  798. dec bp
  799. ret 2
  800. cEnd nogen
  801. cProc IGlobalLock,<PUBLIC,FAR>
  802. parmW handle
  803. ifdef WOW
  804. localW gflags
  805. localW accword
  806. endif
  807. cBegin
  808. ifdef WOW
  809. mov gflags,0
  810. endif
  811. xor dx, dx ; Assume failure
  812. cmp handle, -1
  813. jne @F
  814. mov handle, ds
  815. @@:
  816. cCall GetAccessWord,<handle>
  817. ifdef WOW
  818. mov accword, ax
  819. endif
  820. test al, DSC_PRESENT ; Is it present?
  821. jz GL_exit
  822. mov dx, handle ; OK, will return something
  823. Handle_To_Sel dl ; Turn parameter into a selector
  824. ifndef WOW
  825. test ah, DSC_DISCARDABLE ; Is it discardable
  826. jz GL_exit ; no, Lock is a nop
  827. endif
  828. cCall get_arena_pointer,<dx> ; Discardable, get its arena
  829. or ax, ax
  830. jz GL_exit ; No arena, assume an alias
  831. mov es, ax
  832. ifdef WOW
  833. mov al, es:[ga_flags]
  834. mov byte ptr gflags, al
  835. test accword, DSC_DISCARDABLE SHL 8
  836. jz GL_exit
  837. endif
  838. inc es:[ga_count] ; Finally, do the lock
  839. ;;; jz GL_rip ; Rip if we overflow
  840. GL_exit:
  841. ifdef WOW
  842. test gflags, GAH_CURSORICON
  843. jz GL_NotIcon
  844. push dx ; save
  845. push handle ; arg for CursorIconLockOp
  846. push FUN_GLOBALLOCK ; func id
  847. call WowCursorIconOp
  848. pop dx ; restore
  849. GL_NotIcon:
  850. endif
  851. xor ax, ax
  852. mov es, ax ; Clean out ES
  853. mov cx, dx ; HISTORY - someone probably does a jcxz
  854. cEnd
  855. cProc IGlobalUnlock,<PUBLIC,FAR>
  856. parmW handle
  857. ifdef WOW
  858. localW gflags
  859. localW accword
  860. endif
  861. cBegin
  862. mov gflags,0
  863. cmp handle, -1
  864. jne @F
  865. mov handle, ds
  866. @@:
  867. ;
  868. ; Does this thing have any ring bits or LDT bit? If not, then it
  869. ; could be a selector incorrectly converted to a handle.
  870. ;
  871. test byte ptr handle,7
  872. jnz @F
  873. if KDEBUG
  874. Trace_Out "GlobalUnlock:"
  875. push seg ThisIsForTurboPascal
  876. push offset ThisIsForTurboPascal
  877. cCall OutputDebugString
  878. INT3_WARN
  879. endif
  880. dec handle
  881. @@:
  882. xor cx, cx ; Assume zero lock count
  883. cCall GetAccessWord,<handle>
  884. ifdef WOW
  885. mov accword, ax
  886. endif
  887. test al, DSC_PRESENT ; Is it present?
  888. jz GU_exit ; no, must be discarded, return 0:0
  889. ifndef WOW
  890. test ah, DSC_DISCARDABLE ; Is it discardable
  891. jz GU_exit ; no, Lock is a nop
  892. endif
  893. cCall get_arena_pointer,<handle> ; Discardable, get its arena
  894. or ax, ax
  895. jz GU_exit ; No arena, assume an alias
  896. mov es, ax
  897. ifdef WOW
  898. mov al, es:[ga_flags]
  899. mov byte ptr gflags, al
  900. test accword, DSC_DISCARDABLE SHL 8
  901. jz GU_exit
  902. endif
  903. mov cl, es:[ga_count] ; Get current count
  904. dec cl
  905. cmp cl, 0FEh
  906. jae @F
  907. dec es:[ga_count] ; Finally, do the unlock
  908. jmps GU_Exit
  909. @@:
  910. ;;; ; Rip if we underflow
  911. xor cx, cx ; Return zero on underflow
  912. GU_exit:
  913. ifdef WOW
  914. test gflags, GAH_CURSORICON
  915. jz GUL_NotIcon
  916. push cx ; save
  917. push handle ; arg for CursorIconLockOp
  918. push FUN_GLOBALUNLOCK ; UnLocking
  919. call WowCursorIconOp
  920. pop cx ; restore
  921. GUL_NotIcon:
  922. endif
  923. xor ax, ax
  924. mov es, ax ; Clean out ES
  925. mov ax, cx
  926. cEnd
  927. ;-----------------------------------------------------------------------;
  928. ; GlobalWire ;
  929. ; ;
  930. ; Locks a moveable segment and moves it down as low as possible. ;
  931. ; This is meant for people who are going to be locking an object ;
  932. ; for a while and wish to be polite. It cannot work as a general ;
  933. ; panacea, judgement is still called for in its use! ;
  934. ; ;
  935. ; Arguments: ;
  936. ; WORD object handle ;
  937. ; ;
  938. ; Returns: ;
  939. ; DWORD object address ;
  940. ; ;
  941. ; Error Returns: ;
  942. ; ;
  943. ; Registers Preserved: ;
  944. ; ;
  945. ; Registers Destroyed: ;
  946. ; ;
  947. ; Calls: ;
  948. ; xhandle ;
  949. ; gmovebusy ;
  950. ; ;
  951. ; History: ;
  952. ; ;
  953. ; Wed Dec 03, 1986 01:07:13p -by- David N. Weise [davidw] ;
  954. ; Wrote it. ;
  955. ;-----------------------------------------------------------------------;
  956. cProc IGlobalWire,<PUBLIC,FAR>
  957. ; parmW handle
  958. cBegin nogen
  959. SetKernelDS es
  960. or Kernel_Flags[1],kf1_MEMORYMOVED
  961. UnSetKernelDS es
  962. if KDEBUG
  963. push ds
  964. SetKernelDS
  965. cmp [fBooting], 0
  966. jnz shutup
  967. push bx
  968. mov bx, sp
  969. mov bx, ss:[bx+8]
  970. krDebugOut <DEB_WARN OR DEB_KrMemMan>, "GlobalWire(#BX of %BX2) (try GlobalLock)"
  971. pop bx
  972. shutup:
  973. pop ds
  974. UnSetKernelDS
  975. endif
  976. call xhandle
  977. push si
  978. jz gw_done ; Ignore invalid or discarded objects
  979. push bx ; Save handle
  980. push cx
  981. test cl,GA_DISCARDABLE
  982. jz @F
  983. inc es:[di].ga_count ; don't want to discard if discardable
  984. @@: xor ax,ax ; Try to get a fixed segment.
  985. mov bx,es:[di].ga_size
  986. mov cx,es:[di].ga_owner
  987. call gsearch ; AX = segment
  988. pop cx
  989. pop bx ; Object handle.
  990. push ax ; Return from gsearch
  991. cCall get_arena_pointer,<bx> ; Get arena header, gsearch may
  992. mov es,ax ; have moved the global object!
  993. test cl,GA_DISCARDABLE
  994. jz @F
  995. dec es:[di].ga_count ; undo lock
  996. @@:
  997. ;;; mov es, es:[di].ga_next
  998. ;;; mov ax, es:[di].ga_prev ; REAL arena header
  999. mov si,ax
  1000. ;;; mov es,ax
  1001. pop ax
  1002. or ax,ax
  1003. push bx ; Handle
  1004. jz lock_in_place ; Couldn't get memory.
  1005. push ax ; New Block
  1006. mov bx,ax
  1007. cCall cmp_sel_address,<bx,si> ; Flags set as if cmp bx,si
  1008. ja oh_no_mr_bill ; Let's not move it up in memory!!
  1009. pop es
  1010. ; mov bx,ga_next ; This is always an exact fit.
  1011. call gmovebusy ; Wire it on down.
  1012. lock_in_place:
  1013. pop bx ; Handle
  1014. inc es:[di].ga_count ; Lock it down.
  1015. test es:[di].ga_flags,GA_DISCCODE
  1016. jz not_disccode
  1017. call glrudel
  1018. and es:[di].ga_flags,NOT GA_DISCCODE
  1019. not_disccode:
  1020. mov ax,es
  1021. mov ax, es:[di].ga_handle
  1022. Handle_To_Sel al
  1023. gw_done:
  1024. mov dx,ax
  1025. xor ax,ax ; Make address SEG:OFF.
  1026. pop si
  1027. gw_ret: jmp xhandlex
  1028. oh_no_mr_bill:
  1029. pop bx ; kill what's on stack
  1030. push es
  1031. mov es, ax
  1032. xor si, si
  1033. call gmarkfree
  1034. pop es
  1035. jmp lock_in_place
  1036. cEnd nogen
  1037. ;-----------------------------------------------------------------------;
  1038. ; GlobalUnWire ;
  1039. ; ;
  1040. ; ;
  1041. ; Arguments: ;
  1042. ; ;
  1043. ; Returns: ;
  1044. ; ;
  1045. ; Error Returns: ;
  1046. ; ;
  1047. ; Registers Preserved: ;
  1048. ; ;
  1049. ; Registers Destroyed: ;
  1050. ; ;
  1051. ; Calls: ;
  1052. ; ;
  1053. ; History: ;
  1054. ; ;
  1055. ; Wed Sep 16, 1987 04:28:49p -by- David N. Weise [davidw] ;
  1056. ; Wrote it. ;
  1057. ;-----------------------------------------------------------------------;
  1058. cProc IGlobalUnWire,<PUBLIC,FAR>
  1059. ; parmW handle
  1060. cBegin nogen
  1061. call xhandle
  1062. jnz guw_go
  1063. jmp xhandlex
  1064. guw_go:
  1065. cCall GetAccessWord,<bx>
  1066. test ah, DSC_DISCARDABLE
  1067. jz guw_not_disccode
  1068. test al, DSC_CODE_BIT
  1069. jz guw_not_disccode
  1070. or es:[di].ga_flags,GA_DISCCODE
  1071. call glruadd
  1072. guw_not_disccode:
  1073. if KDEBUG
  1074. cmp ch,00h ; Debugging check for count underflow
  1075. jne unlock1
  1076. push bx ; then the count is wrong.
  1077. push cx
  1078. push dx
  1079. xor cx,cx
  1080. kerror ERR_GMEMUNLOCK,<GlobalUnWire: Object usage count underflow>,cx,bx
  1081. pop dx
  1082. pop cx
  1083. pop bx
  1084. unlock1:
  1085. endif
  1086. call gunlock
  1087. mov ax, 0FFFFh ; TRUE
  1088. jcxz guw_done
  1089. inc ax ; FALSE
  1090. guw_done:
  1091. jmp xhandlex
  1092. cEnd nogen
  1093. ;-----------------------------------------------------------------------;
  1094. ; GlobalCompact ;
  1095. ; ;
  1096. ; Compacts the global arena until a free block of the requested size ;
  1097. ; appears. Contrary to the toolkit it ALWAYS compacts! ;
  1098. ; ;
  1099. ; Arguments: ;
  1100. ; DWORD minimum bytes wanted ;
  1101. ; ;
  1102. ; Returns: ;
  1103. ; ;
  1104. ; Error Returns: ;
  1105. ; ;
  1106. ; Registers Preserved: ;
  1107. ; ;
  1108. ; Registers Destroyed: ;
  1109. ; ;
  1110. ; Calls: ;
  1111. ; ;
  1112. ; History: ;
  1113. ; ;
  1114. ; Wed 26-Apr-1989 15:33:18 -by- David N. Weise [davidw] ;
  1115. ; Added the zero'ing of ES on exit. ;
  1116. ; ;
  1117. ; Wed Dec 03, 1986 01:09:02p -by- David N. Weise [davidw] ;
  1118. ; Added this nifty comment block. ;
  1119. ;-----------------------------------------------------------------------;
  1120. assumes ds,nothing
  1121. assumes es,nothing
  1122. cProc GlobalCompact,<PUBLIC,FAR>,<bx,si,di>
  1123. parmD minBytes
  1124. cBegin
  1125. call genter ; About to modify memory arena
  1126. PROFILE GLOBALCOMPACT
  1127. CheckHeap GlobalCompact
  1128. cCall DpmiFreeSpace
  1129. cmp dx,seg_minBytes
  1130. jb GCReallyCompact
  1131. ja GCWorked
  1132. cmp ax,off_minBytes
  1133. jnb GCWorked
  1134. GCReallyCompact:
  1135. if KDEBUG
  1136. push ax
  1137. push bx
  1138. mov ax, seg_minBytes
  1139. mov bx, off_minBytes
  1140. krDebugOut DEB_TRACE, "%SS2 GlobalCompact(#ax#BX), discarding segments"
  1141. pop bx
  1142. pop ax
  1143. endif
  1144. mov ax,-1
  1145. lea bx,minBytes
  1146. call gbtop
  1147. assumes es, nothing
  1148. clc ; galign should be called with CF = 0
  1149. call galign
  1150. call gavail ; Returns paragraphs in DX:AX
  1151. mov cx,4 ; Convert paragraphs to bytes
  1152. push ax
  1153. gcsize1:
  1154. shl ax,1
  1155. rcl dx,1
  1156. loop gcsize1
  1157. pop cx ; Let caller do jcxz to test failure.
  1158. jmp GCDone
  1159. GCWorked:
  1160. cmp dx,0fh ; make sure return value not too large
  1161. jb GCAlmostDone
  1162. ja GCAD1
  1163. cmp ax,0ffb0h
  1164. jb GCAlmostDone
  1165. GCAD1:
  1166. mov dx,0fh
  1167. mov ax,0ffb0h
  1168. GCAlmostDone:
  1169. mov cx,dx
  1170. mov bx,ax
  1171. shr bx,4
  1172. shl cx,12
  1173. or cx,bx
  1174. GCDone:
  1175. call ShrinkHeap
  1176. call gleave
  1177. mov es,di
  1178. cEnd
  1179. ;-----------------------------------------------------------------------;
  1180. ; GlobalNotify ;
  1181. ; ;
  1182. ; This sets a procedure to call when a discardable segment belonging ;
  1183. ; to this task gets discarded. The discardable object must have been ;
  1184. ; allocated with the GMEM_DISCARDABLE bit set. ;
  1185. ; ;
  1186. ; Arguments: ;
  1187. ; parmD NotifyProc ;
  1188. ; ;
  1189. ; Returns: ;
  1190. ; nothing ;
  1191. ; ;
  1192. ; Error Returns: ;
  1193. ; ;
  1194. ; Registers Preserved: ;
  1195. ; AX,CX,DX,DI,SI,DS ;
  1196. ; ;
  1197. ; Registers Destroyed: ;
  1198. ; BX,ES ;
  1199. ; ;
  1200. ; Calls: ;
  1201. ; nothing ;
  1202. ; ;
  1203. ; History: ;
  1204. ; ;
  1205. ; Tue Jun 23, 1987 10:16:32p -by- David N. Weise [davidw] ;
  1206. ; Wrote it. ;
  1207. ;-----------------------------------------------------------------------;
  1208. cProc IGlobalNotify,<PUBLIC,FAR>
  1209. parmD NotifyProc
  1210. cBegin
  1211. push ds
  1212. les bx,NotifyProc ; verify pointer
  1213. SetKernelDS
  1214. mov ds,curTDB
  1215. UnsetKernelDS
  1216. mov word ptr ds:[TDB_GNotifyProc][2],es
  1217. mov word ptr ds:[TDB_GNotifyProc][0],bx
  1218. pop ds
  1219. cEnd
  1220. cProc GlobalMasterHandle,<PUBLIC,FAR>
  1221. cBegin nogen
  1222. push ds
  1223. SetKernelDS
  1224. mov ax,hGlobalHeap
  1225. mov dx,pGlobalHeap
  1226. UnSetKernelDS
  1227. pop ds
  1228. ret
  1229. cEnd nogen
  1230. ;-----------------------------------------------------------------------;
  1231. ; GetTaskDS ;
  1232. ; ;
  1233. ; Gets the segment of the current task's DS. ;
  1234. ; ;
  1235. ; Arguments: ;
  1236. ; none ;
  1237. ; ;
  1238. ; Returns: ;
  1239. ; AX = selector. ;
  1240. ; DX = selector. ;
  1241. ; ;
  1242. ; Error Returns: ;
  1243. ; ;
  1244. ; Registers Preserved: ;
  1245. ; ;
  1246. ; Registers Destroyed: ;
  1247. ; ;
  1248. ; Calls: ;
  1249. ; nothing ;
  1250. ; ;
  1251. ; History: ;
  1252. ; ;
  1253. ; Thu Jun 25, 1987 10:52:10p -by- David N. Weise [davidw] ;
  1254. ; Wrote it. ;
  1255. ;-----------------------------------------------------------------------;
  1256. cProc GetTaskDS,<PUBLIC,FAR>
  1257. cBegin nogen
  1258. push ds
  1259. SetKernelDS
  1260. mov ds,curTDB
  1261. UnsetKernelDS
  1262. mov ax,ds:[TDB_Module]
  1263. mov dx,ax
  1264. pop ds
  1265. ret
  1266. cEnd nogen
  1267. assumes ds, nothing
  1268. assumes es, nothing
  1269. cProc IGlobalLRUOldest,<PUBLIC,FAR>
  1270. ; parmW handle
  1271. cBegin nogen
  1272. call xhandle ; Call ghandle with handle in DX
  1273. jz xhandlex2
  1274. call glrubot
  1275. xhandlex2:
  1276. jmp xhandlex
  1277. cEnd nogen
  1278. cProc IGlobalLRUNewest,<PUBLIC,FAR>
  1279. ; parmW handle
  1280. cBegin nogen
  1281. call xhandle ; Call ghandle with handle in DX
  1282. jz xhandlex2
  1283. call glrutop
  1284. jmp xhandlex
  1285. cEnd nogen
  1286. ;-----------------------------------------------------------------------;
  1287. ; SwitchStackTo ;
  1288. ; ;
  1289. ; Switched to the given stack, and establishes the BP chain. It also ;
  1290. ; copies the last stack arguments from the old stack to the new stack. ;
  1291. ; ;
  1292. ; Arguments: ;
  1293. ; parmW new_ss ;
  1294. ; parmW new_sp ;
  1295. ; parmW stack_top ;
  1296. ; ;
  1297. ; Returns: ;
  1298. ; A new stack! ;
  1299. ; ;
  1300. ; Error Returns: ;
  1301. ; ;
  1302. ; Registers Preserved: ;
  1303. ; DI,SI,DS ;
  1304. ; ;
  1305. ; Registers Destroyed: ;
  1306. ; AX,BX,CX,DX,ES ;
  1307. ; ;
  1308. ; Calls: ;
  1309. ; nothing ;
  1310. ; ;
  1311. ; History: ;
  1312. ; ;
  1313. ; Tue Sep 22, 1987 08:42:05p -by- David N. Weise [davidw] ;
  1314. ; Wrote it. ;
  1315. ;-----------------------------------------------------------------------;
  1316. assumes ds,nothing
  1317. assumes es,nothing
  1318. cProcVDO SwitchStackTo,<PUBLIC,FAR>
  1319. ; parmW new_ss
  1320. ; parmW new_sp
  1321. ; parmW stack_top
  1322. cBegin nogen
  1323. SetKernelDS es
  1324. FCLI
  1325. mov GSS_SI,si
  1326. mov GSS_DS,ds
  1327. pop word ptr GSS_RET[0] ; get the return address
  1328. pop word ptr GSS_RET[2]
  1329. assumes es, nothing
  1330. pop ax ; stack_top
  1331. pop bx ; new_sp
  1332. pop dx ; new_ss
  1333. mov si,bp ; Calculate # of parameters on stack.
  1334. dec si ; remove DS
  1335. dec si
  1336. mov cx,si
  1337. sub cx,sp
  1338. shr cx,1
  1339. push bp ; save BP
  1340. smov es,ss
  1341. mov ds,dx ; new_ss
  1342. mov ds:[2],sp
  1343. mov ds:[4],ss
  1344. mov ds:[pStackTop],ax
  1345. mov ds:[pStackMin],bx
  1346. mov ds:[pStackBot],bx
  1347. ; switch stacks
  1348. mov ss,dx
  1349. mov sp,bx
  1350. mov bp,bx
  1351. xor ax,ax
  1352. push ax ; null terminate bp chain
  1353. jcxz no_args
  1354. copy_args:
  1355. dec si
  1356. dec si
  1357. push es:[si]
  1358. loop copy_args
  1359. no_args:
  1360. SetKernelDS
  1361. mov es,curTDB
  1362. mov es:[TDB_taskSS],ss
  1363. mov es:[TDB_taskSP],sp
  1364. push GSS_RET.sel
  1365. push GSS_RET.off ; get the return address
  1366. mov si,GSS_SI
  1367. mov ds,GSS_DS
  1368. FSTI
  1369. ret
  1370. cEnd nogen
  1371. ;-----------------------------------------------------------------------;
  1372. ; SwitchStackBack ;
  1373. ; ;
  1374. ; Switches to the stack stored at SS:[2], and restores BP. Preserves ;
  1375. ; AX and DX so that results can be passed back from the last call. ;
  1376. ; ;
  1377. ; Arguments: ;
  1378. ; none ;
  1379. ; ;
  1380. ; Returns: ;
  1381. ; The old stack! ;
  1382. ; ;
  1383. ; Error Returns: ;
  1384. ; ;
  1385. ; Registers Preserved: ;
  1386. ; AX,DX,DI,SI,DS ;
  1387. ; ;
  1388. ; Registers Destroyed: ;
  1389. ; BX,CX,ES ;
  1390. ; ;
  1391. ; Calls: ;
  1392. ; nothing ;
  1393. ; ;
  1394. ; History: ;
  1395. ; ;
  1396. ; Tue Sep 22, 1987 09:56:32p -by- David N. Weise [davidw] ;
  1397. ; Wrote it. ;
  1398. ;-----------------------------------------------------------------------;
  1399. assumes ds,nothing
  1400. assumes es,nothing
  1401. cProc SwitchStackBack,<PUBLIC,FAR>
  1402. cBegin nogen
  1403. push ds
  1404. SetKernelDS
  1405. FCLI
  1406. pop GSS_DS
  1407. pop GSS_RET.off ; get the return address
  1408. pop GSS_RET.sel
  1409. xor bx,bx
  1410. xor cx,cx
  1411. xchg bx,ss:[4]
  1412. xchg cx,ss:[2]
  1413. mov ss,bx
  1414. mov sp,cx
  1415. mov es,curTDB
  1416. mov es:[TDB_taskSS],ss
  1417. mov es:[TDB_taskSP],sp
  1418. pop bp
  1419. push GSS_RET.sel
  1420. push GSS_RET.off ; get the return address
  1421. mov ds,GSS_DS
  1422. UnSetKernelDS
  1423. FSTI
  1424. ret
  1425. cEnd nogen
  1426. ;
  1427. ; GetFreeMemInfo - reports Free and Unlocked pages
  1428. ; in paging systems. -1 for non paging system.
  1429. ;
  1430. cProc GetFreeMemInfo,<PUBLIC,FAR>
  1431. cBegin nogen
  1432. mov ax, -1
  1433. mov dx, ax
  1434. ret
  1435. cEnd nogen
  1436. ;-----------------------------------------------------------------------;
  1437. ; GetFreeSpace ;
  1438. ; ;
  1439. ; Calculates the current amount of free space ;
  1440. ; ;
  1441. ; Arguments: ;
  1442. ; flags - ignored for non-EMS system ;
  1443. ; ;
  1444. ; Returns: ;
  1445. ; DX:AX Free space in bytes ;
  1446. ; ;
  1447. ; Error Returns: ;
  1448. ; ;
  1449. ; Registers Preserved: ;
  1450. ; DI,SI,DS ;
  1451. ; ;
  1452. ; Registers Destroyed: ;
  1453. ; BX,CX,ES ;
  1454. ; ;
  1455. ; Calls: ;
  1456. ; nothing ;
  1457. ; ;
  1458. ; History: ;
  1459. ; ;
  1460. ; Wed 26-Apr-1989 15:33:18 -by- David N. Weise [davidw] ;
  1461. ; Added the zero'ing of ES on exit. ;
  1462. ; ;
  1463. ;-----------------------------------------------------------------------;
  1464. assumes ds, nothing
  1465. assumes es, nothing
  1466. cProc IGetFreeSpace,<PUBLIC,FAR>,<si,di>
  1467. parmW flags
  1468. localV MemInfo,30h
  1469. cBegin
  1470. call genter
  1471. xor si, si
  1472. xor dx, dx
  1473. mov es, [di].hi_first
  1474. gfs_loop:
  1475. mov es, es:[di].ga_next
  1476. cmp es:[di].ga_sig, GA_ENDSIG
  1477. je gfs_last ; End of heap
  1478. mov ax, es:[di].ga_owner
  1479. cmp ax, GA_NOT_THERE
  1480. je gfs_loop ; Nothing there
  1481. or ax, ax ; Free?
  1482. jz gfs_freeblock
  1483. test flags, 2 ; Ignore discardable?
  1484. jnz gfs_loop
  1485. mov bx, es:[di].ga_handle
  1486. test bl, GA_FIXED
  1487. jnz gfs_loop ; Fixed block if odd
  1488. cmp es:[di].ga_sig, 0
  1489. jne gfs_loop ; skip if locked
  1490. cCall GetAccessWord,<bx>
  1491. test ah, DSC_DISCARDABLE
  1492. jz gfs_loop
  1493. gfs_freeblock:
  1494. mov ax, es:[di].ga_size
  1495. inc ax
  1496. add si, ax
  1497. adc dx, 0 ; Keep 32 bit total
  1498. jmps gfs_loop
  1499. gfs_last:
  1500. test flags, 2 ; No fence stuff if ignoring discardable
  1501. jnz @F
  1502. sub si, [di].gi_reserve ; Subtract out that above fence
  1503. sbb dx, 0
  1504. @@:
  1505. mov ax, si ; Return in DX:AX
  1506. ; Convert to bytes
  1507. REPT 4
  1508. shl ax, 1
  1509. rcl dx, 1
  1510. ENDM
  1511. ;
  1512. ; Get the ammount of free memory
  1513. ;
  1514. push bx
  1515. push cx
  1516. push ax
  1517. push dx
  1518. call DpmiFreeSpace
  1519. pop dx
  1520. pop ax
  1521. add ax,bx
  1522. adc dx,cx
  1523. pop cx
  1524. pop bx
  1525. @@: call gleave
  1526. mov es,di
  1527. cEnd
  1528. ;-----------------------------------------------------------------------;
  1529. ; GlobalDOSAlloc
  1530. ;
  1531. ; Allocates memory that is accessible by DOS.
  1532. ;
  1533. ; Entry:
  1534. ; parmD nbytes number of bytes to alloc
  1535. ;
  1536. ; Returns:
  1537. ; AX = memory handle
  1538. ; DX = DOS segment paragraph address
  1539. ;
  1540. ; History:
  1541. ; Tue 23-May-1989 11:30:57 -by- David N. Weise [davidw]
  1542. ; Wrote it!
  1543. ;-----------------------------------------------------------------------;
  1544. assumes ds,nothing
  1545. assumes es,nothing
  1546. cProc GlobalDOSAlloc,<PUBLIC,FAR>,<di,si>
  1547. parmD nbytes
  1548. cBegin
  1549. mov ax,GA_ALLOC_DOS shl 8
  1550. cCall IGlobalAlloc,<ax,nbytes>
  1551. xor dx,dx ; In case of error return
  1552. or ax,ax
  1553. jz short gda_exit
  1554. push ax
  1555. cCall get_physical_address,<ax>
  1556. REPT 4
  1557. shr dx,1
  1558. rcr ax,1
  1559. ENDM
  1560. xchg dx,ax
  1561. pop ax
  1562. gda_exit:
  1563. cEnd
  1564. ;-----------------------------------------------------------------------;
  1565. ; GlobalDOSFree
  1566. ;
  1567. ; Frees memory allocated by GlobalDOSAlloc.
  1568. ;
  1569. ; Entry:
  1570. ; parmW handle
  1571. ;
  1572. ; Returns:
  1573. ;
  1574. ; Registers Destroyed:
  1575. ;
  1576. ; History:
  1577. ; Tue 23-May-1989 17:48:03 -by- David N. Weise [davidw]
  1578. ; Wrote it!
  1579. ;-----------------------------------------------------------------------;
  1580. assumes ds,nothing
  1581. assumes es,nothing
  1582. cProc GlobalDOSFree,<PUBLIC,FAR>
  1583. parmW handle
  1584. cBegin nogen
  1585. jmp IGlobalFree
  1586. cEnd nogen
  1587. if ALIASES
  1588. ;-----------------------------------------------------------------------;
  1589. ; GlobalAllocHuge
  1590. ;
  1591. ;
  1592. ; Entry:
  1593. ;
  1594. ; Returns:
  1595. ;
  1596. ; Registers Destroyed:
  1597. ;
  1598. ; History:
  1599. ; Sun 21-Jan-1990 16:35:10 -by- David N. Weise [davidw]
  1600. ; Wrote it!
  1601. ;-----------------------------------------------------------------------;
  1602. assumes ds,nothing
  1603. assumes es,nothing
  1604. cProc GlobalAllocHuge,<PUBLIC,FAR>,<di,si>
  1605. parmW flags
  1606. parmD nbytes
  1607. parmW maxsegs ; !!! check for maxsegs = 0
  1608. localW hMem
  1609. localW hAlias
  1610. cBegin
  1611. cCall GlobalAlloc,<0,nbytes>
  1612. or ax,ax
  1613. jz gah_exit
  1614. mov hMem,ax
  1615. cCall get_physical_address,<ax>
  1616. mov cx,maxsegs
  1617. cmp cx,0Fh
  1618. jb @F
  1619. mov cx,0Fh
  1620. @@: shl cx,12
  1621. or cx,0FFFh
  1622. cCall alloc_data_sel,<dx,ax,cx>
  1623. or ax,ax
  1624. jz gah_error_return
  1625. mov hAlias,ax
  1626. mov bx,hMem
  1627. call add_alias ; the key point!
  1628. mov bx,ax
  1629. mov ax,maxsegs ; the only way to remember
  1630. call add_alias ; the number of selectors
  1631. mov cx,nbytes.hi
  1632. mov bx,nbytes.lo
  1633. cCall set_sel_limit,<hAlias>
  1634. mov ax,hAlias
  1635. jmps gah_exit
  1636. gah_error_return:
  1637. cCall GlobalFree,<hMem>
  1638. xor ax,ax
  1639. gah_exit:
  1640. cEnd
  1641. ;-----------------------------------------------------------------------;
  1642. ; GlobalReAllocHuge
  1643. ;
  1644. ;
  1645. ; Entry:
  1646. ;
  1647. ; Returns:
  1648. ;
  1649. ; Registers Destroyed:
  1650. ;
  1651. ; History:
  1652. ; Sun 21-Jan-1990 16:35:10 -by- David N. Weise [davidw]
  1653. ; Wrote it!
  1654. ;-----------------------------------------------------------------------;
  1655. assumes ds,nothing
  1656. assumes es,nothing
  1657. cProc GlobalReAllocHuge,<PUBLIC,FAR>,<si,di>
  1658. parmW handle
  1659. parmD nbytes
  1660. cBegin
  1661. mov ax,handle
  1662. call get_alias_from_original
  1663. cmp bx,nbytes.hi
  1664. jb grh_error_exit
  1665. call get_original_from_alias
  1666. push es
  1667. or bx,SEG_RING
  1668. cCall GlobalRealloc,<bx,nbytes,0>
  1669. pop es
  1670. or ax,ax ; did we get the memory?
  1671. jz grh_exit
  1672. cmp ax,es:[di].sae_sel ; did the selector change?
  1673. jz grh_exit
  1674. mov es:[di].sae_sel,ax
  1675. cCall get_physical_address,<ax>
  1676. cCall set_physical_address,<handle>
  1677. mov ax,handle
  1678. jmps grh_exit
  1679. grh_error_exit:
  1680. xor ax,ax
  1681. grh_exit:
  1682. cEnd
  1683. ;-----------------------------------------------------------------------;
  1684. ; GlobalFreeHuge
  1685. ;
  1686. ;
  1687. ; Entry:
  1688. ;
  1689. ; Returns:
  1690. ;
  1691. ; Registers Destroyed:
  1692. ;
  1693. ; History:
  1694. ; Mon 22-Jan-1990 21:24:02 -by- David N. Weise [davidw]
  1695. ; Wrote it!
  1696. ;-----------------------------------------------------------------------;
  1697. assumes ds,nothing
  1698. assumes es,nothing
  1699. cProc GlobalFreeHuge,<PUBLIC,FAR>,<di,si>
  1700. parmW handle
  1701. cBegin
  1702. mov ax,handle
  1703. call get_alias_from_original
  1704. mov es:[di].sae_sel,0
  1705. mov es:[di].sae_alias,0
  1706. mov cx,bx
  1707. mov bx,0FFFFh
  1708. cCall set_sel_limit,<ax>
  1709. mov dx,ax
  1710. mov ax,handle
  1711. call get_original_from_alias
  1712. push bx
  1713. push ax
  1714. call delete_alias
  1715. pop ax ; wastes a couple of bytes
  1716. cCall FreeSelector,<ax>
  1717. pop ax
  1718. cCall GlobalFree,<ax>
  1719. cEnd
  1720. endif ; ALIASES
  1721. ;-----------------------------------------------------------------------;
  1722. ; GlobalHuge
  1723. ;
  1724. ; Random place holder of an entry point.
  1725. ;
  1726. ; Entry:
  1727. ;
  1728. ; Returns:
  1729. ;
  1730. ; Registers Destroyed:
  1731. ;
  1732. ; History:
  1733. ; Tue 23-Jan-1990 00:53:59 -by- David N. Weise [davidw]
  1734. ; Stubbed it!
  1735. ;-----------------------------------------------------------------------;
  1736. assumes ds,nothing
  1737. assumes es,nothing
  1738. cProc GlobalHuge,<PUBLIC,FAR>
  1739. cBegin nogen
  1740. ret 10
  1741. cEnd nogen
  1742. cProc DpmiFreeSpace,<PUBLIC,NEAR>,<di,si,es>
  1743. localV MemInfo,30h
  1744. cBegin
  1745. ;
  1746. ; Get Memory Info
  1747. ;
  1748. mov ax,ss
  1749. mov es,ax
  1750. lea di,MemInfo
  1751. DPMICALL 500h
  1752. jc dfs30
  1753. ;
  1754. ; Convert pages to bytes
  1755. ;
  1756. mov bx,MemInfo[14h]
  1757. mov cx,MemInfo[16h]
  1758. REPT 12
  1759. shl bx,1
  1760. rcl cx,1
  1761. ENDM
  1762. ;
  1763. ; Get the rest of the info
  1764. ;
  1765. mov ax,MemInfo[0]
  1766. mov dx,MemInfo[2]
  1767. jmp dfs40
  1768. dfs30: xor ax,ax
  1769. mov bx,ax
  1770. mov cx,ax
  1771. mov dx,ax
  1772. dfs40:
  1773. cEnd
  1774. ifdef WOW
  1775. ;--------------------------------------------------------------------------;
  1776. ;
  1777. ; Similar to GlobalFlags
  1778. ;
  1779. ;--------------------------------------------------------------------------;
  1780. cProc SetCursorIconFlag,<PUBLIC,FAR>
  1781. parmW handle
  1782. parmW fSet
  1783. cBegin
  1784. cCall get_arena_pointer,<handle> ; get the owner
  1785. mov es,ax
  1786. or ax,ax
  1787. jz sf_error
  1788. mov ax,fSet
  1789. or ax,ax
  1790. jz sf_unset
  1791. or es:[ga_flags], GAH_CURSORICON
  1792. jmps sf_error
  1793. sf_unset:
  1794. and es:[ga_flags], NOT GAH_CURSORICON
  1795. sf_error:
  1796. xor ax,ax
  1797. mov es,ax
  1798. cEnd
  1799. ;--------------------------------------------------------------------------;
  1800. ;
  1801. ; Stamp the 01h in globalarena for DDE handles. This is GAH_PHANTOM flag
  1802. ; which is not used any longer.
  1803. ;
  1804. ;--------------------------------------------------------------------------;
  1805. cProc SetDdeHandleFlag,<PUBLIC,FAR>
  1806. parmW handle
  1807. parmW fSet
  1808. cBegin
  1809. cCall get_arena_pointer,<handle> ; get the owner
  1810. mov es,ax
  1811. or ax,ax
  1812. jz sd_error
  1813. mov ax,fSet
  1814. or ax,ax
  1815. jz sd_unset
  1816. or es:[ga_flags], GAH_WOWDDEFREEHANDLE
  1817. jmps sd_error
  1818. sd_unset:
  1819. and es:[ga_flags], NOT GAH_WOWDDEFREEHANDLE
  1820. sd_error:
  1821. xor ax,ax
  1822. mov es,ax
  1823. cEnd
  1824. endif
  1825. sEnd CODE
  1826. end