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