




          ===========================================================
                DDDDD           DDDDD               SSSS
                 D   Dunfield    D   D             S
                 D   D           D   Development    SSSS 
                 D   D           D   D                  Systems
                DDDDD           DDDDD               SSSS
          ===========================================================
          MM   MM  IIIIIII    CCCC   RRRRRR     OOO             CCCC
          M M M M     I      C    C  R     R   O   O           C    C
          M  M  M     I     C        R     R  O     O         C
          M     M     I     C        RRRRRR   O     O  -----  C
          M     M     I     C        R   R    O     O         C
          M     M     I      C    C  R    R    O   O           C    C
          M     M  IIIIIII    CCCC   R     R    OOO             CCCC
          ===========================================================



                                 A 'C' compiler

                                      for

                             The CUBIX/6809 system


                                Technical Manual


                                  Release 3.23

                               Revised 01-Nov-02










                          Dunfield Development Systems
                          ----------------------------
                             High quality tools for
                              Embedded Development
                                 at low prices.

                            http://www.dunfield.com


                       Copyright 1988-2005 Dave Dunfield
                              All rights reserved



                                    MICRO-C

                               TABLE OF CONTENTS


                                                                         Page

     1. INTRODUCTION                                                        1

        1.1 Document conventions                                            1
        1.2 Code Portability                                                1
        1.3 Setting up MICRO-C                                              2
        1.4 The compiling process                                           3

     2. THE MICRO-C PROGRAMMING LANGUAGE                                    4

        2.1 Constants                                                       4
        2.2 Symbols                                                         4
        2.3 Arrays & Pointers                                               8
        2.4 Functions                                                       8
        2.5 Structures & Unions                                             9
        2.6 Control Statements                                             13
        2.7 Expression Operators                                           15
        2.8 Inline Assembly Language                                       17
        2.9 Preprocessor Commands                                          19
        2.10 Error Messages                                                20
        2.11 Quirks                                                        25

     3. ADVANCED TOPICS                                                    29

        3.1 Conversion Rules                                               29
        3.2 Assembly Language Interface                                    30

     4. THE MICRO-C PREPROCESSOR                                           32

        4.1 The MCP command                                                33
        4.2 Preprocessor Commands                                          34
        4.3 Predefined symbols                                             37
        4.4 Error messages                                                 37
        4.5 String Concatenation                                           40

     5. THE MICRO-C COMPILER                                               41

        5.1 The MCC09 command                                              41
        5.2 Symbol Information Comments                                    42

     6. THE MICRO-C OPTIMIZER                                              43

        6.1 The MCO09 command                                              43

     7. THE SOURCE LINKER                                                  44

        7.1 The SLINK Command                                              44
        7.2 Multiple Input Files                                           45

    MICRO-C                                                Table of Contents

                                                                         Page
        7.3 The Library File                                               46
        7.4 Source file information                                        47

     8. The MICRO-C/CUBIX Library                                          48

    MICRO-C                                                          Page: 1


    1. INTRODUCTION

          This complete development package includes all tools and utilities
       you need to develop 'C'  and 'ASM'  code for the 6809 processor under
       the CUBIX operating system.

       1.1 Document conventions

             The following conventions are used in this document:

            <text>          - Text shown in angle braces indicates data or
                              options that the user MUST supply.
            [text]          - Text shown in square braces indicates data or
                              options that are optional.
            ...             - Multiple options may be specified.


       1.2 Code Portability

             With few exceptions,  this compiler follows the syntax  of  the
          "standard"  UNIX compiler.  Programs  written  in  MICRO-C  should
          compile with few changes under other "standard" compilers.

          1.2.1 Unsupported Features:

                MICRO-C does not currently support the following features of
             standard 'C':

                Long/Double/Float/Enumerated types, Typedef and Bit fields.

            * 32 bit "long" number functions are supported via library calls.
              These may easily be modified to support larger numbers.

          1.2.2 Additional Features

                MICRO-C provides a few additional  features  which  are  not
             always included in "standard" 'C' compilers:

                Unsigned character variables, Nested comments, C++ comments,
                16 bit character constants, Inline assembly code capability.
                #message/#error/#file/#forget preprocessor directives.
    MICRO-C                                                          Page: 2


       1.3 Setting up MICRO-C

             Install the toolset by copying the files from the  distribution
          diskette onto your CUBIX system diskette.  The normal location for
          these files  is  the  [MC]  directory,  although  you  can  use  a
          different location if you edit the CC.@ command  file  which  runs
          the compiler.

             It is also a good idea to install the  CC.@  file  it  to  your
          [SYSTEM] directory so that you can execute it from any location.

             You may wish to edit CC.@ and make the following changes:

          - If you wish the compiler files to reside on a different diskette
            from your "current" direcrtory, add drive specifiers to all file
            and directory references.

          - If you wish to change the compiler options, or remove steps from
            the compile process (such a Preprocess or Optimize steps).

          - If the ASM assembler and BUILD utility are not in your  [SYSTEM]
            directory, then adjust these commands accordingly.

             Once everything is installed and configured correctly,  you are
          ready to begin using  the  compiler.  Try  compiling  the  HELLO.C
          example program with the command:

                                    CC HELLO

    MICRO-C                                                          Page: 3


       1.4 The compiling process

             There are five  programs  which  work  together  to  completely
          compile a MICRO-C program:

             The PREPROCESSOR  (MCP)  takes the original  'C'  source  file,
          performs MACRO expansion and incorporates the contents of  INCLUDE
          files  to  get  a  "pure"  'C'  output  file.  A   less   powerful
          preprocessor is also contained inside the COMPILER,  which  allows
          this step to  be  skipped  for  programs  which  use  only  simple
          preprocessor functions.

             The COMPILER  (MCC09)  reads a file  containing  a  'C'  source
          program,  and translates it into an equivalent  assembly  language
          program.

             The OPTIMIZER  (MCO09)  reads the assembly language output from
          the compiler identifying and replacing "general"  code produced by
          the compiler with more  efficient  code  which  is  equivalent  in
          specific cases.  This step is optional,  allowing  you  to  choose
          between faster compile time and greater program efficiency.

             The SOURCE LINKER (SLINK) combines the assembly language output
          from the compiler with any  required  routines  from  the  runtime
          library, to create an entire program file.

             The  ASSEMBLER  (ASM)  assembles  this  program  file  into   a
          downloadable binary image in either INTEL  or  MOTOROLA  hex  file
          format.
    MICRO-C                                                          Page: 4


    2. THE MICRO-C PROGRAMMING LANGUAGE

          The following pages contain a brief summary of  the  features  and
       constructs implemented in MICRO-C.

       2.1 Constants

             The following forms of constants are supported by the compiler:

                <num>       - Decimal number        (0 - 65535)
                0<num>      - Octal number          (0 - 0177777)
                0x<num>     - Hexadecimal number    (0x0 - 0xffff)
                '<char>'    - Character             (1 or 2 chars)
                "<string>"  - Address of literal string.

             The following "special" characters may be used within character
          constants or strings:

                \n          - Newline (line-feed)   (0x0a)
                \r          - Carriage Return       (0x0d)
                \t          - Tab                   (0x09)
                \f          - Formfeed              (0x0c)
                \b          - Backspace             (0x08)
                \<num>      - Octal value <num>     (Max. three digits)
                \x<num>     - Hex value <num>       (Max. two digits)
                \<char>     - Protect character <char> from input scanner.

       2.2 Symbols

             Symbol names  may  include  the  characters  'a'-'z',  'A'-'Z',
          '0'-'9',  and '_'.  The characters '0'-'9'  may not be used as the
          first character in the  symbol  name.  Symbol  names  may  be  any
          length, however, only the first 15 characters are significant.

             The "char" modifier may be used to declare a symbol as an 8 bit
          value, otherwise it is assumed to be 16 bits.

                              eg: char input_char;

             The "int"  modifier may be used to declare a symbol as a 16 bit
          wide value. This is assumed if neither "int" or "char" is given.

                                  eg: int abc;

             The  "unsigned"  modifier may be used to declare a symbol as an
          unsigned positive only value. Note that unlike some 'C' compilers,
          this modifier may be applied to a character (8 bit) variable.

                            eg: unsigned char count;

             The  "extern"  modifier causes the compiler to be aware of  the
          existence and  type  of  a  global  symbol,  but  not  generate  a
          definition for that symbol.  This allows the module being compiled
          to reference a symbol which is defined  in  another  module.  This
          modifier may not be used with local symbols.

                            eg: extern char getch();
    MICRO-C                                                          Page: 5


             A  symbol  declared  as  external  may  be  redeclared   as   a
          non-external at a later  point  in  the  code,  in  which  case  a
          definition for it will be generated.  This allows  "extern"  to be
          used to inform the compiler of a function or variable type so that
          it can be referenced  properly  before  that  symbol  is  actually
          defined.

             The  "static"  modifier causes global symbols to  be  available
          only in the file where they are defined.  Variables  or  functions
          declared  as  "static"  will  not  be   accessible   as   "extern"
          declarations in other object files,  nor will they cause conflicts
          with duplicate names in those files.

                         eg: static int variable_name;

             When applied to local symbols,  the  "static"  modifier  causes
          those variables to be allocated in  a  reserved  area  of  memory,
          instead of on the processor stack.  This has the effect  that  the
          contents of the variable will be retained  between  calls  to  the
          function.  It also means that the variable may be  initialized  at
          compile time (just like global variables).

             The  "register"  modifier indicates to the code generator  that
          this is a high priority variable,  and should be kept where it  is
          easy to get at.  See "Functions"  for a special use of  "register"
          when defining a function.

                          eg: register unsigned count;

             The "const"  modifier indicates to the compiler that this value
          should never be modified.  In the case of a pointer, it means that
          the data pointed to should never  be  modified  (but  the  pointer
          itself can be).  The compiler will attempt to  detect  any  direct
          modifications and issue an error message. (Note that constant data
          can still be  modified  indirectly  through  a  non-const  pointer
          without an error message).

             Symbols declared with a preceding '*'  are assumed to be 16 bit
          pointers to the declared type.

                             eg: int *pointer_name;

             Symbol names declared followed by square brackets  are  assumed
          to be arrays with a number of dimensions equal to  the  number  of
          '[]'  pairs that follow.  The size of each dimension is identified
          by a constant value  contained  within  the  corresponding  square
          brackets.

                          eg: char array_name[5][10];
    MICRO-C                                                          Page: 6


             Under certain conditions,  the first (highest)  array dimension
          may  be  left  unspecified.  Only  the  first  dimension  may   be
          unspecified,  because  the  compiler  needs  to  know  all   other
          dimensions to perform indexing calculations. These conditions are:

          - If the array is initialized in  the  declaration,  the  compiler
          will automatically set the  unspecified  first  dimension  to  the
          lowest value which will cause the array to be large enough to hold
          all of the initial values.

          - If the array is  a  function  argument,  no  actual  storage  is
          reserved, and the first dimension in not needed. The compiler will
          correctly calculate  all  indexes,  but  since  the  actual  first
          dimension in not known,  the sizeof()  function will always return
          zero.

          - If the array is prototyped with "extern", the first dimension is
          also  not  needed.  the  compiler  will  correctly  calculate  all
          indexes,  but since the actual first dimension is not  known,  the
          sizeof()  function will  always  return  zero.  If  the  array  is
          subsequently redeclared with a first dimension,  the compiler will
          update it's internal tables,  and sizeof()  will return the actual
          size of the array thereafter.  (Note that this is  the  only  case
          where you may redeclare an array with a  dimension  which  differs
          from the original prototype).

             The  "void"  modifier is a special case which means this symbol
          should never be used as a value.  It is usually used to indicate a
          function which returns  nothing,  or  a  pointer  which  is  never
          dereferenced.

                               eg: void *pointer;

          2.2.1 Global Symbols

                Symbols  declared  outside  of  a  function  definition  are
             considered to  be  global  and  will  have  memory  permanently
             reserved for them.  Global symbols are defined by name  in  the
             output file, allowing other modules to access them.

                Global variables may be initialized with one or more values,
             which are expressed as a single array of integers REGARDLESS of
             the size and shape of the variable.  If more than one value  is
             expressed, '{' and '}' must be used.

                   eg: int i = 10, j[2][2] = { 1, 2, 3, 4 };

                When arrays are  initialized  in  the  declaration,  a  null
             dimension may be used as the first  dimension  size,  in  which
             case the size of the array will be determined  by  the  initial
             values.

                         eg: int array[] = { 1, 2, 3 };
    MICRO-C                                                          Page: 7


                Initialized global variables are automatically saved  within
             the code image,  insuring  that  the  initial  values  will  be
             available at run time. Any non-initialized elements of an array
             which has been partly initialized will be set to zero.

                Non-initialized global variables are not preset in any  way,
             and will be undefined at the beginning of program execution.

          2.2.2 Local Symbols

                Symbols declared within a function definition are  allocated
             on the stack,  and exist  only  during  the  execution  of  the
             function.

                To simplify the allocation and deallocation of stack  space,
             all local symbols must be declared  at  the  beginning  of  the
             function before any code producing statements are encountered.

                MICRO-C does not support initialization of non-static  local
             variables in the declaration statement.  Since local  variables
             have to be initialized every time the function is entered,  you
             can get the same effect  using  assignment  statements  at  the
             beginning of the function.

                No type is assumed for  arguments  to  functions.  Arguments
             must be explicitly declared,  otherwise they will be  undefined
             within the scope of the function definition.

          2.2.3 More Symbol Examples

            /* Global variables are defined outside of any function */
            char a;                     /* 8 bit signed */
            unsigned char b;            /* 8 bit unsigned */
            int c;                      /* 16 bit signed */
            unsigned int d;             /* 16 bit unsigned */
            unsigned e;                 /* also 16 bit unsigned */
            extern char f();            /* external function returning char */
            static int g;               /* 16 bit signed, local to file */
            int h[2] = { 1, 2 };        /* initialized array (2 ints) */

            main(a, b)                  /* "int" function containing code */
            /* Function arguments are defined between function name and body */
                int a;                  /* 16 bit signed */
                unsigned char *b;       /* pointer to 8 bit unsigned */
            {
            /* Local variables are defined inside the function body */
            /* Note that in MICRO-C, only "static" locals can be initialized */
                unsigned c;             /* 16 bit unsigned */
                static char d[5];       /* 8 bit signed, reserved in memory */
                static int e = 1;       /* 16 bit signed, initial value is 1 */
            /* Function code goes here ... */
                c = 0;                  /* Initialize 'c' to zero */
                strcpy(d, "Name");      /* Initialize 'd' to "name" */
            }
    MICRO-C                                                          Page: 8


       2.3 Arrays & Pointers

             When MICRO-C passes an array to a function,  it actually passes
          a POINTER to the array.  References to arrays which are  arguments
          are automatically performed through the pointer.

             This  allows  the  use   of   pointers   and   arrays   to   be
          interchangeable through the context of a  function  call.  Ie:  An
          array passed to a function may be declared and used as a  pointer,
          and a pointer passed to a function may be declared and used as  an
          array.

       2.4 Functions

             Functions are  essentially  initialized  global  symbols  which
          contain executable code.

             MICRO-C accepts  any  valid  value  as  a  function  reference,
          allowing  some  rather  unique  (although  non-standard)  function
          calls.

          For example:

                function();     /* call function */
                variable();     /* call contents of a variable */
                (*var)();       /* call indirect through variable */
                (*var[x])();    /* call indirect through indexed array */
                0x5000();       /* call address 0x5000 */

             MICRO-C accepts both the  "classic"  and  "modern"  formats  of
          argument definition for a function.

             In the "classic" format,  only the argument names are placed in
          the brackets following the function name.  The closing bracket  is
          followed by formal declarations for the arguments (in any order):

              eg: int function(a, b, c) int a, c; char b; { ... }

             If the "modern" format, complete declarations for EACH argument
          are enclosed in the brackets following the function name:

                 eg: int function(int a, char b, int c) { ... }

             Since this is a single pass compiler, operands to functions are
          evaluated and pushed on the stack in the order in which  they  are
          encountered,  leaving the last operand closest to the top  of  the
          stack.  This is the opposite  order  from  which  many  other  'C'
          compilers push operands.
    MICRO-C                                                          Page: 9


             For functions with a fixed number of arguments,  the  order  of
          which operands  are  passed  is  of  no  importance,  because  the
          compiler looks after generating  the  proper  stack  addresses  to
          reference variables.  HOWEVER,  functions  which  use  a  variable
          number of arguments are affected for two reasons:

          1)  The location of the LAST arguments are known (as fixed offsets
             from the stack pointer) instead of the FIRST.

          2)  The symbols defined as arguments in  the  function  definition
             represent the LAST arguments instead of the FIRST.

             If a function is declared as  "register",  it serves a  special
          purpose and causes the accumulator to be loaded with the number of
          arguments passed whenever the function is called.  This allows the
          function to know how many  arguments  were  passed  and  therefore
          determine the location of the first argument.

       2.5 Structures & Unions

             Combinations of other variable  types  can  be  organized  into
          STRUCTURES or UNIONS,  which allow them to  be  manipulated  as  a
          single entity.

             In a structure,  the individual  items  occur  sequentially  in
          memory,  and the total size of the structure is  the  sum  of  its
          elements.  Structures are usually used  to  create  "records",  in
          which related items are grouped together.  An array of  structures
          is the common method of implementing an "in-memory" database.

             A union is similar to a structure,  except that the  individual
          items are overlaid in memory,  and the total size of the union  is
          the size of its largest element.  Unions are usually used to allow
          a single block of memory to be accessed as different 'C'  variable
          types.  An example of this would be in handling a message received
          in memory,  in which a "type"  byte indicates how the remainder of
          the message data should be interpreted.

             Here are some example of how structures are  defined  and  used
          (unions are defined and used in an identical manner,  except  that
          the word 'union' is substituted for 'struct'):

            /* Create structure named 'data' with 'a,b,c & d' as members */
            struct {
                int a;
                int b;
                char c;
                char d; } data;

            /* Create structure template named 'mystruc'... */
            /* No actual structure variable is defined */
            struct mystruc {
                int a;
                int b;
                char c;
                char d; };
    MICRO-C                                                          Page: 10


            /* Create structure named 'data' using above template */
            struct mystruc data;

            /* Create structure template 'mystruc', AND define a */
            /* structure variable named 'data' */
            struct mystruc {
                int a;
                int b;
                char c;
                char d; } data;

            /* Create an array of structures, a pointer to a structure */
            /* and an array of pointers to a structure *
            struct mystruct array[10], *pointer, *parray[10];

            /* To set value in structure variable/members */
            data.a = 10;            /* Direct access */
            array[1].b = 10;        /* Direct array access */
            pointer->c = 'a';       /* Pointer access */
            parray[2]->d = 'b';     /* Pointer array access */

            /* To read value in structure variable/members */
            value = data.a;         /* Direct access */
            value = data[1].b;      /* Direct array access */
            value = pointer->c;     /* Pointer access */
            value = parray[2]->d;   /* Pointer array access */

          2.5.1 Notes on MICRO-C structure implementation:

                Structures and Unions as implemented in MICRO-C are  similar
             to the implementation of the original UNIX  'C'  compiler,  and
             are bound by similar limitations,  as well  as  a  few  MICRO-C
             specific ones.  Here  is  a  list  of  major  differences  when
             compared to a modern ANSI compiler:

                All structure and member names MUST  be  unique  within  the
             scope of the definition.  A special case exists,  where  common
             member names may be used in  multiple  structure  templates  if
             they have EXACTLY the same type and offset into the  structure.
             This also saves symbol table memory, since only one copy of the
             member definition is actually kept.

                MICRO-C does NOT pass entire structures to functions on  the
             stack.  Like arrays,  MICRO-C  passes  structures  by  ADDRESS.
             Structure variables which are function arguments  are  accessed
             through pointers.  For source code compatibility with compilers
             which do pass the entire structure, if you declare the argument
             as a direct (non-pointer) structure,  the direct ('.') operator
             is used to dereference it, even though it is actually a pointer
             reference.
    MICRO-C                                                          Page: 11


                If you  MUST  have  a  local  copy  of  the  structure,  use
             something like:

                func(sptr)
                    struct mystruc *sptr;
                {
                    struct mystruc data;
                    memcpy(data, sptr, sizeof(data));
                    ...
                }

                To obtain the size of a structure from  its  template  name,
             use the  'struct'  keyword in  conjunction  with  the  'sizeof'
             operator.   In   the   above   example,   you   could   replace
             'sizeof(data)' with 'sizeof(struct mystruc)'.

                To obtain the size of a structure member,  you must  specify
             it in the context of a structure reference with another symbol:

              sizeof(variable.member) or sizeof(variable->member)

                NOTE:  The current compiler allows almost any symbol to  the
             left of the '.' or '->' operator in a 'sizeof',  however future
             versions of the compiler may insist on a structure variable  or
             a pointer to structure variable.

                MICRO-C is quite limited in its implementation  of  pointers
             to structures.  Such pointers are internally stored as pointers
             to 'char', and therefore dereferencing (*), indexing ([]),  and
             all forms of pointer  arithmetic  (++,  --,  +,  -,  ...)  will
             generally  not  perform  as  you  would  expect  them  to  with
             structures.  The only meaningful things that can be done with a
             pointer to a structure is assign it to another  variable,  pass
             it as a function argument and apply the '->' operator to access
             individual members.

             Use this to  "increment"  a pointer to a structure to point  to
             the next structure:
                         ptr += sizeof(struct mystruc)

             Use this to access the 'n'th structure from the pointer:
                  (ptr + (n * sizeof(struct mystruc)))->member

                The  'struct'  and  'union'  keywords are not accepted in  a
             TYPECAST.  This is most commonly used to setup a pointer  to  a
             structure.  Since MICRO-C stores its pointers to structures  as
             pointers to char, you can use (char*) as the typecast,  and get
             the same functionality.

                A structure name by itself  (without  '.member')  acts in  a
             manner similar to a character array name.  With  no  operation,
             the address of the structure is returned. You can also use '[]'
             to access  individual  bytes  in  the  structure  by  indexing,
             although doing so is highly non-portable.
    MICRO-C                                                          Page: 12


                MICRO-C allows static or global structures to be initialized
             in the declaration,  however the initial values are read as  an
             array of bytes,  and are assigned directly to structure  memory
             without regard for the type or size of its members:

                struct mystruc data = { 0, 1, 0, 2, 3, 4 };
                /* A=0:1, B=0:2, C=3, D=4 */

                You can use INT and CHAR to switch back  and  forth  between
             word/byte initialization within the value list:

                struct mystruct data = { int 0, 1, char 2, 3 };
                /* A=0, B=1, C=2, D=3 */

                Strings encountered during structure initializations will be
             encoded as a series of bytes if byte initialization  (char)  is
             in effect,  or as  pointers  into  the  literal  pool  if  word
             initialization (int) is in effect.

                MICRO-C does not WORD ALIGN structure elements. When using a
             processor which requires word alignment,  it is the programmers
             responsibility to maintain alignment,  using filler bytes  etc.
             when necessary.
    MICRO-C                                                          Page: 13


       2.6 Control Statements

             The following control statements are implemented in MICRO-C:

                if(expression)
                    statement;

                if(expression)
                    statement;
                else
                    statement;

                while(expression)
                    statement;

                do
                    statement;
                while expression;

                for(expression; expression; expression)
                    statement;

                return;

                return expression;

                break;

                continue;

                switch(expression) {
                    case constant_expression :
                        statement;
                        ...
                        break;
                    case constant_expression :
                        statement;
                        ...
                        break;
                        .
                        .
                        .
                    default:
                        statement; }

                label: statement;

                goto label;

                asm "...";

                asm {
                    ...
                    }
    MICRO-C                                                          Page: 14


    2.6.1 Notes on Control Structures

        1)  Any "statement" may be a single statement or a compound
            statement enclosed within '{' and '}'.

        2)  All three "expression"s in the "for" command are optional.

        3)  If a "case" selection does not end with "break;", it will
            "fall through" and execute the following case as well.

        4)  Expressions following 'return' and 'do/while' do not have
            to be contained in brackets (although this is permitted).

        5)  Label names may precede any statement, and must be any
            valid symbol name, followed IMMEDIATELY by ':' (No spaces
            are allowed). Labels are considered LOCAL to a function
            definition and will only be accessible within the scope
            of that function.

        6)  The 'asm' statement used to implement the inline assembly
            language capability of MICRO-C accepts two forms:
                asm "...";      <- Assemble single line.
                asm {           <- Assemble multiple lines.
                    ...
                    }
    MICRO-C                                                          Page: 15


       2.7 Expression Operators

             The following expression operators are implemented in MICRO-C:

    2.7.1 Unary Operators

        -           - Negate
        ~           - Bitwise Complement
        !           - Logical complement
        ++          - Pre or Post increment
        --          - Pre or post decrement
        *           - Indirection
        &           - Address of
        sizeof      - Size of a object or type
        (type)      - Typecast

    2.7.2 Binary Operators

        +           - Addition
        -           - Subtraction
        *           - Multiplication
        /           - Division
        %           - Modulus
        &           - Bitwise AND
        |           - Bitwise OR
        ^           - Bitwise EXCLUSIVE OR
        <<          - Shift left
        >>          - Shift right
        ==          - Test for equality
        !=          - Test for inequality
        >           - Test for greater than
        <           - Test for less than
        >=          - Test for greater than or equal to
        <=          - Test for less than or equal to
        &&          - Logical AND
        ||          - Logical OR
        =           - Assignment
        +=          - Add to self assignment
        -=          - Subtract from self assignment
        *=          - Multiply by self assignment
        /=          - Divide by and reassign assignment
        %=          - Modular self assignment
        &=          - AND with self assignment
        |=          - OR with self assignment
        ^=          - EXCLUSIVE OR with self assignment
        <<=         - Shift left self assignment
        >>=         - Shift right self assignment
    MICRO-C                                                          Page: 16


    NOTES:

        1)  The expression "a && b" returns 0 if "a" is zero, otherwise the
            value of "b" is returned. The "b" operand is NOT evaluated if
            "a" is zero.

        2)  The expression "a || b" returns the value of "a" if it is not 0,
            otherwise the value of "b" is returned. The "b" operand is NOT
            evaluated if "a" is non-zero.

    2.7.3 Other Operators

        ;           - Ends a statement.
        ,           - Allows several expressions in one statement.
                    + Separates symbol names in multiple declarations.
                    + Separates constants in multi-value initialization.
                    + Separates operands in function calls.
        ?           - Conditional expression (ternary operator).
        :           - Delimits labels, ends CASE and separates conditionals.
        .           - Access a structure member directly.
        ->          - Access a structure member through a pointer.
        { }         - Defines a BLOCK of statements.
        ( )         - Forces priority in expression, indicates function calls.
        [ ]         - Indexes arrays. If fewer index values are given than the
                      number of dimensions which are defined for the array,
                      the value returned will be a pointer to the appropriate
                      address.

                    Eg:
                        char a[5][2];

                        a[3] returns address of forth row of two characters.
                        (remember indexes start from zero)

                        a[3][0] returns the character at index [3][0];
    MICRO-C                                                          Page: 17


       2.8 Inline Assembly Language

             Although  'C'  is a powerful and flexible language,  there  are
          sometimes instances where a particular operation must be performed
          at the assembly language level.  This most often  involves  either
          some processor feature for which there  is  no  corresponding  'C'
          operation, or a section of very time critical code.

             MICRO-C provides access to assembly  language  with  the  'asm'
          statement, which has two basic forms. The first is:

                                  asm "..." ;

             In this form,  the entire text  contained  between  the  double
          quote characters (")  is output as a single line to the assembler.
          Note that a  semicolon  is  required,  just  like  any  other  'C'
          statement.

             Since this is a standard  'C'  string,  you can use any of  the
          "special" characters,  and thus you could output multiple lines by
          using '\n' within the string.  Another important characteristic of
          it being a string is that it will be protected  from  preprocessor
          substitution.

             The second form of the 'asm' statement is:

                                     asm {
                                      ...
                                       }

             In this form,  all lines between '{' and '}'  are output to the
          assembler.  Any text following the opening '{'  (on the same line)
          is ignored.  Due to the  unknown  characteristics  of  the  inline
          assembly code,  the closing '}' will only be recognized when it is
          the first non-whitespace character on a line.

             The integral preprocessor will not perform substitution on  the
          inline assembly code, however the external preprocessor (MCP) will
          substitute in this  form.  This  allows  you  to  create  assembly
          language "macros" using MCP,  and have parameters substituted into
          them when they are expanded:

            /*
             * This macro issues a 'SSR' instruction for its parameter
             */
            #define ssr(service) asm {\
                SSR service\
            }

            /*
             * This macro WILL NOT WORK, since the 'service' operand to the
             * SSR instruction is contained within a string and is therefore
             * protected from substitution by the preprocessor
             */
            #define ssr(service) asm " SETB service";
    MICRO-C                                                          Page: 18


             The  'asm'  keyword may also be  used  as  a  expression  value
          element. When used in this manner, the value returned is the value
          of the processor accumulator register following the  execution  of
          the inline assembly instructions.  Note that the 'asm' keyword and
          the following string or {} block are considered  to  be  a  single
          value item by the parser.

             When used within a function,  arguments can be passed to inline
          assembly using the form:

                          asm(arg1, arg2, ...) "...";

                                      -or-

                             asm(arg1, arg2, ...) {
                                      ...
                                       }

          All arguments are pushed on the processor stack  (left  to  right)
          except for the LAST one,  which is passed in the  accumulator.  If
          there is only one argument it is passed in the accumulator and  no
          values are stacked.  The inline  assembly  code  MUST  remove  the
          stacked arguments before it finishes:

            variable = asm(1, 2, 3) {
                ...     ; asm-code receives last arg (3) in accumulator
                ...     ; asm-code must retrieve args 1&2 from stack
                ...     ; asm-code must remove 2 words from stack
                ...     ; asm-code must set return value in accumulator
            };      <= Note ';' is required to terminate expression

            // In the following example:
            // asm-code receives it's only argument (a) in accumulator
            // asm-code does not have to remove anything from stack
            // asm-code must set return value in accumulator
            if(asm(a)"asm-code") {
                ... }   // Do this if asm-code returns accumulator!=0

            // Since asm{} needs separate lines, the following "if"
            // statement looks odd, but is perfectly legal.
            if(asm(a,b) {
                ... ; asm-code receives last arg (b) in accumulator
                ... ; asm-code must retrieve arg (a) from stack
                ... ; asm-code must remove 1 word from stack
                ... ; asm-code must set return valeu in accumulator
            } ) {
                ... }   // Do this if asm-code returns accumulator !=0
    MICRO-C                                                          Page: 19


       2.9 Preprocessor Commands

             The  MICRO-C  compiler  supports  the  following   preprocessor
          commands.  These commands are recognized only if they occur at the
          beginning of the input line.

             NOTE: This describes the limited preprocessor which is integral
          to the compiler,  see  also  the  section  on  the  more  powerful
          external processor (MCP).

          2.9.1 #define <name> <replacement_text>

                The  "#define"  command allows a global name to be  defined,
             which will be replaced with the indicated text whenever  it  is
             encountered in the input file.  This occurs prior to processing
             by the compiler.

          2.9.2 #file <filename>

                Sets the filename of the currently processing  file  to  the
             given string. This command is used by the external preprocessor
             (MCP)  to insure that  error  messages  indicate  the  original
             source file.

          2.9.3 #include <filename>

                This command causes the indicated file to be opened and read
             in as the source  text.  When  the  end  of  the  new  file  is
             encountered,  processing will continue with the line  following
             "#include" in the original file.

          2.9.4 #ifdef <name>

                Processes the following lines  (up to #else or #endif)  only
             if the given name is defined.

          2.9.5 #ifndef <name>

                Processes the following lines  (up to #else or #endif)  only
             if the given name is NOT defined.

          2.9.6 #else

                Processes the following lines  (up to #endif)  only  if  the
             preceding #ifdef or #ifndef was false.

          2.9.7 #endif

                Terminates #ifdef and #ifndef

                NOTE:  The integral preprocessor does not support nesting of
             the #ifdef and #idndef constructs.  If you wish to  nest  these
             conditionals, you must use the external preprocessor (MCP).
    MICRO-C                                                          Page: 20


       2.10 Error Messages

             When MICRO-C detects an  error,  it  outputs  an  informational
          message indicating the type of problem encountered.

             The error message is preceded by the filename and  line  number
          where the error occurred:

                           program.c(5): Syntax error

             In  the  above  example,  the  error  occurred  in   the   file
          "program.c" at line 5.

             The following error messages are produced by the compiler:

          2.10.1 Compilation aborted

                The preceding error was so severe than the  compiler  cannot
             proceed.

          2.10.2 Constant expression required

                The compiler requires a constant  expression  which  can  be
             evaluated at compile time (ie: no variables).

          2.10.3 Declaration must precede code.

                All local variables must be defined at the beginning of  the
             function, before any code producing statements are processed.

          2.10.4 Dimension table exhausted

                The compiler has encountered more  active  array  dimensions
             than it can handle.

          2.10.5 Duplicate local: 'name'

                You have declared the named  local  symbol  more  than  once
             within the same function definition.

          2.10.6 Duplicate global: 'name'

                You have declared the named global symbol more than once.

          2.10.7 Expected '<token>'

                The compiler  was  expecting  the  given  token,  but  found
             something else.

          2.10.8 Expression stack overflow

                The compiler has found a more complicated expression than it
             can handle.  Check that it is of correct  syntax,  and  if  so,
             break it up into two simpler expressions.
    MICRO-C                                                          Page: 21


          2.10.9 Expression stack underflow

                The compiler has made an error in  parsing  the  expression.
             Check that it is of correct syntax.

          2.10.10 Illegal indirection

                You have attempted to perform an indirect operation  ('*' or
             '[]') on an entity which is not a pointer or array.  This error
             will also result if you attempt to index  an  array  with  more
             indices than it has dimensions.

          2.10.11 Illegal initialization

                Local variables may not be initialized  in  the  declaration
             statement.  Use assignments at the beginning  of  the  function
             code to perform the initialization.

          2.10.12 Illegal nested function

                You may not declare a  function  within  the  definition  of
             another function.

          2.10.13 Illegal null dimension

                You  have  attempted  to  declare  an  array  using  a  null
             dimension value which is not in the first dimension position.

          2.10.14 Illegal pointer operation

                You are attempting to perform  an  operation  which  is  not
             allowed in pointer arithmetic.

          2.10.15 Improper type of symbol: 'name'

                The named  symbol  is  not  of  the  correct  type  for  the
             operation that you are attempting.  Eg: 'goto' where the symbol
             is not a label.

          2.10.16 Improper #else/#endif

                A #else or #endif statement is out of place.

          2.10.17 Inconsistent member type/offset: 'name'

                The named structure member is multiply defined,  and  has  a
             different type, offset or dimension than its first definition.

          2.10.18 Inconsistent redeclaration: 'name'

                You have attempted to redefine  the  named  external  symbol
             with a type which does not match its previously declared type.
    MICRO-C                                                          Page: 22


          2.10.19 Incorrect declaration

                A statement occurring outside of a  function  definition  is
             not a valid declaration for a function or global variable.

          2.10.20 Invalid '&' operation

                You have attempted to reference  the  address  of  something
             that has no address. This error also occurs when you attempt to
             take the address of an array without giving it a  full  set  of
             indices.  Since the address is already returned in  this  case,
             simply drop the  '&'.  (The error occurs because you are trying
             to take the address of an address).

          2.10.21 Macro expansion too deep

                The compiler has encountered a nested macro reference  which
             is too deep to be resolved.

          2.10.22 Macro space exhausted

                The compiler has encountered  more  macro  ("#define")  text
             than it has room to store.  Use the external  MCP  preprocessor
             which has much greater macro storage capability.

          2.10.23 No active loop

                A "continue"  or  "break"  statement was encountered when no
             loop is active.

          2.10.24 No active switch

                A  "case"  or  "default"  statement was encountered when  no
             "switch" statement is active.

          2.10.25 Not an argument: 'name'

                You have declared the named variable as an argument,  but it
             does not appear in the argument list.

          2.10.26 Non-assignable

                You have attempted an operation which results in  assignment
             of a value to an entity which cannot be assigned. (eg: 1 = 2);

          2.10.27 Numeric constant required

                The compiler requires a constant expression which returns  a
             simple numeric value.

          2.10.28 String space exhausted

                The compiler has encountered more literal  strings  than  it
             has room store.
    MICRO-C                                                          Page: 23


          2.10.29 Symbol table full

                The compiler has encountered more symbol definitions than it
             can handle.

          2.10.30 Syntax error

                The statement shown does not follow syntax rules and  cannot
             be parsed.

          2.10.31 Too many active cases

                The compiler has run out of space  for  storing  switch/case
             tables. Reduce the number of active "cases".

          2.10.32 Too many defines

                The compiler has encountered more '#define'  statements than
             it can handle. Reduce the number of #defines.

          2.10.33 Too many errors

                The compiler is aborting because of excessive errors.

          2.10.34 Too many includes

                The compiler has encountered more  nested  "#include"  files
             than it can handle.

          2.10.35 Too many initializers

                You have specified more initialization values than there are
             locations in the global variable.

          2.10.36 Too many pointer levels

                You have declared an item with more  levels  of  redirection
             ('*'s) than the compiler can handle.

          2.10.37 Type clash

                You have attempted to use a  value  in  a  manner  which  is
             inconsistent with its typing information.  Also results from an
             attempt to declare a non-pointer variable with the "void" type.

          2.10.38 Unable to open: 'name'

                A "#include"  command specified the named file,  which could
             not be opened.

          2.10.39 Undefined: 'name'

                You have referenced a name which is not defined as  a  local
             or global symbol.
    MICRO-C                                                          Page: 24


          2.10.40 Unknown structure/member: 'name'

                You have referenced a  structure  template  or  member  name
             which is not defined.

          2.10.41 Unreferenced: 'name'

                The named  symbol  was  defined  as  a  local  symbol  in  a
             function, but was never used in that function.  This error will
             occur at the end of  the  function  definition  containing  the
             symbol declaration.  It is only a warning,  and will not  cause
             the compile to abort.

          2.10.42 Unresolved: 'name'

                The named symbol was forward  referenced  (Such  as  a  GOTO
             label), and was never defined. This error will occur at the end
             of the function definition containing the reference.

          2.10.43 Unterminated conditional

                The end of file was encountered  when  a  "#if"  or  "#else"
             conditional block was being processed.

          2.10.44 Unterminated function

                The  end  of  the  file  was  encountered  when  a  function
             definition was still open.
    MICRO-C                                                          Page: 25


       2.11 Quirks

             Due  to  its  background  as  a  highly  compact  and  portable
          compiler, and its target application in embedded systems,  MICRO-C
          deviates from standard  'C'  in some areas.  The  following  is  a
          summary of the major infractions and quirks:

             PLEASE NOTE that this  section  should  not  be  considered  as
          evidence that the compiler  is  somehow  inferior  or  buggy!  ALL
          compilers have quirks.  Most vendors just keep quiet and hope  you
          won't notice.

          2.11.1 Preprocessor quirks

             *** NOTE:  The quirks in this section apply ONLY to the limited
             INTERNAL preprocessor.  They DO NOT  APPLY  when  the  external
             preprocessor (MCP) is used.

                When using the INTERNAL preprocessor,  the operands  to  '#'
             commands are parsed based on separating spaces, and any portion
             of the  line  not  required  is  ignored.  In  particular,  the
             '#define'  command only accepts a definition  up  to  the  next
             space or tab character.

            eg: #define APLUSONE A+1        <-- uses "A+1"
                #define APLUSONE A +1       <-- uses "A"

                Comments are stripped by the  token  scanner,  which  occurs
             AFTER the '#' commands are processed.

            eg: #define NULL    /* comment */   <-- uses "/*"

                Note that  since  comments  can  therefore  be  included  in
             "#define"  symbols,  you can  use  "/**/"  to  simulate  spaces
             between tokens.

            eg: #define BYTE unsigned/**/char

                Include filenames are not delimited by '""' or '<>'  and are
             passed to the operating system exactly as entered.

            eg: #include [MC]STDIO.H

          2.11.2 Function/Variable declaration quirks

                The appearance of a variable name in the argument  list  for
             an old style function declaration serves only to identify  that
             variables location on the stack.  MICRO-C will not  define  the
             variable unless it is explicitly declared (between the argument
             list and the main function body). In other words, all arguments
             to a function must be explicitly declared.

                MICRO-C does not support  "complex"  declarations which  use
             brackets  '()'  for other than function parameters.  These  are
             most often used in establishing pointers to functions:
                    int (*a)();     /* Pointer to function returning INT */
                    (*a)();         /* Call address in 'a' */
    MICRO-C                                                          Page: 26


                Since MICRO-C allows you to call any value by  following  it
             with '()', you can get the desired effect in the above case, by
             declaring 'a'  as a simple pointer to int,  and calling it with
             the same syntax:
                    int *a;         /* Pointer to INT */
                    (*a)();         /* Call address in 'a' */

                MICRO-C will not output external declarations to the  output
             file for any variables  or  functions  which  are  declared  as
             "extern",  unless that symbol is actually referenced in the 'C'
             source code.  This prevents  "extern"  declarations  in  system
             header files  (such as "STDIO.H")  which are used as prototypes
             for some library functions from causing those functions  to  be
             loaded into the object file.  Therefore,  any "extern"  symbols
             which are referenced only  by  inline  assembly  code  must  be
             declared in the assembly code,  not  by  the  MICRO-C  "extern"
             statement.

                Read  the  notes  at  the  end  of  the   section   entitled
             "Structures and  Unions"  for  information  on  limitations  or
             differences from standard  'C'  in MICRO-C's implementation  of
             structures and unions.

          2.11.3 Operator/Expression quirks

                MICRO-C is more strict about its  handling  of  the  ADDRESS
             operator  ('&')  than most other compilers.  It will produce an
             error message if you attempt to take the  address  of  a  value
             which is already a fixed address (such as an array name without
             a full set of indices). Since an address is already produced in
             such cases, simply drop the '&'.

                The INDEXING operator '[]' is not commutative in MICRO-C. In
             other words 'array[index]' is NOT equivalent to 'index[array]'.

                The 'x' in '0x' and '\x' is accepted in lower case only.

                When  operating  on  pointers,  MICRO-C  only   scales   the
             increment (++),  decrement (--)  and index  ([])  operations to
             account for the size of the pointer:

                eg: char *cptr;     /* pointer to character */
                    int  *iptr;     /* pointer to integer */
                    ++cptr;         /* Advance one character */
                    ++iptr;         /* Advance one integer */
                    cptr[10];       /* Access the tenth character */
                    iptr[10];       /* Access the tenth integer */
                    cptr += 10;     /* Advance 10 characters */
                    iptr += 10;     /* Advance ONLY FIVE integers */

                NOTE: A portable way to advance "iptr" by integers is:

                    iptr = &iptr[10];   /* Advance 10 integers */
    MICRO-C                                                          Page: 27


                Since structures are internally  represented  as  arrays  of
             "char", incrementing a pointer to a structure will advance only
             one  (1)  byte in memory.  To advance to the "next" instance of
             the structure, use:

                        ptr += sizeof(struct template);

                Unlike some  'C'  compilers,  MICRO-C will process character
             expressions using only BYTE values.  Character values  are  not
             promoted to INT unless there is an INT value  involved  in  the
             expression.  This results in  much  more  efficient  code  when
             dealing with characters, particularly on small processors which
             have limited 16 bit instructions. Consider the statement:

                                 return c + 1;

                On some compilers,  this  will  sign  extend  the  character
             variable 'c'  into an integer value,  and then ADD an integer 1
             and return the result.  MICRO-C will ADD the character variable
             and a character 1,  and then promote the result to  INT  before
             returning it  (results of expressions as operands  to  'return'
             are always promoted to int).

                Unfortunately,  programs have been written which rely on the
             automatic promotion of characters to INTs to work properly. The
             most common source of problems is code which attempts to  treat
             CHAR variables as UNSIGNED values (many older compilers did not
             support UNSIGNED CHAR). For example:

                                return c & 255;

                In a compiler which always evaluates  character  expressions
             as INT,  the above statement will extract the value of  'c'  as
             positive integer ranging from 0 to 255.

                In MICRO-C,  ANDing a character with 255 results in the same
             character, which gets promoted to an integer value ranging from
             -128 to 127.  To force the promotion within the expression, you
             could CAST the variable to an INT:

                              return (int)c & 255;

                The same objective can be achieved in a more efficient  (and
             correct) manner by declaring the variable 'c' as UNSIGNED CHAR,
             or by CASTing the variable to an UNSIGNED value:

                              return (unsigned)c;

                Note that this is not only more clearly shows the intent  of
             the programmer,  but also results is more  efficient  generated
             code.
    MICRO-C                                                          Page: 28


                A related quirk occurs because MICRO-C  automatically  casts
             untyped constants used in binary operations to match the  other
             type used in the operation,  again this is done to  preserve  8
             bit arithmetic wherever possible,  but it can surprise  you  if
             you use a number which cannot be expressed  in  8  bits  in  an
             operation with a character type.  The high bits of  the  number
             will be dropped as it is truncated to a matching 8 bit type. If
             such a number is truly needed in an 8  bit  expression,  simply
             cast it to the appropriate 16 bit type:

                eg: 0x1234 / c;         /* 0x34 / c (8 bit arithmetic) */
                    (int)0x1234 / c;    /* 0x1234 / c (16 bit arithmetic) */

                Most processors do not support a simple efficient method for
             adding or subtracting a SIGNED 8 bit  quantity  and  a  16  bit
             quantity.  The code generators supplied with MICRO-C  make  the
             assumption that character  values  being  added  or  subtracted
             to/from integers will contain only POSITIVE  values,  and  thus
             use  UNSIGNED  addition/subtraction.  This  allows  much   more
             efficient code to be generated,  as the carry/borrow  from  the
             low order byte of the operation is  simply  propagated  to  the
             high order byte  of  the  result  (an  operation  supported  in
             hardware by the CPU).

                For those rare instances where you do wish to add/subtract a
             potentially negative character value to/from an  int,  you  can
             force the expression to be performed in less efficient fully 16
             bit arithmetic by casting the character to an int.

                    int i;
                    char c;
                    ...
                    i += c;         /* Very efficient... C must be positive */
                    i += (int)c;    /* Less efficient... C can be negative */
    MICRO-C                                                          Page: 29


    3. ADVANCED TOPICS

          This section provides information on the more advanced aspects  of
       MICRO-C,  which is  generally  not  needed  for  casual  use  of  the
       language.

       3.1 Conversion Rules

             MICRO-C keep track of the  "type"  of each value  used  in  all
          expressions.  This type identifies certain characteristics of  the
          value,  such  as   size   range   (8/16   bits),   numeric   scope
          (signed/unsigned), reference (value/pointer) etc.

             When an  operation  is  performed  on  two  values  which  have
          identical "types", MICRO-C assigns that same "type" to the result.

             When the  two  value  "types"  involved  in  an  operation  are
          different,  MICRO-C calculates the "type"  of the result using the
          following rules:

          3.1.1 Size range

                If both values are  direct  (not  pointer)  references,  the
             result will be 8 bits only if  both  values  were  8  bits.  If
             either value was 16 bits, the result will be 16 bits.

                If one value is a pointer,  and the  other  is  direct,  the
             result will be a pointer to the same size value as the original
             pointer.

                If both values were pointers,  the result will be a  pointer
             to 16 bits only if both original  pointers  referenced  16  bit
             values. If either pointer referenced an 8 bit value, the result
             will reference an 8 bit value.

          3.1.2 Numeric Scope

                The result of an expression is considered to be signed  only
             if both original values were signed.  If either  value  was  an
             unsigned value, the result is unsigned.

          3.1.3 Reference

                If either of the original values was a pointer,  the  result
             will  be  a  pointer.  One  exception  to  this  rule  is   the
             subtraction of two pointers, which yields an integer result.

             Note that this  "calculated"  result type is used  for  partial
          results within an expression. Whenever a symbol such as a variable
          or function is referenced,  the type of that symbol is taken  from
          its declaration,  no matter what  "type"  of value was last stored
          (variable) or returned (function).

             The TYPECAST  operation  may  be  used  to  override  the  type
          calculated for the result of an expression if necessary.
    MICRO-C                                                          Page: 30


       3.2 Assembly Language Interface

             Assembly language programs may be called from 'C' functions and
          vice versa.  These programs may be in the form of inline  assembly
          language statements in the 'C'  source code,  or separately linked
          modules.

             The MICRO-C runtime  library  includes  a  number  of  assembly
          language subroutines which provide various services  (such  as  16
          bit  multiplication,  division,  etc).  These  routines  are  well
          documented in the library startup code files (6809RL?.ASM),  which
          you should examine before  attempting  to  use  assembly  language
          within MICRO-C.

             Global variables defined in 'C' exist at absolute addresses and
          may be referenced directly by name from assembly language.  Global
          names which are referenced  by  both  assembly  language  and  'C'
          should not be longer than 15 characters.

             When MICRO-C calls any routine  ('C'  or assembler),  it  first
          pushes all arguments to the routine onto the processor  stack,  in
          the order in  which  they  occur  in  the  argument  list  to  the
          function.  This means that the LAST argument to  the  function  is
          CLOSEST to the top of the processor stack.

             Arguments are always pushed as 16 bit values.  Character values
          are extended to 16 bits,  and arrays are passed as 16 bit pointers
          to the array.  (MICRO-C knows that arrays which are arguments  are
          actually  pointers,  and  automatically  references  through   the
          pointer).

             After pushing the arguments,  MICRO-C then generates a  machine
          language subroutine  call,  thereby  executing  the  code  of  the
          routine.

             Once the called routine returns, the arguments are removed from
          the stack by the calling program.

             It is the responsibility of the called function to  remove  any
          saved registers and local variable space from the stack before  it
          returns.  If a value is to be returned to the calling program,  it
          is expected to be in the 16 bit ACCUMULATOR.

             Examine  the  supplied  library  functions,  as  well  as  code
          produced by the compiler to gain more insight into the  techniques
          of accessing local variables and arguments.
    MICRO-C                                                          Page: 31


             The 16 bit accumulator is maintained in registers A:B  (A=High,
          B=Low)

             Local variables in a function may be referenced as offsets from
          the stack pointer.  Note that offsets must  be  adjusted  for  the
          number of additional bytes which are  pushed  and  popped  on  the
          stack during the execution of  the  function.  The  address  of  a
          particular local variable is calculated as:

                                "stack pointer"
                                       +
                   (# bytes pushed during function execution)
                                       +
                (size of all preceding local variables in bytes)

             Arguments to a  function  may  also  be  referenced  as  direct
          offsets from the stack pointer,  in much the  same  way  as  local
          variables are.  The address of a particular argument is calculated
          as:

                                "stack pointer"
                                       +
                   (# bytes pushed during function execution)
                                       +
                     (size of all local variables in bytes)
                                       +
                     (Size of return address on stack (2))
                                       +
                      (# arguments from LAST argument) * 2

             If a function has been declared  as  "register",  MICRO-C  will
          load the  'D'  accumulator with the number of arguments which were
          passed, each time the function is called. This allows the function
          to determine the location of the  first  argument,  which  may  be
          calculated as:

                                "stack pointer"
                                       +
                           (accumulator contents) * 2
                                       +
                   (# bytes pushed during function execution)
                                       +
                     (size of all local variables in bytes)
                                       +
                     (Size of return address on stack (2))
    MICRO-C                                                          Page: 32


    4. THE MICRO-C PREPROCESSOR

          The MICRO-C Preprocessor is a source code filter,  which  provides
       greater capabilities than the preprocessor which is integral  to  the
       MICRO-C compiler.  It has been implemented as a stand  alone  utility
       program which processes the source code before it is compiled.

          Due to the higher complexity of  this  preprocessor,  it  operates
       slightly slower than the the integral MICRO-C preprocessor.  This  is
       mainly due to the fact that it reads each line from the file and then
       copies it to a new line while performing the macro substitution. This
       is necessary since each macro may contain parameters  which  must  be
       replaced "on the fly" when it is referenced.

          The integral MICRO-C preprocessor is very FAST,  because  it  does
       not copy the input line.  When it encounters a '#define'd symbol,  it
       simply adjusts the input scanner pointer to point to  the  definition
       of that symbol.

          Keeping the extended preprocessor as a stand alone utility  allows
       you  to  choose  between  greater   MACRO   capability   and   faster
       compilation.  It also allows the system to continue to  run  on  very
       small hardware platforms.

          The additional capabilities of the extended preprocessor are:

            - Parameterized MACROs.

            - Multiple line MACROs.

            - Nested conditionals.

            - Numeric conditionals (#if)

            - User generated errors (#error)

            - Ability to undefine MACRO symbols.

            - String concatenation

            - Library reference in include file names (<> and "")
    MICRO-C                                                          Page: 33


       4.1 The MCP command

             The format of the MICRO-C Preprocessor command line is:

                    MCP [input_file] [output_file] [options]

             [input_file]  is the name of the  source  file  containing  'C'
          statements to read.  If no filenames are given, MCP will read from
          standard input.

             [output_file]  is the name of the file to which  the  processed
          source code is written.  If less than two filenames are specified,
          MCP will write to standard output.

          4.1.1 Command Line Options

                MCP accepts the following command line [options],  which are
             recognized in lower case only:

                -C      - Instructs MCP to keep comments from  the input
                          file (except for those in '#' statements which
                          are always removed). Normally, MCP will remove
                          all comments.

                -D      - Warns of duplicate macro definitions.

                -L      - Causes the output file to contain line numbers.
                          Each line in the output file will be  prefixed
                          with the line number of the  originating  line
                          from the input file.

                L=path  - Defines the directory path which will be taken
                          to reference  "library"  files when  '<>'  are
                          used around an  '#include'  file name.  Unless
                          otherwise specified, the path defaults to:
                                        '[MC]'

                -Q      - Instructs MCP to be quiet, and not display the
                          startup message when it is executed.

          <name>=<text> - Pre-defines a non-parameterized macro  of  the
                          specified <name> with the string value <text>.

                NOTE: "doubled up" options (eg: -ql) are not accepted.
    MICRO-C                                                          Page: 34


       4.2 Preprocessor Commands

             The following commands are recognized by the MCP utility,  only
          if they occur at the beginning of the source file line:

          4.2.1 #define <name>(parameters) <replacement text>

                Defines a global macro name which will be replaced with  the
             indicated  <replacement text>  wherever it occurs in the source
             file.

                Macro  names  may  be  any  length,  and  may  contain   the
             characters 'a'-'z',  'A'-'Z',  '0'-'9' and '_'.  Names must not
             begin with the characters '0'-'9'.

                If the macro name is IMMEDIATELY followed by a list of up to
             10 parameter names contained in brackets, those parameter names
             will be substituted with parameters passed to the macro when it
             is referenced.  Parameter names follow the same rules as  macro
             names.

                     eg: #define min(a, b) (a < b ? a : b)

                If any spaces exist between the macro name and  the  opening
             '(',  the macro will not be parameterized,  and  all  following
             text  (including '('  and  ')')  will be entered into the macro
             definition.

                If the very last character of a  macro  definition  line  is
             '\',  MCP will continue the definition with the next line  (The
             '\' is not included). Pre-processor statements included as part
             of a macro definition will not be processed by MCP, but will be
             passed on and handled by the integral MICRO-C preprocessor.

          4.2.2 #undef <symbol>

                Undefines the named macro symbol. further references to this
             symbol will not be replaced.

                NOTE: With MCP, macro definitions operate on a STACK. IE: If
             you define a macro  symbol,  and  then  re-define  it  (without
             '#undef'ing it first),  subsequently  '#undef'ing it will cause
             it to revert to its  previous  definition.  A  second  '#undef'
             would then cause it to be completely undefined.
    MICRO-C                                                          Page: 35


          4.2.3 #forget <symbol>

                Similar  to  '#undef',  except  that  the  symbol  and   ALL
             SUBSEQUENTLY DEFINED SYMBOLS will be undefined.

                Useful for releasing any local symbols  (used only within  a
             single include file).

                For example:

                        #define GLOBAL "xxx"    /* first global symbol */
                            ...                 /* more globals */
                        #define LOCAL   "xxx"   /* first local symbol */
                            ...                 /* more locals */
                        /* body of include file goes here */
                        #forget LOCAL           /* release locals */

          4.2.4 #if <expression>

                Evaluates an expression,  and causes the following lines (up
             to '#else', '#elif' or '#endif' to be processed and included in
             the output file only if the result of the expression  was  TRUE
             (non-zero).  The expression may contain only numeric constants,
             and the following operators:

                +  Addition                     << Shift Left
                -  Subtract & Unary negate      >> Shift Right
                *  Multiplication               == Test equal to
                /  Division                     != Test not equal to
                %  Modulus                      >  Test greater than
                &  Bitwise AND                  >= Test greater or equal
                |  Bitwise OR                   <  Test less than
                ^  Bitwise XOR                  <= Test less or equal
                && Logical AND                  ~  Unary bitwise complement
                || Logical OR                   !  Unary logical complement

                Note that the simplified expression parser in MCP  does  NOT
             follow standard rules of operator  precedence.  Operations  are
             performed from left  to  right  in  the  order  that  they  are
             encountered.  Brackets  '()'  can be used to force  a  specific
             order of evaluation.

                Macro substitution will occur on the expression before it is
             evaluated,  and any symbol names which  are  not  resolved  are
             assumed to have a value of 0 (FALSE).

          4.2.5 #ifdef <symbol>

                Causes the following lines to be processed and  included  in
             the output file only if the named symbol is defined as a macro.
    MICRO-C                                                          Page: 36


          4.2.6 #ifndef <symbol>

                Causes the following lines to be processed and  included  in
             the output file only if the named symbol is NOT  defined  as  a
             macro.

                NOTE: '#if/#ifdef/#ifndef/#else/#elif/#endif' may be nested.

          4.2.7 #else

                Causes the following lines  to  be  processed  only  if  the
             preceding '#if', '#ifdef', '#ifndef' and all '#elif' statements
             at this level have been false.  Only one #else  is  allowed  in
             each conditional block,  and it must be the last section of the
             block.

          4.2.8 #elif <expression>

                Behaves like '#else' followed by '#if',  except that it does
             not create another nesting level  (ie:  Only  one  '#endif'  is
             required).  Multiple  '#elif's are permitted  within  a  single
             conditional block.

          4.2.9 #endif

                Terminates  an  #if/#ifdef/#ifndef/#else/#elif   conditional
             block.

          4.2.10 #include <filename>

                Causes MCP to open the named file and include  its  contents
             as part of the input source.

                If the filename is contained within '"' characters,  it will
             be opened exactly as  specified,  and  (unless  it  contains  a
             directory path) will reference a file in the current directory.

                If the filename is contained within the characters  '<'  and
             '>',  it will be prefixed  with  the  library  path  (See  'l='
             option),  and will therefore reference a file in  that  library
             directory.

                For example:

                        #include "HEADER.H" /* from current directory */
                        #include <STDIO.H>  /* from library directory */

          4.2.11 #error <text>

                Causes  MCP  to  issue  an  error  message  containing   the
             specified text, and then terminate.

          4.2.12 #message <text>

                Outputs an informational message (does not terminate).
    MICRO-C                                                          Page: 37


          4.2.13 #index <expression>

             Sets the value of the __INDEX__ count (see below).

       4.3 Predefined symbols

          The following symbols are predefined within MCP:

            __FILE__    - Current file name
            __LINE__    - Current line number
            __INDEX__   - Index count, increments every time referenced

       4.4 Error messages

             When MCP detects an error  during  processing,  an  message  is
          displayed along with  the  filename  and  line  number.  MCP  will
          terminate if more than 10 errors occur.  The following errors  are
          reported by MCP:

          4.4.1 Cannot open include file

                A  '#include'  statement on the indicated line  specified  a
             file which could not be opened for reading.

          4.4.2 Invalid constant in expression

                An expression on the indicated line does not contain a valid
             numeric constant at a point where one was expected.
    MICRO-C                                                          Page: 38


          4.4.3 Invalid include file name

                A  '#include'  statement on the indicated line  specified  a
             file  name  which  was  not  contained  within  '"'   or   '<>'
             characters.

          4.4.4 Invalid macro name

                A '#define' statement on the indicated line contains a macro
             name which does not follow the name rules.

          4.4.5 Invalid macro parameter

                A '#define' statement on the indicated line contains a macro
             parameter name which does not follow the name rules.

                A reference to a macro does not have a proper ')'  character
             to terminate the parameter list.

          4.4.6 Invalid operator in expression

                An expression on the  indicated  line  does  not  contain  a
             supported operator at a point where one was expected (see #if).

          4.4.7 Misplaced #else / #elif / #endif

                The indicated conditional control statement was found  in  a
             place where it was not expected.

          4.4.8 Too many errors

                More  than  10  errors  has  been  encountered  and  MCP  is
             terminating.

          4.4.9 Too many macro definitions

                MCP has encountered more  '#define'  statements than it  can
             handle.

          4.4.10 Too many macro parameters

                A  '#define'  statement on the indicated line specifies more
             parameters to the macro than MCP can handle.

          4.4.11 Too many include files

                MCP has encountered more nested  '#include'  statements than
             it can handle.

          4.4.12 Undefined macro

                A  '#undef'  or  '#forget'  statement on the indicated  line
             references a macro name which has not been defined.
    MICRO-C                                                          Page: 39


          4.4.13 Unterminated comment

                The END OF FILE has  been  encountered  while  processing  a
             comment.

          4.4.14 Unterminated string

                A quoted string  on  the  indicated  line  has  no  end.  To
             continue a string to  the  next  line,  use  '\'  as  the  last
             character on the line.  The  '\'  will not be included  in  the
             string.

             NOTE:  MCP is not aware  of  inline  assembly  code,  and  will
             therefore  generate  an  "Unterminated  string"  error  if   it
             encounters unbalanced single or double quotes in  the  assembly
             comments. To prevent this, either avoid using unbalanced quotes
             in assembly comments,  or use the  'C'  form  (/* ...  */)  for
             comments within the assembly blocks.
    MICRO-C                                                          Page: 40


       4.5 String Concatenation

             MCP supports a non-standard-C extension which allows  for  very
          flexible concatenation of strings,  including the incorporation of
          non-string items into adjacent strings.  This works as follows: If
          any string is followed immediately by the '#' character,  MCP does
          two things:

          - The trailing quote is removed from the preceding string.
          - The opening quote is removed from the next string encountered.

                "one"#" two"            -> Results in "one two"
                #define NAME Dave
                "Hello "#NAME"!"        -> Results in "Hello Dave!"

          Note1:  EVERYTHING (including spaces) from the '#' until the start
          of the next string will be included in the concatenated string.

          Note2: If you want to append a non-string to a string, without any
          further appended text,  you MUST use a null string ("")  to supply
          the closing quote: "Hello "#NAME""
    MICRO-C                                                          Page: 41


    5. THE MICRO-C COMPILER

          The heart of the MICRO-C programming environment is the  COMPILER.
       This program reads a  file  containing  a  'C'  source  program,  and
       translates it into an equivalent assembly language program.

          The compiler includes its  own  limited  pre-processor,  which  is
       suitable for  compiling  programs  requiring  only  non-parameterized
       MACRO substitution, simple INCLUDE file capability,  and single-level
       CONDITIONAL processing.

          A complete description of the language accepted by MCC09,  as well
       as error messages and other details is given in the section  entitled
       "THE MICRO-C PROGRAMMING LANGUAGE".

       5.1 The MCC09 command

             The format of the MICRO-C 6809 Compiler command line is:

                   MCC09 [input_file] [output_file] [options]

             [input_file]  is the name of the  source  file  containing  'C'
          statements to read.  If no filenames are given,  MCC09  will  read
          from standard input.

             [output_file]  is the name of the file to which  the  generated
          assembly language code is written.  If less than two filenames are
          specified, MCC09 will write to standard output.

          5.1.1 Command Line Options

                MCC09 accepts the following command  line  [options],  which
             are recognized in upper case only:

                -C      - Include the 'C' source code as assembly comments.

                -F      - Causes the compiler to "Fold" its literal pool.
                          (Identical strings not contained in explicit
                          variables occur only once in memory).

                -L      - Enables MCC09 to accept line numbers.
                          (At beginning of line, followed by ':').

                -Q      - Causes MCC09 to be quiet (no startup message).

                -S      - Output symbolic comments (see below).

                NOTE: "doubled up" options (eg: -ql) are not accepted.
    MICRO-C                                                          Page: 42


       5.2 Symbol Information Comments

             When the -S option is used, MCC09 outputs special comments into
          the listing file which provide information about symbols  used  in
          the program:

          #fun <symbol_name> <stack_allocation> <local_reference>

             This indicates the start of  a  function  named  <symbol_name>.
          <stack_allocation>  is the amount of stack used for local variable
          storage,  and  <local_reference>  is an value that increments with
          each function,  and is used in a unique prefix  for  local  static
          variables.

          #end

             This comment indicates  the  end  of  the  function  code.  The
          addresses listed with #fun and #end can be used to  determine  the
          memory block occupied by the function code.

          #lcl <symbol_name> <type> <index> [#dims dim...]

             This comment indicates a symbol local to the current  function.
          #lcl will always occur between the #fun and a  #end  comments  for
          the function in which these symbols are in scope.

          #gbl <symbol_name> <type> <index> [#dims dim...]

             This comment indicates a symbol which is global to  the  entire
          program.

          <type>  is a 16  bit  value  (in  decimal)  which  indicates  type
          information from the compilers symbol table,  in bit positions  as
          follows:

        REFERENCE   0x8000  - symbol has been referenced
        INITED      0x4000  - symbol is initialized in declaration
        ARGUMENT    0x2000  - symbol is a function argument
        EXTERNAL    0x1000  - external attribute
        STATIC      0x0800  - static attribute
        REGISTER    0x0400  - register attribute
        TVOID       0x0200  - void attribute
        UNSIGNED    0x0100  - unsigned attribute
        BYTE        0x0080  - 0=16 bit, 1=8 bit
        CONSTANT    0x0040  - const attribute
        SYMTYPE     0x0030  - Symbol type (see below):
                        0   - A simple variable
                        1   - A structure member
                        2   - A structure template
                        3   - A function(global) or GOTO label(local)
        ARRAY       0x0008  - symbol is an array
        POINTER     0x0007  - level of pointer indirection

          <index> is a 16 bit value with the following meaning:
    MICRO-C                                                          Page: 43


        Global symbol:              Set to zero
        Local (!static) variable:   Offset of variable into stack frame
        Function argument:          Offset from stack at function entry
        Goto label (always local):  Compiler generated symbol number
        Static symbol:              Local ref. number (unique to function)
        Struct/Union tag:           Size (in bytes) of structure
        Struct/Union member:        Offset of member into structure

          If the symbol represents an array  (ARRAY bit set in <type>),  the
          next value will indicate the total number  of  dimensions  to  the
          array. Following that are the sizes of each dimension.

    6. THE MICRO-C OPTIMIZER

          The MICRO-C optimizer is an output code filter which examines  the
       assembly code produced by the compiler, recognizing known patterns of
       inefficient code (using the "peephole" technique),  and replaces them
       with more optimal code  which  performs  the  same  function.  It  is
       entirely table driven,  allowing it to be modified for virtually  any
       processor.

          Due its many table lookup operations,  the optimizer  may  perform
       quite slowly when processing a large  file.  For  this  reason,  most
       people prefer not to optimize during the debugging of a program,  and
       utilize the optimizer only when creating the final copy.

       6.1 The MCO09 command

             The format of the MICRO-C Optimizer command line is:

                   MCO09 [input_file] [output_file] [options]

             [input_file] is the name of the source file containing assembly
          statements to read.  If no filenames are given,  MCO09  will  read
          from standard input.

             [output_file]  is the name of the file to which  the  optimized
          assembly  code  is  written.  If  less  than  two  filenames   are
          specified, MCO09 will write to standard output.

          6.1.1 Command Line Options

                MCO09 accepts the following command  line  [options],  which
             are recognized in upper case only:

                -D      - Instructs MCO09 to produce a 'debug' display on
                          standard output showing the  source code  which
                          it is removing and replacing in the input file.
                          NOTE: If you do not specify an explicit  output
                                file, you will get the  debug  statements
                                intermixed with  the  optimized  code  on
                                standard output.

                -Q      - Instructs  MCO09  to be quiet,  and not display
                          the startup message when it is executed.

                NOTE: "doubled up" options (eg: -qd) are not accepted.
    MICRO-C                                                          Page: 44


    7. THE SOURCE LINKER

          The CUBIX system assembler does not  directly  support  an  object
       linker.  This causes a problem  with  'C'  development,  because  the
       library functions must be included in the source code,  with  several
       drawbacks:

        1)  There is no way to automatically tell which library functions
            to include, therefore, you must do it manually.

        2)  'C' library functions must be  re-compiled every  time,  in
            order to avoid conflict between compiler generated labels.

          The MICRO-C Source Linker  (SLINK)  helps overcome these problems,
       by automatically  joining  previously  compiled  (assembly  language)
       source code from the library  to  your  programs.  Only  those  files
       containing functions which you  reference  are  joined  (Taking  into
       consideration functions called  by  the  included  library  functions
       etc...).  As the files are  joined,  compiler  generated  labels  are
       adjusted to be unique within each file.

       7.1 The SLINK Command

             The format of the SLINK command line is:

                   SLINK input_file... [options] output_file

             "input_file"  is the name of the  source  file  containing  the
          compiler output from your program.  Several  input  files  may  be
          specified,  in which case they will all be processed into a single
          output file.

             "output_file"  is the name of the  file  to  which  the  linked
          source code is written.
    MICRO-C                                                          Page: 45


          7.1.1 Command line options

                SLINK accepts the following command line [options]:

            ?       - Display command line help summary.

            -C      - Removes comments from the output file

            l=path  - Specify directory path taken to reference the
                      library files. If not given, defaults to:
                        '[MC]MCLIB.LIB'

            -Q      - Inhibit display of the startup message.

            NOTE: "doubled up" options (eg: -cq) are not accepted.

       7.2 Multiple Input Files

             SLINK accepts multiple input files on  the  command  line,  and
          processes each file to build the output file.  This allows you  to
          "link" together several previously compiled (or assembly language)
          modules into one final program.

             Any external references  which  are  not  resolvable  from  the
          library are assumed to be resolved by  one  of  the  input  source
          files.  Since SLINK does not have knowledge of the public  symbols
          defined  in  the  input  files,  the  absence  of  an   externally
          referenced symbol will not be detected  until  the  assembly  step
          (where it will cause an undefined symbol error).
    MICRO-C                                                          Page: 46


       7.3 The Library File

             SLINK uses a special file as the library of code from which  to
          resolve external symbols.  This is called the  LIBRARY  file  (see
          'L=' option).

             This file contains blocks of code,  which are identified  by  a
          line containing one of the following markers:

            1)  Blocks beginning with  '<' indicate code blocks which are
                always included at the BEGINNING of the  prgoram  (Before
                your source file(s)). This the best way  to  include  the
                startup code and any  runtime library  routines which are
                required at all times.

            2)  Blocks beginning with '^'  indicate code blocks which are
                to be included AFTER the program and library source files,
                but BEFORE any uninitialized data areas are output.  This
                is the best way to set up the location and  storage class
                of the uninitialized data if it does not immediately
                follow the executable program code.

            3)  Blocks beginning with  '>' indicate code blocks which are
                to be included at the END of the program, after all other
                information is  output.  This is the  best way  to define
                heap memory storage, and to provide any post-amble needed
                by the assembler.

            4)  Blocks beginning with '-' indicate  optional code blocks,
                included only if a  global symbol  occuring  within  that
                block is referenced within the remainder of the program.

            For a complete example, please refer to the [MC]MCLIB.LIB
            library file included with the MICRO-C/CUBIX distribution.

            In summary, the output file is written from:

                1 - The '<' (prefix) blocks             *
                2 - The program source file(s)          *\
                3 - Library blocks referenced (if any)  * > See note
                4 - The '^' (middle) blocks              */
                5 - Uninitialized data definitions      (if any)
                6 - The '>' (suffix) files

    MICRO-C                                                          Page: 47


       7.4 Source file information

          7.4.1 SLINK Directives

                SLINK interprets two  "directives"  which may be inserted in
             the input source files or library blocks to control the  source
             linking process.  These directives must be on a separate  line,
             beginning in column 1,  and must  be  in  uppercase.  They  are
             removed by SLINK during processing,  and thus  will  not  cause
             conflict with the normal syntax used by the assembler.

                              $DD:<symbol> <size>

                The  '$DD'  directive is used to define  uninitialized  data
             storage areas, which will be allocated by SLINK between the '^'
             (middle)  and '>' (suffix)  files.  This allows you to allocate
             uninitialized data outside of  the  bounds  of  the  executable
             image, and thus exclude it from being saved to disk.

                                  $EX:<symbol>

                The '$EX' directive is used by SLINK to identify any symbols
             which are externally referenced.  Whenever a '$EX' directive is
             found,  SLINK searches the LIBRARY for the  named  symbol,  and
             marks the corresponding block for inclusion in the program.

             Notes:
             - $EX directives will have no effect in MIDDLE or SUFFIX files,
               because the external references have already been resolved by
               the time they are processed.
             - $DD directives will have no effect in SUFFIX  files,  because
               uninitialized storage has  already  been  allocated  at  that
               point.

          7.4.2 Compiler generated labels

                As it processes each source file  or  library  block,  SLINK
             scans each line for symbols which consist of the '?' character,
             followed by a number.  If it finds such as symbol, it inserts a
             two character sequence ranging from 'AA'  to  'ZZ'  between the
             '?', and the number. This sequence will be incremented for each
             source file processed,  and  thus  insures  that  the  compiler
             generated symbols will remain unique for each file.

                If you  are  writing  assembly  language  programs  for  the
             library,  you must be careful to avoid  using  identical  local
             symbols in any of the library files,  one way to do this is  to
             use symbols which meet the above criteria.
    MICRO-C                                                          Page: 48



                    +--------------------------------------+
                    |                                      |
                    |  **********************************  |
                    |  * The MICRO-C CUBIX/6809 library *  |
                    |  **********************************  |
                    |                                      |
                    +--------------------------------------+










    8. The MICRO-C/CUBIX Library

          The  library  functions  described  on  the  following  pages  are
       currently available in the MICRO-C CUBIX/6809 library  as  "standard"
       functions.
    ABORT                                                             ABORT



    PROTOTYPE:

        abort(char *message)


    ARGUMENTS:

        message - Pointer to message to display


    RETURN VALUE:

        N/A - Function never returns


    DESCRIPTION:

          This function writes the string passed as an argument to  standard
       error, and then terminates the program. This provides a simple method
       of terminating a  program  on  an  error  condition  with  a  message
       explaining why.


    EXAMPLES:

        abort("Invalid operand\n");
    ABS                                                                 ABS



    PROTOTYPE:

        int abs(int number)


    ARGUMENTS:

        number  - Any integer value


    RETURN VALUE:

        The absolute value of "number"


    DESCRIPTION:

          The "abs" function returns the absolute value of the argument.  If
       "number" is a positive value, it is returned unchanged.  If negative,
       the negate of that value is returned (giving a positive result).


    EXAMPLES:

        difference = abs(value1 - value2);
    ATOI                                                               ATOI



    PROTOTYPE:

        int atoi(char *string)


    ARGUMENTS:

        string  - Pointer to a string containing a decimal number


    RETURN VALUE:

        16 bit integer value


    DESCRIPTION:

          The  "atoi"  function converts an ASCII string containing a signed
       decimal number (-32768 to 32767) to a 16 bit value which is returned.
       An unsigned number of the range  (0 to 65535)  may also be used,  and
       the result if assigned to an "unsigned" variable will be correct.


    EXAMPLES:

        value = atoi("1234");
        value = atoi("-1");
    CHKCH                                                             CHKCH



    PROTOTYPE:

        int chkch()


    ARGUMENTS:

        None


    RETURN VALUE:

        0       - No character available from console input device.
        !0      - Character read from console input device.


    DESCRIPTION:

          The  "chkch"  function checks to see if a character is ready to be
       received from the console input device. If no character is available,
       a zero (0) is returned, otherwise the character is read and its value
       is  passed  back.  The  CARRIAGE  RETURN  character  (0x0D)  will  be
       translated into a NEWLINE (0x0A) for compatibility with 'C'.


    EXAMPLES:

        if(chkch() == 0x1B)     /* Escape KEY pressed ? */
            return;
    CHKCHR                                                           CHKCHR



    PROTOTYPE:

        int chkchr()


    ARGUMENTS:

        None


    RETURN VALUE:

        0-255   - Character read from console input device.
        -1      - No character was available.


    DESCRIPTION:

          The  "chkch"  function checks to see if a character is ready to be
       received from the console input device. If no character is available,
       a -1 is returned, otherwise the character is read and its "raw" value
       is passed back (without translation).


    EXAMPLES:

        if(chkchr() == '\r')        /* Return KEY pressed ? */
            return;
    CONCAT                                                           CONCAT



    PROTOTYPE:

        register concat(char *dest, char *source, ...)


    ARGUMENTS:

        dest    - Pointer to destination string
        source  - Pointer to source string
        ...     - Additional sources may be given


    RETURN VALUE:

        None


    DESCRIPTION:

          The  "concat"  function concatenates the given source strings into
       one destination string.  The destination string must be large  enough
       to hold all of the source strings plus the string  terminator  (zero)
       byte. No value is returned.

          NOTE: This function uses a variable number of arguments,  and must
       be declared as "register" (See stdioio.h").


    EXAMPLES:

        concat(filename,"[DIR]", input_name);
    DELETE                                                           DELETE



    PROTOTYPE:

        int delete(char *pathname)



    ARGUMENTS:

        pathname- Name of file to delete


    RETURN VALUE:

        0 if successful, otherwise an operating system error code


    DESCRIPTION:

          The "delete" function removes an existing file from the disk.  Any
       disk space occupied by the file is released.


    EXAMPLES:

        delete("temp");
    DISABLE                                                         DISABLE



    PROTOTYPE:

        disable()


    ARGUMENTS:

        None


    RETURN VALUE:

        None


    DESCRIPTION:

          The  "disable"  function  disables  the  6809  standard  interrupt
       system,  preventing the processor from servicing  interrupts.  It  is
       used whenever the execution of an  interrupt  handler  may  interfere
       with a particular operation.

          When this function is used, the "enable" function should be called
       as soon as possible after "disable". Failure to do this may result in
       loss of system functions performed under interrupts.


    EXAMPLES:

        disable();                  /* Disallow interrupts */
        /* ... */
        enable();                   /* Re-allow interrupts */
    DISABLEF                                                       DISABLEF



    PROTOTYPE:

        disablef()


    ARGUMENTS:

        None


    RETURN VALUE:

        None


    DESCRIPTION:

          The  "disablef"  function disables the 6809 fast interrupt system,
       preventing the  processor  from  servicing  interrupts.  It  is  used
       whenever the execution of an interrupt handler may interfere  with  a
       particular operation.

          When this function is  used,  the  "enablef"  function  should  be
       called as soon as possible after  "disablef".  Failure to do this may
       result in loss of system functions performed under interrupts.


    EXAMPLES:

        disablef();                 /* Disallow interrupts */
        /* ... */
        enablef();                  /* Re-allow interrupts */
    ENABLE                                                           ENABLE



    PROTOTYPE:

        enable()


    ARGUMENTS:

        None


    RETURN VALUE:

        None


    DESCRIPTION:

          The "enable"  function enables the 6809 standard interrupt system,
       allowing the processor to service interrupts.  It should be called as
       soon as possible following the use of the "disable" function.


    EXAMPLES:

        disable();                  /* Disallow interrupts */
        /* ... */
        enable();                   /* Re-allow interrupts */
    ENABLEF                                                         ENABLEF



    PROTOTYPE:

        enablef()


    ARGUMENTS:

        None


    RETURN VALUE:

        None


    DESCRIPTION:

          The  "enablef"  function enables the 6809 fast  interrupt  system,
       allowing the processor to service interrupts.  It should be called as
       soon as possible following the use of the "disablef" function.


    EXAMPLES:

        disablef();                 /* Disallow interrupts */
        /* ... */
        enablef();                  /* Re-allow interrupts */
    EXIT                                                               EXIT



    PROTOTYPE:

        exit(unsigned char rc)


    ARGUMENTS:

        rc      - Return (exit) code value


    RETURN VALUE:

        N/A - Function never returns


    DESCRIPTION:

          This function terminates the execution of the program, and returns
       control to the CUBIX operating system.


    EXAMPLES:

        exit(2);        /* Terminate with exit code 2 */
    FCLOSE                                                           FCLOSE



    PROTOTYPE:

        int fclose(FILE *fp)


    ARGUMENTS:

        fp      - File pointer to an open file


    RETURN VALUE:

        0 if successful, otherwise an operating system error code


    DESCRIPTION:

          This function closes a file  which  was  previously  opened  using
       "fopenr"  or  "fopenw".  The I/O buffer space used  by  the  file  is
       released.  In the case of a file open for write ('w'),  the last disk
       buffer is flushed and written to disk.


    EXAMPLES:

        fclose(fp);
    FGETB                                                             FGETB



    PROTOTYPE:

        int fgetb(char *buffer, int size, FILE *fp)


    ARGUMENTS:

        buffer  - Pointer to buffer to receive data
        size    - Number of bytes to read
        fp      - File pointer to an input file


    RETURN VALUE:

        Number of bytes read from file


    DESCRIPTION:

          This function reads a block of data from a file and places  it  in
       memory at the address of "buffer".  Data will be read in BINARY mode,
       which means that no translations will occur for newline  or  EOF.  If
       the number of bytes  returned  is  less  than  the  number  of  bytes
       requested,  either the end of the file was encountered  or  an  error
       condition occurred (in which case the value will be zero).


    EXAMPLES:

        fgetb(block, 512, input_fp);
    FGETC                                                             FGETC



    PROTOTYPE:

        int fgetc(FILE *fp)


    ARGUMENTS:

        fp      - File pointer to an input file


    RETURN VALUE:

        Value of a character read from the file (0-255)
        EOF (-1) if end of file or an error condition occurs


    DESCRIPTION:

          This function reads a single character from  an  input  file,  and
       returns it as a positive value in the range of 0 to 255.  A  full  16
       bit value is returned,  allowing the end  of  file  condition  to  be
       distinct from the character value 255.

          The character is read in TEXT mode,  which means  that  the  CUBIX
       line end (carriage-return)  is translated into the newline character.
       Also,  a  0xFF  character  occuring  in  the  file  is   treated   as
       End-Of-File.


    EXAMPLES:

        if((c = fgetc(input_file)) == EOF)
            abort("End of file encountered\n");
    FGETR                                                             FGETR



    PROTOTYPE:

        int fgetc(FILE *fp)


    ARGUMENTS:

        fp      - File pointer to an input file


    RETURN VALUE:

        Value of a character read from the file (0-255)
        EOF (-1) if end of file or an error condition occurs


    DESCRIPTION:

          This function reads a single character from  an  input  file,  and
       returns it as a positive value in the range of 0 to 255.  A  full  16
       bit value is returned,  allowing the end  of  file  condition  to  be
       distinct from the character value 255.

          The character is read in BINARY mode,  which means  that  no  data
       translations will occur.


    EXAMPLES:

        if((c = fgetr(input_file)) == EOF)
            abort("Physical End of file encountered\n");
    FGETS                                                             FGETS



    PROTOTYPE:

        char *fgets(char *buffer, int size, FILE *fp)


    ARGUMENTS:

        buffer  - Pointer to string to receive line
        size    - Maximum size of line to read
        fp      - File pointer to an input file


    RETURN VALUE:

        Pointer to "buffer", or 0 if end of file


    DESCRIPTION:

          The  "fgets"  function reads characters from the  specified  input
       file,  and places them in the character buffer  until  one  of  three
       things happens:

          1) A NEWLINE character is encountered.

          2) The END of the file is encountered.

          3) The limit of "size" character is read.

          The string is terminated with the standard  NULL  (00)  character.
       The trailing NEWLINE  '\n'  character is NOT included  in  the  input
       buffer.

          The line is read in TEXT mode, which means that the CUBIX line end
       (carriage-return) is translated into the newline character.  Also,  a
       0xFF character occuring in the file is treated as End-Of-File.

          MICRO-C's  implementation  of  this  function  differs  from  ANSI
       standards in that it does not include the NEWLINE  '\n'  character in
       the input buffer.


    EXAMPLES:

        fgets(input_line, 80, input_file);
    FPRINTF                                                         FPRINTF



    PROTOTYPE:

        register fprintf(FILE *fp, char *format, arg, ...)


    ARGUMENTS:

        fp      - File pointer to an output file
        format  - Pointer to format string
        arg     - Argument as determined by format string
        ...     - Additional arguments may be required


    RETURN VALUE:

        None


    DESCRIPTION:

          This routine performs a formatted print to  a  file  specified  by
       'fp'.  The 'format'  string is written to the file with the arguments
       substituted for special "conversion characters".

          See "fprintf" for more information on format strings.

          NOTE: This function uses a variable number of arguments,  and must
       be declared as "register" (See "stdio.h").



    EXAMPLES:

        fprintf(stderr,"Filename='%s'\n", filename);
        fprintf(stdout,"Address=%04x\n", address);
        fprintf(outfile,"Amount: $%3u.%02u\n", amount / 100, amount % 100);
    FPUTB                                                             FPUTB



    PROTOTYPE:

        int fputb(char *block, int size, FILE *fp)


    ARGUMENTS:

        block   - Pointer to a block of data to write
        size    - Number of bytes to write
        fp      - File pointer to an output file


    RETURN VALUE:

        None


    DESCRIPTION:

          This function writes a block of data to the  indicated  file  from
       memory at the specified address.  Data is written in BINARY mode with
       no newline or EOF translations.


    EXAMPLES:

        fputb(buffer, 100, fp);
    FPUTC                                                             FPUTC



    PROTOTYPE:

        fputc(char c, FILE *fp)


    ARGUMENTS:

        c       - Any character value
        fp      - File pointer to an output file


    RETURN VALUE:

        Operating system error code


    DESCRIPTION:

          This function writes the character  'c'  to the file indicated  by
       the file pointer 'fp' in TEXT mode.  This means that the '\n' newline
       character is translated to the 0x0D carriage-return used by CUBIX.


    EXAMPLES:

        fputc('*', fp);
        fputc('\n', stderr);
    FPUTR                                                             FPUTR



    PROTOTYPE:

        fputr(char c, FILE *fp)


    ARGUMENTS:

        c       - Any character value
        fp      - File pointer to an output file


    RETURN VALUE:

        Operating system error code


    DESCRIPTION:

          This function writes the character  'c'  to the file indicated  by
       the file pointer 'fp' in BINARY mode. No translations are made on the
       character value.


    EXAMPLES:

        fputr(0x01, fp);
        fputr(0x0A, fp);
    FPUTS                                                             FPUTS



    PROTOTYPE:

        fputs(char *string, FILE *fp)


    ARGUMENTS:

        string  - Pointer to a character string
        fp      - FIle pointer to output file


    RETURN VALUE:

        Operating system error code


    DESCRIPTION:

          The "fputs"  function writes the specified string to the indicated
       output file. The zero terminating the string is NOT written.


    EXAMPLES:

        fputs("Text message", output_file);
    FOPENR                                                           FOPENR



    PROTOTYPE:

        FILE *fopenr(char *filename)


    ARGUMENTS:

        filename- Name of the file to open

    RETURN VALUE:

        File pointer to the file buffer for the open file
        Zero (0) if file could not be opened


    DESCRIPTION:

          This function opens a file  for  buffered  input  (read)  allowing
       subsequent I/O operations to read the file.

          This function automatically allocates  a  522  byte  File  Control
       Block (FCB) which is used to access the file.


    EXAMPLES:

        fp1 = fopenr("input_file");
        fp2 = fopenw("output_file");
    FOPENW                                                           FOPENW



    PROTOTYPE:

        FILE *fopenw(char *filename)


    ARGUMENTS:

        filename- Name of the file to open

    RETURN VALUE:

        File pointer to the file buffer for the open file
        Zero (0) if file could not be opened


    DESCRIPTION:

          This function opens a file for buffered  output  (write)  allowing
       subsequent I/O operations to write the file.

          This function automatically allocates  a  522  byte  File  Control
       Block (FCB) which is used to access the file.


    EXAMPLES:

        fp1 = fopenr("input_file");
        fp2 = fopenw("output_file");
    FREE                                                               FREE



    PROTOTYPE:

        free(char *ptr)


    ARGUMENTS:

        ptr     - Pointer to a previously allocated memory block


    RETURN VALUE:

        None


    DESCRIPTION:

          The "free" function releases (deallocates)  a block of memory that
       was obtained via a call to "malloc", and returns it to the heap. This
       makes it available for use by other memory allocations.


    EXAMPLES:

        if(!(ptr = malloc(BUFSIZ)))     /* Allocate a temporary buffer */
            abort("Not enough memory");
        /* ... Use the memory block ... */
        free(ptr);                      /* Release temporary buffer */
    GETCH                                                             GETCH



    PROTOTYPE:

        int getch()


    ARGUMENTS:

        None


    RETURN VALUE:

        Value of a character read from the console input device.


    DESCRIPTION:

          This function reads a single  character  from  the  console  input
       device,  and returns it as a positive value in the range of 0 to 255.
       If the character is a carriage return  (0x0D),  is translated into  a
       NEWLINE (0x0A) for compatibility with 'C'.


    EXAMPLES:

        while(getch() != 0x1B);     /* Wait for an ESCAPE character */
    GETCHR                                                           GETCHR



    PROTOTYPE:

        int getchr()


    ARGUMENTS:

        None


    RETURN VALUE:

        Value of a character read from the console input device.


    DESCRIPTION:

          This function reads a single  character  from  the  console  input
       device,  and returns it as a positive value in the range of 0 to 255.
       The  character  is  read  in  "raw"  format,  with  no   translations
       performed.


    EXAMPLES:

        while(getchr() != '\r');        /* Wait for a RETURN */
    GETSTR                                                           GETSTR



    PROTOTYPE:

        char *getstr(char *buffer, int size)


    ARGUMENTS:

        buffer  - Pointer to string to receive line
        size    - Maximum size of line to read


    RETURN VALUE:

        The number of characters received into the line.


    DESCRIPTION:

          The "getstr" function reads a string of character from the console
       input device and places them  into  the  specified  character  buffer
       until either a NEWLINE character is  encountered,  or  the  limit  of
       "size" character is read.

          The string is terminated with the standard  NULL  (00)  character.
       The trailing NEWLINE  '\n'  character is NOT included in  the  output
       buffer.

          The BACKSPACE or DEL keys can be used to edit the input line.


    EXAMPLES:

        getstr(input_line, 80);
    ISALNUM                                                         ISALNUM



    PROTOTYPE:

        int isalnum(char c)


    ARGUMENTS:

        c       - Any character value


    RETURN VALUE:

        1 if 'c' is alphabetic or numeric
        0 if 'c' is not alphabetic or numeric


    DESCRIPTION:

          Returns  TRUE  (1)  if  the  passed  character  'c'  is  an  ASCII
       alphabetic letter in either upper or  lower  case  or  if  'c'  is  a
       numeric digit, otherwise FALSE (0) is returned.


    EXAMPLES:

        while(isalnum(*ptr))        /* Copy over symbol name */
            *name++ = *ptr++;
    ISALPHA                                                         ISALPHA



    PROTOTYPE:

        int isalpha(char c)


    ARGUMENTS:

        c       - Any character value


    RETURN VALUE:

        1 if 'c' is alphabetic
        0 if 'c' is not alphabetic


    DESCRIPTION:

          Returns  TRUE  (1)  if  the  passed  character  'c'  is  an  ASCII
       alphabetic letter in either upper or lower case,  otherwise FALSE (0)
       is returned.


    EXAMPLES:

        flag = isalpha(input_char);
    ISASCII                                                         ISASCII



    PROTOTYPE:

        int isascii(int c)


    ARGUMENTS:

        c       - Any character value


    RETURN VALUE:

        1 if 'c' is an ASCII character
        0 if 'c' is not an ASCII character


    DESCRIPTION:

          Returns TRUE  (1)  if the passed character  'c'  is a valid  ASCII
       character (0x00-0xFF), otherwise FALSE (0) is returned.


    EXAMPLES:

        if(!isascii(*ptr))
            abort("Invalid character data");
    ISCNTRL                                                         ISCNTRL



    PROTOTYPE:

        int iscntrl(char c)


    ARGUMENTS:

        c       - Any character value


    RETURN VALUE:

        1 if 'c' is a "control" character
        0 if 'c' is not a "control" character


    DESCRIPTION:

          Returns TRUE (1) is the passed character 'c' is an ASCII "control"
       character (0x00-0x1F or 0x7F), otherwise FALSE (0) is returned.


    EXAMPLES:

        putch(iscntrl(c) ? '.' : c);    /* Display controls as '.' */
    ISDIGIT                                                         ISDIGIT



    PROTOTYPE:

        int isdigit(char c)


    ARGUMENTS:

        c       - Any character value


    RETURN VALUE:

        1 if 'c' is numeric
        0 if 'c' is not numeric


    DESCRIPTION:

          Returns TRUE  (1)  is the passed character  'c'  is an ASCII digit
       ('0'-'9'), otherwise FALSE (0) is returned.


    EXAMPLES:

        value = 0;
        while(isdigit(*ptr))
            value = (value * 10) + (*ptr++ - '0');
    ISGRAPH                                                         ISGRAPH



    PROTOTYPE:

        int isgraph(char c)


    ARGUMENTS:

        c       - Any character value


    RETURN VALUE:

        1 if 'c' is a non-space printable character
        0 if 'c' is a space or not printable


    DESCRIPTION:

          Returns TRUE (1)  if the passed character 'c' is a printable ASCII
       character other than  a  space  character,  otherwise  FALSE  (0)  is
       returned.


    EXAMPLES:

        putch(isgraph(c) ? c : '.');
    ISLOWER                                                         ISLOWER



    PROTOTYPE:

        int islower(char c)


    ARGUMENTS:

        c       - Any character value


    RETURN VALUE:

        1 if 'c' is lower case alphabetic
        0 if 'c' is not lower case alphabetic


    DESCRIPTION:

          Returns  TRUE  (1)  if  the  passed  character  'c'  is  an  ASCII
       alphabetic letter of lower case, otherwise FALSE (0) is returned.


    EXAMPLES:

        flag = islower(input_char);
    ISPRINT                                                         ISPRINT



    PROTOTYPE:

        int isprint(char c)


    ARGUMENTS:

        c       - Any character value


    RETURN VALUE:

        1 if 'c' is a printable character
        0 if 'c' is not printable


    DESCRIPTION:

          Returns TRUE (1)  if the passed character 'c' is a printable ASCII
       character, otherwise FALSE (0) is returned.


    EXAMPLES:

        while(isprint(*ptr))
            ++ptr;
    ISPUNCT                                                         ISPUNCT



    PROTOTYPE:

        int ispunct(char c)


    ARGUMENTS:

        c       - Any character value


    RETURN VALUE:

        1 if 'c' is a printable non-alphanumeric character
        0 if 'c' is not printable or alphanumeric


    DESCRIPTION:

          Returns TRUE (1)  if the passed character 'c' is a printable ASCII
       character which is not a letter of the alphabet or a  numeric  digit,
       otherwise FALSE (0) is returned.


    EXAMPLES:

        while(ispunct(*ptr))
            ++ptr;
    ISSPACE                                                         ISSPACE



    PROTOTYPE:

        int isspace(char c)


    ARGUMENTS:

        c       - Any character value


    RETURN VALUE:

        1 if 'c' is a space character (space, tab or newline)
        0 if 'c' is not a space character


    DESCRIPTION:

          Returns TRUE  (1)  if the passed character 'c'  is one of a space,
       tab or newline, otherwise FALSE (0) is returned.


    EXAMPLES:

        while(isspace(*ptr))
            ++ptr;
    ISUPPER                                                         ISUPPER



    PROTOTYPE:

        int isupper(char c)


    ARGUMENTS:

        c       - Any character value


    RETURN VALUE:

        1 if 'c' is upper case alphabetic
        0 if 'c' is not upper case alphabetic


    DESCRIPTION:

          Returns  TRUE  (1)  if  the  passed  character  'c'  is  an  ASCII
       alphabetic letter of upper case, otherwise FALSE (0) is returned.


    EXAMPLES:

        flag = isupper(input_char);
    ISXDIGIT                                                       ISXDIGIT



    PROTOTYPE:

        int isxdigit(char c)


    ARGUMENTS:

        c       - Any character value


    RETURN VALUE:

        1 if 'c' is a hexadecimal digit
        0 if 'c' is not a hexadecimal digit


    DESCRIPTION:

          Returns TRUE  (1)  is the passed character  'c'  is an valid ASCII
       hexadecimal digit ('0'-'9', 'A'-'F', 'a'-'f'), otherwise FALSE (0) is
       returned.


    EXAMPLES:

        value = 0;
        while(isxdigit(*ptr))
            value = (value * 16) +
                (isdigit(*ptr) ? *ptr++ - '0' : toupper(*ptr++) - ('A'-10));
    LONGJMP                                                         LONGJMP



    PROTOTYPE:

        longjmp(int savenv[2], int rvalue)


    ARGUMENTS:

        savenv  - Save area for program context
        rvalue  - Value to be returned by "setjmp"


    RETURN VALUE:

        N/A - Function never returns


    DESCRIPTION:

          The  "longjmp"  function  causes  execution  to  transfer  to  the
       "setjmp"  call which set  up  the  "savenv"  variable.  The  "setjmp"
       function will appear to return the value of "rvalue".

          NOTE-1:  "longjmp"  may only be  used  from  within  the  function
       calling "setjmp"  or a function which has been called "beneath"  that
       function. IT MUST NOT BE USED AFTER THE FUNCTION CALLING "SETJMP" HAS
       TERMINATED.

          NOTE-2:  If "rvalue" is zero,  the function calling "setjmp"  will
       assume that it is returning from initialization. Unless you want this
       unusual behavior,  you should not pass a  return  value  of  zero  to
       "longjmp".

          See also SETJMP.


    EXAMPLES:

        if(getch() == ('C'-'@'))        /* If Control-C entered... */
            longjmp(savearea, 1);       /* Return to main function */
    LONGMATH                                                       LONGMATH



    PROTOTYPES:

        int longadd(char *num1, char *num2);
        int longsub(char *num1, char *num2);
        longmul(char *num1, char *num2);
        longdiv(char *num1, char *num2);
        int longshr(char *num1);
        int longshl(char *num1);
        longcpy(char *num1, char *num2);
        longset(char *num1, unsigned value);
        int longtst(char *num1);
        int longcmp(char *num1, char *num2);
        extern char Longreg[];

    ARGUMENTS:

        num1    - First LONG operand, receives result if generated
        num2    - Second LONG operand, is not altered
        value   - 16 bit value to initialize LONG number


    RETURN VALUE:

        longadd - 0 = Ok, 1 = addition overflowed
        longsub - 0 = Ok, 1 = subtraction underflowed
        longshr - Carry out of shift (1/0)
        longshl - Carry out of shift (1/0)
        longtst - 0 = Number is zero, !0 = Number is not zero
        longcmp - 0 = (num1 == num2), 1 = (num1 > num2), -1 = (num1 < num2)


    DESCRIPTION:

          This set of functions performs basic arithmetic functions on  LONG
       numbers:

        longadd(num1, num2)     ->  num1 += num2
        longsub(num1, num2)     ->  num1 -= num2
        longmul(num1, num2)     ->  num1 *= num2 , Longreg = num1 * num2
        longdiv(num1, num2)     ->  num1 /= num2 , Longreg = num1 % num2
        longshr(num1)           ->  num1 >>= 1
        longshl(num1)           ->  num1 <<= 1
        longcpy(num1, num2)     ->  num1 = num2
        longset(num1, value)    ->  num1 = (long) value
        longtst(num1)           ->  Test (num1 != 0)
        longcmp(num1, num2)     ->  Compare num1 and num2

          As shipped,  a LONG number is 32 bits (4 bytes)  in size,  however
       this can be changed by altering the LONGMATH.ASM in the library.

          For a complete example of using  these  functions,  refer  to  the
       LONGCALC.C example program included with the package.
    MALLOC                                                           MALLOC



    PROTOTYPE:

        char *malloc(int size)


    ARGUMENTS:

        size    - Size of memory block to allocate (in bytes).


    RETURN VALUE:

        0       - Memory allocation failed
        !0      - Pointer to allocated memory block


    DESCRIPTION:

          The "malloc" function allocates a block of memory of the specified
       size from the heap,  and returns a pointer to it.  This  memory  will
       remain allocated until it is  explicitly  released  with  the  "free"
       function.


    EXAMPLES:

        if(!(ptr = malloc(BUFSIZ)))     /* Allocate a temporary buffer */
            abort("Not enough memory");
        /* ... Use the memory block ... */
        free(ptr);                      /* Release temporary buffer */
    MAX                                                                 MAX



    PROTOTYPE:

        int max(int value1, int value2)


    ARGUMENTS:

        value1  - Any integer value
        value2  - Any integer value


    RETURN VALUE:

        The greater of "value1" or "value2"


    DESCRIPTION:

          The "max" function returns the higher of its two argument values.


    EXAMPLES:

        biggest = max(a, b);
    MEMCPY                                                           MEMCPY



    PROTOTYPE:

        memcpy(char *dest, char *source, unsigned size)


    ARGUMENTS:

        dest    - Pointer to the destination
        source  - Pointer to the source
        size    - Number of bytes to copy


    RETURN VALUE:

        None


    DESCRIPTION:

          The "memcpy" function will copy the specified number of bytes from
       the source to the destination.


    EXAMPLES:

        memcpy(buffer1, buffer2, 256);
    MEMSET                                                           MEMSET



    PROTOTYPE:

        memset(char *block, char value, unsigned size)


    ARGUMENTS:

        block   - Pointer to a block of memory
        value   - Value to initialize memory with
        size    - Number of bytes to initialize


    RETURN VALUE:

        None


    DESCRIPTION:

          Sets a block of memory  beginning  at  the  pointer  "block",  for
       "size" bytes to the byte value "value".


    EXAMPLES:

        memset(buffer, 0, 100);
    MIN                                                                 MIN



    PROTOTYPE:

        int min(int value1, int value2)


    ARGUMENTS:

        value1  - Any integer value
        value2  - Any integer value


    RETURN VALUE:

        The smaller of "value1" or "value2"


    DESCRIPTION:

          The "min" function returns the lower of its two argument values.


    EXAMPLES:

        least = min(a, b);
    NARGS                                                             NARGS



    PROTOTYPE:

        int nargs()


    ARGUMENTS:

        None


    RETURN VALUE:

        The number of arguments passed to the calling function


    DESCRIPTION:

          Returns the number of arguments passed to a "register" function.

          NOTE:  When calling  a  "register"  function,  MICRO-C  loads  the
       accumulator with the number of arguments just prior  to  calling  the
       function.  This  "nargs"  routine is simply a null  definition  which
       returns with the same value in the accumulator as was there  when  it
       was called.  Therefore  "nargs"  MUST BE THE FIRST ARITHMETIC  ENTITY
       EVALUATED WITHIN  THE  REGISTER  FUNCTION  or  the  contents  of  the
       accumulator will be lost. Some examples of "register" definitions and
       the use of "nargs" may be found in the library source code.


    EXAMPLES:

        first_arg = nargs() * 2 + &arguments;
    PEEK                                                               PEEK



    PROTOTYPE:

        int peek(unsigned address)


    ARGUMENTS:

        address - 16 bit memory address


    RETURN VALUE:

        The 8 bit value read from the given memory address


    DESCRIPTION:

          The "peek" function reads and returns a byte (8 bits)  from memory
       as an integer value between 0 and 255.


    EXAMPLES:

        while(peek(0)); /* Wait for flag to clear */
    PEEKW                                                             PEEKW



    PROTOTYPE:

        int peekw(unsigned address)


    ARGUMENTS:

        address - 16 bit memory address


    RETURN VALUE:

        The 16 bit value read from the given memory address


    DESCRIPTION:

          The  "peekw"  function reads and returns a  word  (16  bits)  from
       memory as an integer value between 0 and 65535 (-1).


    EXAMPLES:

        var = peekw(0));
    POKE                                                               POKE



    PROTOTYPE:

        poke(unsigned address, int value)


    ARGUMENTS:

        address - 16 bit memory address
        value   - Value to be written to memory


    RETURN VALUE:

        None


    DESCRIPTION:

          The "poke" function writes a byte (8 bit) value to memory.


    EXAMPLES:

        poke(0, 0);     /* Write 0 to location 0 */
    POKEW                                                             POKEW



    PROTOTYPE:

        pokew(unsigned address, int value)


    ARGUMENTS:

        address - 16 bit memory address
        value   - Value to be written to memory


    RETURN VALUE:

        None


    DESCRIPTION:

          The "pokew" function writes a word (16 bit) value to memory.


    EXAMPLES:

        pokew(0, 0);    /* Write 0 to locations 0 and 1 */
    PRINTF                                                           PRINTF



    PROTOTYPE:

        register printf(char *format, arg, ...)


    ARGUMENTS:

        format  - Pointer to format string
        arg     - Argument as determined by format string
        ...     - Additional arguments may be required


    RETURN VALUE:

        None


    DESCRIPTION:


          The "printf" function performs a formatted print to console serial
       port.  The  'format'  string is written to the serial port  with  the
       arguments substituted  for  special  "conversion  characters".  These
       "conversion characters" are identified by a preceding '%', and may be
       one of the following:

                    b       - Binary number
                    c       - Character
                    d       - Decimal (signed) number
                    o       - Octal number
                    s       - String
                    u       - Unsigned decimal number
                    x       - Hexadecimal number
                    %       - A single percent sign (No argument used)

          A numeric "field width" specifier may be placed in between the '%'
       and the conversion character,  in which case the value will be output
       in a field of that width.  If the "field width" is a negative number,
       the output will be left justified in the field, otherwise it is right
       justified. If the field width contains a leading '0', then the output
       field will be padded with zeros, otherwise spaces are used.

          If no  "field width"  is given,  the output is free format,  using
       only as much space as required.

          NOTE: This function uses a variable number of arguments,  and must
       be declared as "register" (See "6809io.h").


    EXAMPLES:

        printf("Hello world!!!\n");
        printf("%u interrupts have occurred!\n", int_count);
    PUTCH                                                             PUTCH



    PROTOTYPE:

        putch(char c)


    ARGUMENTS:

        c       - Any character value


    RETURN VALUE:

        None


    DESCRIPTION:

          This function writes the  character  'c'  to  the  console  output
       device.  The  NEWLINE  character  is  translated  into  a  LINE-FEED,
       followed by a CARRIAGE return,  which causes the printing position to
       advance to the first column of the next line.


    EXAMPLES:

        putch('*');
        putch('\n');
    PUTCHR                                                           PUTCHR



    PROTOTYPE:

        putchr(char c)


    ARGUMENTS:

        c       - Any character value


    RETURN VALUE:

        None


    DESCRIPTION:

          This function writes the  character  'c'  to  the  console  output
       device.  The  character  is  written  in  "raw"   format,   with   no
       translations of any kind.


    EXAMPLES:

        putchr('*');
        putchr('\r');
    PUTSTR                                                           PUTSTR



    PROTOTYPE:

        putstr(char *string)


    ARGUMENTS:

        string  - Pointer to a character string


    RETURN VALUE:

        None


    DESCRIPTION:

          The  "putstr"  function writes the specified string to the console
       output device. The zero terminating the string is NOT written.


    EXAMPLES:

        putstr("Text message");
    RAND                                                               RAND



    PROTOTYPE:

        unsigned rand(unsigned limit)


    ARGUMENTS:

        limit   - Maximum value to return


    RETURN VALUE:

        A pseudo-random number in the range of 0 to (limit-1)


    DESCRIPTION:

          The  "rand"  function calculates the next value of a pseudo-random
       sequence, based on a 16 bit unsigned "seed" value, which it maintains
       in the global variable "RANDSEED". The new value is stored as the new
       seed value,  and is then divided by the "limit" parameter,  to obtain
       the remainder, which is returned.  This results in a random number in
       the range of zero (0) to (limit - 1).

          Any  particular  sequence  may  be  repeated,  by  resetting   the
       "RANDSEED" value.


    EXAMPLES:

        value = rand(52);
    SETJMP                                                           SETJMP



    PROTOTYPE:

        int setjmp(int savenv[2])


    ARGUMENTS:

        savenv  - Save area for program context


    RETURN VALUE:

        0 is returned when actually called
        Value passed to "longjmp" is returned otherwise


    DESCRIPTION:

          When called,  the  "setjmp"  function stores the current execution
       state of the program into the passed integer array,  and returns  the
       value zero.

          The  "longjmp"  function may then be used to return the program to
       the "setjmp" call.  In this case, the value returned by "setjmp" will
       be the value which was passed to "longjmp".  This allows the function
       containing "setjmp" to determine which call to "longjmp"  transferred
       execution to it.

          See also LONGJMP.


    EXAMPLES:

        switch(setjmp(savearea)) {
            case 0 : printf("Longjmp has been set up"); break;
            case 1 : printf("Control-C Interrupt");     break;
            case 2 : printf("Reset command executed");  break;
            default: printf("Software error trap");     break; }
    SPRINTF                                                         SPRINTF



    PROTOTYPE:

        register sprintf(char *dest, char *format, arg, ...)


    ARGUMENTS:

        dest    - Pointer to destination string
        format  - Pointer to format string
        arg     - Argument as determined by format string
        ...     - Additional arguments may be required


    RETURN VALUE:

        None


    DESCRIPTION:

          The  "sprintf"  routine performs a formatted print to a string  in
       memory. The "format" string is written to the destination string with
       the arguments substituted for special "conversion characters".

          See "printf" for more information on format strings.

          NOTE: This function uses a variable number of arguments,  and must
       be declared as "register" (See "6809io.h").


    EXAMPLES:

        sprintf(header_file, "/lib/%s.h", header_name);
    SQRT                                                               SQRT



    PROTOTYPE:

        int sqrt(unsigned value)


    ARGUMENTS:

        value   - Number for which to calculate square root


    RETURN VALUE:

        The integer square root (rounded up) of the argument value


    DESCRIPTION:

          The  SQRT  function  returns  the  smallest  number   which   when
       multiplied by itself will give a number equal to or larger  that  the
       argument value.


    EXAMPLES:

    /*
     * Draw a circle about point (x, y) of radius (r)
     */
    circle(x, y, r)
        int x, y, r;
    {
        int i, j, k, rs, lj;

        rs = (lj = r)*r;
        for(i=0; i <= r; ++i) {
            j = k = sqrt(rs - (i*i));
            do {
                plot_xy(x+i, y+j);
                plot_xy(x+i, y-j);
                plot_xy(x-i, y+j);
                plot_xy(x-i, y-j); }
            while(++j < lj);
            lj = k; }
    }
    STRCAT                                                           STRCAT



    PROTOTYPE:

        char *strcat(char *dest, char *source)


    ARGUMENTS:

        dest    - Pointer to destination string
        source  - Pointer to source string


    RETURN VALUE:

        Pointer to zero terminating destination string


    DESCRIPTION:

          This function concatenates the source string on to the tail of the
       destination string.  The destination string must be large  enough  to
       hold the entire contents of both strings.


    EXAMPLES:

        strcat(program_name, ".c");
    STRCHR                                                           STRCHR



    PROTOTYPE:

        char *strchr(char *string, char chr)


    ARGUMENTS:

        string  - Pointer to a character string
        chr     - Character to look for


    RETURN VALUE:

        Pointer to the first occurrence of 'chr' in 'string'
        Zero (0) if character was not found


    DESCRIPTION:

          Searches the  passed  string  got  the  first  occurrence  of  the
       specified character.  If the character is found,  a  pointer  to  its
       position in the string is returned.  If the character is not found, a
       null pointer is returned.

          The null (0)  character is treated as valid data by this function,
       thus:
          strchr(string, 0);

       would return the position of the null terminator of the string.


    EXAMPLES:

        comma = strchr(buffer, ',');
    STRCMP                                                           STRCMP



    PROTOTYPE:

        int strcmp(char *string1, char *string2)


    ARGUMENTS:

        string1 - Pointer to first string
        string2 - Pointer to second string


    RETURN VALUE:

        0   - Strings match exactly
        1   - String1 is greater than string2
        -1  - String2 is greater than string1


    DESCRIPTION:

          This function compares two strings character by character.  If the
       two strings are identical,  a zero  (0)  is returned.  If  the  first
       string is greater than the second  (as far as ASCII is concerned),  a
       one (1) is returned.  If the second string is greater, a negative one
       (-1) is returned.


    EXAMPLES:

        if(!strcmp(command, "quit"))
            exit(0);
    STRCPY                                                           STRCPY



    PROTOTYPE:

        char *strcpy(char *dest, char *source)


    ARGUMENTS:

        dest    - Pointer to destination string
        source  - Pointer to source string


    RETURN VALUE:

        Pointer to zero terminating destination string


    DESCRIPTION:

          This function copies the source string to the destination  string.
       All data is copied up to and including the zero byte which terminates
       the string.  The destination string must be large enough to hold  the
       entire source.


    EXAMPLES:

        strcpy(filename, argv[1]);
    STRLEN                                                           STRLEN



    PROTOTYPE:

        int strlen(char *string)


    ARGUMENTS:

        string  - Pointer to a character string


    RETURN VALUE:

        The length of the string


    DESCRIPTION:

          Returns the length in character of the passed string.  The  length
       does not include the zero byte which terminates the string.


    EXAMPLES:

        length = strlen(command);
    TEMPMEM                                                         TEMPMEM



    PROTOTYPE:

        void *tempmem()


    ARGUMENTS:

        None


    RETURN VALUE:

        Point to temporary buffer space


    DESCRIPTION:

          Returns the memory address of the first available memory  location
       following the last data item allocated on the heap.  This can be used
       as a temporary buffer consisting of all available unallocated memory.

          Execution of a malloc()  function,  or  any  function  which  uses
       malloc()  [Fopenr,  Fopenw etc.]  may allocate memory within the area
       returned by tempmem() - in general,  tempmem() should be called every
       time the temporary memory is used to insure that heap allocation does
       not get corrupted.


    EXAMPLES:

        ptr = tempmem();
    TOLOWER                                                         TOLOWER



    PROTOTYPE:

        char tolower(char c)


    ARGUMENTS:

        c   - Any character value


    RETURN VALUE:

        The value of 'c', converted to lower case


    DESCRIPTION:

          Returns the value of 'c' converted to lower case.  If 'c' is not a
       letter of upper case,  no change is made,  and the original value  of
       'c' is returned.


    EXAMPLES:

        input_char = tolower(getch());
    TOUPPER                                                         TOUPPER



    PROTOTYPE:

        char toupper(char c)


    ARGUMENTS:

        c   - Any character value


    RETURN VALUE:

        The value of 'c', converted to upper case


    DESCRIPTION:

          Returns the value of 'c' converted to upper case.  If 'c' is not a
       letter of lower case,  no change is made,  and the original value  of
       'c' is returned.


    EXAMPLES:

        putch(toupper(output_char));
