home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / oslib / oslib_1 / OSLib / ReadMe < prev    next >
Encoding:
Text File  |  1995-08-22  |  18.4 KB  |  470 lines

  1. Introduction
  2. ============
  3.  
  4.    OSLib is a set of functions and C headers to provide complete
  5. coverage of the RISC O S application programmer's interface in C. It
  6. provides access from C code to all RISC O S system calls ("SWI's") which
  7. is
  8.  
  9.       efficient: often, memory access is completely avoided;
  10.       type-safe: every argument can be type-checked by the compiler;
  11.       obvious: a SWI is called by the "obvious" syntax;
  12.       complete: every SWI is covered;
  13.       register-safe: hides (often idiosyncratic) register allocation;
  14.       language-independent: although the headers are specific to C, the
  15.          library is not - any A P C S-conformant language can call it.
  16.  
  17. It also provides names for all the data structures and reason codes used
  18. by the A P I. Code that uses it is superior to similar code using
  19. _kernel_swi() or _swix(), both in terms of the compile-time checking
  20. that is available, and the size and speed of the code generated.
  21.  
  22.    In addition to the module files, there is also a file "types.h" which
  23. contains macros and types useful for any programme.
  24.  
  25.    This file explains how OSLib relates to the P R M descriptions of the
  26. SWI's in complete detail. It is best read in conjunction with the header
  27. files themselves.
  28.  
  29. The OSLib Structuring Conventions
  30. === ===== =========== ===========
  31.  
  32.    Each header file provides
  33.  
  34.       function prototypes
  35.       typedefs
  36.       macros
  37.  
  38. that completely specify the interface to a module. All symbols provided by
  39. "<module>.h" are of the form <module>_<name> (except some of the form
  40. <module><name>_<reason>). For functions, <name> is the name of the SWI,
  41. converted to lower-case, and with underscores inserted between each word:
  42.  
  43.       SWI                     Function
  44.       ---                     --------
  45.       OS_ReadLine             os_read_line
  46.       Wimp_CreateWindow       wimp_create_window
  47.  
  48. For typedefs, <name> is a sequence of words in lower-case, separated by
  49. underscores:
  50.  
  51.       Type                    Meaning
  52.       ----                    -------
  53.       os_colour               a palette entry value (0xbbggrr00)
  54.       wimp_window             a window definition structure
  55.  
  56. For macros, <name> is a sequence of words in upper-case, separated by
  57. underscores:
  58.  
  59.       Macro                   Meaning
  60.       -----                   -------
  61.       os_MODEVAR_XEIG_FACTOR  a value for os_read_mode_variable
  62.       error_ESCAPE            the error number of Escape (17)
  63.       wimp_ICON_NAME_LIMIT    the largest length of an icon name
  64.  
  65. (all macros for maximum values end in _LIMIT). There is also a special set
  66. of macros provided for more convenient handling of structures with a
  67. variable number of trailing parts, as used for mode selectors or Wimp
  68. window definitions, for example:
  69.  
  70.       Macro                   Meaning
  71.       -----                   -------
  72.       os_PALETTE (nc)         Declarator for a palette with |nc| colours
  73.       os_SIZEOF_PALETTE (nc)  Size of that palette
  74.       wimp_WINDOW (ni)        Declarator for a window with |ni| icons
  75.       wimp_SIZEOF_WINDOW (ni) Size of the complete window definition
  76.  
  77. Furthermore, every SWI number and SWI reason code has a macro defined of the
  78. form <Module>_<Name> (in mixed case form):
  79.  
  80.       Macro                   Value
  81.       -----                   -----
  82.       OS_WriteC               0
  83.       Font_FindFont           0x40081
  84.  
  85. These are rarely needed.
  86.  
  87.    In fact, for each SWI, two functions are provided: one has a name
  88. prefixed with an x and returns a value of type |os_error *|, which is non-
  89. null if the SWI fails; the other does not start with an x, and never returns
  90. an error: if the SWI fails, a signal (|SIGOSERROR|, number 10) is raised,
  91. and may be caught by installing a signal handler for it. The non-x form can
  92. therefore return a result, instead of having to write to an output argument:
  93. for example, the SWI Wimp_CreateWindow can be called by either of the
  94. prototypes
  95.  
  96.       os_error *xwimp_create_window (wimp_window *window, wimp_w *w);
  97.       wimp_w wimp_create_window (wimp_window *window);
  98.  
  99. They have exactly the same effect if all goes well, but if there is an
  100. error, the first just returns it, while the other raises |SIGOSERROR| and
  101. does not return at all. (If you use the second, the signal handler for
  102. |SIGOSERROR| can use _kernel_last_oserror() to find out what the error was.)
  103.  
  104.    The function prototype is derived from the SWI description in the
  105. following way. Arguments corresponding to input registers appear first in
  106. order in the argument list, followed by the addresses of variables in which
  107. the output registers' values are to be written. If an output register value
  108. is not needed, a null pointer can be written in that position. (Since |int|
  109. and all pointer types are 32 bits on the ARM, it doesn't matter which type
  110. of null pointer is used.)
  111.  
  112.    Most of the types are fully defined: e g, a |wimp_window| is a structure
  113. type with all the fields defined with the right type and name to be passed to
  114. any SWI that uses it. Some types are "abstract," however: they are exported
  115. by a module, but the internal structure is not accessible to its clients.
  116. The best way of representing this in C is by an unspecified pointer type: a
  117. definition of the form
  118.  
  119.       typedef struct <tag> *<type>
  120.  
  121. where the structure is never defined in full. Doing this allows the
  122. compiler to typecheck arguments of these types, as in the wimp_-
  123. create_window() example above.
  124.  
  125.    In addition, various modules use values from name spaces that are
  126. centrally allocated by Acorn. These include: |error_|, |message_|,
  127. |...v|, |event_| and |upcall_|, and they each have their own prefix.
  128. They correspond to error numbers, WIMP message numbers, vectors (which
  129. are reason codes for OS_CallAVector), service calls (reason codes for
  130. OS_ServiceCall), events (reason codes for OS_GenerateEvent) and upcalls
  131. (reason codes for OS_UpCall), respectively. In cases where name clashes
  132. are possible, the module name occurs in the <name> part:
  133.  
  134.       error_BUFFER_MANAGER_BUFFER_TOO_SMALL
  135.       error_COLOUR_TRANS_BAD_DEPTH
  136.  
  137. (Vectors are represented by a suffix, |...v|, rather than a prefix, since
  138. this is familiar.) These rules mean that if you are writing code for RISC
  139. O S, and you avoid
  140.  
  141.          (a) all names that start with the name <module> of any
  142.       "<module>.h" you need to include;
  143.  
  144.          (b) all names that start with |error|, |message|, |event|
  145.       or |upcall|, or end with |v|;
  146.  
  147. then no names clashes will occur.
  148.  
  149. Types.h
  150. =======
  151.  
  152.    All OSLib header files ensure that "types.h" is included. This file
  153. contains various types, macros for values, and function-like macros that
  154. are generally useful. There are further macros in "macros.h." They are
  155. described here:
  156.  
  157. Types
  158. -----
  159.  
  160.    |bits|: Used for flags values and masks, normally consisting of fields of
  161. 1 or more bits. Macros are normally provided to help with getting these
  162. fields out: for a 1-bit field, a macro |X| such that
  163.  
  164.       To                      Use
  165.       --                      ---
  166.       Read the field          (v & X) != NONE
  167.       Write a 0               v &= ~X
  168.       Write a 1               v |= X
  169.  
  170. and for a multi-bit field, macros X and X_SHIFT such that
  171.  
  172.       To                      Use
  173.       --                      ---
  174.       Read the field          (v & X) >> X_SHIFT
  175.       Write a value |w|       v = (v & ~X) | w << X_SHIFT.
  176.  
  177.    |bool|: Used for a truth value.
  178.  
  179.    |byte|: Used for a single byte value, as an alternative to |char| when the
  180. values are just data, rather than being characters as such. It is an unsigned
  181. type, which means that 2 instructions can be saved in P C C mode, where
  182. |char| is signed and must be sign-extended.
  183.  
  184. Constant-like macros
  185. ------------- ------
  186.  
  187.    |NULL|: the usual C null pointer constant.
  188.  
  189.    |FALSE|: value of type |bool| representing falsehood.
  190.  
  191.    |TRUE|: value of type |bool| representing truth.
  192.  
  193.    |NONE|: value of type |bits| with all bits clear.
  194.  
  195.    |ALL|: value of type |bits| with all bits set.
  196.  
  197.    |SKIP|: may be used as a "don't care" value for |int|, pointers,
  198. |bits|.
  199.  
  200.    |SIG_LIMIT|: largest signal number + 1.
  201.  
  202.    |_C|, |_Z|, |_N|, |_V|: masks for the flags in the P S R.
  203.  
  204.    |DEC_WIDTH|: the length of INT_MAX (2147483647) printed with %d.
  205.  
  206.    |SHORT_DEC_WIDTH|: the length of SHRT_MAX (32767) printed with %hd.
  207.  
  208.    |LONG_DEC_WIDTH|: the length of LONG_MAX (2147483647) printed with %ld.
  209.  
  210.    |OCT_WIDTH|: the length of UINT_MAX (37777777777) printed with %o.
  211.  
  212.    |SHORT_OCT_WIDTH|: the length of USHRT_MAX (177777) printed with %ho.
  213.  
  214.    |LONG_OCT_WIDTH|: the length of ULONG_MAX (37777777777) printed with %lo.
  215.  
  216.    |UNSIGNED_WIDTH|: the length of UINT_MAX (4294967295) printed with %u.
  217.  
  218.    |SHORT_UNSIGNED_WIDTH|: the length of USHRT_MAX (65535) printed with %hu.
  219.  
  220.    |LONG_UNSIGNED_WIDTH|: the length of ULONG_MAX (4294967295) printed with
  221. %lu.
  222.  
  223.    |HEX_WIDTH|: the length of UINT_MAX (FFFFFFFF) printed with %x.
  224.  
  225.    |SHORT_HEX_WIDTH|: the length of USHRT_MAX (FFFF) printed with %hx.
  226.  
  227.    |LONG_HEX_WIDTH|: the length of ULONG_MAX (FFFFFFFF) printed with %lx.
  228.  
  229.    |FLT_WIDTH|: the precision needed to distinguish 1 + FLT_EPSILON from 1
  230. printed with %f.
  231.  
  232.    |DBL_WIDTH|: the precision needed to distinguish 1 + DBL_EPSILON from 1
  233. printed with %f.
  234.  
  235.    |LDBL_WIDTH|: the precision needed to distinguish 1 + LDBL_EPSILON from 1
  236. printed with %Lf.
  237.  
  238.    |FLT_EXP_WIDTH|: the length of the exponent of FLT_MAX printed with %f.
  239.  
  240.    |DBL_EXP_WIDTH|: the length of the exponent of DBL_MAX printed with %f.
  241.  
  242.    |LDBL_EXP_WIDTH|: the length of the exponent of LDBL_MAX printed with %Lf.
  243.  
  244.    |ERROR|: intended as an "out-of-band" value to be returned by functions
  245. like fgetc() which return |EOF| on end-of-file. |ERROR| may be used to
  246. indicate an error condition.
  247.  
  248.    |UNKNOWN|: used to declare (but not define) arrays of unknown size, as
  249. an argument to the type macros (e g, wimp_WINDOW()) described above.
  250.  
  251. Function-like macros
  252. ------------- ------
  253.  
  254.    |WHETHER|: convert a bool value to a string.
  255.  
  256.    |MAX|: larger of two values.
  257.  
  258.    |MIN|: smaller of two values.
  259.  
  260.    |MAXAB|: larger of two values and assign.
  261.  
  262.    |MINAB|: smaller of two values and assign.
  263.  
  264.    |ABS|: absolute value.
  265.  
  266.    |SGN|: signum.
  267.  
  268.    |DIM|: positive difference.
  269.  
  270.    |SQR|: square.
  271.  
  272.    |RATIO|: integer division, rounding to nearer.
  273.  
  274.    |BOOL|: convert an integer to bool.
  275.  
  276.    |UCHAR|: character corresponding to a digit (upper case preferred).
  277.  
  278.    |LCHAR|: ditto, lower case.
  279.  
  280.    |BINEXP|: 2 to the power of.
  281.  
  282.    |ISDIGIT|: a digit?
  283.  
  284.    |ISXDIGIT|: a hex digit?
  285.  
  286.    |DIGIT|: if a digit, then which, else undefined.
  287.  
  288.    |XDIGIT|: if a hex digit, then which, else undefined.
  289.  
  290.    |DBLEQ|: equality for floating-point numbers (requires a tolerance)
  291.  
  292.    |BIT|: the bit at an offset from a pointer.
  293.  
  294.    |SET|: set a bit at an offset from a pointer.
  295.  
  296.    |CLR|: clear a bit at an offset from a pointer.
  297.  
  298.    |CLEAR|: clear a string.
  299.  
  300.    |EMPTY|: is a string empty?
  301.  
  302.    |NCOPY|: copy at most a given number of characters from a string, and
  303. terminate it.
  304.  
  305.    |STR_|: helper macro for STR.
  306.  
  307.    |STR|: convert a macro to source string.
  308.  
  309.    |COUNT|: number of elements in an array.
  310.  
  311.    |ALIGN|: round an integer up to the next multiple of 4.
  312.  
  313.    |WORD|: assembles an |int| from an unaligned byte pointer.
  314.  
  315.    |SHORT|: assembles a |short| from an unaligned byte pointer.
  316.  
  317. Macros that "change the language" 
  318. ------ ---- ------- --- ---------
  319.  
  320.    (Not everyone likes using these!) 
  321.  
  322.    |AS| is the same as |.|, but can be used to let the reader know that the
  323. left operand is a |union| rather than a |struct|.
  324.  
  325.    |ASREF| is the same as |->|, but can be used to let the reader know that
  326. the left operand is a |union *| rather than a |struct *|.
  327.  
  328.    |_| is the same as |,|, but if used to separate the arguments of a macro
  329. call is not recognised as a comma by the preprocessor. This lets you write
  330. macros with variable numbers of arguments.
  331.  
  332.    |__swi| is understood as a compiler directive by C release 5 (but not
  333. by earlier versions of C, nor by CFront) to call a function using a SWI
  334. instruction rather than by a BL. "Types.h" therefore includes some
  335. directives to enable the uses of |__swi| in the headers to be "hidden"
  336. in these cases by using -D__swi on the cc command line.
  337.  
  338. Macros to suppress compiler warnings
  339. ------ -- -------- -------- --------
  340.  
  341.    |NOT_USED|: Suppress "variable not used" message.
  342.  
  343.    |UNSET|: Suppress "variable may be used before being set" message.
  344.  
  345. Additional Structuring Rules 
  346. ========== =========== =====
  347.  
  348.    The design aims listed in paragraph 1 are not completely compatible. In
  349. order to provide type-safety, it is necessary to provide multiple veneers
  350. for some SWI's. These fall into two classes: where a SWI has multiple reason
  351. codes, each reason code is provided with a separate function; and where a
  352. SWI has two or more different variants, each variant is provided with its
  353. own function.
  354.  
  355. Reason codes 
  356. ------ -----
  357.  
  358.    Many SWI's have several reason codes each of which has its own distinct
  359. purpose and register usage. In this case, each reason code is provided with
  360. its own function. (SWI's with a "reason code" parameter which does not
  361. affect the interpretation of the other parameters are not treated like this:
  362. instead, the reason codes are just provided as macros.) In some cases, one
  363. reason code may itself have different sub-reason codes. In every case,
  364. the functions that are derived from the SWI use the entirety of the SWI
  365. name (with no underscore) as their prefix. Some have their own header
  366. file (e g, OS_SpriteOp, reason codes in "osspriteop.h"), others share
  367. the header file with the SWI (e g, PDriver_MiscOp, reason codes in
  368. "pdriver.h"). Toolbox_object_misc_op() has a dynamically extensible set
  369. of reason codes provided by object modules: these use the name of the
  370. object, and are in the object's header file.
  371.  
  372.    Where a header file name is longer than 10 characters, the full name
  373. should be used in |#include| statements. FileCore-based filing systems will
  374. truncate the file name to 10 characters, if the *Configure option 'Truncate'
  375. is 'On' (which is recommended). This means that, for example, the line
  376. |#include "messagetrans.h"| will work on all filing systems: FileCore-based
  377. ones will convert the name to "messagetra.h."
  378.  
  379.    OS_WriteI might be considered to have a reason code (the character to be
  380. written), but since it is part of the SWI number, each character has a
  381. separate function. This is not worthwhile for printing characters, but for
  382. other VDU codes gives useful calls like os_clg() (to clear the graphics
  383. window), os_bell() (to ring the bell) etc. (The complete list is
  384. in "os.h.")
  385.  
  386.    Many of the reason codes of OS_CallAVector have been omitted, namely,
  387. those where there are many sub-reason codes, and the purpose of the vector
  388. is exactly duplicated by a SWI or SWI's. So you will not find findv_-
  389. openin() (to call sub-reason code OSFind_OpenIn of reason code FindV of
  390. SWI OS_CallAVector), because it is identical in purpose to osfind_openin().
  391. If there are reason codes but no SWI, the reason codes do have functions
  392. provided (e g, PaletteV), and if there are no reason codes, the function is
  393. provided even if it does duplicate a SWI - for example, you can call
  394. os_writec() or wrchv() with the same effect (unless you are implementing
  395. them, of course). This is all just to keep the library size down: if it
  396. causes a problem, it can be reviewed. (Since calls to OS_GenerateEvent
  397. and OS_UpCall are already distributed through many files, vectored
  398. versions of them would have to be distributed in the same way.)
  399.  
  400.    Lastly, calls provided by FileSwitch are in "fileswitch.h", unless they
  401. have their own header. (The separate headers are "osargs.h," osfile.h,"
  402. osfind.h," osfscontrol.h," "osgbpb.h.") Also, some of the types that
  403. might be expected to be defined in these headers are actually defined in
  404. "fileswitch.h," to avoid circular references.
  405.  
  406. Variants
  407. --------
  408.  
  409.    Some SWI's have two or more different functions that call them, because
  410. they have two different calling conventions that cannot be easily captured
  411. using C's type system. These should be obvious from the name; failing
  412. that, the header file says exactly which SWI is called, and which values
  413. are placed into which registers. A few examples are described here, to
  414. give an idea of why variants exist.
  415.  
  416.    Colourtrans_select_table_for_sprite() (variant of
  417. colourtrans_select_- table()) takes an |osspriteop_area *| and an
  418. |osspriteop_id|, rather than an |os_mode| and an |os_palette *|, as its
  419. first two arguments. The same applies to
  420. colourtrans_generate_table_for_sprite() (variant of colourtrans_-
  421. generate_table()) and colourtrans_select_gcol_table_for_sprite() (variant of
  422. colourtrans_select_gcol_table()).
  423.  
  424.    Os_read_colour() (variant of os_set_colour()) is provided so that
  425. os_set_colour() can remain backwards-compatible.
  426.  
  427.    Squash_compress_return_sizes() (variant of squash_compress()) and
  428. squash_decompress_return_sizes() (variant of squash_decompress()) are
  429. provided because of the different purposes dependent on bit 3 of R0.
  430.  
  431.    Stringset{set,get}selected_string() and 
  432. stringset{set,get}selected_index() are both provided, to allow correct
  433. typechecking of the string or integer argument.
  434.  
  435.    Territory_read_symbols() is divided into 3 variants, territory_read_-
  436. boolean_symbols(), territory_read_integer_symbols() and territory_read_-
  437. string_symbols(), because different symbols have different types.
  438.  
  439.    Wimp_send_message_to_window() (variant of wimp_send_message()) takes
  440. a |wimp_w| and a |wimp_i| rather than a |wimp_t|, and returns a result
  441. (the task handle) which wimp_send_message() does not.
  442.  
  443. Conclusion
  444. ==========
  445.    Although there seem to be a lot of rules, that is because the RISC O S
  446. A P I is large. For normal application programming, most of it is not
  447. needed: applications don't normally deal with vectors, upcalls or service
  448. calls, for example, or do any direct access to disc structures. However,
  449. this is not ruled out. The C headers contain the complete description of
  450. exactly what each function does in terms of the mapping of the arguments to
  451. ARM registers, so no other documentation is needed.
  452.  
  453.    OSLib provides a very convenient interface to the RISC O S programmer,
  454. since all the facilities of the C compiler are available to catch errors
  455. and generate good code. It is conceptually very small, in that it is
  456. completely documented by this file. As a bonus, code written using it is
  457. smaller and faster than code written using other means.
  458.  
  459. Disclaimer
  460. ==========
  461.  
  462.    OSLib is copyright © 1995 Acorn Computers Ltd. It is distributed in
  463. the hope that it will be useful, but without any warranty; without even
  464. the implied warranty of merchantability or fitness for a particular
  465. purpose.
  466.  
  467.    Fault reports and suggestions for improvement may be sent to the
  468. author, Jonathan Coxhead <jcoxhead@acorn.co.uk>. Although this is an
  469. Acorn address, OSLib is not an official Acorn product.
  470.