        *************************************************************
        *                                                           *
        *                       STJ-Oberon-2                        *
        *                                                           *
        *             An Oberon-2 implementation for Atari          *
        *                                                           *
        *************************************************************


                           Author: Stephan Junker

                              Date: 21.10.1995



                    Contributions: Dirk Theisen
                                   Wolfgang Radtke
                                   Holger Kleinschmidt
                                   Charles Geiser




Table of contents

  1. Introduction to STJ-Oberon-2
  2. The STJ-Oberon-2 Compiler V2
  3. The STJ-Oberon-2 Linker V2
  4. The STJ-Oberon-2 Make V2
  5. The STJ-Oberon-2 Loader V2
  6. The STJ-Oberon-2 Debugger V2
  7. Other debugging facilities
  8. The STJ-Oberon-2 Optimizer V2
  9. The Browser
  10. PShell
  11. Commands
  12. Programming with a garbage collector
  13. Library modules









**************************************************************************
  1. Introduction to STJ-Oberon-2
**************************************************************************


General information
-------------------

STJ-Oberon-2 V2.14 consists of an Oberon-2 compiler, linker and make tool.
All tools are available as object files and can be executed using the
loader.
STJ-Oberon-2 should run on all ST-compatible hardware and software. Some
configurations will not support the full possibilities of the software. If
you have just 1 MB of ram, you will be forced to reduce the memory usage of
STJ-Oberon-2. You can work with a primitive shell called PShell ("P" for
primitive) instead of using Chatwin which should save about 250K of memory.
If you decide to do so, you will be forced to improve PShell, its no fun
using it. You might even program your own editor so you don't need to have
the space for an external editor. Linking the compiler and linker to
standalone programs is another option.



Copying policy
--------------

STJ-Oberon-2 is freeware. It is not supported anymore since I do not have
the time for it. You are allowed to make changes and use my libraries in
any kind of program. You may publish changes in separate archives, but you
may not charge any fee for it. It is, of course, not allowed to
redistribute my software under a different name or delete my name in the
copyright messages. You are allowed to add your name if you have done a
significant imrovement.
This software comes without warrenty. Use it at your own risk. I do not pay
for any damage it causes. STJ-Oberon-2 is tested on a TT with 4MB ST-ram
running Mag!X and an ST with 2.5 MB ram running TOS 1.4.


- per snail mail:

  Stephan Junker
  Aachener Str. 115
  D-52076 Aachen
  Germany

- per e-mail:

  Stephan Junker @ AC2        (MausNet)
  Stephan_Junker@AC2.maus.de  (InterNet)

My bank account is:

  Sparkasse Aachen
  Kontonummer : 16013351
  Bankleitzahl: 390 500 00




Getting started
---------------

You unpacked STJ-Oberon-2 V2.10 and want to know how to work with it? Then
follow these steps:

Use an ascii editor to edit OBERON.ENV. Set the paths correctly. If you
want to run Chatwin instead of PShell, change the value for DEFSTART to
CHATWIN.OBJ. If you run Chatwin, you can use the autotake take file in
folder TAKE. Adjust it to your needs.

If you started O2LOAD.PRG and it started Chatwin with my AUTOTAKE file, it
should report the function keys with their function. In order to run the
compiler, a project must be set. This simply means you start a take file
which sets the environment for a certain project. Type t and return to call
macro t which lets you select a take file in the TAKE folder. Select
TUTORIAL.PRJ for example. It sets the variable MODPATH to
$OBERON\TUTORIAL.PRJ.

Now type F2 and select file GEMDEMO.MOD in the TUTORIAL folder. This will
make Gemdemo the workfile and add it to Chatwin's filelist. Type F3 and
select this file again to make it the main file. Type F5 if you want to
take a look at it or F6 to compile it. It can be executed by typing its
module name. You can press F8 to link an executable program. After that,
you can type F4 and select GEMDEMO.PRG in the BIN folder to make it the
current program file. Type F9 to debug or F10 to execute it.

If you don't want to use load time linking at all, you must link the
compiler, linker and make. Start PShell by double click on the loader since
PShell is set as default execution module. When the terminal window opens,
type "Install.Run". This module will link the three programs. Exit PShell.
The programs should be found in folder BIN. You are not able to use the
debugger without load time linking.

If you cannot (or don't want to) use Chatwin or PShell, you can link the
compiler, the linker and the make utility. Execute O2LOAD.PRG with
"Install" as parameter. It should link the three programs, but it crashes
with a bus error if memory is unsufficient. That has still to be fixed.




**************************************************************************
  2. The STJ-Oberon-2 Compiler V2
**************************************************************************


Overview
--------

The STJ-Oberon-2 compiler (OCOMP.OBJ / COMPILE.TTP) is used to translate
Oberon source files (*.MOD) into object (*.OBJ), symbol (*.SYM) and
information (*.INF) files. The object file contains 680X0 code with some
additional information, the symbol file contains the exported symbols of a
module. The information files are used by the debugger to display variables
and thelike.

The version 2 of the compiler is a completely new implementation. This
was needed since the old design was not able to include all the desired
features.



Call
----

The compiler object file is executed by typing

  OComp.Compile {options} <name> {<name>}

whereas the program is excecuted as

  COMPILE.TTP {options} <name> {<name>}

The options are described below. At least the name of one module to compile
must be given. Enter only the first 8 characters if the name is longer.
No extension is needed.
For convenience, there is an alias "compile" for OComp.Compile under
Chatwin and the key F6 is predefined to compile the current work file.



Options
-------

Options can be set in three ways: First, the environment is checked for a
variable named OCOPT and its contents scanned for options, overwriting the
default values. After that the command line will be scanned for options,
thus overwriting those from the environment. At last, options can be
altered in the source file. Command line options must appear before the
first name of a module to compile.

The options format is as follows:

 An option is marked by a "+" or "-" in front of a character. "+" is used
 to switch it on, "-" to switch it off. If it is an option with a parameter
 instead of a switch, only "-" is allowed (as "-" is the usual option
 delimiter).

These options are available:

Notation | Meaning                                       | Default value
------------------------------------------------------------------------
 +/-/=A  | Assert check on / off / restore               | +
 +/-/=I  | Index check on / off / restore                | +
 +/-/=T  | Type check on / off / restore                 | +
 +/-/=K  | stacK check on / off / restore                | +
 +/-3    | 68030 code on / off                           | -
 +/-F    | Fpu code on / off                             | -
 +/-R    | Reassemble on / off                           | -
 +/-/=P  | oPtimize on / off / restore                   | +
 +/-H    | Highest optimization on /off                  | +
 +/-X    | language eXtensions on / off                  | +
 +/-/=W  | Warning output on / off / restore             | +
 +/-C    | Compiler Code on / off                        | +
 +/-Y    | copY dYnamic array on / off                   | +
 +J<proc>| Jump to proc after every statement            | -
 -J      | do not Jump after every statement             | -
 -E<ext> | set Extension to ext                          | OBJ
 -D<num> | set Distance between errors to num            | 20
 -U<num> | set maximUm number of errors to num           | 100
 -M<var> | read module path from env. variable var       | MODPATH
 -O<var> | read object path from env. variable var       | OBJPATH
 -S<var> | read symbol path from env. variable var       | SYMPATH

The letters may be capitals or not.

- Assert check
    Determines whether ASSERT code is entered in the object file or not.

- Index check
    Additional code to check the value of indices.

- Type check
    Additional code to check if types are correct.

- Stack check
    Add code at the beginning of every procedure which checks for stack
    overflows. Stack overflows are usually the result of an endless
    recursion.

- 68030 code
    Set usage of code available only in 68030.

- Fpu code
    Set usage of code available with FPU.

- Reassemble
    Enable producing a ressembler file.

- Optimize
    Set optimizing of the produced code. The code will be quite good, but
    cannot compete with an assembler programmer.

- Highest optimization
    This comprises optimizations which consume very much time. At the
    moment, the contents and branch optimization of the assembler code
    optimizer is affected by this option.

- Language extensions
    Set usage of language extensions not available in standard Oberon-2.

- Warning output
    Warnings are issued if the compiler encounters a possible code which
    may not be correct. I reduced them to real problems so you will not get
    any silly warnings. At the moment, it only reports if there are
    function procedures which do not have any RETURN statement.

- Compiler code
    This is additional code the compiler produces on procedure entry and
    exit, like LINK, UNLK and the copying of dynamic arrays called by
    value. Should only be switched off when programming in assembler.

- Copy dynamic array
    When defining a call by value parameter with a dynamic array type
    (ARRAY OF ...), this array is copied onto the stack when entering the
    procedure. This option enables or disables copy.

- Jump after every statement
    You may set a procedure which is called after every statement. The
    purpose is to call procedures in the debugger to trace and control
    program flow. The procedure must be visible everywhere it is called.

- Extension
    The compiler can produce object files with a different extension than
    OBJ. I don't remember what that should be useful for.

- Distance between errors
    The number of characters which have to pass before another error can be
    reported. Avoids output of errors caused by a previous error.

- Maximum number of errors
    Set the number of errors after which output should stop. Compilation
    will continue.

- Module path
    Set the environment variable containing the search paths for source
    files.

- Object path
    Set the environment variable containing the search paths for object
    files. Not used at the moment.

- Symbol path
    Set the environment variable containing the search paths for symbol
    files.

All these options (no matter if it makes sense) can be set in source
files using exactly the same format. Write (*$<options> *) and the options
will be stored. There may be no space between "(*" and "$" and no space
between "$" and the options. There must be a space before "*)". There may
also be additional comment after the space character. These comments are
also written into a reassembler file. If you want comment to show up there
without setting options, you can do that by (*$ <comment> *).
Note: The compiler makes several passes through pseudo code containing
these options. So make sure the options are reset at the end of the source
(which may be after the period). Otherwise it might use different options
in the second pass than in the first pass.



Environment
-----------

The environment is used to read default values for the options. If you are
not able or don't want to change the environment, you may set environment
variables in the file OBERON.ENV. This file must reside in the default
path on linker call, usually the directory of the compiler, in order to be found.
Inside this file, you can set one variable per line writing the variable name,
an equal sign and the the variables' value.
The following variables are used by the compiler:

OCOPT
    May contain default options in the same notation as in the command line

MODPATH
    Contains the search paths for source files. It uses the standard
    format: Different paths can be separated by either a comma or semicolon;
    A backslash at the end is not necessary; A "*" denotes all directories
    in that path.

SYMPATH
    Contains the search paths for symbol files. The format is the
    same as described above. If SYMPATH is undefined, MODPATH is used.

ERRFORM
    This variable may contain a string used to define the error report
    format. You can use \d for the file name, \z for line number, \s for
    the column (counting from 1), \p for absolute position and \f for the error
    message itself. Default is "Error \d \z, \s: \f".



Output
------

The compiler reports all imported modules with their path names onto IO.
Errors are also reported onto IO, but written into a file as well. That file
will get the extension ERR and will be stored in the same path as the source
file.
If compilation was successful, the object file is written into the path of the
source file. The symbol file is compared with the previous one. If it does
not contain changes, it will receive the same key and time stamp of the
previous one, but it is always written. If the symbols changed, it is reported.



Standard procedures
--------------------

The following tables show the predefined functions and proper procedures
of STJ-Oberon-2. Those procedures not available in standard Oberon-2 are
marked with a "*".
v denotes a variable, a an address, T a type and x and n denote expressions.
Integer means one of the integer types SHORTINT, INTEGER or LONGINT.

Functions:

+-------------+--------------+-------------+-----------------------+
| Name        | Argumenttype | Resulttype  | Function              |
+-------------+--------------+-------------+-----------------------+
| ABS(x)      | Numerical    | Type of x   | Absolute value        |
|             | Types        |             |                       |
| ASH(x,n)    | x,n: Integer | Type of x   | x * 2^n               |
| CAP(x)      | CHAR         | CHAR        | Capital letter        |
| CHR(x)      | Integer      | CHAR        | Integer to CHAR       |
|             |              |             | conversion            |
| ENTIER(x)   | Realtype     | LONGINT     | Largest integer not   |
|             |              |             | larger than x         |
| TRUNC(x) *  | Realtype     | LONGINT     | Truncate              |
| LEN(v,n)    | v: Array;    | INTEGER     | Length of v in        |
|             | n: Integer-  |             | dimension n           |
|             | constant     |             | (0 = first dim.)      |
| LEN(v)      | v: Array     | INTEGER     | = LEN(v,0)            |
| LONG(x)     | SHORTINT     | INTEGER     | extend                |
|             | INTEGER      | LONGINT     |                       |
|             | REAL         | LONGREAL    |                       |
| MAX(T)      | T = basetype | T           | maximum of T          |
|             | T = SET      | INTEGER     | highest               |
|             |              |             | setelement (31)       |
| MIN(T)      | T = Basetype | T           | minimum of T          |
|             | T = SET      | INTEGER     | 0                     |
| ODD(x)      | Integer      | BOOLEAN     | x MOD 2 = 1           |
| ORD(x)      | CHAR         | INTEGER     | ordinal value of x    |
| SHORT(x)    | LONGINT      | INTEGER     | shorten value         |
|             | INTEGER      | SHORTINT    |                       |
|             | LONGREAL     | REAL        |                       |
| SIZE(T)     | any Typ      | Integer     | number of bytes       |
|             |              |             | needed by T           |
+-------------+--------------+-------------+-----------------------+

Procedures:

+--------------------+-----------------------------+-----------------------+
| Name               | Argumente type              | Function              |
+--------------------+-----------------------------+-----------------------+
| ASSERT(x, n)       | x: Boolean expression       | IF ~x THEN HALT(n)    |
|                    | n: integer constant         | depending on option   |
| COPY(x,v)          | x: Char. Array, String;     | v := x                |
|                    | v: Char. Array              |                       |
| DEC(v)             | Integer                     | v := v-1              |
| DEC(v,n)           | v,n: Integer                | v := v-n              |
| EXCL(v,x)          | v: SET; x: Integer          | v := v - {x}          |
| HALT(x)            | Integerconstant             | terminate program     |
| INC(v)             | Integer                     | v := v+1              |
| INC(v,n)           | v,n: Integer                | v := v+n              |
| INCL(v,x)          | v: SET; x: Integer          | v := v + {x}          |
| NEW(v)             | Pointer                     | allocate v^           |
| NEW(v,x_0,...,x_n) | v : Pointer to open array;  | allocate v^           |
|                    | x_i: Integer                | with lengths x_0..x_n |
+--------------------+-----------------------------+-----------------------+


Functions in SYSTEM:

+-------------+------------------+-------------+-------------------------+
| Name        | Argumente type   | Result type | Function                |
+-------------+------------------+-------------+-------------------------+
| ADR(v)      | all              | LONGINT     | Adress of v             |
| ANL(a,b) *  | a,b: Integer     | as a,b      | bitwise AND             |
| BIT(a,n)    | a: LONGINT       | BOOLEAN     | Bit n of Mem[a]         |
|             | n: Integer       |             |                         |
| CC(n)       | Integerconstant  | BOOLEAN     | Condition n (0n15)    |
| LONG(a) *   | SHORTINT         | INTEGER     | unsigned extension      |
|             | INTEGER          | LONGINT     |                         |
| LSH(x,n)    | x: Integer,      | Type of x   | logic shift             |
|             | CHAR,BYTE        |             |                         |
|             | n: Integer       |             |                         |
| NTL(a) *    | a: Integer       | as a        | bitwise invert          |
| ORL(a,b) *  | a,b: Integer     | as a,b      | bitwise OR              |
| ROT(x,n)    | x: Integer       | Type of x   | Rotation                |
|             | CHAR,BYTE        |             |                         |
|             | n: Integer       |             |                         |
| VAL(T,x)    | T,x: alle Typen  | T           | take x as of type T     |
| XOL(a,b) *  | a,b: Integer     | wie a,b     | bitwise exklusive OR    |
+-------------+------------------+-------------+-------------------------+

Procedures in SYSTEM:

+----------------+---------------------+------------------------+
| Name           | Argumente type      | Function               |
+----------------+---------------------+------------------------+
| DISPOSE(p)     | Pointer             | deallocate memory      |
| GET(a,v)       | a: LONGINT          | v := Mem[a]            |
|                | v: simple types     |                        |
| GETREG(n,v)    | n: Integer constant | v := Register n        |
|                | v: simple types     | (0n15)               |
| INLINE(...) *  | Word constants      | enter the constants    |
|                |                     | into the code          |
| MOVE(a0,a1,n)  | a0,a1: LONGINT      | copy n bytes           |
|                | n: Integer          | at a0 to a1            |
| NEW(v,n)       | v: Pointer, LONGINT | allocate n bytes       |
|                | n: Integer          | and store adress in v  |
| PUT(a,v)       | a: LONGINT          | Mem[a] := v            |
|                | v: simple types     |                        |
| PUTREG(n,v)    | n: Integer constant | Register n := v        |
|                | v: simple types     | (0n15)               |
+----------------+---------------------+------------------------+



Optimization
------------

The optimization consists of three parts: The first optimizer searches for
repeating expressions and assigns them to temporary variables. The second
optimizer tries to assign as much variables as possible to registers. The
last optimization works on the assembler code and reduces branch sizes,
eliminates stupid code and things like that. It might be needed to switch
optimizing off when programming in Assembler, because it also optimizes
assembler code not produced by the compiler but entered by the programmer.
This might not always be desired, e.g. if code size may not change.

Note: The optimization does not reach an optimized code as an assembler
programmer. If the highest optimum is desired, one has to optimize the
code by hand.

Note: One part of the optimization has been disabled temporarily because it
produced nonsens code.



Constant expressions
--------------------

It should now be possible to use even standard procedure calls in constant
expressions.
Example:

CONST
  size = SIZE(Files.Rider);
  value = SYSTEM.VAL( INTEGER, 8000H);  (* 8000H normally LONGINT *)
  rot = SYSTEM.ROT( value, 5);



Extending modules without invalidating client modules
-----------------------------------------------------

This was an idea I got when Dirk Theisen wrote that Oberon/F had this
feature. After thinking about it I saw more benefits than problems, so I
decided to introduce it in V2.00.
In previous versions, as in the original version by Wirth, the new symbol
file was compared byte by byte with the previous one. So if an exported
identifier was added, the symbol file would change.
In V2.00, the previous symbol file is imported almost like the other
imports, except that it won't appear in the symbol table. Now when the new
symbol file is to be saved, it is first checked if all the identifiers
previously exported match those now exported. If so, the new symbol file
will replace the old one but retain its key and file time stamp.
There are, however, some rules to follow:

1. If you add variables, always add them at the end of the variable list.
   Variables are identified by offsets and these will change if you add a
   variable in front of others. You may add variables in front of others if
   no exported variable follows.
2. If you add record, fixed, dynamic or open array types, their type
   descriptors must be stored in the data segment. The offset of record
   type descriptor is stored in the symbol file if that record is exported.
   So you may only add these types behind the last record type in the
   global type segment. Local record types present no problem as they
   cannot be exported.
3. Type bound procedures present a special problem. If a record is extended
   in a client module, the TBPs there get offsets in the type descriptor
   depending on the TBPs already defined. So if you add a TBP in a module,
   these offsets would increase. So I implemented the possibility to
   reserve offsets of TBPs for later extension. Usually, 10 TBPs are
   reserved. If you add TBPs, this will decrease and if you add the 11th
   TBP, the symbol file will change and another 10 TBPs are reserved. By
   using the option -N, you can set the number of TBPs to reserve. Note
   that every reservation will occupie 4 bytes in the object, 8 bytes in
   the symbol file and 60 bytes when imported.

All other extensions should be possible without problems. New exported
procedures including TBPs can be added anywhere since the procedure
assigning procedure numbers checks for previously used numbers. Constants
present no problem at all. Changing the parameter names of exported
procedures is possible. Exporting previously not exported identifiers is
always possible.



Differences to standard Oberon-2
----------------------------------

- AND and NOT are identical to & and ~. As I took the step from Modula to
  Oberon, I preferred this. By now, I do not use it anymore and recommend
  to use & and ~. This extension might disappear sometime.

- SYSTEM.ADR can answer adresses of procedures and constant strings.

- A "-" behind the key word PROCEDURE is used to declare trap procedures.
  These are used to call TOS system functions.
  Example:

   PROCEDURE- Fclose(Handle : INTEGER) : INTEGER 62,1;

  The first number denotes the function value, the second the trap value.
  Using it will enter a trap call into the code.
  Since C pushes its parameters in the opposite order than STJ-Oberon-2,
  all parameters have to be declared in opposite order.

- Procedures which were used to assign to procedure variables had to be
  marked by a "*" behind the key word PROCEDURE. This is not necessary
  in STJ-Oberon-2 but will not lead to compilation errors.

- Strings may be enclosed in single quotes as well as in double quotes.

More complex extensions are described below.



ASSERT
------

ASSERT is a new standard procedure which is also availabe in Oberon/F. It
evaluates the first parameter which must be an expression with a boolean
result. If result of that expression is FALSE, a HALT with the number given
by the second parameter is called.



Unqualified import
------------------

It is possible to import modules in a way that no module name needs to be
written in front of their identifiers. This implies that the client module
cannot define identifiers with a name used in a module imported
unqualified. To do this, write the module name and a "*" behind it. Then
its identifiers can be accessed by <module>.<ident> or just by <ident>.
This is also possible with SYSTEM.

Implementation: The identifiers are added at the end of the global symbol
table rather than only their module symbol.

Unqualified import is very bad programming style and should only be used if
really necessary.

This is enabled only in extended mode.



Equal module and identifier names
---------------------------------

If a module exports an identifier identical to its module name, this
identifier can always be accessed by its name only. So if a module "Object"
exports an identifier "Object", you can access it by "Object.Object" or by
"Object".

Implementation: If a module is accessed without a period following it, its
identifiers are searched for an identical name.

This is enabled only in extended mode.



Assigment expressions
---------------------

Assignments are also accepted in expressions.
Example:

  IF v THEN          (* previously needed *)
    ass := b-c;
    IF ass > 0 THEN b := ass END;
  END;

  IF v & ((ass := b-c) > 0) THEN b := ass END;  (* now possible *)

The assignment expression has the lowest priority, therefore it is written
in parenthesis (otherwise it would get the result of the comparison).
This also allows multiple assignments:

  a := proc(); b := a;        (* previously needed *)

  a := b := proc();        (* now possible *)

This is enabled only in extended mode.



Return value derefencing
------------------------

When programming object oriented, it is common practice to access instance
variables via methods (TBPs). If this variable is a pointer, it always had
to be assigned to a pointer variable before it could be dereferenced. This
compiler allows dereferencing return values.
Example:

TYPE
  ptr = POINTER TO ARRAY 10 OF CHAR;

PROCEDURE ret() : ptr;
 ...

  p := ret(); p[0] := 0X;  (* previously needed *)

  ret()[0] := 0X    (* now possible *)

This is enabled only in extended mode.



Multiple method calls
---------------------

Object oriented languages like Smalltalk allow several messages to be sent
to an object at one time. This is now also possible in Oberon.
Example:

VAR
  viewer: WinView.Viewer;

  viewer.Init; viewer.Open;  (* previously needed *)

  viewer.Init
        .Open;      (* now possible *)

This is possible as long the method does not return anything. If it would,
than the return value would be dereferenced.

This is enabled only in extended mode.



Extended return from procedures
-------------------------------

It is now possible to return from a procedure and terminate global
procedures at the same time.
Example:

PROCEDURE test() : BOOLEAN;

  PROCEDURE test2;
   BEGIN
    RETURN^ TRUE
   END test2;

 BEGIN
  test2;
  RETURN FALSE
 END test;

In this example, the call of test2 will terminate test2 and test. Every "^"
sets the return level one step higher. The return statement in test would
not be reached. If a global procedure calls a RETURN^, this would terminate
that procedure and the module body. If the program was running, this equals
a program termination. If that procedure was called in a module body, that
body is terminated, but the program continues initialization.
If you do not see the benefits of this feature, you'll see it in the
following chapter.

This is enabled only in extended mode.



Assignment procedures
---------------------

There is a new type of procedure which I called assignment procedures. They
are declared with a "~" after the key word "PROCEDURE". To explain its
benefits, lets look at an example:

IMPORT
  BinTree;

PROCEDURE Includes(VAR tree: BinTree.Tree; obj: BinTree.Node) : BOOLEAN;
(*
 Should return true if tree contains obj.
 *)

  PROCEDURE~ Compare(cont: BinTree.Node);
   BEGIN
    IF cont = obj THEN RETURN^ TRUE END;
   END Compare;

 BEGIN
  tree.Traverse( BinTree.inorder, Compare);
  RETURN FALSE
 END Includes;

The method Traverse calls Compare with every object stored. If Compare
finds an object which is the same as obj, it terminates itself and Includes
and returns TRUE. If that does not happen, Traverse terminates and Includes
returns FALSE.
In standard Oberon, you would have to declare Compare as a global procedure
and store obj in a global variable. Then you need another global variable
which is set true if Compare finds the object. Comparison would continue
even if it was already found. Now what is more elegant?
There are some restrictions:
1. Assignment procedures have to be local procedures of a global procedure.
2. These procedures are not fully recursively callable. The procedure
   itself may call any other procedure including itself and its global
   procedure. But the procedure which calls it (Traverse in the example)
   may not call its global procedure (Includes in the example). This
   should be acceptable.

Implementation: The link register of the global procedure is stored in
front of the assignment procedure. That procedure restores it from there
when entered. This is the reason for restriction 2.

This is enabled only in extended mode.



Strings and characters
----------------------

No difference is made between " and '. Both can be used for strings and, if
the string is one character long, for characters.

Implementation: Both literals are stored as strings no matter what length
it has. If it is used as character and the length is one, it is converted
into a character.

Notes:
1. Constant strings are always stored with a terminating zero byte, but
   this byte is not counted when dealing with the length of a string.
2. An empty string ("") is optimized and will not be stored as string.
   Assigning an empty string will cause the first byte to be cleared and
   comparison with an empty string tests the first byte against zero.
3. String assignment (including COPY) and string comparison always check
   for length and zero byte.



Other new extensions
--------------------

HALT: Accepts any expression assignment compatible to INTEGER.
VAL:  Accepts any identifier as first parameter, only its type matters.
MIN,MAX,SIZE: Accept any identifier, only its type matters.



SYSTEM extensions
-----------------

If you call a function procedure but do not need its return value, you can
ignore it by writing

  SYSTEM.VOID( func() );

The function TRUNC, previously a global identifier, is now available in
SYSTEM.

The function procedure SWAP, expecting a longint parameter, returns the
parameter with high and low word exchanged. Similar to assembler command
swap.

The proper procedure EXG exchanges two variables of any, but identical
type.



The integrated assembler
------------------------

The integrated assembler was improved to accept 68030 and FPU code. It is
also decreased in size by not having a scanner on its own. It uses the same
scanning technique as the Oberon part. Some features like macros were
eliminated to reduce its complexity.
Normal Oberon constant expressions are accepted everywhere values are
needed. This includes standard procedure calls like SIZE, ASH etc.
Besides usual commands, it knows the following identifiers:

DC.B <data>  Stores bytes of data. <data> may also contain strings.

DC.W <data>  Stores words of data.

DC.L <data>  Stores long words of data.

BASE <label>  The pseudo command BASE defines a label which is to be
    used as base label for the following DC commands.
    Example:
      BASE label1
    label1:
      DC.B label2, label3, label4

    Result: Not the labels 2 to 4 are stored, but the (byte
    size) difference to label1.

TD(<type>)  Can be used in expressions to reveal the address of the
    type descriptor of a fixed, dynamic or open array type or a
    record type. <type> must be the type name.

RETURN    Terminates a procedure just like in Oberon. It should
    always be used because the compiler might have to produce
    additional code (like UNLK).

Assembler code can be entered inside an assembler statement which consists
of the keyword ASSEMBLER at the beginning and END at the end.

It understands SP as well as A7.

All mnemonics and registers have to be entered in capital letters.

Labels may contain "_", but may not begin with it. Capital letters are
distinguished from non capital letters. A colon is needed behind a label
definition, but they do not have to be entered in the first column of a row.
If a label is followed by a "*" (before the colon), it is entered in the global
symbol table so that following assembler code outside the current procedure
can access it.

The usual Oberon comment using (* *) is known as well as a semicolon
to declare the rest of the line as comment.

The assembler is enabled only in extended mode.



Reassembling
------------

If you enable the reassembling option using +r, a file with the extension
ASM will be stored which contains the code of the Oberon input module
written in assembler notation. This module can be compiled again. This
allows to optimize the code by hand.
With this option and the optimizing option set, the assembler optimizer
deletes all labels not needed. This task consums time proportional to the
square (estimated) of the source file size (for 50K source about 3 minutes
on a TT). This optimization does not shorten the code in anyway.
There is one problem which could not be fixed: If a procedure has a local
procedure, its temporary variables are not written into the reassembler
file. Avoid this.



68030 support
-------------

The standard compilation uses some commands of the 68030, e.g. long
integer multiplication. If 68000 code is desired, these commands are
emulated by calling procedures in module Emu030.
This emulation works on the assembler code, thus also on assembler code
entered by the programmer. Therefore I recommend using these commands
even if you do not have an 68030. First it is simpler to program and
second your code might be used by other people or you might get an
68030 later. To do this, you need to know exactly which commands are
emulated.

- Emulated 68030 commands

  muls.l mulu.l  divs.l  divu.l  mulul.l  mulsl.l  divul.l  divsl.l
  chk.l  extb.l

- Emulated 68030 addressing modes

  Address register indirect with 32 bit displacement
  Address register indirect with index and 32 bit displacement
  Memory indirect postindexed
  Memory indirect preindexed
  PC memory indirect postindexed
  PC memory indirect preindexed



FPU support
-----------

The standard compilation uses many FPU commands, e.g. FADD. If code for
a system without FPU is desired, these commands are emulated by calling
procedures in module EmuFPU.
This emulation also works on the assembler code, so the same as
described above applies to FPU support.

- Emulated FPU commands

  fmove fadd  fsub  fmul  fdiv  fsglmul
  fabs  fneg  fbeq  fbne  fbge  fble
  fbgt  fblt  fcmp



Return of values
----------------

Only simple values can be returned, like integers or reals. There are two
different return methods: Types REAL and LONGREAL are returned in FP0
(maybe emulated FP0), all other types are returned in D0.



Return from a procedure
-----------------------

On return from a procedure, the link register must get an UNLK command.
Since you may not be sure what register that is, use the command RETURN
even when programming in Assembler. This command will enter an UNLK and an
RTS instruction.



Additional compiler code
------------------------

Even when programming in Assembler, the compiler adds some code at certain
points:
1. On every code block begin, a LINK command is entered to build a
   local stack.
2. On every procedure entry, dynamic arrays called by value are copied onto
   the stack.
3. On every code block end, an UNLK and an RTS command is entered if it was
   a proper procedure or the module body, or a JSR command to Sys.RetFail
   if it was a function procedure.
These additional commands can be suppressed using a -c option in the code.
Then you are responsible for correct procedure entry and exit. No access to
local variables functions properly if you suppress the LINK command.
Don't forget to enter a +c command afterwards, at least right after the
source end.



Differences to V1.24
--------------------

When compiling sources originally compiled by V1.24, there might occur some
error messages which did not occur with V1.24.

TRUNC: Is not globally known anymore. Import it from SYSTEM.
LSH, ASH: Return LONGINT types as specified in the standard.
Options: The old option notation does not have any effect anymore.
Assembler: Many features were removed. See "The integrated assembler".

The symbol file format is not compatible anymore. Old symbol files will
cause an error message when imported.
The object file format is almost the same. However, there are differences
that make interchange of old and new object files impossible.

Indices may be of type LONGINT. This will cause more code when index check
is enabled and 68030 is emulated.



Known problems
--------------

An expression of the form

        a & b > c

will be compiled correctly as if you would write

        a & (b > c)

like you should. This is to be regarded as a bug but will not be removed.
The same might apply to similar faulty expressions.




**************************************************************************
  3. The STJ-Oberon-2 Linker V2
**************************************************************************



Overview
--------

The STJ-Oberon-2 Linker (OLINK.OBJ / LINK.TTP) produces an executable
program file from object modules.


Call
----

The linker is executed as object file by typing

  OLink.Link {options} <name>

or as standalone program by typing

  LINK.TTP {options} <name>

The options are described below. At least the name of a module to link
must be given. Enter only the first 8 characters if the name is longer.
No extension is needed.
For convenience, there is an alias "link" for OLink.Link under Chatwin and
the key F7 is predefined to link the current main file.


Options
-------

Options can be set in two ways: First, the environment is checked for a
variable named OLOPT and its contents scanned for options, overwriting the
default values. After that the command line will be scanned for options,
thus overwriting those from the environment. Command line options must
appear before the name of the module to link.
The options format is as follows:
 An option is marked by a "+" or "-" in front of a character. "+" is used
 to switch it on, "-" to switch it off. If it is an option with a parameter
 instead of a switch, only "-" is allowed (as "-" is the usual option
 delimiter).

These options are available:

Notation | Meaning                                       | Default value
------------------------------------------------------------------------
 +/-T    | symbol Table on / off                         | +
 +/-Y    | extended sYmbol table on / off                | +
 +/-A    | absolute symbol table on / off                | +
 -E<ext> | set object Extension to ext                   | OBJ
 -D<path>| set program Destination to path               | same as module
 -N<name>| set program Name to name (no ext)             | same as module
 -X<ext> | set program eXtension to ext                  | PRG
 -S<num> | set Stack size to num                         | 30000
 -M<var> | read module path from env. variable var       | MODPATH
 -O<var> | read object path from env. variable var       | OBJPATH

The letters may be capitals or not.

Symbol table:
        Is needed for low level debuggers. I know three of them:
        1. DB: The Atari debugger is not very comfortable but runs on every
           system. Sometimes Mag!X is a problem. It needs an absolute symbol
           table.
        2. Bugaboo: A great tool but does not support big screens and has
           some other problems on TT (as far as I know). Works with
           absolute and relative symbol tables.
        3. Peacebug: A Bugaboo clone. Works on Mag!X and big screen. It
           needs a relative symbol table.
        All three support GST-Format.
Extended symbol table:
        The standard format allows 8 characters per symbol, the extended
        GST format 22.
Absolute or relative symbol table:
        For different debuggers; see above. Program OBERON.PRG must always
        have an absolute symbol table.
Stack size:
        Every program needs stack for calling subroutines and local
        variables. If there are deep recursions and/or large amounts of
        local data, the stack may overflow. Then choose a higher value for
        the stack size.


Environment
-----------

The environment is used to read default values for the options. If you are
not able or don't want to change the environment, you may set environment
variables in the file OBERON.ENV. This file must reside in the default
path on linker call, usually the directory of the linker, in order to be found.
Inside this file, you can set one variable per line writing the variable name,
an equal sign and the the variables' value.
The following variables are used by the linker:

OLOPT
    May contain default options in the same notation as in the command line

OBJPATH: Contains the search paths for object files. It uses the standard
    format: Different paths can be separated by either a comma or semicolon;
    A backslash at the end is not necessary; A "*" denotes all directories
    in that path.
    If OBJPATH is undefined, the contents of MODPATH is used.

LINKALSO: May contain a list of module names separated by commas.
    Those object files will be linked to the program even if not imported.
    Only enter the first 8 characters of the name without an extension.
    The number of modules is limited to 5.
    For example, if you link a GEM program, you should set the variable
    LINKALSO=GEMIO. Then all accesses to IO will be redirected to GEMIO.
    (GEMIO redirects IO calls).

LINK_... : All variables starting with LINK_ are used to rename imports.
    This feature is quite problematic to use because all exported
    procedures have to be available and in the same order. You can achieve
    this by equal ordering of the procedures and recompilation of both
    modules after deleting their symbol files. This is necessary because
    the order stored in the symbol files are kept by the compiler.
    For example, if you link a TOS program, you should set the variable
    LINK_FORM=IOFORM. Then all accesses to Form.Alert will be redirected to
    IOForm.Alert.
    Do not define LINK_IO=GEMIO! This possibility was used in version 1.XX,
    but does not work anymore in V2.XX. Use LINKALSO=GEMIO.


Output
------

The linker reports all linked modules with complete path names onto standard
IO. Possible errors are:
- version error: An object file is older than the symbol file of a module
  imported by it. You may ignore this or abort linking. Usually, you will
  have to recompile the old module.
- module not found: A module is imported but its object file is not found
  in the search paths. Set the correct search paths.
- Unknown import: A module uses an import code which is unknown. This
  can only happen if the compiler or linker has a bug or the object file is
  destroyed. The latter may also cause severe breakdowns.

If linking was completed succesfully, it reports the size of the code and data
and what kind of symbol table was produced.




**************************************************************************
  4. The STJ-Oberon-2 Make V2
**************************************************************************



Overview
--------

The STJ-Oberon-2 Make (OMAKE.OBJ / MAKE.TTP) checks for modules which
need to be translated. It imports the compiler and linker.


Call
----

Make is executed as object file by typing

  OMake.Make {options} [<name>]

or as program by typing

  MAKE.TTP {options} [<name>]

The options are described below. You may enter the name of a module
so that only its imports are checked. Otherwise all modules in the
search path are checked.
No extension is needed.
For convenience, there is an alias "make" for OMake.Make under Chatwin and
the key F8 is predefined to make the current main module.


Options
-------

Options can be set in two ways: First, the environment is checked for a
variable named OMOPT and its contents scanned for options, overwriting the
default values. After that the command line will be scanned for options,
thus overwriting those from the environment. Command line options must
appear before the name of the module to make.
An option is marked by a "-" in front of a character.

These options are available:

Notation | Meaning                                       | Default value
------------------------------------------------------------------------
 -C<opt> | set options to be used for the compiler call  | none
 -K<var> | read make path from env. variable var       |MAKEPATH
 -M<var> | read module path from env. variable var       | MODPATH

The letters may be capitals or not.


Environment
-----------

The environment is used to read default values for the options. If you are
not able or don't want to change the environment, you may set environment
variables in the file OBERON.ENV. This file must reside in the default
path on make call, usually the directory of make, in order to be found.
Inside this file, you can set one variable per line writing the variable name,
an equal sign and the the variables' value.
The following variables are used by make:

MAKEPATH: Contains the search paths for source, object and symbol files.
    If no module is specified in the command, all source modules in these
    search paths are checked if they need to be compiled.
    It uses the standard format: Different paths can be separated by either a
    comma or semicolon; A backslash at the end is not necessary; A "*"
    denotes all directories in that path.
    If MAKEPATH is undefined, the contents of MODPATH is used.


Output
------

Make reports all module tested. If it finds a module which needs to be
compiled, it reports the reason briefly.
If the compiler reports an error, make is aborted.




**************************************************************************
  5. The STJ-Oberon-2 Loader V2
**************************************************************************


Overview
--------

The STJ-Oberon-2 Loader (O2LOAD.PRG) can load, link and execute object
files produced by the compiler V2.XX.


Call
----

You can call make from any kind of shell including the desktop. The
command must have the following format:

  O2LOAD.PRG [<name>]

The name may define the module to be executed.
No extension is needed.



Options
-------

Options can be set in two ways: First, the environment is checked for a
variable named OLDOPT and its contents scanned for options, overwriting the
default values. After that the command line will be scanned for options,
thus overwriting those from the environment. Command line options must
appear before the name of the module to execute.

The options format is as follows:

 An option is marked by a "+" or "-" in front of a character. "+" is used
 to switch it on, "-" to switch it off. If it is an option with a parameter
 instead of a switch, only "-" is allowed (as "-" is the usual option
 delimiter).

These options are available:

Notation | Meaning                                       | Default value
------------------------------------------------------------------------
 -E<ext> | set object Extension to ext                   | OBJ
 -O<var> | read object path from env. variable var       | OBJPATH

The letters may be capitals or not.



Environment
-----------

The environment is used to read the search paths for modules. If you are
not able or don't want to change the environment, you may set environment
variables in the file OBERON.ENV. This file must reside in the default
path on loader call, usually the directory of o2load, in order to be found.
Inside this file, you can set one variable per line writing the variable name,
an equal sign and the the variables' value.
The following variables are used by O2load:

OLDOPT
    May contain default options in the same notation as in the command line

LOADPATH
    Contains the search paths for object files. These paths are used to
    look for the object files imported by the module to be executed.
    It uses the standard format: Different paths can be separated by either a comma or semicolon;
    A backslash at the end is not necessary; A "*" denotes all directories
    in that path.
    If LOADPATH is undefined, the contents of MODPATH is used.

DEFSTART
    May contain the name of a module to be called if no command is
    specified.

LTLSTART
    This is no variable of the loader, but it is the equivalent to DEFSTART
    for module LTL. If you started LTL, the module or program specified by
    LTLSTART is executed.



Output
------

The loader does not report anything unless an error occurs. If this happens, it is
reported onto standard IO.



Chatwin
-------

Chatwin is a programming shell by Dirk Haun. It has a special interface to
communicate with the loader. This way, it is possible to use modules the
same way as normal programs under Chatwin. You can enter a command in the
console window and the command will be executed by the load time linking
support. You are also able to store an object file as one of the programs
you can set in Chatwin.
To use Chatwin, you must specify its name and path in the environment
variable LTLSTART and the name of the object file in DEFSTART, for example
in OBERON.ENV. You may also drop the object file onto the loader. The
loader will execute LTL which in term calls Chatwin.
Chatwin can be found on some german ftp servers and in the mouse WI2 and
will be provided with the private version.
Chatwin is shareware, the fee is 30 DM. The author can be contacted under:

        Dirk Haun
        Europastr. 8
        D-64569 Nauheim
        Germany

        Mausnetz: Dirk Haun @ WI2
        Internet: Dirk_Haun@wi2.maus.de




**************************************************************************
  6. The STJ-Oberon-2 Debugger V2
**************************************************************************


Overview
--------

The debugger (DEBUG.OBJ) is a quick port of the version used in V1.24. It
enables viewing variables and sources after an exception occurred (post
mortem debugging). Exceptions are all HALT commands. Other exceptions must
be converted into HALT commands. Modules Exceptions and Break (see below)
do so.
The debuggger must be explicitly called to install itself. It is not
installed automatically. You may use macro "d" which is available in
Chatwin (see AUTOTAKE.T).


Environment
-----------

The debugger uses the environment variable MODPATH to search source files.
If not found there, you may search yourself with a file selector. The
information files are searched in the paths of SYMPATH.


Operation
---------

If installed, the alert box of halt command will have a button named
"Debug", which allows you to enter the debugger. It opens a window
displaying the module list and another window containing the execution
stack. The execution stack does not contain local procedure calls. This bug
cannot be fixed easily.
If the program was stopped without a visible mouse, try to execute the menu
item "Call exits" (Control-E) which should make the mouse visible and some
other terminating calls.
The debugger is operated by clicking on the items showed in the windows.
Depending on the kind of item, you get a popup menu displaying the actions
the debugger can perform using the item. Among these are displaying of
source code, variables, hexdump and disassembling.
The position of the execution in a procedure is just estimated. No exact
position can be determined. Take a look at the source surrounding the
marked position in order to find the cause of the exception.
When exiting the debugger, its windows are not closed because it does not
know about all of them. If the execution returns to Chatwin, the windows
are automatically closed. When you use PShell, you must close them
yourself.
If a user breakpoint (a HALT call) was the cause of the exception,
continuing is possible. You have to use the menu item in order to be asked
if you want to continue. If you press control-Q, Task.Exit is called so
that the debugger is left immediately.


Other exceptions
----------------

Module Exceptions links procedures into the exception verctors and calls
HALT on exceptions. This way, all processor exceptions like bus error can
be debugged.
Use Module Exceptions with care. It might not work on every platform.

Module Break links a procedure into the VBL interrupt and checks if
the control key and both shift keys are pressed. Then a HALT is called so
you are able to interrupt an endless loop.
Use Module Break with care. It might not work on every platform.

Both modules have to be installed explicitly. This is done by DEBUG.T.




**************************************************************************
  7. Other debugging facilities
**************************************************************************


Debugging output
----------------

Modul Traces (mainly by Wolfgang Radtke) provides some helpful procedures
to display values. Use it in the debugging phase to output the results of
your operation. You may use a grep tool to remove all lines containing the
word "Traces" after debugging.


Low level debugging
-------------------

The load time linking supports Robert Federle's Resident Symbol Driver.
Together with a debugger supporting the RSD you are able to debug quite
efficient. Suitable debuggers are Peacebug and TempleMon, the latter is
not tested. Install the debugger resident, then call SYMBOL.PRG. When the
load time linking finds an RSD installed, it will add the symbol tables
of every module loaded to the RSD's list. Every symbol is stored using
the module name in capital letters and with a maximum of eight
characters, followed by a period (".") and the name of the symbol. So if
you want to specify the symbol RemoveTables in module RSDManipulation,
you have to type ".RSDMANIP.RemoveTables". The leading point specifies a
symbol (in Peacebug, at least). Strangely, Peacebug does not allow any
characters to follow such a definition, so you cannot calculate with it
or even specify a number of lines.
If an exception occurs, you are always able to terminate the current task
correctly by setting the PC to TASK.Exit and continue execution.
If a HALT exception occurs and you need more information, you can enter
the debugger (Alt-F10 for Peacebug) and set a break point behind the call
of Form.Alert in procedure HALT.ShowError. Then return to the alert box
and select a button. The debugger will be entered and you can trace what
happened.

Upon termination of the loader, every symbol table is removed.

Peacebug is shareware and the fee is 30 SFr. It can be found on several
german ftp sites.
The author can be contacted under:

      Emanuel Moecklin
      Rainfussweg 7
      CH-8038 Zuerich
      Switzerland

      Internet: peace@soziologie.unizh.ch
      Decnet: ezinfo::peace


The resident symbol driver is freeware. It can be found included in the
TempleMon V2.02 archive on several german ftp sites. The author can be
contacted under:

      Mausnetz: Robert Federle @ K
      Internet: Robert_Federle@k.maus.de




**************************************************************************
  8. The STJ-Oberon-2 Optimizer V2
**************************************************************************


Overview
--------

The optimizer (OPTIMIZE.OBJ / OPTIMIZE.PRG) is tool to reduce program
length. It needs all sources to operate, so you need to be registered.


Call
----

The optimizer is executed as object file by typing

  Optimize {options} <name>

or as program by typing

  OPTIMIZE.TTP {options} <name>

The options are described below. You have to enter the name of the main
module which is to be optimized. No extension is needed.


Options
-------

Options can be set in two ways: First, the environment is checked for a
variable named OPOPT and its contents scanned for options, overwriting the
default values. After that the command line will be scanned for options,
thus overwriting those from the environment. Command line options must
appear before the name of the module to optimize.
An option is marked by a "-" in front of a character.

These options are available:

Notation | Meaning                                       | Default value
------------------------------------------------------------------------
 -D<opt> | destination path for optimized sources        | "D:\"

The letters may be capitals or not.


Operation
---------

The optimizer loads every module source needed for a program (all imports).
It then marks all procedures and type bound procedures, which must be
available. The sources are stored in the destination path with those
procedures deleted which are not used.
The system modules are not scanned and must be available when linking. See
macro "opt" defined in AUTOTAKE.T for an example of how to optimize. It
will store the optimized source files in a new directory and compile all of
them into that directory. Then the linker is invoked producing the program
file.


Example
-------

This is a really simple example:

    MODULE HelloWorld; (* SJ *)

    IMPORT
      IO;

    PROCEDURE Run*;
      VAR
        c : CHAR;
     BEGIN
      IO.WriteString("Hello world"); IO.WriteLn;
      IO.WriteString("Press any key ..."); IO.WriteLn;
      c := IO.ReadChar();
     END Run;

    BEGIN
      Run;
    END HelloWorld.


Unoptimized       Optimized       Reduction
-------------------------------------------
25866 Bytes       4583 Bytes      82%


The reduction decreases for bigger programs.




**************************************************************************
  9. The Browser
**************************************************************************


Overview
--------

The Browser, mainly programmed by Dirk Theisen, allows you to create a
readable interface of a module. It uses the symbol file of the compiler
output for creating a DEFINITION MODULE. Comments from the source can be
entered in it file if you desire.


Usage
-----

The Browser needs at least the symbol file of a module. The extension can
be discarded, default is SYM.
A second parameter may be defined to specify a destination path. This is
the path where the created DEFINITION MODULE is stored. If not defined, it
will be placed in the first path defined by the environment variable
DEFPATH. If that variable is not defined, it will be placed in the current
directory.
The output file will have the same name as the symbol file with extension
DEF.


Options
-------

|-i<Nr>| This option lets you define the indentation. No space character is
    allowed between i and the number. Only one digit is allowed. Default is
    2.
    Example:: -i8 sets indentation to 8 space characters.

|-h| Tells the browser to enter hypertext links for 1STGuide. This requires
    all definition files to be located in the same directory.

|-c| The browser will try to enter comments from the source file into the
    definition file. The source file is searched in the paths defined by
    environment variable MODPATH.



**************************************************************************
  10. PShell
**************************************************************************


Overview
--------

PShell (Primitive Shell) is just a terminal window with every input
interpreted as a procedure call. It is not suited for everyday programming,
but it enables using load time linking without Chatwin. If you don't want
to use Chatwin, you can improve PShell to suite your needs.


Usage
-----

Set the variable DEFSTART to PSHELL and start the loader or start it with
PSHELL as command. The terminal window will open and all your input of the
form <module>.<procedure> will execute that procedure with the optional
command.




**************************************************************************
  11. Commands
**************************************************************************


The following commands are available using load time linking:

OComp.Compile
    Compile the specified modules. See "The STJ-Oberon-2 Compiler V2".
    Usage: OComp.Compile [<options>] {<module>}


OLink.Link
    Link a program from object files. See "The STJ-Oberon-2 Linker V2".
    Usage: OLink.Link [<options>] <module>


OMake.Make
    Checks for modules which need to be compiled. See "The STJ-Oberon-2
    Make V2".
    Usage: OMake.Make [<options>] [<module>]


Tools.Free
    Free modules defined in the parameter list. Unlike the definition
    of Wirth imported modules are not deleted.
    Usage: Tools.Free {<module name>}

Tools.ShowModules
    Shows a list of all modules stored.
    Usage: Tools.ShowModules

Tools.ShowCommands
    Lists all commands of a module.
    Usage: Tools.ShowCommands <module name>

Tools.ShowProcedures
    Lists all procedures of a module.
    Usage: Tools.ShowProcedures <module name>

Tools.ShowVariables
    Lists all variables of a module.
    Usage: Tools.ShowVariables <module name>

Tools.Dump
    Dump bytes in hex.
    Usage: Tools.Dump <address> [<bytes>]
      where <address> may be a hex number or an ident
      and <bytes> is a hex number.

Tools.Set
    Set bytes.
    Usage: Tools.Set <address> {<byte>}
      where <address> may be a hex number or an ident
      and {<byte>} are hex numbers.

Tools.Address
    Displays the address of an identifier.
    Usage: Tools.Address <module>[.<ident>]
      where <module> is a module name and
      ident an identifier in that module.

Tools.ShowMemory
    Displays the status of the memory management.
    Usage: Tools.ShowMemory

Tools.KeepFree
    Allows to get or set the amount of memory which is to be left unused.
    Usage: Tools.KeepFree [<amount>]
      where amount is a decimal value.


Env.Set                                                   (PShell only)
    Set environment variable(s).
    Usage: Env.Set <name>[=[<value>]]

Env.List                                                  (PShell only)
    List the environment.
    Usage: Env.List



**************************************************************************
  12. Programming with a garbage collector
**************************************************************************


Since the garbage collector is now well functioning and the run time
support starts to rely on it, you must know some things to be considered.


The run time support
--------------------

When you execute LTL.OBJ via the loader, the garbage collector is available
and working as a coroutine. Usually, you won't have to call it directly but
if you need to, you can execute GC.Collect without parameters.
When memory gets scarce, it is automatically called by the memory
management in the hope it returns enough memory to continue. So if
execution seems to stop, don't panic and press reset. Instead, give the
collector time to do its job. The typical collection time is less than 2
seconds for 500 K allocated memory.
If the collector cannot return enough memory, an alert warns you that
memory is run out and you can terminate the task. Although highly
undesirable, you will be forced to quit the loader and restart in order to
get clean memory.
If you want to see the collector working as a coroutine, just enter
"Tools.ShowMemory" in the console window. If you do it fast enough, you
will notice an increase of allocated memory of about 300 bytes for every
call. After some calls, you should see that the allocated memory decreased
again. This was the collector's work.


Programming
-----------

If you program something to run with garbage collection, follow these
rules:

- Initialize your global variables when you start executing. Your module
  body is just executed once after loading.

- Set all your pointers to NIL after execution. Otherwise the memory they
  point to cannot be collected. Especially think of pointers in global
  arrays and records, e.g. the element base in type BFiles.Rider which
  points to a file. Since a task can be terminated without its exit
  procedures executed, you also should also delete the pointers at the
  beginning of execution. Now that the stack is also searched for pointers,
  you should set local pointers to NIL before exiting a procedure if they
  point to a lot of memory. Under special circumstances, it is possible
  that this pointer is found and its memory not disposed.






**************************************************************************
  13. Library modules
**************************************************************************

This is a brief description of the available library modules. For more
information, see the definition files of the according module. If you
already executed DEF2REF, you simply select the module name and type help.

AES
  The basic AES control

Appl
  AES application control functions

Application
  This is a new module with an interface similar to GemApp. Its intention
  is to program TOS applications which can be ported to GEM by replacing
  Application with GemApp. It also allows background activities like
  garbage collection.

BFiles
  File management using type bound procedures by Dirk Theisen.

BinTree
  Binary tree implementation by H.Mssenbck and Dirk Theisen.

BIOS
  The usual BIOS commands with parameters in reversed order.

Break
  Replaces the part of the old module Exceptions which makes it possible to
  interrupt a program if linked to it. Will not run under MTOS.

Char
  Some operations with characters

CoApp
  Timer procedure for module Application calling coroutines

ConvTypes
  ISO-M2 compatible module containing types for conversion routines.
  By Holger Kleinschmidt.

CommandLine
  Command line evaluation by Dirk Theisen.

Cookie
  Read, enter and delete cookies.

Coroutines
  Coroutine management

Dialogs
  Display modal dialog boxes

Emu030
  Replaces the part of Sys which emulates 68030 commands. Will never be
  accessed directly.

EmuFPU
  Replaces the part of Sys which emulates FPU commands. Will never be
  accessed directly.

Env
  Manipulate environment.

Environment
  Read environment variables.

Error
  Simple error output.

Evnt
  AES event control functions

Execute
  Execute programs or modules.

Exceptions
  Catches CPU exceptions and turns them into HALT commands

FIFO
  FIFO (First In First Out) buffer implementation by Dirk Theisen

File
  Manipulate files, load and save complete files.

Filename
  Manipulate GEMDOS filenames.

FontSelect
  Simple font selection dialog

Form
  AES form control functions

Fsel
  AES file select control functions

GC
  Garbage collector

GEMDOS
  The usual GEMDOS commands with parameters in reversed order.

GEMIO
  Similar to IO but using a window. Redirects IO so that you only import
  GEMIO and all calls of IO use the window.

GemApp
  GEM application control

Graf
  AES graphics control functions

Halt
  Display a HALT exception.

ICFS
  Support of ICFS

IconifiedWindow
  Controls iconifying of windows using ICFS

IMGViewer
  Display IMG files in a window, by Wolfgang Radtke

IO
  Character IO using standard input.

IOForm
  A replacement for Form in TOS programs.

Items
  Store items in a list

LinkedList
  Full object oriented linked list

ListView
  Displays selectable lines of text in a window

LongConv
  ISO-M2 compatible module containing conversion routines from string to
  LONGREAL. By Holger Kleinschmidt.

LongStr
  ISO-M2 compatible module containing conversion routines from LONGREAL
  to string. By Holger Kleinschmidt.

LongSupport
  C-like low level math library by Holger Kleinschmidt

LowReal
  ISO REAL math library by Holger Kleinschmidt

LowLong
  ISO LONGREAL math library by Holger Kleinschmidt

LRU
  LRU (Least Recently Used) buffer implementation by Dirk Theisen

LTLHalt
  Do not use directly. Replaces module Halt under LTL.

LTLProgram
  Do not use directly. Replaces module Program under LTL.

Math
  Oakwood compatible math library by Holger Kleinschmidt

MathCom
  Basic mathematic functions from LPR-Modula.

MathL
  Oakwood compatible math library by Holger Kleinschmidt

MathLib0
  Common mathematic functions from LPR-Modula.

Memory
  Fast memory copy and fill.

Menu
  AES menu control functions

Menus
  Simple menu control

MiNT
  The usual MiNT commands with parameters in reversed order.

MinMax
  Answer smaller or higher value for different types

Model
  Controls models and their dependants

ModelList
  Controls lists of models for WinView

NumStr
  Conversion of numbers to strings and vice versa.

O2Init
  Always the first module of a program, initializing it

Objc
  AES object control functions

ObjFile
  Handles object files.

ObnEnv
  Installs the environment variables set in OBERON.ENV.

Paths
  Search path control

Popup
  Display popup menus

ProcList
  Controls list of procedures

Program
  Gives information about the current program.

QSort
  Implementation of the quicksort algorithm for arrays of any type

RealSupport
  C-like low level math library by Holger Kleinschmidt

RealConv
  ISO-M2 compatible module containing conversion routines from string to
  REAL. By Holger Kleinschmidt.

Reals
  Compatible to the standard Reals module

RealStr
  ISO-M2 compatible module containing conversion routines from REAL
  to string. By Holger Kleinschmidt.

Redirect
  Redirect procedures to others

RSD
  Support of the resident symbol driver

RSDManipulation
  Produces symbol tables for the RSD

Rsrc
  AES resource control functions with extensions

Scrp
  AES scrap control functions by Christian Felsch

Shel
  AES shell control functions by Christian Felsch

Stack
  Stack buffer implementation by Dirk Theisen

StdPath
  Get / set GEMDOS standard path

Storage
  Memory management

StringDictionary
  Store data with strings as dictionary key in a hashed table

Strings
  String manipulation

Supervisor
  Switch to supervisor mode and back

Sys
  Some basic variables and functions.

Task
  Enables proper abortion of tasks

TermWin
  Controls terminal windows

TextFiles
  The beginning of character oriented file I/O.

TextViewer
  Displays ascii files.

Traces
  Debugging help by Wolfgang Radtke

UFSL
  Support of the universal font selector

VA
  Constants for Venus <> Application protocol.

VDI
  The basic VDI control

VDIAttributes
  VDI attribute control functions

VDIControl
  VDI control functions

VDIEscapes
  VDI escape functions

VDIInput
  VDI input functions

VDIInquiry
  VDI inquiry functions

VDIOutput
  VDI ooutput functions

VDIRaster
  VDI raster functions

Wind
  AES window control functions

WindowDialog
  Display nonmodal dialogs in a window

WinView
  Basic window control

XBIOS
  The usual XBIOS commands with parameters in reversed order.

XCoroutines
  Extended coroutine management

XFSL
  Support of the extended font selector



Differences to V1.24
--------------------


CDCL
  Replaced by LinkedList.

Cookie
  Procedure Entry was changed into Enter (an english language error).

DCL
  Replaced by LinkedList.

Exceptions
  Has a new interface.

FileBuffer
  Does not exist anymore. Use BFiles instead.

GemApp
  Completely redesigned. The is no such thing as an application descriptor
  anymore. It is even more simple now to program GEM applications. See
  TUTORIAL\TUTOR1.MOD for the simplest possible application.

LinkedList
  Advanced version of DCL and CDCL.

Loader
  Replaced by O2Modules.

MVC
  Replaced by Model.

ProcList
  Stores and executes procedures in a list.

Redirect
  Redirect procedure calls.

Storage
  Has a new interface.

Task
  Task.Exit expects an integer parameter as return value and Task.RetCode
  does not exist anymore.


