; ; dynAnchor.s ; ; Useful handle RMA allocation for dynamite ; ; © 1994-1998 Straylight ; ;----- Licensing note ------------------------------------------------------- ; ; This file is part of Straylight's Dynamite ; ; Dynamite 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. ; ; Dynamite 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 Dynamite. If not, write to the Free Software Foundation, ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ;----- Standard header ------------------------------------------------------ GET libs:header GET libs:swis ;----- External dependencies ------------------------------------------------ GET sh.wSpace ;----- Constants ------------------------------------------------------------ danc__chunk EQU 16 ;Number of handles to get ;----- Main code ------------------------------------------------------------ AREA |Dynamite$$Code|,CODE,READONLY ; --- danc_alloc --- ; ; On entry: -- ; ; On exit: R0 == pointer to block allocated, or V set and pointer to ; error ; ; Use: Allocates an anchor to use with dynamite from the RMA, ; in a very quick way indeed. EXPORT danc_alloc danc_alloc ROUT STMFD R13!,{R1-R3,R14} ; --- Are there any free blocks? --- LDR R2,dyn_ancTable ;Get the free list offset CMP R2,#0 ;Are there any free blocks? BEQ %01danc_alloc ;No -- better allocate some ; --- Mess about with the free list and return --- 00danc_alloc LDR R3,[R2] ;Get next pointer from block STR R3,dyn_ancTable ;This is now first free block MOV R0,R2 ;Point to the block LDMFD R13!,{R1-R3,PC}^ ;Restore registers and return ; --- Create a big block --- 01danc_alloc MOV R0,#6 ;Allocate memory please MOV R3,#danc__chunk*4+4 ;Get the chunk size SWI XOS_Module ;Allocate the big block then LDMVSFD R13!,{R1-R3,PC} ;If it failed, return error LDR R14,dyn_ancList ;Load current list head STR R2,dyn_ancList ;Save this as new list head STR R14,[R2],#4 ;And save old list head ; --- Now set up the links for the free list --- MOV R0,#0 ;Next free pointer start at 0 SUB R3,R3,#8 ;Offset to next field of sub 02danc_alloc STR R0,[R2,R3] ;Store in next field ADD R0,R2,R3 ;Point to that block SUBS R3,R3,#4 ;Point to previous block BGE %02danc_alloc ;If more to do, continue... ; --- The links are set up -- now take off a block --- B %00danc_alloc ;Then allocate as normal LTORG ; --- danc_free --- ; ; On entry: R0 == pointer to block ; ; On exit: Registers preserved ; ; Use: Frees an anchor allocated using danc_alloc. EXPORT danc_free danc_free ROUT STMFD R13!,{R0,R1,R14} ;Preserve registers ; --- Mess about with the list --- LDR R1,dyn_ancTable ;Get current first block STR R1,[R0] ;Store in newly freed block STR R0,dyn_ancTable ;And insert new block in list LDMFD R13!,{R0,R1,PC}^ ;Oh, and return to caller LTORG ; --- danc_quit --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Frees everyone's anchors nicely when the module quits. EXPORT danc_quit danc_quit ROUT STMFD R13!,{R0-R2,R14} ;Save some registers LDR R2,dyn_ancList ;Load the list head CMP R2,#0 ;Is there anything to do? LDMEQFD R13!,{R0-R2,PC}^ ;No -- return then MOV R0,#7 ;Free RMA block 00danc_quit LDR R1,[R2,#0] ;Load the next pointer SWI XOS_Module ;Free the block MOVS R2,R1 ;Point to next one BNE %00danc_quit ;And loop round for more LDMFD R13!,{R0-R2,PC}^ ;Return when all done LTORG ;----- That's all, folks ---------------------------------------------------- END