4 * Definitions for using Sapphire from C
9 #if !defined(__CC_NORCROFT) || !defined(__arm)
10 #error You must use the Norcroft ARM Compiler for Sapphire programs
13 #pragma force_top_level
14 #pragma include_only_once
19 /*----- Note --------------------------------------------------------------*
21 * This header file contains definitions and directives which are highly
22 * compiler specific. Only use /genuine/ Norcroft ARM C compilers!
25 /*----- Important types ---------------------------------------------------*/
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.
45 * Defines a register block, which is the only sane way of fiddling with
56 /* --- Hacky definition of a routine --- *
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.
63 typedef struct _opaque routine[];
67 * In case no-one else has defined it yet.
72 typedef unsigned size_t;
75 /*----- Sapphire-to-C veneers ---------------------------------------------*/
77 /* --- __sapph_veneer --- *
79 * This routine is used internally by the _sapph macro to build
80 * callable-from-Sapphire functions in C.
83 extern void __sapph_veneer(void);
87 * Allows you to build callable-from-Sapphire functions in C. The syntax
90 * _sapph(foo)(regset *r,<struct> *obj,<struct> *wsp,char *scratch)
95 * The routine must return an int built by using the macros below, for
96 * setting flags on exit.
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,
104 * _sapph(foo)(regset *r,<struct> *obj)
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.
112 * For reference, the code built by the macro is as follows:
119 #define _sapph(name) \
120 void name(void){_word(0xE92D4000);_word(0xE1A0E00F);__sapph_veneer();} \
123 /* --- Macros for returning flags --- *
125 * You can OR these together using the | operator to obtain interesting
126 * effects. For example,
128 * return (V_set | C_clear);
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.
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.
150 /* --- C-to-Sapphire veneers --- */
154 * Arguments: routine p == the routine to call
155 * regset *r == pointer to register block to use
157 * Returns: Zero, if no error was returned, or a pointer to the error.
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.
165 extern error *call(routine /* p */, regset */* r */);
167 /* --- _call, _callx --- *
169 * Arguments: routine p == the routine to call
170 * unsigned flags == various flags controlling arguments
171 * ... == a list of arguments and things
173 * Returns: For _call, the _return register (0 by default). For _callx,
174 * zero if no error, or a pointer to the error.
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:
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
186 extern int _call(routine /* p */, unsigned /* flags */, ...);
187 extern error *_callx(routine /* p */, unsigned /* flags */, ...);
189 /*----- SWI veneers -------------------------------------------------------*/
193 * Arguments: int swi == SWI number to call
194 * regset *r == registers to pass
196 * Returns: Pointer to error, or 0
198 * Use: Calls a SWI. Returned registers are stored in the regset,
202 extern error *swi(int /* swi */, regset */* r */);
204 /* --- _swi, _swix --- *
206 * Arguments: int swi == number of the SWI to call
207 * unsigned flags == various flags controlling arguments
208 * ... == a list of arguments and things
210 * Returns: For _swi, the _return register (0 by default). For _swix,
211 * zero if no error, or a pointer to the error.
213 * Use: Calls a SWI. The flags are described below. The optional
214 * arguments are as above.
217 extern int _swi(int /* swi */, unsigned /* flags */, ...);
218 extern error *_swix(int /* swi */, unsigned /* flags */, ...);
220 /*----- Flags for the veneers ---------------------------------------------*/
222 /* --- _flags -- return or output processor flags --- */
224 #define _flags (0x10)
226 /* --- _in and _inr -- input a register, or a range of registers --- */
228 #define _in(r) (1u << (r))
229 #define _inr(ra,rb) (((~0) << (ra)) ^ ((~0) << ((rb)+1)))
231 /* --- _out and _outr -- output a register, or a range of registers --- */
233 #define _out(r) (1u << (31-((r) == _flags ? 10 : (r))))
234 #define _outr(ra,rb) (((~0) << (31-(rb))) ^ ((~0) << (32-(ra))))
236 /* --- _block -- point a register at block built from arguments --- */
238 #define _block(r) (((r) << 12) | 0x800)
240 /* --- _return -- return register from _swi (not _swix) --- */
242 #define _return(r) ((r) == _flags ? 0xF0000 : (r) << 16)
244 /* --- Constants for ARM processor flags --- */
246 #define _n (0x80000000u)
247 #define _z (0x40000000u)
248 #define _c (0x20000000u)
249 #define _v (0x10000000u)
251 /* --- Acorn style capital-letter macros --- */
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)
265 /*----- C library support -------------------------------------------------*
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.
279 extern __pure int *cmath_errno(void);
280 #define errno (*cmath_errno())
284 * Sapphire's normal `sqrt' routine is an integer square root (courtesy of
285 * David Seal), so we need to cheat a bit here.
291 extern __pure double cmath_huge(void);
292 #define HUGE_VAL (cmath_huge())
294 #define sqrt(x) __sapph_sqrt(x)
298 * We define macros for toupper and tolower, since this is very simple under
299 * the Sapphire implementation of ctype.
305 extern __pure char *ctype_findTable(void);
306 #define __ctype (ctype_findTable())
308 #define tolower(c) (isupper(c) ? __ctype[c+256] : c)
309 #define toupper(c) (islower(c) ? __ctype[c+256] : c)
311 /* --- Memory moving routines --- */
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)
317 /*----- Basic Sapphire routines -------------------------------------------*/
319 /* --- Access to Sapphire environment block --- */
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.
328 /* --- Simple string functions --- *
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.
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.
345 #define strlen(s) str_len(s)
346 extern int strlen(const char */* s */);
347 /* Returns the length of a string.
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.
358 extern int strcmp(const char * /* a */, const char */* b */);
359 /* Compares two strings, returning <0, ==0 or >0 according to whether a<b,
363 extern int stricmp(const char */* a */, const char */* b */);
364 /* Compares to strings in a case-insensitive manner. Returns as strcmp.
367 extern char *strbuffer(void);
368 /* Returns the address of a 256-byte buffer. There are two buffers, which
369 * are returned alternately.
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.
377 /* --- Message routines --- */
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.
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
394 /* --- Memory allocation --- */
396 extern void *malloc(size_t /* size */);
397 /* Allocate a block of memory from a heap. The block won't move around.
400 #define free(p) __sapph_free(p)
401 extern void free(void * /* p */);
402 /* Free a block of memory allocated by malloc.
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.
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.
418 #define flex_free(a) __sapph_flex_free(a)
419 extern void flex_free(void */* a */);
420 /* Frees a flex block.
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.
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
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
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.
445 #define flex_load(x) __sapph_flex_load(x)
446 extern void *flex_load(void);
447 /* Restores a pointer from the relocation stack.
450 /*----- Sapphire routines -------------------------------------------------*/
452 /* --- sapphire_init --- *
454 * On entry: R0 == pointer to application name
455 * R1 == application's workspace size
456 * R2 == size of stack required
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
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
473 extern routine sapphire_init;
475 /* --- sapphire_disable --- *
477 * On entry: R0 == pointer to 0-terminated list of initialise routines
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
489 extern routine sapphire_disable;
491 /* --- sapphire_libInit --- *
497 * Use: Initialises the Sapphire library and client units.
500 extern routine sapphire_libInit;
502 /* --- sapphire_doInit --- *
504 * On entry: R0 == pointer to application name
505 * R1 == client workspace size
506 * R2 == requested stack size
507 * R3 == pointer to initialisation table
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
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
520 extern routine sapphire_doInit;
522 /* --- sapphire_doLibInit --- *
524 * On entry: R0 == address of library initialisation table
528 * Use: Initialises all currently uninitialised library units.
531 extern routine sapphire_doLibInit;
533 /* --- sapphire_doDisable --- *
535 * On entry: R0 == pointer to list of initialise routines to disable
536 * R1 == pointer to initialisation table
540 * Use: Prevents the given initialisation routines from being
541 * called. This is mainly useful in a dynamically linked
545 extern routine sapphire_doDisable;
547 /* --- sapphire_heapAddr --- *
551 * On exit: R1 == pointer to the heap base (for passing to OS_Heap)
553 * Use: Returns the address of the Sapphire heap.
556 extern routine sapphire_heapAddr;
558 /* --- sapphire_appName --- *
562 * On exit: R0 == pointer to application name (NULL terminated)
564 * Use: Returns a pointer to the application's name.
567 extern routine sapphire_appName;
569 /* --- sapphire_resetStack --- *
573 * On exit: R13 == stack pointer
575 * Use: Resets R13 to point to the top of the stack.
578 extern routine sapphire_resetStack;
580 /* --- sapphire_global --- *
582 * On entry: R0 == magic identifier for global variable
583 * R1 == size of area required
585 * On exit: R0 == pointer to area
586 * CS if the area already exists, CC otherwise
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.
592 * There is a limit on the number of global areas allowed, but
593 * this can be raised fairly easily if necessary.
595 * If an area can't be created, an error is generated.
598 extern routine sapphire_global;
600 /* --- Data relative to R11 --- */
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)
611 /*----- That's all, folks -------------------------------------------------*/