; ; flex.sh ; ; Flexible memory handling ; ; © 1994-1998 Straylight ; ;----- Licensing note ------------------------------------------------------- ; ; This file is part of Straylight's Sapphire library. ; ; Sapphire is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2, or (at your option) ; any later version. ; ; Sapphire is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with Sapphire. If not, write to the Free Software Foundation, ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ;----- Overview ------------------------------------------------------------- ; ; Functions provided: ; ; flex_reduce ; flex_compact ; flex_free ; flex_alloc ; flex_size ; flex_extend ; flex_midExtend ; flex_init ; flex_stackPtr ; flex_save ; flex_load ; flex_dump ; ; Macros provided: ; ; FSAVE ; FLOAD [ :LNOT::DEF:flex__dfn GBLL flex__dfn ;+ LIB sapphire:^.bsh.flex ; --- flex_reduce --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Compacts the flex heap by one iteration. IMPORT flex_reduce ; --- flex_compact --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Completely compacts the flex heap. IMPORT flex_compact ; --- flex_free --- ; ; On entry: R0 == pointer to the flex anchor ; ; On exit: -- ; ; Use: Frees a flex block allocated by flex_alloc. IMPORT flex_free ; --- flex_alloc --- ; ; On entry: R0 == pointer to a flex anchor ; R1 == desired size of flex block ; ; On exit: CS if no memory could be allocated, CC otherwise ; ; Use: Allocates a block in the shifting heap. IMPORT flex_alloc ; --- flex_size --- ; ; On entry: R0 == pointer to flex anchor ; ; On exit: R0 == size of allocated block ; ; Use: Reads the size of a flex block. IMPORT flex_size ; --- flex_extend --- ; ; On entry: R0 == pointer to flex anchor ; R1 == new size of block to set ; ; On exit: CS if it failed due to lack of memory, CC otherwise ; ; Use: Alters the size of a block to the given value. IMPORT flex_extend ; --- flex_midExtend --- ; ; On entry: R0 == pointer to a flex anchor ; R1 == `at' -- position in block to extend from ; R2 == `by' -- how many bytes to extend (may be -ve) ; ; On exit: CS if it failed due to lack of memory, CC otherwise ; ; Use: Either creates a gap in a block (by>0) or deletes bytes ; from a block. This is always done in such a way that the ; byte originally at offset `at' is now at offset `at'+`by'. IMPORT flex_midExtend ; --- flex_init --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Initialises the flex heap for use. IMPORT flex_init ; --- flex_stackPtr --- ; ; On entry: R0 == 0 to read, or value to set ; ; On exit: R0 == old value ; ; Use: Either reads or writes the flex stack pointer. This sort ; of thing is useful in exception handlers etc. IMPORT flex_stackPtr ; --- flex_save --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Saves some registers on the flex relocation stack. R13 ; and R14 cannot be saved -- these registers are corrupted ; during this routine's execution. ; ; Values saved on the flex relocation stack are adjusted as ; flex moves blocks of memory around, so that they still point ; to the same thing as they did before. Obviously, values ; which aren't pointers into flex blocks may be corrupted. ; Values pointing to objects deleted (either free blocks, or ; areas removed by flex_midExtend) may also be corrupted. ; ; Since this routine takes no arguments, some other method has ; to be used. The method chosen is to follow the call to ; flex_save with a LDM or STM instruction containing the ; registers to be saved. This instruction is skipped by the ; routine, and thus not executed. ; ; Note that if you give the LDM or STM the same condition code ; as the BL preceding it, it will never be executed, since ; flex_save skips it if the condition is true and it can't be ; executed if the condition is false. IMPORT flex_save ; --- flex_load --- ; ; On entry: -- ; ; On exit: Registers loaded from relocation stack as requested ; ; Use: Restores registers saved on flex's relocation stack. See ; flex_save for calling information and details about the ; relocation stack. IMPORT flex_load ;----- Useful macros -------------------------------------------------------- ; --- Macro: FSAVE --- ; ; Arguments: rList == quoted register list to save on relocation stack ; ; Use: Assembles code to write the given register list on the ; flex relocation stack. The register list should be in the ; same form as that for an STM or LDM instruction. ; ; For full details about the flex relocation stack, see ; flex_save. MACRO $label FSAVE $rList $label BL flex_save STMEA R14!,{$rList} MEND ; --- Macro: FLOAD --- ; ; Arguments: rList == quoted register list to read from relocation stack ; ; Use: Assembles code to read the given register list from the ; flex relocation stack. The register list should be in the ; same form as that for an STM or LDM instruction. ; ; For full details about the flex relocation stack, see ; flex_save. MACRO $label FLOAD $rList $label BL flex_load LDMEA R14!,{$rList} MEND ] ;----- That's all, folks ---------------------------------------------------- END