;***************************************************** ;* ;* Memory Allocation Unit Routines ;* ;* Memory Allocation Unit ;* A Memory Allocation Unit is a contiguous ;* area of memory that is described by a MD. ;* At the beginning of this area is a Suballocation ;* table that describes areas within it that are ;* allocated or free ;* ;* +----+----+----+----+----+----+----+----+ ;* MD | Link | Start | Length | Plist | ;* +----+----+----+----+----+----+----+----+ ;* ;* Link - Link field for placing MAUs on Linked ;* lists ;* Start - Segment Address of the area covered ;* Length - Length of area ;* Plist - used for a linked list of partitions ;* that are included in this area. ;* ;* Suballocation Table ;* The m_start field is the segment ;* address of the suballocation table (offset 0). ;* The first entry of the table is special and ;* has the following format. ;* ;* +----+----+----+----+----+ ;* SAT0 |ents| reserved | ;* +----+----+----+----+----+ ;* ;* sat1_ents - number of SAT entries ;* not including SAT0 ;* Subsequent entries have the following format ;* ;* +----+----+----+----+----+ ;* SAT | Start | Length |nall| ;* +----+----+----+----+----+ ;* ;* start - start address of this contiguous ;* piece of memory ;* length - of this piece of memory ;* nall - number of times allocated ;* 0 = free 2 = share ;* ;***************************************************** sat_start equ word ptr 0 sat_length equ word ptr sat_start + word sat_nall equ byte ptr sat_length + word satlen equ sat_nall + byte ;============== maualloc_entry: ; Alloc from MAU ;============== ; Allocate a piece of memory from an MAU ; ; input: BX = address of MAU ; DX = MPB in u_wrkseg ; mpb_start = abs addr (0 = any) ; mpb_min = minimum necessary ; mpb_max = maximum wanted ; ; output: BX = 0h if success ; 0ffffh if failure ; CX = Error Code ; mpb_start = start address ; mpb_min = mcb_max = length push es ! mov es,u_wrkseg ; if absolute, see if within MAU mov si,dx ! mov cx,es:mpb_start[si] cmp cx,0 ! je maua_rel mov ax,m_start[bx] cmp cx,ax ! jb maua_err add ax,m_length[bx] cmp cx,ax ! jae maua_err maua_rel: mov ds,m_start[bx] maua_start: sub bx,bx ! mov dl,bl ;BX->SAT entry ;DL = SAT number maua_nsat: inc dl ! add bx,satlen cmp dl,.0 ! ja maua_err ;?out of table entries? cmp sat_start[bx],0 ! je maua_err ;?end of used table? cmp sat_nall[bx],0 ! jne maua_nsat ;?already allocated? mov cx,es:mpb_start[si] cmp cx,0 ! je maua_nabs ;?abs req? mov ax,sat_start[bx] cmp cx,ax ! jb maua_nsat ;?in this area? add ax,sat_length[bx] cmp cx,ax ! jae maua_nsat mov dl,.0 cmp cx,sat_start[bx] ! je maua_nabs ;?exact? sub cx,sat_start[bx] mov bx,cx ! call mau_split ;make exact jmps maua_start maua_err: mov bx,0ffffh ! mov cx,e_no_memory jmps maua_out maua_nabs: mov cx,es:mpb_min[si] mov ax,sat_length[bx] cmp cx,ax ! ja maua_nsat mov cx,es:mpb_max[si] cmp cx,ax ! jae maua_alloc cmp sat_nall[bx],0 ! je maua_splitit mov ax,es:mpb_flags[si] and ax,mf_share ! jz maua_nsat jmps maua_alloc maua_splitit: push si ! call mau_split ! pop si maua_alloc: mov ax,sat_length[bx] mov es:mpb_min[si],ax mov es:mpb_max[si],ax mov ax,sat_start[bx] mov es:mpb_start[si],ax inc sat_nall[bx] call mau_collapse sub bx,bx ! mov cx,bx jmps maua_out maua_out: mov ds,sysdat pop es ! ret ;============= maufree_entry: ; Free from MAU ;============= ; free SAT in given MAU ; input: DX = address of MAF in u_wrkseg ; output: CX = 0 if successful ; CX = 0ffffh on failure ; if CX = 0, ; BX = 0 if MAU still in use ; BX = 0ffffh if MAU is empty ; if CX = 0ffffh ; BX = 0ffffh push es ! mov es,u_wrkseg mov si,dx mov bx,es:maf_mau[si] mov ds,m_start[bx] ; ES:SI -> MAF ; DS: 0 -> SAT table sub bx,bx ! mov cx,bx mov dx,es:maf_sat[si] ; DS:BX -> current SAT ; CX = SAT entry number ; DX = MAF_SAT start mauf_nsat: add bx,satlen ! inc cx cmp cx,.0 ! ja mauf_err cmp dx,sat_start[bx] ! jne mauf_nsat cmp dx,es:maf_start[si] ! je mauf_free mov cx,es:maf_start[si] mov ax,sat_start[bx] add ax,sat_length[bx] cmp ax,cx ! jb mauf_err ; must split this SAT sub cx,dx ! call mau_split sub cx,cx ! mov bx,cx ! jmps mauf_c mauf_free: dec sat_nall[bx] mauf_c: call mau_collapse ! jmps mauf_out mauf_err: mov bx,0ffffh ! mov cx,e_no_memory mauf_out: pop es ! mov ds,sysdat ret mau_split: ;split SAT into 2 ;--------- ----------------- ; new SAT element starting at split boundary ; with nall=0, old has same nall. ; input: BX = address of SAT element ; CX = length to split at ; output: BX = address of original SAT element push bx ! push cx add bx,satlen ! call mau_insert cmp cx,0 ! pop cx pop bx ! jne maus_err ;create hole if error lea di,satlen[bx] ! mov dx,sat_length[bx] sub dx,cx ! mov sat_length[di],dx mov dx,cx ! add dx,sat_start[bx] mov sat_start[di],dx ! mov sat_nall[di],0 maus_err: mov sat_length[bx],cx ret mau_collapse: ;collapse adjacent unallocated SATs ;------------ ----------------------------------- ; collapse adjacent unallocated SATs and holes in table ; if possible ; return: BX = 0 if not empty ; = 0ffffh if empty ; CX = 0 mov bp,0ffffh ;assume empty sub bx,bx ! mov cx,bx mov di,satlen mauc_nsat: inc cx cmp cx,.0 ! jb mauc_notend mauc_done: sub cx,cx ! mov bx,bp ! ret mauc_notend: add bx,satlen ! lea di,satlen[bx] cmp sat_start[bx],0 ! je mauc_done cmp sat_start[di],0 ! je mauc_done cmp sat_nall[bx],0 ! jne mauc_notfree ;this SAT is free mov ax,sat_start[bx] ! add ax,sat_length[bx] cmp ax,sat_start[di] ! je mauc_fnohole ;followed by a hole mov ax,sat_start[di] ! sub ax,sat_start[bx] mov sat_length[bx],ax mauc_fnohole: ;free SAT., no hole cmp sat_nall[di],0 ! jne mauc_nsat ;followed by free SAT mov ax,sat_length[di] add sat_length[bx],ax push bx ! push cx mov bx,di ! call mau_release pop cx ! pop bx sub bx,satlen ! dec cx jmp mauc_nsat mauc_notfree: ;allocated SAT sub bp,bp ;not empty mov ax,sat_start[bx] ! add ax,sat_length[bx] cmp ax,sat_start[di] ! je mauc_nsat ;followed by a hole cmp sat_nall[di],0 ! je mauc_nfhole ;next SAT is allocated push bx ! push cx mov di,bx ! call mau_insert pop cx ! pop bx jmp mauc_nsat mauc_nfhole: ;Alloc SAT, followed by hole ;next SAT is free mov ax,sat_start[di] ! sub ax,sat_start[bx] sub sat_start[di],ax ! add sat_length[di],ax jmp mauc_nsat mau_release: ;----------- ; input: BX = SAT to release push es ! mov ax,ds ! mov es,ax mov ax,satlen mul byte ptr .0 push ax ! mov cx,ax ! sub cx,bx mov di,bx ! add bx,satlen mov si,bx ! rep movs al,al pop bx ! mov sat_length[bx],0 mov sat_start[bx],0 mov sat_nall[bx],0 pop es ! ret mau_insert: ;---------- ; input: BX = SAT to place new SAT in front ; output: CX = 0 if successful mov ax,satlen ! mul byte ptr .0 mov si,ax ! mov cx,0ffffh cmp sat_start[si],0 ! jne maui_r mov cx,si ! sub cx,bx dec si ! lea di,satlen[si] push es ! push ds ! pop es std ! rep movsb ! cld pop es ! sub cx,cx mov sat_start[bx],cx mov sat_length[bx],cx mov sat_nall[bx],cl maui_r: ret