File: mem.asm - Tab length: 1 2 4 8 - Lines: on off - No wrap: on off

;===============================================================================
;
;   FreeObjectHandles
;
;   Free all handles used while assembling a source
;
;   in  fp  Stack frame
;
;   out nothing
;
;   destroy d0-d2/a0-a1
;
;===============================================================================

FreeObjectHandles:
    move.w  BIN_HD(fp),d0
    bsr FreeHandle
    clr.w   BIN_HD(fp)

    move.w  LABELS_HD(fp),d0
    bsr.s   FreeHandle
    clr.w   LABELS_HD(fp)

    rts


;===============================================================================
;
;   FreeHandle
;
;   Free an handle, deleting the file if it belongs to one
;   Return without error if Handle is H_NULL
;
;   in  d0.w    Handle
;       fp  Stack frame
;
;   out nothing
;
;   destroy d0-d2/a0-a1
;
;===============================================================================

FreeHandle:
    move.w  d0,-(sp)
    beq.s    \End
    RAMT    RAM_kernel::Hd2Sym
    move.l  a0,d0
    bne.s   \FreeFile
        ROMT    HeapFree    ; No symbol associated to this handle, free it
        bra.s   \End
\FreeFile:              ; A file is associated to the handle, its SYM_ENTRY is at a0
    pea (a0)
    jsr UNLINK(fp)
    addq.l  #4,sp
\End:   addq.l  #2,sp
    rts


;===============================================================================
;
;   AllocHandle
;
;   Allocate an handle on the heap
;   Will call NeedRAM if first attempt fails. NeedRAM checks is swapping is allowed
;   Will call MainExit if the handle could not be allocated
;
;   in  d0.l    size
;       fp  Stack frame
;
;   out d0.w    handle
;       a0  ptr to the handle
;
;   destroy d0-d2/a0-a1
;
;===============================================================================

AllocHandle:
    move.l  d0,-(sp)
    move.l  d0,-(sp)
    ROMT    HeapAlloc
    addq.l  #4,sp
    tst.w   d0
    bne.s   \End
        moveq.l #0,d0       ; We can archive all
        bsr NeedRAM
        ROMT    HeapAlloc
        tst.w   d0
        bne.s   \End
            move.w  #ERROR_MEMORY,ERROR(fp)
            pea StrErrorMemory(pc)
            bsr PrintToStderr
            bra MainExit
\End:   movea.w d0,a0
    trap    #3
    addq.l  #4,sp
    rts


;===============================================================================
;
;   ReallocHandle
;
;   Reallocate an handle on the heap
;
;   SwapOut is automatically called for this handle
;   Call NeedRAM if first attempt fails. NeedRAM checks is swapping is allowed
;   Call MainExit if the handle could not be allocated
;
;   in  d0.l    size
;       d1.w    handle
;       fp  Stack frame
;
;   out d0.w    handle
;       a0  ptr to the handle
;
;   destroy d0-d2/a0-a1
;===============================================================================

ReallocHandle:
    move.l  d0,-(sp)
    move.w  d1,-(sp)
    move.l  d0,-(sp)
    move.w  d1,-(sp)

    move.w  d1,d0
    bsr SwapOut

    jsr REALLOC(fp)     ; Use Pedrom's realloc to allow files larger than 64 kb
    addq.l  #6,sp
    tst.w   d0
    bne.s   \End
        move.w  (sp),d0     ; This handle musn't be swapped !
        bsr NeedRAM
        jsr REALLOC(fp)
        tst.w   d0
        bne.s   \End
            move.w  #ERROR_MEMORY,ERROR(fp)
            pea StrErrorMemory(pc)
            bsr PrintToStderr
            bra MainExit
\End:   movea.w d0,a0
    trap    #3
    addq.l  #6,sp
    rts


;===============================================================================
;
;   NeedRAM
;
;   Swap all possible data in flash, if allowed by the flag
;   This function is called only by AllocHandle and ReallocHandle
;   It won't throw an error if nothing can be swapped, calling functions will do that
;
;   in  d0.w    Handle which musn't be swapped in case of reallocation
;           Set to 0 by swapout to prevent a random file to be not swapped in
;       fp  Stack frame
;
;   out nothing
;
;   destroy nothing
;
;===============================================================================

NeedRAM:
    movem.l d0-d5/a0-a1,-(sp)
    move.w  d0,d3

    ;----------------------------------------------------------------------
    ;   Check if swapping is allowed
    ;----------------------------------------------------------------------

    movea.l CURRENT_FLAGS_PTR(fp),a0
    move.l  (a0),d0
    btst.l  #BIT_SWAP,d0
    beq.s   \End

    ;----------------------------------------------------------------------
    ;   Try to swap all availables handles and files
    ;   It doesn't matter if all files are not really put in flash, the
    ;   next (re)allocation will fail, that's all.
    ;   So don't check if something is really performed
    ;----------------------------------------------------------------------

    ;----------------------------------------------------------------------
    ;   Swap sources files
    ;----------------------------------------------------------------------

    move.w  FILES_LIST_HD(fp),d4
    moveq.l #0,d5

\Loop:  movea.w d4,a0
    trap    #3
    cmp.w   (a0)+,d5
    beq.s   \EndLoop
        move.w  d5,d0
        mulu.w  #FILE.sizeof,d0
        move.w  FILE.Handle(a0,d0.l),d0 ; SwapIn () needs the Z-Flag to be set if the handle exists, so don't change that !
        bsr.s   \SwapIn
        addq.w  #1,d5
        bra.s   \Loop
\EndLoop:

    ;----------------------------------------------------------------------
    ;   Swap objects handles
    ;----------------------------------------------------------------------

    move.w  FILES_LIST_HD(fp),d0
    bsr.s   \SwapIn             ; SwapIn () needs the Z-Flag to be set if the handle exists, so don't change that !

    move.w  BIN_HD(fp),d0
    bsr.s   \SwapIn

    move.w  LABELS_HD(fp),d0
    bsr.s   \SwapIn

\End:   movem.l (sp)+,d0-d5/a0-a1
    rts


;-------------------------------------------------------------------------------
;   Swap a file :
;   - chekc that the handle exists
;   - check that the handle mustn't be kept in RAM
;   -   get a tmp filename if the handle doesn't belong to a file
;   -   create a file and give it the handle
;   - archive the file
;
;   This function is called only by NeedRAM
;-------------------------------------------------------------------------------

\SwapIn:
    beq.s   \NoSwapIn           ; Handle not created yep (Z-flag already set)
    cmp.w   d0,d3               ; Handle currently reallocated : don't swap it
    beq.s   \NoSwapIn
        lea -18(sp),sp      ; Frame buffer for pdtlib::Hd2FullName
        movea.l sp,a0
        move.w  d0,d2           ; Save handle
        jsr HD_2_FULL_NAME(fp)
        tst.w   d0
        bne.s   \ArchiveFile        ; This handle already belongs to a file
            move.w  d2,-(sp)    ; Save Hd
            suba.l  a0,a0       ; Use PedroM internal buffer
            jsr TMPNAM(fp)  ; We don't care about the filename itself and don't have to save it
            move.w  (sp)+,d0    ; Hd
            pea (a0)        ; Save filename
            jsr CREATE_FILE(fp)
            movea.l (sp)+,a0    ; Filename
            tst.w   d0
            beq.s   \Fail

\ArchiveFile:   jsr ARCHIVE_FILE(fp)
\Fail:      lea 18(sp),sp
\NoSwapIn:
    rts


;===============================================================================
;
;   SwapOut
;
;   Swap an handle in RAM. If it fails, call NeedRAM, then retry.
;   If it fails again, throw an error and call Main Exit
;
;   in  d0.w    Handle which must be swapped in RAM
;       fp  Stack frame
;
;   out nothing
;
;   destroy nothing
;
;===============================================================================

SwapOut:
    movem.l d0-d3/a0-a2,-(sp)
    move.w  d0,d3

    ;----------------------------------------------------------------------
    ;   Check if the file is already in RAM
    ;----------------------------------------------------------------------

    movea.w d0,a0
    trap    #3
    cmpa.l  ROM_BASE(fp),a0
    bcs.s   \End            ; Already in RAM

    ;----------------------------------------------------------------------
    ;   Try twice to pop in RAM. Call NeedRAM if first attempt fails
    ;----------------------------------------------------------------------

    bsr.s   \Unarchive
    bne.s   \End
    bsr NeedRAM         ; d0 already set to 0
    bsr.s   \Unarchive
    bne.s   \End

    ;----------------------------------------------------------------------
    ;   Failed. Throw an error and quit
    ;----------------------------------------------------------------------

    move.w  #ERROR_MEMORY,ERROR(fp)
    pea StrErrorMemory(pc)
    bsr PrintToStderr
    bra MainExit

    ;----------------------------------------------------------------------
    ;   Success
    ;----------------------------------------------------------------------

\End:   movem.l (sp)+,d0-d3/a0-a2
    rts

    ;----------------------------------------------------------------------
    ;   Unarchive a file. Z-flag set according to success
    ;----------------------------------------------------------------------

\Unarchive:
    lea -18(sp),sp      ; Buffer for pdtlib::Hd2FullName
    move.w  d3,d0           ; Handle
    movea.l sp,a0
    jsr HD_2_FULL_NAME(fp)
    jsr UNARCHIVE_FILE(fp)
    tst.w   d0
    lea 18(sp),sp
    rts