mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-25 17:34:06 +00:00
485 lines
11 KiB
Plaintext
485 lines
11 KiB
Plaintext
;*****************************************************
|
|
;*
|
|
;* MEM Entry Points
|
|
;*
|
|
;* Each process descriptor points to a linked
|
|
;* list of MDs that describe memory segments that
|
|
;* it owns. The MDs note the starting paragraph
|
|
;* and a MAU that the Memory Segment is in.
|
|
;*
|
|
;* Format of MDs on p_mem lists:
|
|
;*
|
|
;* +----+----+----+----+----+----+----+----+----+----+
|
|
;* | link | start | length | flags | mau |
|
|
;* +----+----+----+----+----+----+----+----+----+----+
|
|
;*
|
|
;* link link field for p_mem list
|
|
;* start starting paragraph of memory segment
|
|
;* length length in paragraphs of memory segment
|
|
;* flags load,code,and share as in MPB
|
|
;* mau offset of MAU in SYSDAT that segment is
|
|
;* allocated from
|
|
;*
|
|
;*****************************************************
|
|
|
|
;============
|
|
malloc_entry:
|
|
;============
|
|
; Allocate Memory - memory is allocated from MAUs.
|
|
; First we try to allocate memory from MAUs that has
|
|
; memory segments already allocated by this process.
|
|
; If that fails, we try to create a new MAU from the
|
|
; Memory Free List (MFL). If both fails, an error is
|
|
; is returned to the user.
|
|
;
|
|
; input: DX = MPB in u_wrkseg
|
|
; output: BX = 0 if successful (unused memory)
|
|
; = 1 if successful (shared code)
|
|
; = 0ffffh if failure
|
|
; CX = error code
|
|
;
|
|
; Format of MPB:
|
|
;
|
|
; +----+----+----+----+----+----+----+----+----+----+
|
|
; | start | min | max | pdadr | flags |
|
|
; +----+----+----+----+----+----+----+----+----+----+
|
|
;
|
|
; start - if non-zero, an absolute request
|
|
; min - minimum length that will satisfy the request
|
|
; max - maximum length wanted
|
|
; We will try to allocate the maximum
|
|
; but will be satisfied with as little as the
|
|
; minimum.
|
|
; pdadr - Process Descriptor to allocate memory to.
|
|
; Note - PD can not be a current process unless
|
|
; it is the calling process.
|
|
; The Calling process must explicitly release
|
|
; the memory if the PD never becomes a process.
|
|
; Otherwise, memory is released upon termination.
|
|
; If pdadr is 0, then calling process allocates
|
|
; the memory.
|
|
; flags - 00001h Load This segment initialized from
|
|
; a disk file
|
|
; 00002h Shared This is a sharable segment
|
|
; 00004h Code This is a Code segment
|
|
|
|
; Get a MD for use in the p_mem list
|
|
|
|
; DX -> MPB (u_wrkseg)
|
|
push dx ! call getmd ! pop dx ; BX -> MD
|
|
jcxz mall_gmd
|
|
mov bx,0ffffh ! ret
|
|
mall_gmd:
|
|
; fill PDADR field in case its zero
|
|
|
|
push es ! mov es,u_wrkseg ;save UDA
|
|
mov di,dx ! mov ax,es:mpb_pdadr[di]
|
|
cmp ax,0 ! jne mall_gpd
|
|
mov ax,rlr
|
|
mov es:mpb_pdadr[di],ax
|
|
mall_gpd:
|
|
pop es ;ES=UDA
|
|
cmp ax,rlr ! je mall_pdv1
|
|
|
|
push ax ! push bx
|
|
push dx ! push di
|
|
mov bx,offset thrd_spb ;ok to call sync on
|
|
mov cx,f_sync ;thread after sync-ing
|
|
call osif ;on memory
|
|
pop di ! pop dx
|
|
pop bx ! pop ax
|
|
mov si,(offset thrdrt)-p_thread
|
|
|
|
mall_pdnxt: mov si,p_thread[si]
|
|
|
|
cmp si,0 ! je mall_pdver
|
|
cmp si,ax ! jne mall_pdnxt
|
|
cmp si,rlr ! je mall_pdver
|
|
mov cx,e_active_pd
|
|
push bx ; save MD addr
|
|
mov bx,offset thrd_spb
|
|
mov cx,f_unsync
|
|
call osif
|
|
pop bx ; restore MD addr
|
|
jmp mall_err
|
|
mall_pdver:
|
|
push ax ! push bx
|
|
push dx ! push di
|
|
mov bx,offset thrd_spb
|
|
mov cx,f_unsync
|
|
call osif
|
|
pop di ! pop dx
|
|
pop bx ! pop ax
|
|
|
|
; verify MIN <= MAX
|
|
|
|
mall_pdv1:
|
|
push es ! mov es,u_wrkseg
|
|
mov cx,es:mpb_min[di]
|
|
cmp cx,es:mpb_max[di]
|
|
jbe mpb_ok
|
|
mov es:mpb_max[di],cx
|
|
mpb_ok:
|
|
|
|
; Make sure total allocation <= MMP
|
|
|
|
mov si,ax ! add si,(p_mem - ms_link)
|
|
sub cx,cx ! push si
|
|
max_chk_nxt:
|
|
mov si,ms_link[si]
|
|
cmp si,0 ! je max_chk_done
|
|
add cx,ms_length[si]
|
|
jmps max_chk_nxt
|
|
max_chk_done:
|
|
pop si ! mov ax,mmp
|
|
sub ax,cx
|
|
cmp ax,0 ! jne not_zero
|
|
no_min: pop es
|
|
mall_nomem: mov cx,e_no_memory
|
|
mall_err: call freemd ; Free the Memory Descriptor
|
|
mov bx,0ffffh ! ret ; CX=Error Code set previously
|
|
not_zero:
|
|
cmp ax,es:mpb_min[di] ! jb no_min
|
|
cmp ax,es:mpb_max[di] ! jae max_ok
|
|
mov es:mpb_max[di],ax
|
|
max_ok:
|
|
|
|
; initialize local variables
|
|
|
|
push di ! mov di,offset beststart
|
|
mov cx,11 ! sub ax,ax
|
|
mov es,sysdat
|
|
rep stosw ! pop di
|
|
|
|
sub cx,cx
|
|
pop es
|
|
; try to allocate memory
|
|
|
|
mall_next:
|
|
mov si,ms_link[si]
|
|
cmp si,0 ! je mall_ml
|
|
cmp cx,ms_mau[si] ! je mall_next
|
|
; here's a MAU we haven't tried...
|
|
; CX=last MAU tried
|
|
; DX=MPB adr in u_wrkseg
|
|
; BX=New MD
|
|
; SI=current MD
|
|
push cx ! push dx ! push bx ! push si
|
|
mov bx,ms_mau[si]
|
|
call mall_try_mau
|
|
pop si ! pop bx ! pop dx
|
|
; Plus DI=MAU address
|
|
cmp cx,0 ! pop cx ! jne mall_next
|
|
; exact allocation
|
|
; succesful allocation
|
|
jmp mall_linkit
|
|
|
|
mall_ml: ; We must create a new MAU from MFL
|
|
push bx ! push dx
|
|
mov ds,u_wrkseg
|
|
mov bx,offset mfl ! mov cx,f_mlalloc
|
|
call osif
|
|
mov ds,sysdat
|
|
;BX=MAU, (New MD,MPB on stack)
|
|
jcxz mall_ml0
|
|
pop dx ! pop bx
|
|
jmp mall_linkit
|
|
mall_ml0: ; We have a new MAU
|
|
;place MAU on MAL
|
|
mov si,mal
|
|
mov m_link[bx],si
|
|
mov mal,bx
|
|
;allocate memory
|
|
pop dx ! push dx
|
|
sub si,si
|
|
call mall_try_mau
|
|
pop dx ! pop bx
|
|
;DI=MAU, BX=New MD, DX=MPB in u_wrkseg
|
|
|
|
mall_linkit:
|
|
;BX -> MD
|
|
;DX -> MPB in u_wrkseg
|
|
|
|
cmp beststart,0 ! jne yesmem
|
|
|
|
if ccpm
|
|
jmp mall_nomem
|
|
endif
|
|
|
|
if mpm
|
|
|
|
; We couldn't find any memory ...
|
|
; lets take something off the SCL
|
|
|
|
pushf ! cli
|
|
mov di,scl
|
|
cmp di,0 ! jne take_one_off
|
|
|
|
; No where else to try, giveup.
|
|
popf ! jmp mall_nomem
|
|
|
|
; take first SHARE PD off SCL
|
|
take_one_off:
|
|
mov ax,p_thread[di]
|
|
mov scl,ax
|
|
popf
|
|
|
|
; Free its memory
|
|
; We can assume only one memory segment
|
|
|
|
push bx ! push dx
|
|
mov bx,p_mem[di]
|
|
push di ! push ds
|
|
push di ! push ms_start[bx]
|
|
push ss ! pop ds
|
|
mov dx,sp ! mov cx,f_memfree
|
|
call osif
|
|
pop ax ! pop ax
|
|
pop ds ! pop di
|
|
|
|
; There should be no error.
|
|
; Put SHARE PD on PUL
|
|
pushf ! cli
|
|
mov ax,pul
|
|
mov p_link[di],ax
|
|
mov pul,di
|
|
popf
|
|
|
|
|
|
; Let's assume we just released a partition
|
|
; and try the ML Alloc again.
|
|
|
|
pop dx ! pop bx
|
|
jmp mall_ml
|
|
endif
|
|
|
|
; We have memory ...
|
|
yesmem:
|
|
push es ! mov es,u_wrkseg
|
|
mov di,dx
|
|
mov ax,beststart
|
|
mov es:mpb_start[di],ax
|
|
mov ms_start[bx],ax
|
|
mov ax,bestlen
|
|
mov es:mpb_min[di],ax
|
|
mov es:mpb_max[di],ax
|
|
mov ms_length[bx],ax
|
|
mov ax,es:mpb_flags[di]
|
|
mov ms_flags[bx],ax
|
|
mov si,bestsi
|
|
cmp si,0 ! jne mall_l0
|
|
mov si,es:mpb_pdadr[di]
|
|
add si,(p_mem-ms_link)
|
|
mall_l0:mov ax,ms_link[si] ! mov ms_link[bx],ax
|
|
mov ms_link[si],bx
|
|
mov di,bestmau
|
|
mov ms_mau[bx],di
|
|
pop es ! sub cx,cx ! mov bx,cx ! ret
|
|
|
|
mall_try_mau:
|
|
;------------
|
|
; input: BX -> MAU
|
|
; DX -> MPB in u_wrkseg
|
|
; SI = MS Root that MAU came from
|
|
; output: CX = 0, found exact allocation
|
|
; else, exact not found
|
|
|
|
; save root,mau
|
|
mov currsi,si
|
|
mov currmau,bx
|
|
|
|
|
|
; copy user's MPB into local MPB
|
|
push dx ! push ds ! push es
|
|
mov ds,u_wrkseg
|
|
mov es,sysdat
|
|
mov si,dx ! mov di,offset currmpb
|
|
mov cx,5 ! rep movsw
|
|
pop es ! pop ds
|
|
|
|
mov dx,offset currmpb
|
|
mov cx,f_maualloc ! call osif
|
|
|
|
pop di
|
|
jcxz chkbest
|
|
ret
|
|
chkbest:
|
|
push es ! mov es,u_wrkseg
|
|
mov si,offset currmpb
|
|
mov ax,mpb_max[si]
|
|
sub cx,cx
|
|
cmp ax,es:mpb_max[di]
|
|
pop es
|
|
jz replacebest
|
|
mov cx,3 ! mov bx,currmau
|
|
mov di,si
|
|
cmp ax,bestlen ! jbe freeworst
|
|
replacebest:
|
|
mov di,offset beststart
|
|
mov bx,bestmau
|
|
call freeworst
|
|
mov si,offset currmpb
|
|
mov ax,mpb_start[si] ! mov beststart,ax
|
|
mov ax,mpb_max[si] ! mov bestlen,ax
|
|
mov ax,currmau ! mov bestmau,ax
|
|
mov ax,currsi ! mov bestsi,ax
|
|
savret: ret
|
|
freeworst: ; DI->Start, CX=Return Code, BX=MAU
|
|
cmp word ptr [di],0 ! je savret
|
|
|
|
; free worst memory
|
|
push cx ! push ds
|
|
push word ptr [di] ! push word ptr [di]
|
|
push bx ! push ss ! pop ds
|
|
mov dx,sp ! mov cx,f_maufree
|
|
call osif
|
|
|
|
|
|
; if MAU empty, free MAU
|
|
cmp cx,0 ! jne mflret
|
|
cmp bx,0ffffh ! jne mflret
|
|
pop bx ! pop ax ! pop ax ! pop ds
|
|
|
|
|
|
; take off MAL
|
|
; BX = MAU address
|
|
mov ax,bx ! mov bx,(offset mal)-m_link
|
|
mfl1: mov si,bx ! mov bx,m_link[si]
|
|
cmp bx,ax ! jne mfl1
|
|
push ax
|
|
mov ax,m_link[bx] ! mov m_link[si],ax
|
|
pop bx
|
|
; Replace into MFL
|
|
mov cx,f_mlfree
|
|
mov dx,bx ! mov bx,offset mfl
|
|
call osif ! pop cx ! ret
|
|
|
|
mflret: pop bx ! pop ax ! pop ax
|
|
pop ds ! pop cx ! ret
|
|
|
|
;===========
|
|
mfree_entry: ; 130 - Memory Free
|
|
;===========
|
|
; Free the memory segment with the given segment addr.
|
|
; input: DX = MFPB in u_wrkseg
|
|
; output: BX = 0 if successful
|
|
; = 0ffffh on failure
|
|
; CX = error code
|
|
;
|
|
; Memory Free Parameter Block (MFPB)
|
|
;
|
|
; +----+----+----+----+
|
|
; | start | pdadr |
|
|
; +----+----+----+----+
|
|
;
|
|
; start - starting paragraph of area to be freed.
|
|
; pdadr - PD to free memory from. If 0, then calling
|
|
; process. If non-zero, the PD must not be
|
|
; a current process.
|
|
|
|
push es ! mov es,u_wrkseg
|
|
mov si,dx
|
|
mov bx,es:mfpb_pd[si]
|
|
mov dx,es:mfpb_start[si]
|
|
pop es
|
|
; BX = pdadr
|
|
; DX = start paragraph
|
|
cmp bx,0 ! jne mfree_chkpd
|
|
mov bx,rlr
|
|
jmps mfree_g1
|
|
mfree_chkpd:
|
|
|
|
push bx ! push dx
|
|
mov bx,offset thrd_spb
|
|
mov cx,f_sync
|
|
call osif
|
|
pop dx ! pop bx
|
|
|
|
mov si,(offset thrdrt)-p_thread
|
|
mfree_nxtpd:
|
|
mov si,p_thread[si]
|
|
cmp si,0 ! je mfree_gotpd
|
|
cmp si,bx ! jne mfree_nxtpd
|
|
cmp si,rlr ! je mfree_gotpd
|
|
mov bx,offset thrd_spb
|
|
mov cx,f_unsync
|
|
call osif
|
|
mov bx,0ffffh
|
|
mov cx,e_active_pd
|
|
ret
|
|
mfree_gotpd:
|
|
push bx ! push dx
|
|
mov bx,offset thrd_spb
|
|
mov cx,f_unsync
|
|
call osif
|
|
pop dx ! pop bx
|
|
|
|
mfree_g1:
|
|
lea si,p_mem[bx]
|
|
mfree_next:
|
|
mov bx,si ! mov si,ms_link[bx]
|
|
cmp si,0 ! je mfree_err
|
|
cmp ms_start[si],dx ! je mfree_it
|
|
ja mfree_next
|
|
mov ax,ms_start[si]
|
|
add ax,ms_length[si]
|
|
cmp ax,dx ! jbe mfree_next
|
|
push dx ! push si
|
|
call mfree_it
|
|
pop si ! pop dx
|
|
cmp cx,0 ! jne mfree_next
|
|
mfree_exit:
|
|
sub bx,bx ! mov cx,bx ! ret
|
|
mfree_err:
|
|
mov bx,0ffffh ! mov cx,e_no_memory
|
|
ret
|
|
|
|
mfree_it:
|
|
;--------
|
|
; input: BX = root
|
|
; SI = MD ([bx])
|
|
; DX = segment to free
|
|
; output: BX = 0,0ffffh (success,failure)
|
|
; CX = Error Code
|
|
|
|
push bx ! push si ! push dx
|
|
;push MAF structure
|
|
push dx ! push ms_start[si]
|
|
push ms_mau[si]
|
|
mov dx,sp ! push ss ! pop ds
|
|
mov cx,f_maufree ! call osif
|
|
mov bp,bx ;if bp=0,MAU not empty
|
|
mov ds,sysdat
|
|
;pop MAF structure
|
|
pop ax ! pop ax ! pop ax
|
|
pop dx ! pop si ! pop bx
|
|
;DX=segment to free
|
|
;BX=root
|
|
;SI=MD ( [BX] )
|
|
cmp cx,0
|
|
jne mfree_err
|
|
cmp dx,ms_start[si] ! je mfree_off
|
|
;decrease length
|
|
sub dx,ms_start[si]
|
|
mov ms_length[si],dx
|
|
mfree_r:
|
|
jmps mfree_exit
|
|
;take off p_mem list
|
|
mfree_off: mov ax,ms_link[si] ! mov ms_link[bx],ax
|
|
;free MD
|
|
push ms_mau[si] ! push bp
|
|
mov bx,si ! call freemd
|
|
pop bp ! pop dx
|
|
;free MAU if empty
|
|
cmp bp,0 ! je mfree_exit
|
|
;find it on MAL
|
|
mov di,(offset mal)-m_link
|
|
mfree_nmal: mov si,di ! mov di,m_link[si]
|
|
cmp di,dx ! jne mfree_nmal
|
|
;release from MAL
|
|
mov ax,m_link[di] ! mov m_link[si],ax
|
|
mov m_link[di],0
|
|
;release to MFL
|
|
mov bx,offset mfl ! mov cx,f_mlfree
|
|
jmp osif
|