⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rxdosmem.asm

📁 dos source
💻 ASM
📖 第 1 页 / 共 3 页
字号:
        ;                                                               ;
        ;  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 + -