home *** CD-ROM | disk | FTP | other *** search
- Introduction
- ============
-
- OSLib is a set of functions and C headers to provide complete
- coverage of the RISC O S application programmer's interface in C. It
- provides access from C code to all RISC O S system calls ("SWI's") which
- is
-
- efficient: often, memory access is completely avoided;
- type-safe: every argument can be type-checked by the compiler;
- obvious: a SWI is called by the "obvious" syntax;
- complete: every SWI is covered;
- register-safe: hides (often idiosyncratic) register allocation;
- language-independent: although the headers are specific to C, the
- library is not - any A P C S-conformant language can call it.
-
- It also provides names for all the data structures and reason codes used
- by the A P I. Code that uses it is superior to similar code using
- _kernel_swi() or _swix(), both in terms of the compile-time checking
- that is available, and the size and speed of the code generated.
-
- In addition to the module files, there is also a file "types.h" which
- contains macros and types useful for any programme.
-
- This file explains how OSLib relates to the P R M descriptions of the
- SWI's in complete detail. It is best read in conjunction with the header
- files themselves.
-
- The OSLib Structuring Conventions
- === ===== =========== ===========
-
- Each header file provides
-
- function prototypes
- typedefs
- macros
-
- that completely specify the interface to a module. All symbols provided by
- "<module>.h" are of the form <module>_<name> (except some of the form
- <module><name>_<reason>). For functions, <name> is the name of the SWI,
- converted to lower-case, and with underscores inserted between each word:
-
- SWI Function
- --- --------
- OS_ReadLine os_read_line
- Wimp_CreateWindow wimp_create_window
-
- For typedefs, <name> is a sequence of words in lower-case, separated by
- underscores:
-
- Type Meaning
- ---- -------
- os_colour a palette entry value (0xbbggrr00)
- wimp_window a window definition structure
-
- For macros, <name> is a sequence of words in upper-case, separated by
- underscores:
-
- Macro Meaning
- ----- -------
- os_MODEVAR_XEIG_FACTOR a value for os_read_mode_variable
- error_ESCAPE the error number of Escape (17)
- wimp_ICON_NAME_LIMIT the largest length of an icon name
-
- (all macros for maximum values end in _LIMIT). There is also a special set
- of macros provided for more convenient handling of structures with a
- variable number of trailing parts, as used for mode selectors or Wimp
- window definitions, for example:
-
- Macro Meaning
- ----- -------
- os_PALETTE (nc) Declarator for a palette with |nc| colours
- os_SIZEOF_PALETTE (nc) Size of that palette
- wimp_WINDOW (ni) Declarator for a window with |ni| icons
- wimp_SIZEOF_WINDOW (ni) Size of the complete window definition
-
- Furthermore, every SWI number and SWI reason code has a macro defined of the
- form <Module>_<Name> (in mixed case form):
-
- Macro Value
- ----- -----
- OS_WriteC 0
- Font_FindFont 0x40081
-
- These are rarely needed.
-
- In fact, for each SWI, two functions are provided: one has a name
- prefixed with an x and returns a value of type |os_error *|, which is non-
- null if the SWI fails; the other does not start with an x, and never returns
- an error: if the SWI fails, a signal (|SIGOSERROR|, number 10) is raised,
- and may be caught by installing a signal handler for it. The non-x form can
- therefore return a result, instead of having to write to an output argument:
- for example, the SWI Wimp_CreateWindow can be called by either of the
- prototypes
-
- os_error *xwimp_create_window (wimp_window *window, wimp_w *w);
- wimp_w wimp_create_window (wimp_window *window);
-
- They have exactly the same effect if all goes well, but if there is an
- error, the first just returns it, while the other raises |SIGOSERROR| and
- does not return at all. (If you use the second, the signal handler for
- |SIGOSERROR| can use _kernel_last_oserror() to find out what the error was.)
-
- The function prototype is derived from the SWI description in the
- following way. Arguments corresponding to input registers appear first in
- order in the argument list, followed by the addresses of variables in which
- the output registers' values are to be written. If an output register value
- is not needed, a null pointer can be written in that position. (Since |int|
- and all pointer types are 32 bits on the ARM, it doesn't matter which type
- of null pointer is used.)
-
- Most of the types are fully defined: e g, a |wimp_window| is a structure
- type with all the fields defined with the right type and name to be passed to
- any SWI that uses it. Some types are "abstract," however: they are exported
- by a module, but the internal structure is not accessible to its clients.
- The best way of representing this in C is by an unspecified pointer type: a
- definition of the form
-
- typedef struct <tag> *<type>
-
- where the structure is never defined in full. Doing this allows the
- compiler to typecheck arguments of these types, as in the wimp_-
- create_window() example above.
-
- In addition, various modules use values from name spaces that are
- centrally allocated by Acorn. These include: |error_|, |message_|,
- |...v|, |event_| and |upcall_|, and they each have their own prefix.
- They correspond to error numbers, WIMP message numbers, vectors (which
- are reason codes for OS_CallAVector), service calls (reason codes for
- OS_ServiceCall), events (reason codes for OS_GenerateEvent) and upcalls
- (reason codes for OS_UpCall), respectively. In cases where name clashes
- are possible, the module name occurs in the <name> part:
-
- error_BUFFER_MANAGER_BUFFER_TOO_SMALL
- error_COLOUR_TRANS_BAD_DEPTH
-
- (Vectors are represented by a suffix, |...v|, rather than a prefix, since
- this is familiar.) These rules mean that if you are writing code for RISC
- O S, and you avoid
-
- (a) all names that start with the name <module> of any
- "<module>.h" you need to include;
-
- (b) all names that start with |error|, |message|, |event|
- or |upcall|, or end with |v|;
-
- then no names clashes will occur.
-
- Types.h
- =======
-
- All OSLib header files ensure that "types.h" is included. This file
- contains various types, macros for values, and function-like macros that
- are generally useful. There are further macros in "macros.h." They are
- described here:
-
- Types
- -----
-
- |bits|: Used for flags values and masks, normally consisting of fields of
- 1 or more bits. Macros are normally provided to help with getting these
- fields out: for a 1-bit field, a macro |X| such that
-
- To Use
- -- ---
- Read the field (v & X) != NONE
- Write a 0 v &= ~X
- Write a 1 v |= X
-
- and for a multi-bit field, macros X and X_SHIFT such that
-
- To Use
- -- ---
- Read the field (v & X) >> X_SHIFT
- Write a value |w| v = (v & ~X) | w << X_SHIFT.
-
- |bool|: Used for a truth value.
-
- |byte|: Used for a single byte value, as an alternative to |char| when the
- values are just data, rather than being characters as such. It is an unsigned
- type, which means that 2 instructions can be saved in P C C mode, where
- |char| is signed and must be sign-extended.
-
- Constant-like macros
- ------------- ------
-
- |NULL|: the usual C null pointer constant.
-
- |FALSE|: value of type |bool| representing falsehood.
-
- |TRUE|: value of type |bool| representing truth.
-
- |NONE|: value of type |bits| with all bits clear.
-
- |ALL|: value of type |bits| with all bits set.
-
- |SKIP|: may be used as a "don't care" value for |int|, pointers,
- |bits|.
-
- |SIG_LIMIT|: largest signal number + 1.
-
- |_C|, |_Z|, |_N|, |_V|: masks for the flags in the P S R.
-
- |DEC_WIDTH|: the length of INT_MAX (2147483647) printed with %d.
-
- |SHORT_DEC_WIDTH|: the length of SHRT_MAX (32767) printed with %hd.
-
- |LONG_DEC_WIDTH|: the length of LONG_MAX (2147483647) printed with %ld.
-
- |OCT_WIDTH|: the length of UINT_MAX (37777777777) printed with %o.
-
- |SHORT_OCT_WIDTH|: the length of USHRT_MAX (177777) printed with %ho.
-
- |LONG_OCT_WIDTH|: the length of ULONG_MAX (37777777777) printed with %lo.
-
- |UNSIGNED_WIDTH|: the length of UINT_MAX (4294967295) printed with %u.
-
- |SHORT_UNSIGNED_WIDTH|: the length of USHRT_MAX (65535) printed with %hu.
-
- |LONG_UNSIGNED_WIDTH|: the length of ULONG_MAX (4294967295) printed with
- %lu.
-
- |HEX_WIDTH|: the length of UINT_MAX (FFFFFFFF) printed with %x.
-
- |SHORT_HEX_WIDTH|: the length of USHRT_MAX (FFFF) printed with %hx.
-
- |LONG_HEX_WIDTH|: the length of ULONG_MAX (FFFFFFFF) printed with %lx.
-
- |FLT_WIDTH|: the precision needed to distinguish 1 + FLT_EPSILON from 1
- printed with %f.
-
- |DBL_WIDTH|: the precision needed to distinguish 1 + DBL_EPSILON from 1
- printed with %f.
-
- |LDBL_WIDTH|: the precision needed to distinguish 1 + LDBL_EPSILON from 1
- printed with %Lf.
-
- |FLT_EXP_WIDTH|: the length of the exponent of FLT_MAX printed with %f.
-
- |DBL_EXP_WIDTH|: the length of the exponent of DBL_MAX printed with %f.
-
- |LDBL_EXP_WIDTH|: the length of the exponent of LDBL_MAX printed with %Lf.
-
- |ERROR|: intended as an "out-of-band" value to be returned by functions
- like fgetc() which return |EOF| on end-of-file. |ERROR| may be used to
- indicate an error condition.
-
- |UNKNOWN|: used to declare (but not define) arrays of unknown size, as
- an argument to the type macros (e g, wimp_WINDOW()) described above.
-
- Function-like macros
- ------------- ------
-
- |WHETHER|: convert a bool value to a string.
-
- |MAX|: larger of two values.
-
- |MIN|: smaller of two values.
-
- |MAXAB|: larger of two values and assign.
-
- |MINAB|: smaller of two values and assign.
-
- |ABS|: absolute value.
-
- |SGN|: signum.
-
- |DIM|: positive difference.
-
- |SQR|: square.
-
- |RATIO|: integer division, rounding to nearer.
-
- |BOOL|: convert an integer to bool.
-
- |UCHAR|: character corresponding to a digit (upper case preferred).
-
- |LCHAR|: ditto, lower case.
-
- |BINEXP|: 2 to the power of.
-
- |ISDIGIT|: a digit?
-
- |ISXDIGIT|: a hex digit?
-
- |DIGIT|: if a digit, then which, else undefined.
-
- |XDIGIT|: if a hex digit, then which, else undefined.
-
- |DBLEQ|: equality for floating-point numbers (requires a tolerance)
-
- |BIT|: the bit at an offset from a pointer.
-
- |SET|: set a bit at an offset from a pointer.
-
- |CLR|: clear a bit at an offset from a pointer.
-
- |CLEAR|: clear a string.
-
- |EMPTY|: is a string empty?
-
- |NCOPY|: copy at most a given number of characters from a string, and
- terminate it.
-
- |STR_|: helper macro for STR.
-
- |STR|: convert a macro to source string.
-
- |COUNT|: number of elements in an array.
-
- |ALIGN|: round an integer up to the next multiple of 4.
-
- |WORD|: assembles an |int| from an unaligned byte pointer.
-
- |SHORT|: assembles a |short| from an unaligned byte pointer.
-
- Macros that "change the language"
- ------ ---- ------- --- ---------
-
- (Not everyone likes using these!)
-
- |AS| is the same as |.|, but can be used to let the reader know that the
- left operand is a |union| rather than a |struct|.
-
- |ASREF| is the same as |->|, but can be used to let the reader know that
- the left operand is a |union *| rather than a |struct *|.
-
- |_| is the same as |,|, but if used to separate the arguments of a macro
- call is not recognised as a comma by the preprocessor. This lets you write
- macros with variable numbers of arguments.
-
- |__swi| is understood as a compiler directive by C release 5 (but not
- by earlier versions of C, nor by CFront) to call a function using a SWI
- instruction rather than by a BL. "Types.h" therefore includes some
- directives to enable the uses of |__swi| in the headers to be "hidden"
- in these cases by using -D__swi on the cc command line.
-
- Macros to suppress compiler warnings
- ------ -- -------- -------- --------
-
- |NOT_USED|: Suppress "variable not used" message.
-
- |UNSET|: Suppress "variable may be used before being set" message.
-
- Additional Structuring Rules
- ========== =========== =====
-
- The design aims listed in paragraph 1 are not completely compatible. In
- order to provide type-safety, it is necessary to provide multiple veneers
- for some SWI's. These fall into two classes: where a SWI has multiple reason
- codes, each reason code is provided with a separate function; and where a
- SWI has two or more different variants, each variant is provided with its
- own function.
-
- Reason codes
- ------ -----
-
- Many SWI's have several reason codes each of which has its own distinct
- purpose and register usage. In this case, each reason code is provided with
- its own function. (SWI's with a "reason code" parameter which does not
- affect the interpretation of the other parameters are not treated like this:
- instead, the reason codes are just provided as macros.) In some cases, one
- reason code may itself have different sub-reason codes. In every case,
- the functions that are derived from the SWI use the entirety of the SWI
- name (with no underscore) as their prefix. Some have their own header
- file (e g, OS_SpriteOp, reason codes in "osspriteop.h"), others share
- the header file with the SWI (e g, PDriver_MiscOp, reason codes in
- "pdriver.h"). Toolbox_object_misc_op() has a dynamically extensible set
- of reason codes provided by object modules: these use the name of the
- object, and are in the object's header file.
-
- Where a header file name is longer than 10 characters, the full name
- should be used in |#include| statements. FileCore-based filing systems will
- truncate the file name to 10 characters, if the *Configure option 'Truncate'
- is 'On' (which is recommended). This means that, for example, the line
- |#include "messagetrans.h"| will work on all filing systems: FileCore-based
- ones will convert the name to "messagetra.h."
-
- OS_WriteI might be considered to have a reason code (the character to be
- written), but since it is part of the SWI number, each character has a
- separate function. This is not worthwhile for printing characters, but for
- other VDU codes gives useful calls like os_clg() (to clear the graphics
- window), os_bell() (to ring the bell) etc. (The complete list is
- in "os.h.")
-
- Many of the reason codes of OS_CallAVector have been omitted, namely,
- those where there are many sub-reason codes, and the purpose of the vector
- is exactly duplicated by a SWI or SWI's. So you will not find findv_-
- openin() (to call sub-reason code OSFind_OpenIn of reason code FindV of
- SWI OS_CallAVector), because it is identical in purpose to osfind_openin().
- If there are reason codes but no SWI, the reason codes do have functions
- provided (e g, PaletteV), and if there are no reason codes, the function is
- provided even if it does duplicate a SWI - for example, you can call
- os_writec() or wrchv() with the same effect (unless you are implementing
- them, of course). This is all just to keep the library size down: if it
- causes a problem, it can be reviewed. (Since calls to OS_GenerateEvent
- and OS_UpCall are already distributed through many files, vectored
- versions of them would have to be distributed in the same way.)
-
- Lastly, calls provided by FileSwitch are in "fileswitch.h", unless they
- have their own header. (The separate headers are "osargs.h," osfile.h,"
- osfind.h," osfscontrol.h," "osgbpb.h.") Also, some of the types that
- might be expected to be defined in these headers are actually defined in
- "fileswitch.h," to avoid circular references.
-
- Variants
- --------
-
- Some SWI's have two or more different functions that call them, because
- they have two different calling conventions that cannot be easily captured
- using C's type system. These should be obvious from the name; failing
- that, the header file says exactly which SWI is called, and which values
- are placed into which registers. A few examples are described here, to
- give an idea of why variants exist.
-
- Colourtrans_select_table_for_sprite() (variant of
- colourtrans_select_- table()) takes an |osspriteop_area *| and an
- |osspriteop_id|, rather than an |os_mode| and an |os_palette *|, as its
- first two arguments. The same applies to
- colourtrans_generate_table_for_sprite() (variant of colourtrans_-
- generate_table()) and colourtrans_select_gcol_table_for_sprite() (variant of
- colourtrans_select_gcol_table()).
-
- Os_read_colour() (variant of os_set_colour()) is provided so that
- os_set_colour() can remain backwards-compatible.
-
- Squash_compress_return_sizes() (variant of squash_compress()) and
- squash_decompress_return_sizes() (variant of squash_decompress()) are
- provided because of the different purposes dependent on bit 3 of R0.
-
- Stringset{set,get}selected_string() and
- stringset{set,get}selected_index() are both provided, to allow correct
- typechecking of the string or integer argument.
-
- Territory_read_symbols() is divided into 3 variants, territory_read_-
- boolean_symbols(), territory_read_integer_symbols() and territory_read_-
- string_symbols(), because different symbols have different types.
-
- Wimp_send_message_to_window() (variant of wimp_send_message()) takes
- a |wimp_w| and a |wimp_i| rather than a |wimp_t|, and returns a result
- (the task handle) which wimp_send_message() does not.
-
- Conclusion
- ==========
- Although there seem to be a lot of rules, that is because the RISC O S
- A P I is large. For normal application programming, most of it is not
- needed: applications don't normally deal with vectors, upcalls or service
- calls, for example, or do any direct access to disc structures. However,
- this is not ruled out. The C headers contain the complete description of
- exactly what each function does in terms of the mapping of the arguments to
- ARM registers, so no other documentation is needed.
-
- OSLib provides a very convenient interface to the RISC O S programmer,
- since all the facilities of the C compiler are available to catch errors
- and generate good code. It is conceptually very small, in that it is
- completely documented by this file. As a bonus, code written using it is
- smaller and faster than code written using other means.
-
- Disclaimer
- ==========
-
- OSLib is copyright © 1995 Acorn Computers Ltd. It is distributed in
- the hope that it will be useful, but without any warranty; without even
- the implied warranty of merchantability or fitness for a particular
- purpose.
-
- Fault reports and suggestions for improvement may be sent to the
- author, Jonathan Coxhead <jcoxhead@acorn.co.uk>. Although this is an
- Acorn address, OSLib is not an official Acorn product.
-