Files
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

480 lines
11 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;*****************************************************
;*
;* 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