]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/MEMM/MEMM/ALLOCMEM.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / MEMM / MEMM / ALLOCMEM.ASM
1
2
3 page 58,132
4 ;******************************************************************************
5 title ALLOCMEM - allocate memory for EMM Pages Pool
6 ;******************************************************************************
7 ;
8 ; (C) Copyright MICROSOFT Corp. 1986
9 ;
10 ; Title: MEMM.EXE - MICROSOFT Expanded Memory Manager 386 Driver
11 ;
12 ; Module: AllocMem - allocate memory for EMM Pages Pool
13 ;
14 ; Version: 0.05
15 ;
16 ; Date: May 24,1986
17 ;
18 ; Author:
19 ;
20 ;******************************************************************************
21 ;
22 ; Change Log:
23 ;
24 ; DATE REVISION Description
25 ; -------- -------- --------------------------------------------
26 ; 05/24/86 Original
27 ; 06/28/86 0.02 code read changes to various routines
28 ; 07/05/86 0.04 Changes due to segment re-org
29 ; 07/06/86 0.04 Made EXT_RES a define
30 ; 07/06/86 0.04 Changed to DGROUP assume
31 ; 07/10/86 0.05 added NOHIMEM flag
32 ; 06/02/88 pc change from VDISK allocation to INT-15 method
33 ; 07/26/88 isp completed work in changing over to int15 alloc
34 ;
35 ;******************************************************************************
36 ; Functional Description:
37 ; This module allocates the pool of memory to be used for the pool of
38 ; EMM pages. The pool of memory is allocated from "high" extended
39 ; memory (located in the 15-16 Meg range)and from "regular" extended memory
40 ; (starting at 1 Meg). This module attempts to allocate high memory first,
41 ; then extended memory. When allocating memory from either area, the memory
42 ; is allocated in 16k byte blocks which are aligned on a physical 4k boundary.
43 ; This module attempts to allocate extended memory using the int15 allocation
44 ; scheme.
45 ;
46 ; NOTE: if this module is compiled with NOHIMEM defined, then
47 ; this code will not attempt to use the OEM specific
48 ; "high" memory.
49 ;
50 ;******************************************************************************
51 .lfcond
52 .386p
53 ;
54 ;
55 ;******************************************************************************
56 ; P U B L I C D E C L A R A T I O N S
57 ;******************************************************************************
58 ;
59 public AllocMem
60 public DeallocMem
61 public xbase_addr_l ; data publics
62 public xbase_addr_h
63 public ext_size
64 public sys_size
65
66 page
67 ;******************************************************************************
68 ; L O C A L C O N S T A N T S
69 ;******************************************************************************
70 ;
71 include vdmseg.inc
72 include vdmsel.inc
73 include emm386.inc
74 include driver.equ
75 include driver.str
76 include romxbios.equ
77 include desc.inc
78 include ascii_sm.equ
79 include oemdep.inc
80 include emmdef.inc
81 ;
82 EXT_RES equ 10h ; must be a power of 2.
83 ;
84 GET_VER equ 30h ; get dos version number
85 MSDOS equ 21h ; DOS interrupt
86 ;
87 FALSE equ 0
88 TRUE equ not FALSE
89
90 ;******************************************************************************
91 ; E X T E R N A L R E F E R E N C E S
92 ;******************************************************************************
93 ;
94 _DATA segment
95
96 extrn dos_version:byte
97 extrn pool_size:word
98 extrn msg_flag:word
99
100 ifndef NOHIMEM
101 extrn hi_size:word ; size of hi memory in kbytes
102 extrn hi_alloc:word ; hi memory allocated
103 extrn hisys_alloc:word ; hi system memory allocated
104 ; in 4k byte blocks
105 endif
106
107 _DATA ends
108
109
110 LAST segment
111 extrn mappable_segs:byte ; mappable segment map
112 extrn set_ext:near ; routine to set amount of ext mem
113 ; reported by int15 handler
114 extrn memreq:near ; memory requirements for move
115 extrn pool_initialise:near ; initialise the pool of extended
116 ; memory
117
118 ifndef NOHIMEM
119 extrn hbuf_chk:near
120 extrn HiAlloc:near
121 extrn HiMod:near
122 endif
123 LAST ends
124 ;
125 page
126 ;******************************************************************************
127 ; S E G M E N T D E F I N I T I O N
128 ;******************************************************************************
129
130 page
131 ;******************************************************************************
132 ; Data segment
133 ;******************************************************************************
134 _DATA segment
135 ASSUME CS:DGROUP,DS:DGROUP
136
137 xbase_addr_l dw 0000h ; 24 bit address of beginning of
138 xbase_addr_h db 10h ; extended mem pool of EMM pages. (1M initially)
139 ext_size dw 0 ; size of extended memory allocated in kb
140 sys_size dw 0 ; size of system memory from 4000h in emm pool
141 total_mem dw 0 ; size of extended memory available at any moment
142 avail_mem dw 0 ; total size (hi+ext) available for MEMM
143 ;
144
145 _DATA ends
146
147
148 ;******************************************************************************
149 ;
150 ; Code Segment
151 ;
152 ;******************************************************************************
153 ;
154 LAST segment
155 assume cs:LAST, ds:DGROUP, es:DGROUP
156
157 page
158 ;******************************************************************************
159 ;
160 ; AllocMem Allocate Extended memory for MEMM using the int15
161 ; method of allocating extended memory.
162 ;
163 ; description:
164 ; This routine attempts to get the requested extended memory
165 ; from two sources: a) the himem area (just below 16M) first
166 ; and if not enough b) extended memory. Extended memory is
167 ; allocated using the int15 scheme. We do not care for
168 ; compatibility with vdisk. The memory we allocate either in
169 ; himem area or in extended memory must start at a 4k boundary
170 ; because we are using them as pages.
171 ;
172 ; entry: DS pts to DGROUP
173 ; DGROUP:[pool_size] = mem size requested (kbytes)
174 ;
175 ; exit: If extended memory pool space is not available then
176 ; set MEM_ERR_MSG bit in DGROUP:[msg_flag] and exit.
177 ;
178 ;
179 ; used: none
180 ;
181 ; stack:
182 ;
183 ; modified: ISP 07/26/88 Changed to a simple check for availability
184 ; of hi / ext memory and allocation of
185 ; of appropriate amounts of each.
186 ;
187 ;
188 ;******************************************************************************
189 ;
190 AllocMem proc near
191 ;
192 push ax
193 push bx
194 push cx
195 push dx
196 push es
197
198
199 ;
200 ; 1. Check available hi/extended memory
201 ;
202 AM_getmem:
203 call xbuf_chk
204 test [msg_flag],MEM_ERR_MSG ;Q: memory error found ?
205 jz AM_nba ; N: continue with allocation
206 jmp AM_exit ; Y: exit
207 ;
208 ; 2. Allocate extended memory
209 ;
210 AM_nba:
211 call ExtAlloc ; alloc ext mem
212
213 ifndef NOHIMEM ; if HI memory in this model
214 ;
215 ; 3. Allocate Hi memory
216 ;
217 AM_halloc:
218 call HiAlloc ; Allocate hi memory
219 jnc AM_exit ; no error
220 or [msg_flag],MEM_ERR_MSG ; memory error
221 endif
222
223 ;
224 ; 4. Allocate system memory
225 ;
226 call SysAlloc
227 ;
228 AM_exit:
229 pop es
230 pop dx
231 pop cx
232 pop bx
233 pop ax
234 ret
235 AllocMem endp ; End of procedure
236 ;
237 page
238 ;******************************************************************************
239 ;
240 ; DeallocMem Deallocate Extended memory for MEMM using the int15
241 ; method of allocating extended memory. Note that since
242 ; we call this routine when we haven't already installed tc.)
243 ; the int15 handler we really don't need to do anything
244 ; as far as the regular extended memory is concerned. We
245 ; only need to deallocate hi memory if allocated.
246 ;
247 ; entry: DS pts to DGROUP
248 ; DGROUP:[hi_alloc] amount of hi memory to deallocate
249 ;
250 ; used: none
251 ;
252 ; stack:
253 ;
254 ; modif: 7/26/88 ISP Removed VDISK deallocation of extended memory
255 ;******************************************************************************
256 ;
257 DeallocMem proc near
258 push ax
259 push bx
260 push cx
261 push dx
262 push si
263 push es
264 ;
265 ifndef NOHIMEM ; if high memory in this model
266 mov ax,[hi_alloc] ; get hi memory to deallocate
267 or ax,ax ; q: did we ever get any?
268 jz deall_hisys ; n: check hi system memory
269 neg ax ; # of 16 byte pieces to remove
270 mov [hi_alloc],0 ; make sure we never do it again
271 deall_hisys:
272 mov bx,[hisys_alloc] ; get hi system memory to deallocate
273 neg bx ; update by a negative amount
274 add bx,ax ; q: any hi or hisys to deallocate?
275 jz deall_ext ; n: don't waste our time doing it
276 sub bx,ax ; y: straighten our regs out
277 mov [hisys_alloc],0 ; make sure we don't do it again
278 call HImod ; modify memory. ignore any errors
279 deall_ext:
280 ;
281 endif ; end of conditional
282 pop es
283 pop si
284 pop dx
285 pop cx
286 pop bx
287 pop ax
288 ;
289 ret
290 DeallocMem endp
291 ;
292 page
293 ;******************************************************************************
294 ;
295 ; xbuf_chk Extended memory pool check.
296 ; Check 1) for previously loaded MEMM,VDISKs in extended memory
297 ; 2) available memory pool space. (hi memory and extended)
298 ;
299 ; entry: DS = DGROUP
300 ; DGROUP:[pool_size] = mem size requested (kbytes)
301 ;
302 ;
303 ; exit: If hi memory pool space is available then
304 ;
305 ; DGROUP:[hi_size] = hi memory size allocated (kbytes).
306 ;
307 ; If extended memory pool space is necessary and available then
308 ;
309 ; DGROUP:[xbase_addr_h] and DGROUP:[xbase_addr_l] contain the
310 ; starting 24-bit address of MEMM extended memory pool.
311 ;
312 ; DGROUP:[pool_size] = mem size ALLOCATED (kbytes)
313 ; DGROUP:[total_mem] = total extended memory left after allocation
314 ; DGROUP:[avail_mem] = available memory for MEMM.
315 ; DGROUP:[ext_size] = extended memory size allocated (kbytes)
316 ;
317 ; If hi/extended memory pool space is not available then
318 ; set MEM_ERR_MSG bit in DGROUP:[msg_flag] and exit.
319 ;
320 ; used: none
321 ;
322 ; stack:
323 ;
324 ; modified: ISP 07/26/88 int15 allocation requires different check
325 ; on extended memory. substancial rewrite.
326 ;******************************************************************************
327 ;
328 xbuf_chk proc near
329 ;
330 push ax
331 push bx
332 push cx
333 push dx
334 push di
335 ;
336 ; determine amount of extended memory and store it in total_mem
337 ;
338 mov ah,EXT_MEM ; function request - ext mem data
339 clc ; clear carry flag
340 int XBIOS ;Q: extended memory supported ?
341 ;
342 jnc store_ext ; Y: go to store the amount got
343 xor ax,ax ; N: Assume zero extended memory
344 store_ext:
345 mov [total_mem],ax
346 ;
347 ifndef NOHIMEM ; if high memory in this model
348 ;
349 ; check for hi memory
350 ;
351 call hbuf_chk ; get available hi memory in AX
352 jc xb_NoHiMem
353 mov [hi_size],ax ; save it
354 mov [avail_mem],ax ; update available memory
355 xb_NoHiMem:
356 mov ax,[pool_size]
357 cmp ax,[hi_size] ; q: enough?
358 ja get_ext ; n: try extended memory
359 mov [hi_size],ax ; y: just use enough
360 jmp x_buf_exit ; and exit
361 endif
362
363 get_ext:
364 mov ax,[total_mem] ; get size of extended memory available
365 ; Y: how much there ?
366 ;
367 ; we have to reserve enough memory here to ship the segments up hi.
368 ;
369 call memreq ; get memory requirements for our o
370 ; our grand operation in cx in K
371 cmp ax,cx ; lets see if we can satisfy
372 jbe x_buf_no_install ; if not we shan't install memm
373
374 push ax
375 sub ax,cx
376 cmp ax,64 + 64 ; we should try to leave enough memory
377 ; for himem and atleast four pages of
378 ; expanded memory.
379 pop ax
380 jbe x_buf_no_install ; if we don't have enough for this we
381 ; shouldn't install memm
382 ;
383 ; we can now get memory to shift things up. and intialise the manager of
384 ; this pool.
385 ;
386 sub ax,cx ; ax = start of this pool as an offset
387 ; in K from 1M
388 ; cx = size in K of this pool
389 call pool_initialise ; intialise the pool
390 or ax,ax ;Q: any extended memory ?
391 jz x_buf_2 ; N: If none go to set buf adj or no
392 ; memory error
393 ; ; Y: continue to process
394 ;
395 mov bx,[pool_size] ; get size requested
396 ;
397 ifndef NOHIMEM ; if high memory in this model
398 sub bx,[hi_size] ; adjust by the size already allocated
399 endif ; from the high memory
400
401 and ax,0fff0h ; round to 16k boundary
402 ;
403 ; it is necessary to support himem. So if we have a 64k block at 1M we
404 ; should leave it for himem. The himem we are talking about here is the
405 ; EMS 4.1 standard himem at 1M
406 ;
407 ; initialise reserved memory for himem
408 ;
409 xor cx,cx ; amount reserved for himem
410 ;
411 ; see if we have 64k available for himem
412 ;
413 cmp ax,64 ; Q:do we have 64k?
414 jb no_himem_alloc ; N: we reserve nothing for himem
415 ; Y: we should reserve 64k for himem
416 ;
417 ; reserve 64k for himem
418 ;
419 mov cx,64
420 sub ax,cx
421 ;
422 no_himem_alloc:
423 ;
424 cmp ax,bx ; compare amount available to size needed
425 jae enough_mem ; Y: fine
426 mov bx,ax ; N: adjust size reuested to size avail
427 enough_mem:
428 ;
429 ; add back the memory reserved for himem as this figures in the size of
430 ; free extended memory
431 ;
432 add ax,cx ; adjust size to include amnt res. himem
433 sub ax,bx ; adjust the size of extended memory
434 ; after allocation
435 mov [total_mem],ax ; store size of extended mem available
436 ;
437 add [avail_mem],bx ; add memory available to memory pool
438 mov [ext_size],bx ; and indicate size allocated
439 ;
440 ; find the start address of extended memory allocated
441 ;
442 mov cx,1024 ; kb multiplier
443 mul cx ; dx:ax = ax*cx
444 add [xbase_addr_l],ax ; adjsut starting address of allocated mem
445 adc [xbase_addr_h],dl ; higher byte of 24 bit address
446 ;
447 x_buf_2:
448 ;
449 mov ax,[avail_mem] ; ax == Available memory
450 cmp ax,[pool_size] ; Q: Extended memory available?
451 jnb x_buf_exit ; Y: Go to finish
452 ;
453 not_enough:
454 or ax,ax ; Q: Any extended memory available?
455 jz x_buf_no_install ; N: Set error flag and exit
456 mov [pool_size],ax ; Y: Set pool_size to remaining memory
457 or [msg_flag],SIZE_ADJ_MSG ; Set buffer adjusted message bit
458 jmp short x_buf_exit ; And jump to exit
459 ;
460 x_buf_no_install:
461 or [msg_flag],MEM_ERR_MSG ; memory error found in x_bufchk
462 ;
463 x_buf_exit:
464 pop di
465 pop dx
466 pop cx
467 pop bx
468 pop ax
469 ret ; *** return ***
470 ;
471 xbuf_chk endp
472 ;
473 page
474 ;******************************************************************************
475 ;
476 ; ExtAlloc - allocate extended memory - update break address for ext. mem.
477 ;
478 ; entry: DS pts to DGROUP
479 ;
480 ; exit: extended memory size
481 ;
482 ; used: none. int15 size reported by int 15 handler in MEMM adjusted.
483 ;
484 ; stack:
485 ;
486 ; modified: ISP 07/26/88 Substancially simplified. For int15 scheme
487 ; allocation is by lowering the size of int15
488 ; reported extended memory size.
489 ;
490 ;******************************************************************************
491 ExtAlloc proc near
492 ;
493 mov bx,[total_mem] ;size left after allocation to MEMM
494 call set_ext ; set this size in the int15 handler
495 ret
496 ;
497 ExtAlloc endp
498 ;
499 ;******************************************************************************
500 ;
501 ; SysAlloc - allocate extended memory - update break address for ext. mem.
502 ;
503 ; entry: DS pts to DGROUP
504 ;
505 ; exit: system memory size
506 ;
507 ; used: none.
508 ;
509 ; stack:
510 ;
511 ; written: ISP 07/28/88 This allocates the system memory from 0000H
512 ; to A000h to the EMM pool. This is for the LIM
513 ; 4.0 implementation.
514 ;
515 ;******************************************************************************
516
517 SysAlloc proc near
518 ;
519 push ax
520 push bx
521 push cx
522 ;
523 ; find end of memory reported by bios int 12 and round this to upper 16k.
524 ;
525 int 12h
526 add ax,0000fh ;
527 and ax,0fff0h ; round it 16k figure
528 ;
529 ; convert this to the a page #
530 ;
531 shr ax, 4 ; number of 16k pages
532 ;
533 ; start search for pages which can be reclaimed from the system mem. region
534 ;
535 mov cx,ax ; number of pages from pg0 to be examined
536 mov [sys_size],0 ; initialise the system memory allocate
537 xor bx,bx ; page #
538
539 jcxz find_sys_done
540 find_sys_page:
541 cmp cs:mappable_segs[bx], PAGE_MAPPABLE
542 jne find_next_sys
543 add [sys_size],16 ; page found add 16k to system mem size
544 find_next_sys:
545 inc bx
546 loop find_sys_page
547 find_sys_done:
548
549 mov ax,[sys_size] ; find the total memory found
550 add [pool_size],ax ; add this to the pool size
551
552 ;
553 pop cx
554 pop bx
555 pop ax
556 ret
557
558 SysAlloc endp
559
560
561
562 LAST ends ; End of segment
563 ;
564 end ; End of module
565 \1a
566 \1a
567 \1a