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