4 * Interface to Dynamite SWIs
9 /*----- Licensing note ----------------------------------------------------*
11 * This file is part of Straylight's Dynamite
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)
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.
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.
31 /*----- Notes -------------------------------------------------------------*
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.
38 * The SWI interface routines are safe to call from SVC mode (e.g. in a
46 /*------ Important types --------------------------------------------------*/
48 /* --- dynamite_anchor --- *
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.
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 *.
60 #define dynamite_anchor void
62 /* --- dynamite_error --- *
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.
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.
74 #if defined(dynamite_USE_OS_ERROR)
80 typedef os_error dynamite_error;
82 #elif defined(dynamite_USE_KERNEL_OSERROR)
88 typedef _kernel_oserror dynamite_error;
90 #elif !defined(dynamite_error)
92 typedef struct dynamite_error
94 int errnum; /* Error number */
95 char errmess[252]; /* Error message text */
101 /* --- dynstr_blockInfo --- *
103 * This structure contains the information dynamite_blockInfo() returns.
106 typedef struct dynstr_blockInfo
108 int size; /* Block size in bytes */
109 int blockID; /* Block's ID number */
113 /* --- dynstr_describe --- *
115 * This structure contains the information dynamite_describe() returns.
118 typedef struct dynstr_describe
120 int area; /* Dynamic area handle, or -1 */
121 int size; /* Total size of Dynamite area */
122 int unused; /* Space unused in Dynamite area */
126 /*----- Interface functions -----------------------------------------------*
128 * Most of these return a pointer to a dynamite_error structure. If the
129 * call was successful, this pointer will be null.
131 * However, where errors are unlikely and a value return is more natural,
132 * this is not the case.
134 * To check for the existance of Dynamite you should check the return value
135 * of dynamite_describe() for an error.
138 /* --- dynamite_alloc --- *
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
144 * Returns: Pointer to possible error
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.
153 extern dynamite_error *dynamite_alloc(dynamite_anchor */*anchor*/,
157 /* --- dynamite_free --- *
159 * Arguments: anchor == the address of block's anchor
161 * Returns: Pointer to possible error
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.
168 extern dynamite_error *dynamite_free(dynamite_anchor */*anchor*/);
170 /* --- dynamite_freeWithID --- *
172 * Arguments: id == the ID of the blocks to free
174 * Returns: Pointer to possible error
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.
181 extern dynamite_error *dynamite_freeWithID(int /*id*/);
183 /* --- dynamite_blockInfo --- *
185 * Arguments: anchor == address of block's anchor
186 * info == address of structure to fill in
188 * Returns: Pointer to possible error
190 * Use: Returns information about a Dynamite block.
193 extern dynamite_error *dynamite_blockInfo(dynamite_anchor */*anchor*/,
194 dynstr_blockInfo */*info*/);
196 /* --- dynamite_changeID --- *
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
202 * Returns: Pointer to possible error
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
209 extern dynamite_error *dynamite_changeID(dynamite_anchor */*anchor*/,
213 /* --- dynamite_resize --- *
215 * Arguments: anchor == address of block's anchor
216 * size == new size to make block
218 * Returns: Pointer to possible error
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.
226 extern dynamite_error *dynamite_resize(dynamite_anchor */*anchor*/,
229 /* --- dynamite_midExtend --- *
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
235 * Returns: Pointer to possible error
237 * Use: Inserts or removes bytes in a block at a given offset.
238 * See the manual for a complete description of this call.
241 extern dynamite_error *dynamite_midExtend(dynamite_anchor */*anchor*/,
245 /* --- dynamite_save --- *
247 * Arguments: value == value to save on the relocation stack
249 * Returns: Pointer to possible error
251 * Use: Saves a value on the Dynamite relocation stack. You can
252 * only save one value at a time through this interface.
255 extern dynamite_error *dynamite_save(void */*value*/);
257 /* --- dynamite_load --- *
261 * Returns: The value from the top of the relocation stack.
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
268 extern void *dynamite_load(void);
270 /* --- dynamite_reduce --- *
274 * Returns: 0 if heap couldn't be compacted, non-0 if it could
276 * Use: Performs a partial compaction of the Dynamite heap.
279 extern int dynamite_reduce(void);
281 /* --- dynamite_compact --- *
285 * Returns: Pointer to possible error.
287 * Use: Fully compacts the Dynamite heap. This is equivalent to
289 * while (dynamite_reduce())
293 extern dynamite_error *dynamite_compact(void);
295 /* --- dynamite_lock --- *
299 * Returns: Pointer to a possible error
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.
307 extern dynamite_error *dynamite_lock(void);
309 /* --- dynamite_unlock --- *
313 * Returns: Pointer to a possible error
315 * Use: Unlocks the heap, allowing compaction to take place again.
318 extern dynamite_error *dynamite_unlock(void);
320 /* --- dynamite_claimAnchor --- *
322 * Arguments: ancptr == where to store the address of the anchor
324 * Returns: Pointer to a possible error
326 * Use: Allocates an anchor from the RMA and returns its address.
329 extern dynamite_error *dynamite_claimAnchor(dynamite_anchor **/*ancptr*/);
331 /* --- dynamite_releaseAnchor --- *
333 * Arguments: anchor == address of anchor to release
335 * Returns: Pointer to possible error
337 * Use: Frees an anchor allocated by dynamite_claimAnchor.
340 extern dynamite_error *dynamite_releaseAnchor(dynamite_anchor */*anchor*/);
342 /* --- dynamite_readSpriteSize --- *
346 * Returns: Actual size of sprite area in bytes
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.
355 extern int dynamite_readSpriteSize(void);
357 /* --- dynamite_describe --- *
359 * Arguments: desc == address of structure to fill in, or 0
361 * Returns: Pointer to possible error
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.
369 extern dynamite_error *dynamite_describe(dynstr_describe */*desc*/);
371 /*----- That's all, folks -------------------------------------------------*/