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