📄 rxdosmem.asm
字号:
; ;
; bx # paragraphs of memory requested ;
; ;
; Returns: ;
; ax segment address of allocated memory block ;
; dx size of largest block of memory available in ;
; paragraphs, if allocation fails. ;
;...............................................................;
_allocateUpperMB:
stc
ret
test word ptr [ _RxDOS_AllocStrategy ], (_MEM_FIRSTFIT_HIGH + _MEM_FIRSTFIT_HIGHONLY )
jnz _allocateUpperMB_14 ; if search upper memory blocks -->
_allocateUpperMB_12:
xor dx, dx
SetError pexterrNotEnoughMemory
ret
_allocateUpperMB_14:
mov ax, _RxDOS_HIGHMEMBLOCK
call _localAreaAllocateMemory
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Allocate Conventional Memory Blocks ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; bx # paragraphs of memory requested ;
; ;
; Returns: ;
; ax segment address of allocated memory block ;
; dx size of largest block of memory available in ;
; paragraphs, if allocation fails. ;
;...............................................................;
_allocateConvMB:
test word ptr [ _RxDOS_AllocStrategy ], (_MEM_FIRSTFIT_HIGHONLY )
jz _allocateConvMB_14 ; if search conv memory blocks -->
_allocateConvMB_12:
; xor dx, dx
; SetError pexterrNotEnoughMemory
; ret
_allocateConvMB_14:
call _collectMemoryBlocks ; collect free blocks
mov ax, word ptr ss:[ _RxDOS_pStartMemBlock ]
call _localAreaAllocateMemory
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Local Zone Memory Allocation ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; ax paragraph to begin search ;
; bx # paragraphs of memory requested ;
; ;
; Returns: ;
; ax segment address of allocated memory block ;
; bx size of largest block of memory available in ;
; paragraphs, if allocation fails. ;
;...............................................................;
_localAreaAllocateMemory:
Entry
def _bestFit, 0000 ; segment pointer to best fit
def _lastFit, 0000 ; segment pointer to last fit
def _sizeFirstBlock ; size of first block
def _sizeSecondBlock ; size of second block
def _returnSegmentAddress ; return segment address
def _firstSegmentAddress ; first seg
def _secondSegmentAddress ; second seg
push ds
push es ; save segment registers
or ax, ax ; zero if no mem allocated
jnz _allocMem_10 ; mem list available -->
xor dx, dx ; no memory available
SetError pexterrNotEnoughMemory, _allocMem_44 ; error -->
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; scan memory blocks
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_allocMem_10:
cli ; prevent interrupts
xor dx, dx ; largest available
mov cx, 0ffffh ; best fit
_allocMem_12:
mov es, ax ; point to memory seg
cmp byte ptr es:[ _memSignature ], _RxDOS_MEMSIGNATURE
jz _allocMem_14 ; if valid arena -->
cmp byte ptr es:[ _memSignature ], _RxDOS_ENDSIGNATURE
jz _allocMem_14 ; if valid arena -->
SetError pexterrInvalidBlock, _allocMem_44 ; else, if error -->
_allocMem_14:
cmp word ptr es:[ _memParent ], 0000 ; 0000 for parent means its free
jnz _allocMem_20 ; not a free block -->
mov si, word ptr es:[ _memAlloc ] ; get available space
sub si, bx ; is block within allocation size ?
jc _allocMem_16 ; no -->
storarg _lastFit, ax ; seg address of last fit
test word ptr [ _RxDOS_AllocStrategy ], _MEM_FIRSTFIT_STRATEGY
jz _allocMem_30 ; ok to allocate this block ->
cmp cx, si ; is this block a better fit ?
jc _allocMem_16 ; not a better strategy -->
mov cx, si ; else save fit
storarg _bestFit, ax ; seg address of best fit
_allocMem_16:
cmp dx, word ptr es:[ _memAlloc ] ; larger block ?
jnc _allocMem_20 ; no -->
mov dx, word ptr es:[ _memAlloc ] ; get size
_allocMem_20:
inc ax
add ax, word ptr es:[ _memAlloc ]
cmp byte ptr es:[ _memSignature ], _RxDOS_ENDSIGNATURE
jnz _allocMem_12 ; not at end yet -->
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; available block not found or allocation deferred to here
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
getarg ax, _bestFit
test word ptr [ _RxDOS_AllocStrategy ], _MEM_BESTFIT_STRATEGY
jnz _allocMem_24 ; if best fit -->
getarg ax, _lastFit
test word ptr [ _RxDOS_AllocStrategy ], _MEM_LASTFIT_STRATEGY
jz _allocMem_26 ; if not last fit -->
_allocMem_24:
or ax, ax ; determine if no allocation
jnz _allocMem_30 ; if block available -->
_allocMem_26:
SetError pexterrNotEnoughMemory, _allocMem_44 ; error exit -->
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Allocate block.
;
; es points to free block from where to allocate
; bx allocation size
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_allocMem_30:
mov es, ax ;
storarg _returnSegmentAddress, es ; save this address
mov dl, byte ptr es:[ _memSignature ] ; current block signature
mov ax, word ptr es:[ _memAlloc ] ; get allocation
sub ax, bx ; this is remaining alloc balance
jz _allocMem_38 ; if exact fit -->
dec ax ; make room for second mem control block
mov cx, es
add cx, ax ; where next block will be if high
inc cx ; adjust for next block header
storarg _sizeFirstBlock, ax ; first block size, assume last fit
storarg _sizeSecondBlock, bx ; second block size, assume last fit
storarg _returnSegmentAddress, cx
test word ptr [ _RxDOS_AllocStrategy ], _MEM_LASTFIT_STRATEGY
jnz _allocMem_32 ; if allocate last fit -->
mov cx, es
add cx, bx ; space we'll need
inc cx ; where next block will be
storarg _sizeFirstBlock, bx ; first block size, assume other fit
storarg _sizeSecondBlock, ax ; second block size, assume other fit
storarg _returnSegmentAddress, es
_allocMem_32:
storarg _firstSegmentAddress, es
storarg _secondSegmentAddress, cx
push dx ; current block signature
mov es, cx ; create a block here
xor bx, bx ; this block is free
getarg ax, _sizeSecondBlock ; second block size
call _initializeMemoryBlock ; initialize memory block.
pop dx
mov byte ptr es:[ _memSignature ], dl ; save real signature
getarg es, _firstSegmentAddress
getarg bx, _sizeFirstBlock ; first block size
mov word ptr es:[ _memAlloc ], bx ; allocate what we need
mov byte ptr es:[ _memSignature ], _RxDOS_MEMSIGNATURE
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; update old mem control block
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_allocMem_38:
getarg es, _returnSegmentAddress ; get return seg address
mov cx, word ptr ss:[ _RxDOS_CurrentPSP ]
or cx, cx
jnz _allocMem_40
mov cx, _RxDOS_PARENT_SIGNATURE ; system block
_allocMem_40:
mov word ptr es:[ _memParent ], cx ; current owner
mov dx, word ptr es:[ _memAlloc ] ; allocated size
mov ax, es
inc ax ; seg address of data
clc ; no carry.
_allocMem_44:
pop es ; restore segment registers
pop ds
sti
Return
RxDOS ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -