Initial revision
[ssr] / StraySrc / Dynamite / dynamite / s / dynAnchor
1 ;
2 ; dynAnchor.s
3 ;
4 ; Useful handle RMA allocation for dynamite
5 ;
6 ; © 1994-1998 Straylight
7 ;
8 ;----- Licensing note -------------------------------------------------------
9 ;
10 ; This file is part of Straylight's Dynamite
11 ;
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)
15 ; any later version.
16 ;
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.
21 ;
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.
25
26
27 ;----- Standard header ------------------------------------------------------
28
29 GET libs:header
30 GET libs:swis
31
32 ;----- External dependencies ------------------------------------------------
33
34 GET sh.wSpace
35
36 ;----- Constants ------------------------------------------------------------
37
38 danc__chunk EQU 16 ;Number of handles to get
39
40 ;----- Main code ------------------------------------------------------------
41
42 AREA |Dynamite$$Code|,CODE,READONLY
43
44 ; --- danc_alloc ---
45 ;
46 ; On entry: --
47 ;
48 ; On exit: R0 == pointer to block allocated, or V set and pointer to
49 ; error
50 ;
51 ; Use: Allocates an anchor to use with dynamite from the RMA,
52 ; in a very quick way indeed.
53
54 EXPORT danc_alloc
55 danc_alloc ROUT
56
57 STMFD R13!,{R1-R3,R14}
58
59 ; --- Are there any free blocks? ---
60
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
64
65 ; --- Mess about with the free list and return ---
66
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
71
72 ; --- Create a big block ---
73
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
78
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
82
83 ; --- Now set up the links for the free list ---
84
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...
91
92 ; --- The links are set up -- now take off a block ---
93
94 B %00danc_alloc ;Then allocate as normal
95
96 LTORG
97
98 ; --- danc_free ---
99 ;
100 ; On entry: R0 == pointer to block
101 ;
102 ; On exit: Registers preserved
103 ;
104 ; Use: Frees an anchor allocated using danc_alloc.
105
106 EXPORT danc_free
107 danc_free ROUT
108
109 STMFD R13!,{R0,R1,R14} ;Preserve registers
110
111 ; --- Mess about with the list ---
112
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
117
118 LTORG
119
120 ; --- danc_quit ---
121 ;
122 ; On entry: --
123 ;
124 ; On exit: --
125 ;
126 ; Use: Frees everyone's anchors nicely when the module quits.
127
128 EXPORT danc_quit
129 danc_quit ROUT
130
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
141
142 LTORG
143
144 ;----- That's all, folks ----------------------------------------------------
145
146 END