4 ; Useful handle RMA allocation for dynamite
6 ; © 1994-1998 Straylight
8 ;----- Licensing note -------------------------------------------------------
10 ; This file is part of Straylight's Dynamite
12 ; Dynamite is free software; you can redistribute it and/or modify
13 ; it under the terms of the GNU General Public License as published by
14 ; the Free Software Foundation; either version 2, or (at your option)
17 ; Dynamite is distributed in the hope that it will be useful,
18 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ; GNU General Public License for more details.
22 ; You should have received a copy of the GNU General Public License
23 ; along with Dynamite. If not, write to the Free Software Foundation,
24 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 ;----- Standard header ------------------------------------------------------
32 ;----- External dependencies ------------------------------------------------
36 ;----- Constants ------------------------------------------------------------
38 danc__chunk EQU 16 ;Number of handles to get
40 ;----- Main code ------------------------------------------------------------
42 AREA |Dynamite$$Code|,CODE,READONLY
48 ; On exit: R0 == pointer to block allocated, or V set and pointer to
51 ; Use: Allocates an anchor to use with dynamite from the RMA,
52 ; in a very quick way indeed.
57 STMFD R13!,{R1-R3,R14}
59 ; --- Are there any free blocks? ---
61 LDR R2,dyn_ancTable ;Get the free list offset
62 CMP R2,#0 ;Are there any free blocks?
63 BEQ %01danc_alloc ;No -- better allocate some
65 ; --- Mess about with the free list and return ---
67 00danc_alloc LDR R3,[R2] ;Get next pointer from block
68 STR R3,dyn_ancTable ;This is now first free block
69 MOV R0,R2 ;Point to the block
70 LDMFD R13!,{R1-R3,PC}^ ;Restore registers and return
72 ; --- Create a big block ---
74 01danc_alloc MOV R0,#6 ;Allocate memory please
75 MOV R3,#danc__chunk*4+4 ;Get the chunk size
76 SWI XOS_Module ;Allocate the big block then
77 LDMVSFD R13!,{R1-R3,PC} ;If it failed, return error
79 LDR R14,dyn_ancList ;Load current list head
80 STR R2,dyn_ancList ;Save this as new list head
81 STR R14,[R2],#4 ;And save old list head
83 ; --- Now set up the links for the free list ---
85 MOV R0,#0 ;Next free pointer start at 0
86 SUB R3,R3,#8 ;Offset to next field of sub
87 02danc_alloc STR R0,[R2,R3] ;Store in next field
88 ADD R0,R2,R3 ;Point to that block
89 SUBS R3,R3,#4 ;Point to previous block
90 BGE %02danc_alloc ;If more to do, continue...
92 ; --- The links are set up -- now take off a block ---
94 B %00danc_alloc ;Then allocate as normal
100 ; On entry: R0 == pointer to block
102 ; On exit: Registers preserved
104 ; Use: Frees an anchor allocated using danc_alloc.
109 STMFD R13!,{R0,R1,R14} ;Preserve registers
111 ; --- Mess about with the list ---
113 LDR R1,dyn_ancTable ;Get current first block
114 STR R1,[R0] ;Store in newly freed block
115 STR R0,dyn_ancTable ;And insert new block in list
116 LDMFD R13!,{R0,R1,PC}^ ;Oh, and return to caller
126 ; Use: Frees everyone's anchors nicely when the module quits.
131 STMFD R13!,{R0-R2,R14} ;Save some registers
132 LDR R2,dyn_ancList ;Load the list head
133 CMP R2,#0 ;Is there anything to do?
134 LDMEQFD R13!,{R0-R2,PC}^ ;No -- return then
135 MOV R0,#7 ;Free RMA block
136 00danc_quit LDR R1,[R2,#0] ;Load the next pointer
137 SWI XOS_Module ;Free the block
138 MOVS R2,R1 ;Point to next one
139 BNE %00danc_quit ;And loop round for more
140 LDMFD R13!,{R0-R2,PC}^ ;Return when all done
144 ;----- That's all, folks ----------------------------------------------------