Initial revision
[ssr] / StraySrc / Dynamite / apcs / h / dynamite
1 /*
2 * dynamite.h
3 *
4 * Interface to Dynamite SWIs
5 *
6 * © 1997 Straylight
7 */
8
9 /*----- Licensing note ----------------------------------------------------*
10 *
11 * This file is part of Straylight's Dynamite
12 *
13 * Dynamite is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * Dynamite is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with Dynamite. If not, write to the Free Software Foundation,
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27
28 #ifndef __dynamite_h
29 #define __dynamite_h
30
31 /*----- Notes -------------------------------------------------------------*
32 *
33 * The interfaces to Dynamite have been written in assembler. This has the
34 * benefit of making them very small and minimising procedure call overhead.
35 * It also has the disadvantage of not setting _kernel_last_oserror()
36 * properly. If this is important, you should use _kernel_swi() directly.
37 *
38 * The SWI interface routines are safe to call from SVC mode (e.g. in a
39 * C module).
40 */
41
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45
46 /*------ Important types --------------------------------------------------*/
47
48 /* --- dynamite_anchor --- *
49 *
50 * This is the type of a Dynamite anchor. It should only be used within
51 * these declarations, since it exists to keep the compiler happy and make
52 * the declarations look neat. Your actual anchors will have various types
53 * depending on what you want to store in your Dynamite blocks.
54 *
55 * To avoid casts, we cheat horridly, and in the knowledge that we will only
56 * be dealing with the *address* of an anchor we macro dynamite_anchor to
57 * void, so that its address is a void *.
58 */
59
60 #define dynamite_anchor void
61
62 /* --- dynamite_error --- *
63 *
64 * This is the type of error which Dynamite SWIs return. Depending on
65 * whether you're using RISC_OSLib or not, you may want these to return
66 * os_errors or _kernel_oserrors, or its own special type. All these error
67 * structures have the same format and member names -- it's just a matter of
68 * naming the structure.
69 *
70 * The way we sort all this out is by allowing the client to set up a macro
71 * to tell us what to do.
72 */
73
74 #if defined(dynamite_USE_OS_ERROR)
75
76 #ifndef __os_h
77 #include "os.h"
78 #endif
79
80 typedef os_error dynamite_error;
81
82 #elif defined(dynamite_USE_KERNEL_OSERROR)
83
84 #ifndef __kernel_h
85 #include "kernel.h"
86 #endif
87
88 typedef _kernel_oserror dynamite_error;
89
90 #elif !defined(dynamite_error)
91
92 typedef struct dynamite_error
93 {
94 int errnum; /* Error number */
95 char errmess[252]; /* Error message text */
96 }
97 dynamite_error;
98
99 #endif
100
101 /* --- dynstr_blockInfo --- *
102 *
103 * This structure contains the information dynamite_blockInfo() returns.
104 */
105
106 typedef struct dynstr_blockInfo
107 {
108 int size; /* Block size in bytes */
109 int blockID; /* Block's ID number */
110 }
111 dynstr_blockInfo;
112
113 /* --- dynstr_describe --- *
114 *
115 * This structure contains the information dynamite_describe() returns.
116 */
117
118 typedef struct dynstr_describe
119 {
120 int area; /* Dynamic area handle, or -1 */
121 int size; /* Total size of Dynamite area */
122 int unused; /* Space unused in Dynamite area */
123 }
124 dynstr_describe;
125
126 /*----- Interface functions -----------------------------------------------*
127 *
128 * Most of these return a pointer to a dynamite_error structure. If the
129 * call was successful, this pointer will be null.
130 *
131 * However, where errors are unlikely and a value return is more natural,
132 * this is not the case.
133 *
134 * To check for the existance of Dynamite you should check the return value
135 * of dynamite_describe() for an error.
136 */
137
138 /* --- dynamite_alloc --- *
139 *
140 * Arguments: anchor == address of the anchor to use
141 * size == the size to allocate, in bytes
142 * id == the id value to give to the block
143 *
144 * Returns: Pointer to possible error
145 *
146 * Use: Allocates memory from the Dynamite heap. If successful,
147 * *anchor on exit contains the address of the block allocated.
148 * Note that the anchor must *not* be in application space --
149 * use dynamite_claimAnchor to get one from the RMA if you
150 * don't have other RMA data.
151 */
152
153 extern dynamite_error *dynamite_alloc(dynamite_anchor */*anchor*/,
154 int /*size*/,
155 int /*id*/);
156
157 /* --- dynamite_free --- *
158 *
159 * Arguments: anchor == the address of block's anchor
160 *
161 * Returns: Pointer to possible error
162 *
163 * Use: Frees memory in the Dynamite heap. The memory is marked
164 * as being free, but no blocks are moved -- this makes freeing
165 * lots of blocks very fast.
166 */
167
168 extern dynamite_error *dynamite_free(dynamite_anchor */*anchor*/);
169
170 /* --- dynamite_freeWithID --- *
171 *
172 * Arguments: id == the ID of the blocks to free
173 *
174 * Returns: Pointer to possible error
175 *
176 * Use: Frees all blocks with the given ID value. This allows
177 * applications and modules to free all their allocated blocks
178 * when they close down.
179 */
180
181 extern dynamite_error *dynamite_freeWithID(int /*id*/);
182
183 /* --- dynamite_blockInfo --- *
184 *
185 * Arguments: anchor == address of block's anchor
186 * info == address of structure to fill in
187 *
188 * Returns: Pointer to possible error
189 *
190 * Use: Returns information about a Dynamite block.
191 */
192
193 extern dynamite_error *dynamite_blockInfo(dynamite_anchor */*anchor*/,
194 dynstr_blockInfo */*info*/);
195
196 /* --- dynamite_changeID --- *
197 *
198 * Arguments: anchor == address of block's anchor, or 0 for all blocks
199 * newID == new ID to set for block or blocks
200 * oldID == optional old ID of blocks to change, if anchor == 0
201 *
202 * Returns: Pointer to possible error
203 *
204 * Use: Changes the ID of a block or blocks. If you specify a single
205 * block by passing a nonzero anchor, you don't have to specify
206 * an oldID value.
207 */
208
209 extern dynamite_error *dynamite_changeID(dynamite_anchor */*anchor*/,
210 int /*newID*/,...
211 /* int oldID */);
212
213 /* --- dynamite_resize --- *
214 *
215 * Arguments: anchor == address of block's anchor
216 * size == new size to make block
217 *
218 * Returns: Pointer to possible error
219 *
220 * Use: Changes a block's size. If you make the block larger, the
221 * data will be unchanged. If you reduce the size, data at the
222 * end will be deleted. The block will usually move as a
223 * result of this operation.
224 */
225
226 extern dynamite_error *dynamite_resize(dynamite_anchor */*anchor*/,
227 int /*size*/);
228
229 /* --- dynamite_midExtend --- *
230 *
231 * Arguments: anchor == address of block's anchor
232 * at == offset within block at which to insert or remove bytes
233 * by == (signed) number of bytes to insert
234 *
235 * Returns: Pointer to possible error
236 *
237 * Use: Inserts or removes bytes in a block at a given offset.
238 * See the manual for a complete description of this call.
239 */
240
241 extern dynamite_error *dynamite_midExtend(dynamite_anchor */*anchor*/,
242 int /*at*/,
243 int /*by*/);
244
245 /* --- dynamite_save --- *
246 *
247 * Arguments: value == value to save on the relocation stack
248 *
249 * Returns: Pointer to possible error
250 *
251 * Use: Saves a value on the Dynamite relocation stack. You can
252 * only save one value at a time through this interface.
253 */
254
255 extern dynamite_error *dynamite_save(void */*value*/);
256
257 /* --- dynamite_load --- *
258 *
259 * Arguments: --
260 *
261 * Returns: The value from the top of the relocation stack.
262 *
263 * Use: Loads a value from Dynamite's relocation stack and returns
264 * it. You can only restore one value at a time through this
265 * interface.
266 */
267
268 extern void *dynamite_load(void);
269
270 /* --- dynamite_reduce --- *
271 *
272 * Arguments: --
273 *
274 * Returns: 0 if heap couldn't be compacted, non-0 if it could
275 *
276 * Use: Performs a partial compaction of the Dynamite heap.
277 */
278
279 extern int dynamite_reduce(void);
280
281 /* --- dynamite_compact --- *
282 *
283 * Arguments: --
284 *
285 * Returns: Pointer to possible error.
286 *
287 * Use: Fully compacts the Dynamite heap. This is equivalent to
288 *
289 * while (dynamite_reduce())
290 * ;
291 */
292
293 extern dynamite_error *dynamite_compact(void);
294
295 /* --- dynamite_lock --- *
296 *
297 * Arguments: --
298 *
299 * Returns: Pointer to a possible error
300 *
301 * Use: Locks the heap, stopping any blocks not explicitly resized
302 * from being moved -- this basically just disables compaction.
303 * You *must* lock the heap while it is being used within a
304 * callback or SWI handler.
305 */
306
307 extern dynamite_error *dynamite_lock(void);
308
309 /* --- dynamite_unlock --- *
310 *
311 * Arguments: --
312 *
313 * Returns: Pointer to a possible error
314 *
315 * Use: Unlocks the heap, allowing compaction to take place again.
316 */
317
318 extern dynamite_error *dynamite_unlock(void);
319
320 /* --- dynamite_claimAnchor --- *
321 *
322 * Arguments: ancptr == where to store the address of the anchor
323 *
324 * Returns: Pointer to a possible error
325 *
326 * Use: Allocates an anchor from the RMA and returns its address.
327 */
328
329 extern dynamite_error *dynamite_claimAnchor(dynamite_anchor **/*ancptr*/);
330
331 /* --- dynamite_releaseAnchor --- *
332 *
333 * Arguments: anchor == address of anchor to release
334 *
335 * Returns: Pointer to possible error
336 *
337 * Use: Frees an anchor allocated by dynamite_claimAnchor.
338 */
339
340 extern dynamite_error *dynamite_releaseAnchor(dynamite_anchor */*anchor*/);
341
342 /* --- dynamite_readSpriteSize --- *
343 *
344 * Arguments: --
345 *
346 * Returns: Actual size of sprite area in bytes
347 *
348 * Use: Returns the real size of the sprite area -- before RISC OS
349 * 3.5, Dynamite has to fake the return value from
350 * OS_ReadDynamicArea so that you can no longer work out how
351 * much memory is free in the system. This call allows you
352 * to find the real sprite area size.
353 */
354
355 extern int dynamite_readSpriteSize(void);
356
357 /* --- dynamite_describe --- *
358 *
359 * Arguments: desc == address of structure to fill in, or 0
360 *
361 * Returns: Pointer to possible error
362 *
363 * Use: If desc is nonzero, this call will read some useful
364 * information about the Dynamite heap. If desc is 0, it will
365 * return an error if Dynamite is not loaded -- you can
366 * therefore test for Dynamite's presence.
367 */
368
369 extern dynamite_error *dynamite_describe(dynstr_describe */*desc*/);
370
371 /*----- That's all, folks -------------------------------------------------*/
372
373 #ifdef __cplusplus
374 }
375 #endif
376
377 #endif