chiark / gitweb /
Initial revision
[ssr] / StraySrc / Libraries / Sapphire / csapph / h / sapphire
1 /*
2  * sapphire.h
3  *
4  * Definitions for using Sapphire from C
5  *
6  * © 1995 Straylight
7  */
8
9 #if !defined(__CC_NORCROFT) || !defined(__arm)
10   #error You must use the Norcroft ARM Compiler for Sapphire programs
11 #endif
12
13 #pragma force_top_level
14 #pragma include_only_once
15
16 #ifndef __sapphire_h
17 #define __sapphire_h
18
19 /*----- Note --------------------------------------------------------------*
20  *
21  * This header file contains definitions and directives which are highly
22  * compiler specific.  Only use /genuine/ Norcroft ARM C compilers!
23  */
24
25 /*----- Important types ---------------------------------------------------*/
26
27 /* --- error --- *
28  *
29  * Defines the layout of a RISC OS error /again/.  If you're using
30  * _kernel_oserror, then #define error _kernel_oserror some time, and
31  * everything should be OK.
32  */
33
34 #ifndef error
35   typedef struct
36   {
37     int errnum;
38     char errmess[252];
39   }
40   error;
41 #endif
42
43 /* --- regset --- *
44  *
45  * Defines a register block, which is the only sane way of fiddling with
46  * registers from C.
47  */
48
49 typedef struct
50 {
51   int r[13];
52   unsigned int flags;
53 }
54 regset;
55
56 /* --- Hacky definition of a routine --- *
57  *
58  * This prevents attempts to call Sapphire routines directly, while still
59  * making references to routines look sensible, and preventing fiddling
60  * with the code, which would (of course) be a Bad Thing.
61  */
62
63 typedef struct _opaque routine[];
64
65 /* --- size_t --- *
66  *
67  * In case no-one else has defined it yet.
68  */
69
70 #ifndef __size_t
71 #define __size_t
72   typedef unsigned size_t;
73 #endif
74
75 /*----- Sapphire-to-C veneers ---------------------------------------------*/
76
77 /* --- __sapph_veneer --- *
78  *
79  * This routine is used internally by the _sapph macro to build
80  * callable-from-Sapphire functions in C.
81  */
82
83 extern void __sapph_veneer(void);
84
85 /* --- _sapph --- *
86  *
87  * Allows you to build callable-from-Sapphire functions in C.  The syntax
88  * is
89  *
90  *   _sapph(foo)(regset *r,<struct> *obj,<struct> *wsp,char *scratch)
91  *   {
92  *     // ...
93  *   }
94  *
95  * The routine must return an int built by using the macros below, for
96  * setting flags on exit.
97  *
98  * The obj and wsp pointers are the values of R10 and R12 respectively on
99  * entry.  Conventionally, these are `object' pointers (like a `this' pointer
100  * in C++) and `workspace' pointers (not really used in C), but can actually
101  * be anything you like.  If you're not interested in the values, you
102  * are allowed to omit them.  For example,
103  *
104  *   _sapph(foo)(regset *r,<struct> *obj)
105  *
106  * is also permissable, because of the way that APCS works.  If you're
107  * feeling adventurous, you can use extra arguments to pull off values
108  * of R0 onwards off the stack.  This starts getting a bit hacky, though.
109  * Alternatively, you can use variadic arguments and fiddle with stdarg
110  * to access these.  This isn't really recommended.
111  *
112  * For reference, the code built by the macro is as follows:
113  *
114  *              STMFD R13!,{R14}
115  *              MOV R14,PC
116  *              B csapph_veneer
117  */
118
119 #define _sapph(name) \
120   void name(void){_word(0xE92D4000);_word(0xE1A0E00F);__sapph_veneer();} \
121   int __sapph__##name
122
123 /* --- Macros for returning flags --- *
124  *
125  * You can OR these together using the | operator to obtain interesting
126  * effects.  For example,
127  *
128  *   return (V_set | C_clear);
129  *
130  * would return V set, and C clear, but the other two flags would be
131  * preserved.  The default (0) is to preserve all the flags.
132  *
133  * If you really want to be strange, nibble 1 is used to BIC the flags,
134  * and nibble 0 is EORed with them.  Alternatively, you can fiddle with
135  * the `flags' member of the regset structure.
136  */
137
138 #define V_set   0x11
139 #define V_clear 0x10
140
141 #define C_set   0x22
142 #define C_clear 0x20
143
144 #define Z_set   0x44
145 #define Z_clear 0x40
146
147 #define N_set   0x88
148 #define N_clear 0x80
149
150 /* --- C-to-Sapphire veneers --- */
151
152 /* --- call --- *
153  *
154  * Arguments:   routine p == the routine to call
155  *              regset *r == pointer to register block to use
156  *
157  * Returns:     Zero, if no error was returned, or a pointer to the error.
158  *
159  * Use:         Calls a general Sapphire routine.  The routine is entered
160  *              with registers as defined in the regset block.  Flags are
161  *              returned in the `flags' member of the regset.  The flags
162  *              are all cleared on entry to the routine.
163  */
164
165 extern error *call(routine /* p */, regset */* r */);
166
167 /* --- _call, _callx --- *
168  *
169  * Arguments:   routine p == the routine to call
170  *              unsigned flags == various flags controlling arguments
171  *              ... == a list of arguments and things
172  *
173  * Returns:     For _call, the _return register (0 by default).  For _callx,
174  *              zero if no error, or a pointer to the error.
175  *
176  * Use:         Calls a Sapphire routine.  Only R0-R9 can be passed.  The
177  *              flags are described below.  The optional arguments are in
178  *              the following order:
179  *
180  *              Input registers:        One word for each input register
181  *              Output registers:       Address to store each reg value
182  *              Flags address:          Address to store PC+flags value
183  *              Block contents:         Build contents of local block at end
184  */
185
186 extern int _call(routine /* p */, unsigned /* flags */, ...);
187 extern error *_callx(routine /* p */, unsigned /* flags */, ...);
188
189 /*----- SWI veneers -------------------------------------------------------*/
190
191 /* --- swi --- *
192  *
193  * Arguments:   int swi == SWI number to call
194  *              regset *r == registers to pass
195  *
196  * Returns:     Pointer to error, or 0
197  *
198  * Use:         Calls a SWI.  Returned registers are stored in the regset,
199  *              as are the flags.
200  */
201
202 extern error *swi(int /* swi */, regset */* r */);
203
204 /* --- _swi, _swix --- *
205  *
206  * Arguments:   int swi == number of the SWI to call
207  *              unsigned flags == various flags controlling arguments
208  *              ... == a list of arguments and things
209  *
210  * Returns:     For _swi, the _return register (0 by default).  For _swix,
211  *              zero if no error, or a pointer to the error.
212  *
213  * Use:         Calls a SWI.  The flags are described below.  The optional
214  *              arguments are as above.
215  */
216
217 extern int _swi(int /* swi */, unsigned /* flags */, ...);
218 extern error *_swix(int /* swi */, unsigned /* flags */, ...);
219
220 /*----- Flags for the veneers ---------------------------------------------*/
221
222 /* --- _flags -- return or output processor flags --- */
223
224 #define _flags          (0x10)
225
226 /* --- _in and _inr -- input a register, or a range of registers --- */
227
228 #define _in(r)          (1u << (r))
229 #define _inr(ra,rb)     (((~0) << (ra)) ^ ((~0) << ((rb)+1)))
230
231 /* --- _out and _outr -- output a register, or a range of registers --- */
232
233 #define _out(r)         (1u << (31-((r) == _flags ? 10 : (r))))
234 #define _outr(ra,rb)    (((~0) << (31-(rb))) ^ ((~0) << (32-(ra))))
235
236 /* --- _block -- point a register at block built from arguments --- */
237
238 #define _block(r)       (((r) << 12) | 0x800)
239
240 /* --- _return -- return register from _swi (not _swix) --- */
241
242 #define _return(r)      ((r) == _flags ? 0xF0000 : (r) << 16)
243
244 /* --- Constants for ARM processor flags --- */
245
246 #define _n              (0x80000000u)
247 #define _z              (0x40000000u)
248 #define _c              (0x20000000u)
249 #define _v              (0x10000000u)
250
251 /* --- Acorn style capital-letter macros --- */
252
253 #define _FLAGS          _flags
254 #define _IN(x)          _in(x)
255 #define _INR(x,y)       _inr(x,y)
256 #define _OUT(x)         _out(x)
257 #define _OUTR(x,y)      _outr(x,y)
258 #define _BLOCK(x)       _block(x)
259 #define _RETURN(x)      _return(x)
260 #define _N              _n
261 #define _Z              _z
262 #define _C              _c
263 #define _V              _v
264
265 /*----- C library support -------------------------------------------------*
266  *
267  * We have to mess about with some bits of the header files, mainly to
268  * point the compiler at bits of Sapphire instead of the normal library.
269  * To support a dynamically linked environment, we need to access static
270  * data items through `finder' functions, declared __pure to allow the
271  * compiler to optimise slightly better.
272  */
273
274 /* --- errno --- */
275
276 #ifdef errno
277   #undef errno
278 #endif
279 extern __pure int *cmath_errno(void);
280 #define errno (*cmath_errno())
281
282 /* --- math --- *
283  *
284  * Sapphire's normal `sqrt' routine is an integer square root (courtesy of
285  * David Seal), so we need to cheat a bit here.
286  */
287
288 #ifdef HUGE_VAL
289   #undef HUGE_VAL
290 #endif
291 extern __pure double cmath_huge(void);
292 #define HUGE_VAL (cmath_huge())
293
294 #define sqrt(x) __sapph_sqrt(x)
295
296 /* --- ctype --- *
297  *
298  * We define macros for toupper and tolower, since this is very simple under
299  * the Sapphire implementation of ctype.
300  */
301
302 #ifdef __ctype
303   #undef __ctype
304 #endif
305 extern __pure char *ctype_findTable(void);
306 #define __ctype (ctype_findTable())
307
308 #define tolower(c) (isupper(c) ? __ctype[c+256] : c)
309 #define toupper(c) (islower(c) ? __ctype[c+256] : c)
310
311 /* --- Memory moving routines --- */
312
313 extern void fastMove(void * /* a */, void */* b */, size_t /* s */);
314 #define memmove(a, b, s) fastMove(a, b, s)
315 #define memcpy(a, b, s) fastMove(a, b, s)
316
317 /*----- Basic Sapphire routines -------------------------------------------*/
318
319 /* --- Access to Sapphire environment block --- */
320
321 extern __pure char *__sapph_scratchpad(void);
322 #define scratchpad (__sapph_scratchpad())
323 #define scratch(t) ((t)__scratchpad())
324 /* `scratchpad' is the address of a buffer of at least 256 bytes, which
325  * you can use more or less as you want to.
326  */
327
328 /* --- Simple string functions --- *
329  *
330  * These functions are veneers onto the standard Sapphire routines.  Hence
331  * their behaviour deviates slightly from the ANSI definitions.  The Sapphire
332  * implementations have been written mainly for simplicity and size, rather
333  * than speed.  If string handling becomes time critical, it's probably a
334  * good idea to use better lookup structures.
335  */
336
337 #define strcpy(d, s) str_cpy(d, s)
338 extern char *strcpy(char */* d */, const char */* s */);
339 /* Copies a string from source to destination.  Note: Returns pointer to
340  * terminating null byte, /not/ input value of d as required by ANSI.  We
341  * think it's more useful like this, and the ANSI result isn't used often
342  * enough for compatiblity to be an issue.
343  */
344
345 #define strlen(s) str_len(s)
346 extern int strlen(const char */* s */);
347 /* Returns the length of a string.
348  */
349
350 extern char *strsubst(const char */* skel */, char */* buff */, ...);
351 /* Veneer to Sapphire's str_subst routine.  In summary, it copies the
352  * skeleton string to the buffer, replacing placeholders of the form
353  * %[<type>]<n>, where <type> is: `s' string, `x' hex number, `i' decimal
354  * integer, `c' single character, and <n> is the argument number, from 0
355  * through 9.  Returns a pointer to the beginning of the buffer.
356  */
357
358 extern int strcmp(const char * /* a */, const char */* b */);
359 /* Compares two strings, returning <0, ==0 or >0 according to whether a<b,
360  * a==b or a>b.
361  */
362
363 extern int stricmp(const char */* a */, const char */* b */);
364 /* Compares to strings in a case-insensitive manner.  Returns as strcmp.
365  */
366
367 extern char *strbuffer(void);
368 /* Returns the address of a 256-byte buffer.  There are two buffers, which
369  * are returned alternately.
370  */
371
372 extern error *strerror(int /* num */, const char */* string */, ...);
373 /* Builds an error in a buffer, as returned by strbuffer.  The string
374  * contains placeholders as for strsubst.
375  */
376
377 /* --- Message routines --- */
378
379 #define msgs_lookup(tag) __sapph_msgs_lookup(tag)
380 extern char *msgs_lookup(const char */* tag */);
381 /* Translates the given message tag into a string.  The tag has the form
382  * <name>[`:'<default>] -- if the name couldn't be found, and a default was
383  * specified, the default is returned.  We prefer to use plain tags, and
384  * put all messages in the messages file, unless it's possible that the
385  * messages haven't been loaded yet.
386  */
387
388 #define msgs_error __sapph_msgs_error
389 extern error *msgs_error(int /* num */, const char */* tag */, ...);
390 /* Builds an error message, like strerror, except that the string is
391  * translated first.
392  */
393
394 /* --- Memory allocation --- */
395
396 extern void *malloc(size_t /* size */);
397 /* Allocate a block of memory from a heap.  The block won't move around.
398  */
399
400 #define free(p) __sapph_free(p)
401 extern void free(void * /* p */);
402 /* Free a block of memory allocated by malloc.
403  */
404
405 #define alloc_error(x) __sapph_alloc_error(x)
406 extern error *alloc_error(void);
407 /* Return a pointer to an error about lack of memory.  This is used to
408  * build helpful error messages to send to the user.
409  */
410
411
412 #define flex_alloc(a,s) __sapph_flex_alloc(a,s)
413 extern void *flex_alloc(void */* a */, size_t /* s */);
414 /* Allocate a block from the flex heap.  Returns a pointer to the block,
415  * or zero if no memory.
416  */
417
418 #define flex_free(a) __sapph_flex_free(a)
419 extern void flex_free(void */* a */);
420 /* Frees a flex block.
421  */
422
423 #define flex_size(a) __sapph_flex_size(a)
424 extern size_t flex_size(void */* a */);
425 /* Returns the size of a flex block.
426  */
427
428 #define flex_extend(a,s) __sapph_flex_extend(a,s)
429 extern void *flex_extend(void */* a */, size_t /* s */);
430 /* Resize a block.  s is the new size.  Returns a pointer to the block, or
431  * zero.
432  */
433
434 #define flex_midExtend(a, w, b) __sapph_flex_midExtend(a, w, b)
435 extern void *flex_midExtend(void */* a */, size_t /* w */, int /* b */);
436 /* Inserts b bytes in the block at offset w.  Returns a pointer to the block
437  * or zero.
438  */
439
440 #define flex_save(p) __sapph_flex_save(p)
441 extern void flex_save(void */* p */);
442 /* Saves a pointer p on the relocation stack.
443  */
444
445 #define flex_load(x) __sapph_flex_load(x)
446 extern void *flex_load(void);
447 /* Restores a pointer from the relocation stack.
448  */
449
450 /*----- Sapphire routines -------------------------------------------------*/
451
452 /* --- sapphire_init --- *
453  *
454  * On entry:    R0 == pointer to application name
455  *              R1 == application's workspace size
456  *              R2 == size of stack required
457  *
458  * On exit:     R10 == pointer to heap base
459  *              R11 == pointer to ScratchPad
460  *              R12 == pointer to application workspace
461  *              R13 == pointer to full descending stack
462  *              Other registers are corrupted
463  *
464  * Use:         Initialises the Sapphire kernel, sets up the memory map,
465  *              and allocates workspace for library and client units.  The
466  *              initialisation performed is fairly minimal; in particular,
467  *              the library units are not initialised -- you must call
468  *              sapphire_libInit for this to take place.  This allows you
469  *              to check command line arguments etc. before initialising
470  *              the Wimp.
471  */
472
473 extern routine sapphire_init;
474
475 /* --- sapphire_disable --- *
476  *
477  * On entry:    R0 == pointer to 0-terminated list of initialise routines
478  *
479  * On exit:     --
480  *
481  * Use:         Prevents the given initialisation routines from being called.
482  *              This is mainly useful in the dynamic-linking environment,
483  *              where all Sapphire units are normally active.  This routine
484  *              allows you to inactivate units which for example do not
485  *              have the resources they require, or use up unnecesary
486  *              memory.
487  */
488
489 extern routine sapphire_disable;
490
491 /* --- sapphire_libInit --- *
492  *
493  * On entry:    --
494  *
495  * On exit:     --
496  *
497  * Use:         Initialises the Sapphire library and client units.
498  */
499
500 extern routine sapphire_libInit;
501
502 /* --- sapphire_doInit --- *
503  *
504  * On entry:    R0 == pointer to application name
505  *              R1 == client workspace size
506  *              R2 == requested stack size
507  *              R3 == pointer to initialisation table
508  *
509  * On exit:     R10 == base address of Sapphire heap
510  *              R11 == pointer to scratchpad and global data
511  *              R12 == pointer to client global workspace
512  *              R13 == pointer to a full descendion stack
513  *
514  * Use:         Performs initialisation of the Sapphire library and the
515  *              client's sections.  This is intended for use by the Sapphire
516  *              stub, while initialising the dynamically linked version of
517  *              Sapphire.
518  */
519
520 extern routine sapphire_doInit;
521
522 /* --- sapphire_doLibInit --- *
523  *
524  * On entry:    R0 == address of library initialisation table
525  *
526  * On exit:     --
527  *
528  * Use:         Initialises all currently uninitialised library units.
529  */
530
531 extern routine sapphire_doLibInit;
532
533 /* --- sapphire_doDisable --- *
534  *
535  * On entry:    R0 == pointer to list of initialise routines to disable
536  *              R1 == pointer to initialisation table
537  *
538  * On exit:     --
539  *
540  * Use:         Prevents the given initialisation routines from being
541  *              called.  This is mainly useful in a dynamically linked
542  *              environment.
543  */
544
545 extern routine sapphire_doDisable;
546
547 /* --- sapphire_heapAddr --- *
548  *
549  * On entry:    --
550  *
551  * On exit:     R1 == pointer to the heap base (for passing to OS_Heap)
552  *
553  * Use:         Returns the address of the Sapphire heap.
554  */
555
556 extern routine sapphire_heapAddr;
557
558 /* --- sapphire_appName --- *
559  *
560  * On entry:    --
561  *
562  * On exit:     R0 == pointer to application name (NULL terminated)
563  *
564  * Use:         Returns a pointer to the application's name.
565  */
566
567 extern routine sapphire_appName;
568
569 /* --- sapphire_resetStack --- *
570  *
571  * On entry:    --
572  *
573  * On exit:     R13 == stack pointer
574  *
575  * Use:         Resets R13 to point to the top of the stack.
576  */
577
578 extern routine sapphire_resetStack;
579
580 /* --- sapphire_global --- *
581  *
582  * On entry:    R0 == magic identifier for global variable
583  *              R1 == size of area required
584  *
585  * On exit:     R0 == pointer to area
586  *              CS if the area already exists, CC otherwise
587  *
588  * Use:         Locates (and creates if necessary) a `named' global area
589  *              which can be used for inter-section communication without
590  *              the necessity for dependencies.
591  *
592  *              There is a limit on the number of global areas allowed, but
593  *              this can be raised fairly easily if necessary.
594  *
595  *              If an area can't be created, an error is generated.
596  */
597
598 extern routine sapphire_global;
599
600 /* --- Data relative to R11 --- */
601
602 #define sapph__R11 0
603
604 #define sapph_scratchpad (sapph__R11-0)
605 #define sapph_workspace (sapph__R11-4)
606 #define sapph_stackBase (sapph__R11-8)
607 #define sapph_heapBase (sapph__R11-12)
608 #define sapph_appName (sapph__R11-16)
609 #define sapph_clientWS (sapph__R11-20)
610
611 /*----- That's all, folks -------------------------------------------------*/
612
613 #endif