chiark / gitweb /
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