                        ARMForth
                        --------
Author: Robert S. Turner
------

1. Overview
-----------

   ARMForth is a windowing implementation of Forth, based on the Forth 79
standard, but with major extensions, including a lot of the functionality of
the Forth 83 standard. The major facilities offered by this implementation
are

 * Works both as a RISCOS task, with its own 'virtual terminal' window, and
   as a full-screen text based program, with the ability to easily switch
   between the two modes.

 * Allows the creation of standalone programs, which can be again either
   window based or full-screen based. A side-effect of this is that it allows
   the Forth system itself to be updated should this be desired.

 * All words are implemented directly in machine code i.e. there is no inner
   interpreter, all words consist of lists of 'branch' instructions, or
   other code sequences. Options allow inline code placement for some words,
   instead of calls to the word.

 * Provides a window based debugger, which shows the computation and return
   stacks during the execution of each word, and allows single stepping
   of words or slow-speed execution.

 * Contains a built-in macro assembler, allowing the assembly of all ARM
   mnemonics. Assembly language sequences can easily be placed within a Forth
   word.

 * Vocabulary contains most BASIC keywords, facilitating the conversion of
   BASIC programs, and allowing Forth access to BASIC files, etc.

 * Can load normal text files, plus the usual Forth 'screens'. The normal
   Forth Editor is provided.

 * Installable Forth libraries contain words allowing access to all RISCOS
   swi calls by name.

 * Provides words allowing coroutines to be written, thus giving parallelism
   within execution of Forth words.

 * Changes to predefined words can conveniently be made to customise the
   system.

2. Modes of operation
---------------------
    ARMForth can operate as a RISCOS task in its own window, or it can be 
    run external to the window manager. The window mode of operation is 
    first described.

2.1 ARMForth Window
-------------------
    Upon startup, the ARMForth icon will be placed on the icon bar. Clicking
the middle button on this icon will invoke a menu, from which three options
can be selected. The 'Info' option gives information on the program. The
'Reset' option allows the ARMForth system to be reset. This is equivalent to
executing the COLD word from the keyboard, but is useful in cases when the
program is in a loop where it is polling the window manager but has lost its
way back to the forth interpreter, so it is ignoring any forth commands. If
the forth system is looping infinitely but not polling the window manager,
then the machine is locked up anyway, so the only option is to reset the
machine. The last menu option is used to quit from the ARMForth system, and
will remove the task from RISCOS.
 
  Clicking the left button on the icon will cause the main ARMForth window
to appear, into which all commands are typed. This window acts as a terminal
interface to the ARMForth system, and is character based. The size of the
terminal is 70 characters wide by 300 lines. All lines of the terminal can
be seen by using the vertical scroll bars. The visual area of the terminal
can be moved and resized using the normal RISCOS window operations. The
terminal can be temporarily removed by clicking on the 'quit' box in the top
left hand corner. This does not terminate the ARMForth system, it only
removes the terminal window. To cause the terminal to reappear, click on the
ARMForth icon with the left button. All text that was previously on the
terminal is restored.

2.1.1 Screen Output
-------------------
    The usual forth route to printing characters on the terminal is by use
of the EMIT word, along with TYPE (for printing character strings), and
ARMForth is no different in this respect. All printing of single characters
to the screen by ARMForth programs MUST be via EMIT for the terminal
interface to work correctly. As mentioned above, TYPE is used to print
character strings. Both EMIT and TYPE need to display the caret on the
screen after their action has been performed. Since displaying the caret
after each letter of a TYPEd string would slow textual output down
considerably, TYPE does not use EMIT, and only displays the caret after the
whole string has been printed. Even this technique is quite slow when a
program is performing a large number of TYPEs in rapid succession (such as
VLIST), so the two words CARET-OFF and CARET-ON are available to enable the
caret to be turned off before printing the strings and to turn it back on
again later.

2.1.1.1 Control Characters
------------------------
    Any control characters which are sent to the terminal window are ignored
except for carriage return (13), line feed (10), form feed (12), and bell
(7), all of which perform their usual actions.

2.1.2 Character Input
---------------------
    The KEY word will only return with characters in the range 32-127
inclusive. In particular it will not detect function keys or control codes.
To check these keys a lower level keyboard scanning word such as INKEY
should be used.

2.2 Non-Wimp Interface
----------------------
    The ARMForth system can be used outside the Wimp Manager. Entering this
mode initially presents a Mode 0 screen. Some of the system words (e.g. the
input/output primitives) are vectored to perform different sections of code
according to whether ARMForth is in Wimp or non-Wimp mode. These are listed
below.

   Main Entry Word       Wimp Vector     Non-Wimp Vector

   EMIT                  <WEMIT>         <EMIT>
   TYPE                  <WTYPE>         <TYPE>


2.2.1 Screen Output
-------------------
    All screen output is performed using the RISCOS supplied routines e.g.
OS_WriteC for EMIT, so all control characters will perform their normal
function in contrast to the Wimp mode control character output where only a
few control characters can be printed.

2.2.2 Character Input
---------------------
    In a similar vein to EMIT, KEY will accept all keystrokes (including
function keys) and return the keystroke value to the program. Again, it
simply calls the operating system OS_ReadC routine to perform its function.

2.3 Switching Between the Wimp and Non-Wimp Modes
-------------------------------------------------
    Once inside Wimp mode a switch to Non-Wimp mode can be achieved by the
word NOWIMPS, resulting in a Mode 0 screen. Note that the program is still
running as a RISCOS task, so all other tasks running in the system are
retained. A switch back to Wimp mode is performed by the WIMPS word.

    An important point here is the mode in which the ARMForth system is
started up in (see section ????). If the system is initiated in Non-Wimp
mode, then it has to stay in that mode all the time and cannot go into Wimp
mode since ARMForth will not be running as a RISCOS task. However, if the
system is started up as a task in Wimp mode, then transitions between the
two modes can easily be achieved.

3. Strings
----------
    One of the predefined types in the ARMForth system is the STRING type.
Strings can be created by the user, then assigned some value. They can be
concatenated, compared, printed, and the majority of the BASIC string
operations can be performed on them. Strings are used by a lot of other
system words, so they are an integral part of the system. Strings consist of
a character count followed by the text of the string. Words which operate on
strings require the address of the string, which is the address of the
count. The structure of strings is described more fully in section ????.

3.1 String Definition
---------------------
    A string is defined as follows.

       len STRING str

    where len = the maximum length of the string.
          str = the name of the string.

    By executing the name of the string, the address of the character count
is placed on the stack.

3.1.1 Assigning To Strings
--------------------------
    After creation a string will initially be a null string. To assign a
value to it we use STRCPY".

       str STRCPY" SOCRATES"

    This will assign the value "SOCRATES" to the string str. Note that the
terminating quote can be missed out if the string is at the end of a line
(i.e. if a crriage return/line feed follows. Strings can include space
characters in them if required. To verify the operation of this word we can
print the string on the terminal using .STR.

       str .STR

    If we want to copy the contents of one string to another we can use a
variant of STRCPY".

       str1 str2 STRCPY   ( Note no quote )

    This will assign the value of str2 to str1.

3.1.2 Concatenating Strings
---------------------------
    To concatenate two strings we use the same method as for STRCPY",
swapping STRCAT" for STRCPY" and STRCAT for STRCPY. For example

       str STRCAT" HERODOTUS"

    concatenates the string "HERODOTUS" to the string variable str.

3.1.3 Comparing Strings
-----------------------
    To compare the value of a string variable to a literal string we can use

       str STRCMP" PARMENIDES"

    This operation leaves a value on the stack, which is

       0 if the strings match
      -1 if the first string is < the second string (alphabetical ordering)
       1 if the first string is > the second string

    Similarly to STRCPY, there is a STRCMP word which compares two string
variables.

       str1 str2 STRCMP

3.1.4 Arrays of Strings
-----------------------
    A two dimensional string array is created by specifying the lengths of
the two dimensions before the word STRING[].

       len1 len2 STRING[] str

    This creates an array of length len1 of strings, each string having
maximum length len2. To peform an operation on one of the strings we use the
same method as for one dimensional strings but before the string array name
we give the index of the wanted string. The index starts at 0 and must be <
len1.

       3 arrstr1 4 arrstr2 STRCMP

3.1.5 BASIC string operations
-----------------------------
    Most of the BASIC string manipulation functions are emulated by the
ARMForth system. These are described in sequence.

3.1.5.1 INSTR 
-------------
    This word finds the position of a substring within a string. The
parameters are

       str1 str2 stpos INSTR

    The string str1 is searched to find the substring str2. stpos is the
position in str1 to begin searching from. The first character in str1 is
position 1.
    If the substring cannot be found then zero is left on the stack, else
the position within str1 where the start of the substring is to be found is
left.
    The inline version of INSTR is INSTR".

       str stpos INSTR" THUCYDIDES"

    searches for the string "THUCYDIDES" in the variable str1.

3.1.5.2 LEFT$
-------------
    This word returns the left part of a string or overwrites the left hand
part of a string with another string.

       deststr srcstr cnt LEFT$

    The left hand cnt characters of srcstr are placed into the string
variable deststr. If cnt is greater than the length of srcstr then the whole
of srcstr is returned. The corresponding inline version is

       deststr cnt LEFT$" APOLLONIUS"

    where the left hand cnt characters of "APOLLONIUS" are placed into
deststr.
    The second use is to overwrite the left part of a string with another
string. This is achieved using LEFT$=.

       deststr srcstr LEFT$=

    The left part of deststr is overwritten with the contents of srcstr.
LEFT$=" is also available.

       deststr LEFT$=" ZENO"

3.1.5.3 LEN
-----------
    LEN returns the length of a string on the stack. It is used in the
following way.

       str LEN

3.1.5.4 MID$
------------
    The MID$ word returns a substring of a string, or overwrites part of a
string with another string.

       deststr srcstr stpos len MID$

    The action of the above is to extract len characters from srcstr
starting at position stpos, and to place those characters into deststr.
srcstr is unaffected.
    The inline word is used as shown below.

       deststr stpos len MID$" PERICLES"

    As in the case of LEFT$, there is a variant of MID$ which overwrites
part of a string with another string.

       deststr stpos srcstr MID$=

    This overwrites deststr starting at position stpos with the string
srcstr. Similarly

       deststr stpos MID$=" PLATO"

    The string "PLATO" is inserted into deststr at position stpos.

3.1.5.5 RIGHT$
--------------
    RIGHT$ is similar to LEFT$ except that it operates on the right hand
side of a string rather than the left. Its parameters are exactly the same
as for LEFT$.

3.1.5.6 STR$
------------
    STR$ converts a number into its textual representation (in base
decimal), placing the text into a string. To convert the number 1234 into
ASCII form we use the following.

       1234 str STR$

    After these words have been executed the string variable str will
contain "1234".
    There is a related word STR$~ which places the text of the hexadecimal
representation of a number into a string. For example if we are in the
decimal base and

       258 str STR$~

   is executed, the string variable str will have the value "102".

3.1.6 How strings are implemented
---------------------------------
    Strings consist of a 32 bit length word immediately after the link
field, followed by the characters of the string, and terminated by a zero
byte. The runtime action of executing a string name is to place the address
of the string length memory location on the stack. Thus the actual
characters of the string are at this address + 4.
    Arrays of strings are laid out as follows. After the link field there is
a 32 bit word which gives the first maximum length of each string (i.e. the
second dimension). Then follows the information for each string in the array
in the same format as for normal strings, given in the last paragraph.
    There are some things to bear in mind when using strings. Firstly, when
using STRCPY(") and STRCAT(") no checking is done to see if the destination
string overflows its allocated space. It is up to the programmer to see that
this does not occur. Secondly, the system cannot check whether the supposed
addresses of strings which are on the stack ARE actually the addresses of
strings i.e. there is no type checking as in more high level languages.
Thirdly, regarding the BASIC functions which accept character positions as
parameters, it is up to the programmer to make sure that these contain
sensible values, as no checking is peformed by the words themselves, which
would only slow things down.
    The zero byte on the end of a string is important, since it is used
frequently even though the length of the string is stored as well. Although
some string manipulation words may work if the zero byte is missing they are
not guaranteed to.
    The length of a string is stored in a 32 bit word. This means that
strings can hold more than 256 characters, which could cause compatibility
problems with some of the BASIC emulation words. For instance the PRINT#
word (described in section ????) only stores up to 256 bytes of the string
in a file. Most of the string manipulation words, however, will accommodate
strings of more than 256 characters.

4. Programmer Window Management
-------------------------------

    Embedded with ARMForth is a means of allowing programs to manage their
own RISCOS windows.

4.1 POLL-ESCAPE
---------------
    Essentially, there is a way for user code to "insert itself" within the
main polling loop of the system. The word which achieves this is the
vectored word POLL-ESCAPE. Each time that the system calls the window
manager (via Wimp_Poll), if a code is returned which is not understood by
ARMForth (e.g. an open window request for a user window) then it passes the
return code along with the address of the poll buffer to POLL-ESCAPE.
POLL-ESCAPE is normall defined to execute 2DROP (i.e. it has no effect) but
the programmer can assign POLL-ESCAPE to execute one of his own words by
means of the ASSIGN ... TO-DO construct. The interface to POLL-ESCAPE is

       (buf_addr\return_code ... )

    It must not leave any value on the stack, or else stack overflow would
occur very quickly.

4.2 Discussion on the Wimp_Poll Loop
------------------------------------
    The entry parameters to Wimp_Poll are such that "null events" are
accepted. If a null event occurs it is still passed to POLL-ESCAPE; by this
method programs can perform some processing possibly unconnected with
windows, then pass control back to the ARMForth system.
    The condition under which POLL-ESCAPE will not be called is that the
window handle returned by Wimp_Poll is the main ARMForth terminal window
handle. There is no (system provided) way that an ARMForth program can find
out the handle of the main terminal window. Of course there are other
techniques that can be used, but they could destroy the consistency of the
terminal output if not used carefully.

5. The creation of standalone Programs
--------------------------------------
    ARMForth provides an extremely powerful method of creating standalone
programs i.e. programs that can be used without the (visible) ARMForth
system. Using this facility new customised versions of ARMForth can also be
created to suit the user.

5.1 CREATE-PROG
---------------
    The CREATE-PROG word is available to create standalone programs. The
action of this word is dependent on a parameter which takes a value between
1 and 5 inclusive. It takes other parameters according to the "action"
parameter. The interface specification of CREATE-PROG is

       <action dependent params> action CREATE-PROG

Each of the action parameters is now described.

    Action = 1
    ----------
        This mode creates a new ARMForth system. One parameter is needed on
the stack. This is the address of a buffer which contains information about
the main terminal window in the form that "Wimp_CreateWindow" expects. This
allows customised windows to be used as the main ARMForth window. The
complete specification of this mode is

       wind_buffer_addr 1 CREATE-PROG

    Action = 2
    ----------
        This mode allows a standalone program to be created which can make
use of the ARMForth window. It allows programs which have a textual
interface to be easily created without the programmer having to be concerned
with the management of windows. The standalone program is run as a RISCOS
task. Upon entry to the program the window appears, and any output in the
program going via the normal ARMForth output words will cause its output to
be placed in this window. The ARMForth icon will not appear. Clicking on the
'quit' icon in the terminal window will cause the task to be terminated. The
complete specifiection of the interface for this mode is

       win_title_addr task_title_addr entry_addr win_buf_addr 2 CREATE-PROG

    win_title_addr is the address of a string which gives the title to
appear in the main window when the program is run.

    task_title_addr is the address of a string which gives the name of the
task (it appears in the task manager window)

    entry_addr is the entry address of the program. For example, if MAIN is
the word which starts the program, the entry address of MAIN is found by the
command sequence

       ' MAIN

    Notice the entry point is just the code field address of the word.

    win_buf_addr is the address of a buffer containing information in the
form used by "Wimp_CreateWindow"

    Action = 3
    ----------
        If action is 3 then a standalone program is created which does not
have any initial windows available to it. It is used in programs which want
to perform all their own window management. All output in these programs
must be achieved by the mean of customised output routines, since EMIT and
TYPE will fail as there is no window for them to output to. There is no
checking done by EMIT and TYPE, so the program will simply crash if these
words are used. The interface specification is

       task_title_addr entry_addr 3 CREATE-PROG

    task_title_addr and entry_addr are the same as in the previous section.

    Action = 4
    ----------
        This mode is used to produce a customised ARMForth system which does
not run in the Wimp mode, and does not run as a task. Upon starting up a
system created this way, Mode 0 is entered. As mentioned in section ????,
the Wimp mode cannot be entered from this situation by means of the word
WIMPS, since the program does not run as a task. This mode is provided for
those who prefer a simple "Arthur type" interface to their ARMForth system.
No extra parameters are required with this action, and the interface
specification is simply

       4 CREATE-PROG

    Action = 5
    ----------
        Again, action 5 creates programs that do not run as a task and enter
Mode 0 on startup, but it creates programs with customisable entry
addresses. The entry address is specified as an extra parameter. The
interface is

       entry_addr 5 CREATE-PROG

5.2 Discussion on CREATE-PROG
-----------------------------
    The total number of characters in the main window of the ARMForth system
cannot be more than the default number i.e. 78 * 300 = 23400. Within this
restriction, the aspect ratio may be as desired.
    The maximum lengths of the window and task titles are set by RISCOS.


6. ARMForth Defining Words 
--------------------------

    ARMForth offers a method of entering words stored as strings into the
dictionary via the usual defining words, in contrast to the usual method of
accepting the word name directly from the input stream. This facility opens
the door to dynamically creating dictionary entries. To illustrate, the
following two methods have the same effect of creating a constant called
SOPHOCLES.

       (a) 10 CONSTANT SOPHOCLES

       (b) 15 STRING SOPH
           SOPH STRCPY" SOPHOCLES"
           10 SOPH ICONSTANT

    The defining words all have a variant with an "I" at the beginning,
which expects the address of a string variable on top of the stack above any
other parameters which are used by the defining word. A complete list of the
defining words is shown below.


     Defining word         String Variant

       <BUILDS               <IBUILDS
       CREATE                ICREATE
       CONSTANT              ICONSTANT
       VARIABLE              IVARIABLE
       USER                  IUSER
       VOCABULARY            IVOCABULARY


7. Vectored Words
-----------------

    ARMForth words can be "vectored" to execute another word. A vectored
word can be assigned to execute any other word, thereby changing the effect
of all words which depend on the vectored word. If a word is defined to
execute a certain sequence of other words, and that word is then embedded in
the definition of another word, then normally a redefinition of the former
would require the redefinition of all words which depended on it. Vectored
words overcome this problem. For example

       : PRINTNAME ." AGAMEMNON" ;
       : DEPENDENT DOSOMETHING PRINTNAME DOSOMEOTHERTHING ;

    If we wanted to change the string that was printed, as well as having to
redefine PRINTNAME we would also have to redefine DEPENDENT.
    Using a vectored word we get the following solution to the problem.

       EXVEC: PRINTNAME
       : PN ." AGAMEMNON"
       ASSIGN PRINTNAME TO-DO PN
       : DEPENDENT DOSOMETHING PRINTNAME DOSOMEOTHERTHING ;

    Now if we wanted to print something else instead we would execute the following.

       : NEWPN ." PRIAM"
       ASSIGN PRINTNAME TO-DO NEWPN

    DEPENDENT would now print "PRIAM", and would not have to be redefined.
    In general the method of creating a vectored word is first to create the
word using EXVEC:. This produces an "empty" definition. If the word were to
be executed at this point an error message would be generated signalling to
the user that the word has not been assigned to another word yet. We then
define an auxiliary word to run the code sequence that we want the vectored
word to execute. Following that, the ASSIGN ... TO-DO command is issued to
link the vectored word with its auxiliary word.

7.1. ARMForth Standard Vectored Words
-------------------------------------
    There are certain words in the ARMForth system which are vectored words.
For example the output primitives (e.g. EMIT) need to perform different
actions depending on whether the system is in the Wimp mode or not. A
convention is used to indicate the auxiliary words for all the vectored
words. The convention is that auxiliary words are surrounded by angle
brackets (< and >), and take the name of the vectored word within the
brackets. Some of the names are preceded by a "W" to indicate that a word is
the Wimp variant of an auxiliary word (e.g. <WEMIT>). A complete list is
given below.

    Vectored Word            Wimp Auxiliary      Non-Wimp Auxiliary

    EMIT                     <WEMIT>             <EMIT>
    TYPE                     <WTYPE>             <TYPE>
    KEY                      <WKEY>              <KEY>
    ?KEY                     <?WKEY>             <?KEY>
    ?KEYBOARD                <?WKEYBOARD>        <?KEYBOARD>
    OSCLI                    <WOSCLI>            <OSCLI>
    <BUILDS                                      <<BUILDS>
    <IBUILDS                                     <<IBUILDS>
    DOES>                                        <DOES>>
    CREATE                                       <CREATE>
    ICREATE                                      <ICREATE>
    NUMBER                                       <NUMBER>
    ERROR                                        <ERROR>
    ABORT                                        <ABORT>
    UPDATE                                       <UPDATE>
    MESSAGE                                      <MESSAGE>
    R/W                                          <R/W>


7.2 Implementation of Vectored Words
------------------------------------
    Vectored words have a branch instruction at the beginning of the code
field, which branches to the auxiliary word they will execute. Peforming an
ASSIGN ... TO-DO just changes this branch instruction to point to a
different place. A consequence of this is that even words which have not
been defined using EXVEC: can be vectored to execute another word, in effect
making every word in the dictionary into a vectored word. The programmer
could make use of this to alter the functioning of some system words if so
desired.




RISCOS Specific Words
   RISCOS Libraries

Interesting Words
   CASE
   SHUFFLE etc

Low Level Info
   No double precision

Hints and Tips

3. Standard Forth 79 Words
--------------------------

 LIT  ( ... n)
      Pushes the 32 bit value at the address after the branch to LIT onto
      the stack. This word is not used when a literal value is met in a colon
      definition, since the pushing of literals is accomplished by inline
      code but this word is used by some of the other system words.

 EXECUTE  (addr ... )
       Executes the word whose address is on the stack

 BRANCH
       Run-time word to cause an unconditional branch. This word is used by
       some of the loop-related words. The contents of the address after the 
       call to BRANCH are added to the program counter.

 0BRANCH  (f ... )
       Run-time word to cause a conditional branch. This word is used by
       some of the loop-related words. If the flag on top of the stack is
       zero, the contents of the address after the call to BRANCH are added
       to the program counter. If the flag is non-zero, the branch is not
       executed.

 (LOOP)
       Run-time word planted by LOOP (dependent on the SPEED user variable)
       whose effect is to increment the loop index by one and branch to the
       start of the loop if it is less than the current loop limit. The word
       after the branch to (LOOP) contains the number of bytes to add to the
       program counter. This will be a negative number.

 (+LOOP)  (n ... )
       Run-time word planted by LOOP (dependent on the SPEED user variable)
       whose effect is to increment the loop index by the contents of the top
       of the stack and branch to the start of the loop if it is less than
       the current loop limit. The word after the branch to (LOOP) contains
       the number of bytes to add to the program counter. This will be a
       negative number.

 (DO)  (n1\n2 ... )
       Run-time word planted by DO which expects an initial loop index (n2)
       and a loop limit (n1) on top of the stack.

 I  ( ... n)
       Puts the current value of the loop index onto the stack. Inline code
       is always planted for I.

 J  ( ... n)
       When one loop is nested inside another, this puts the outer loop index
       onto the stack

 DIGIT  (c\n1 ... n2\tf)
        (c\n1 ... ff)
       Converts ASCII character c, with base n1 to its corresponding binary
       value n2, if possible, and leaves a non-zero flag above the value on
       the stack. If the character is not valid for the stated base, a zero
       flag is left on the stack.

 (FIND)  (addr1\addr2 ... cfa\n\tf)
         (addr1\addr2 ... ff)
       Searches the dictionary starting at the name field address addr2 for
       the text at addr1. If a match is found, the code field address of the
       matched word plus the length of the word name are left on the stack
       with a true flag above them. If no match is found a false flag is left
       on the stack.

 POLL-ESCAPE  (addr\n ... )
       Called by the Forth system each time it performs a Wimp_Poll, if it
       cannot service the event returned by the Wimp manager. addr is the
       address of the buffer used for the Wimp_Poll call, and n is the reason
       code returned from the Wimp_Poll in register R0.

 <EMIT>  (n ... )
       EMIT for the non-wimp mode. The top bit of each character is cleared
       before printing it.

 EMIT  (n ... )
       Vectored word which prints the character whose ASCII code is on the
       stack.

 <WEMIT>  (n ... )
       EMIT for the wimp mode. The characters &0C (clear screen) and 7 (bell)
       are interpreted correctly. All other control characters will not have
       the desired effect.

 <KEY>  ( ... n)
       KEY for the non-wimp mode. Ignores characters which have ASCII codes
       < &20 (except &0D) and >= &80.

 <WTYPE>  (addr\n ... )
       TYPE for the wimp mode. The top bit of each character is cleared
       before it is printed.

 <WKEY>  ( ... n)
       KEY for the wimp mode.

 KEY  ( ... n)
       Vectored word. Accepts a key press and leaves the ASCII value of the
       key pressed on the stack.

 ?TERMINAL ( ... f)
       Tests whether the Escape key is currently being pressed. If it is, a
       true flag is left on the stack. If it isn't, a false flag is left.

 CR
       Prints a carriage return and linefeed.

 CMOVE  (addr1\addr2\n ... )
       Moves n bytes from addr1 to addr2. No checks are performed to
       determine if the areas involved in the copy overlap.

 U*  (n1\n2 ... n3)
       Multiplies n1 by n2 (both unsigned) and puts the result n3 on the
       stack. Because there is no concept of double precision numbers, this
       is the same as the signed multiplication *.

 U/  (n1\n2 ... n3\n4)
       Divides n1 by n2 (both unsigned) and leaves the quotient n4 on the
       stack with r3 as the remainder. (This is NOT the same as / ).
       No check for /0 is made

 AND  (n1\n2 ... n3)
       Logically AND's n1 and n2 and puts the result n3 on the stack.

 OR  (n1\n2 ... n3)
       Logically OR's n1 and n2 and puts the result n3 on the stack.

 XOR  (n1\n2 ... n3)
       Logically XOR's n1 and n2 and puts the result n3 on the stack.

 SP@  ( ... addr)
       Leaves the value (before the operation) of the stack pointer on the
       stack.

 SP!
       Clears the stack

 RP@  ( ... addr)
       Leaves the value of the return stack pointer on the stack.

 RP!
       Clears the return stack.

 ;S
       This word should be deleted!

 LEAVE
       Forces the termination of a loop the next time the bottom of it is
       reached.

 >R  (n ... )
       Moves the top element of the stack to the top of the return stack.

 R>  ( ... n)
       Moves the top element of the return stack to the top of the stack.

 R  ( ... addr)
       Copies the top element of the return stack to the stack. The top ??
       bits are cleared before copying the value, which is assumed to be an
       address.

 >R>  (n ... n)
       Copies the top element of the stack to the return stack.

 N>R  (n1\n2\___ ... )
       Copies n1 items from the stack to the return stack. n2 is the last to
       be put onto the return stack.

 R<N  (n1\n2\___ ... )
       Copies n1 items from the stack to the return stack, in the reverse
       order to N>R, i.e n2 is put onto the return stack first.

 0=  (n ... f)
       Leaves a true flag on the stack if the top element of the stack is
       zero, otherwise a false flag is left.

 0<  (n ... f)
       Leaves a true flag on the stack if the top element of the stack is
       less than zero, otherwise a false flag is left.

 +  (n1\n2 ... n3)
       Adds the top two elements on the stack to leave the result on the
       stack.

 -  (n1\n2 ... n3)
       Subtracts the top stack element from the second value on the stack to
       leave the result on the stack.

 OVER  (n1\n2 ... n1\n2\n1)
       Copies the second element on the stack onto the top of the stack.

 DROP  (n ... )
       Removes the top element from the stack. If in compilation mode, inline
       code is always planted to perform this operation.

 SWAP  (n1\n2 ... n2\n1)
       Swaps the top two elements on the stack.

 DUP  (n ... n\n)
       Duplicates the top element of the stack.

 2DROP  (n1\n2 ... )
       Removes the top two elements from the stack.

 NDROP  (n1\n2\___ ... )
       Removes n1 items from the stack.

 2DUP  (n1\n2 ... n1\n2\n1\n2)
       Duplicates the top two elements on the stack.

 2OVER  (n1\n2\n3\n4 ... n1\n2\n3\n4\n1\n2)
       Copies the third and fourth values on the stack onto the top of the
       stack.

 2SWAP  (n1\n2\n3\n4 ... n3\n4\n1\n2)
       Swaps the first and second values on the stack with the third and
       fourth values.

 +!  (n\addr ... )
       Adds the second element on the stack (n) to the value stored at the
       address (addr) on top of the stack, and stores the result back to the
       address.

 TOGGLE  (addr\n ... )
       XOR's the contents of the address on top of the stack (addr) with the
       value second on the stack (n), storing the result back to the address.

 @  (addr ... n)
       Fetches the value (n) at the address (addr) on top of the stack.

 C@  (addr ... w)
       Fetches the 16 bit value (w) at the address (addr) on top of the
       stack.

 !  (n\addr ... )
       Stores the value second on the stack (n) at the address on top of the
       stack (addr).

 ><!  (addr\n ... )
       Stores the value on top of the stack (n) at the address second on the
       stack (addr).

 C!  (w\addr ... )
       Stores the 16 bit word second on the stack (w) at the address on top
       of the stack (addr).

 :
       Initiates the definition of a new word.

 ;
       Terminates the definition of a new word.

 R:
       Initiates the definition of a new word which can call itself i.e. is
       recursive.

 R;
       Terminates the definition of a recursive word.

 EXIT
       Terminates execution of the word which called EXIT

 NOOP
       Does nothing

 CONSTANT  (n ... )
       Defines a new constant to have the value on top of the stack.

 ICONSTANT  (n\addr ... )
       Same as CONSTANT but the name of the new word is the string at address
       addr.

 VARIABLE  (n ... )
       Defines a new variable to have the value on top of the stack.

 IVARIABLE  (n\addr ... )
       Same as VARIABLE but the name of the new word is the string at address
       addr.

 USER  (n ... )
       Defines a new user variable to have as offset from the start of the
       user variable area the value on top of the stack.

 IUSER  (n\addr ... )
       Same as USER but the name of the new word is the string at address
       addr.

 BL  ( ... n)
       Constant holding the ASCII value for space.

 C/L  ( ... n)
       Constant holding the number of characters per line. This value is
       used in the printing of Forth screens.

 FIRST  ( ... n)
       Constant which holds the address of the mass storage buffer.

 LIMIT  ( ... n)
       Constant holding the address of the first byte after the end of the
       mass storage buffer.

 B/BUF  ( .. n)
       Constant holding the number of bytes per mass storage buffer.

 B/SCR  ( ... n)
       Constant holding the number of buffers per screen.

 S/FILE  ( ... n)
       Constant holding the number of screens per file.

 +ORIGIN  (n ... addr)
       Constant holding the address of the n'th byte after the start of the
       boot up parameter area.

 S0  ( ... addr)
       User variable holding the initial value of the stack.

 R0  ( ... addr)
       User variable holding the initial value of the return stack.

 TIB  ( ... addr)
       User variable holding the address of the terminal input buffer.

 WIDTH  ( ... addr)
       User variable holding the maximum number of characters of a word's
       name which will be stored by the system.

 WARNING  ( ... addr)
       User variable which determines the action upon discovering an error.
       A negative value causes ABORT to be called when an error occurs,
       otherwise an error message is given.

 FENCE  ( ... addr)
       User variable holding the name field address??? of the word which
       acts as a FORGET boundary, in that all words which were defined
       before that word (including the word itself) cannot be forgotten.

 DP  ( ... addr)
       User variable holding the value of the dictionary pointer.

 VOC-LINK  ( ... addr)
       User variable holding the address of the vocabulary link field of the
       most recently created vocabulary.

 BLK  ( ... addr)
       User variable holding the number of the mass storage block from which
       input is being taken. 0 means the keyboard. If bit 31 is set this
       means input is coming from a text file.

 IN  ( ... addr)
       User variable holding the offset of the next character which will be
       read by the Forth interpreter in the input buffer.

 OUT  ( ... addr)
       User variable holding the number of characters printed by EMIT.

 SCR  ( ... addr)
       User variable holding the number of the most recently listed screen.

 OFFSET  ( ... addr)
       User variable holding a block offset into storage. The contents of
       this variable are added to the block number by BLOCK before it reads
       a block.

 CONTEXT  ( ... addr)
       User variable holding a pointer to the vocabulary in which a
       dictionary search will start.

 CURRENT  ( ... addr)
       User variable holding a pointer to the vocabulary into which a new
       definition will be placed.

 STATE  ( ... addr)
       User variable which indicates whether the Forth system is currently
       interpreting (0) or compiling (1??????).

 BASE  ( ... addr)
       User variable holding the current numeric base.

 DPL  ( ... addr)
       User variable which may be used to determine the position of a
       decimal point in a number.

 CSP  ( ... addr)
       User variable used for temporarily storing the stack pointer as an
       aid to determining compilation errors.

 R#   ( ... addr)
       User variable holding the location of the editing cursor. Used by the
       Forth Editor.

 HLD  ( ... addr)
       User variable holding the address of the latest character produced
       during numeric conversion.

 SPEED  ( ... addr)
       User variable holding a value which determines whether speed
       optimisations will be made by certain system words during compilation.

 1-  (n1 ... n2)
       Subtracts 1 from the top value on the stack.

 2-  (n1 ... n2)
       Subtracts 2 from the top value on the stack.

 HERE  ( ... addr)
       Places the dictionary pointer value onto the stack.

 ALLOT  (n ... )
       Allocates n bytes of storage in the dictionary.

 ,  (n ... )
       Compiles the value on top of the stack into the next four bytes of
       the dictionary, advancing the dictionary pointer by 4.

 C,  (n ...)
       Compiles the byte on top of the stack into the next byte of the
       dictionary, advancing the dictionary pointer by 1.

 NEGATE  (n1 ... n2)
       Negates the value on top of the stack.

 =  (n1\n2 ... f)
       Leaves a true flag on the stack if the top two values on the stack
       are equal, otherwise leaves a false flag.

 <  (n1\n2 ...f)
       Leaves a true flag on the stack if the second value on the stack is less than the top value, otherwise leaves a false flag.

 >  (n1\n2 ...f)
       Leaves a true flag on the stack if the second value on the stack is greater than the top value, otherwise leaves a false flag.

 >=  (n1\n2 ...f)
       Leaves a true flag on the stack if the second value on the stack is greater than or equal to the top value, otherwise leaves a false flag.

 <=  (n1\n2 ...f)
       Leaves a true flag on the stack if the second value on the stack is less than or equal to the top value, otherwise leaves a false flag.

 <>  (n1\n2 ... f)
       Leaves a true flag on the stack if the top two values on the stack are not equal, otherwise leaves a false flag.

 ROT  (n1\n2\n3 ... n2\n3\n1)
       Rotates the top three values on the stack so that the third value moves to the top.

 PICK  (___\n1\___\n2 ... n1)
       Copies the n2'th value on the stack (counting the top stack item as 1)to the top of the stack. 1 PICK is equivalent to DUP.

 ROLL  (n ... )
       Rotates the top n values on the stack, so that the n'th stack item (counting the top stack item as 1) moves to the top. n must be >= 2.

 INSERT  (n1\n2 ... )
        Inserts the second item on the stack at position n2, so the previous n2'th item will now be the (n2+1)'th item.

 SHUFFLE  (n1\___\n2\n3 ... )
        Rearranges the top n3 items. The new order is specified by the n3 values below n3. n1 is the current position of 
        the item which will end up on top of the stack. n2 is the current position of the item which will end up at position n3 on the stack.
        e.g. 23 65 78 12    4 3 2 1  4 SHUFFLE
        results in
        12 78 65 23

 QSHUFFLE  (n1\n2 ... )
        Rearranges the top q items on the stack, where q <= 8. Each 4 bit value in n1 indicates the rearrangement position of a 
        corresponding stack element. The least significant 4 bits give the current position of the stack element which will end up 
        in position n2. The next 4 bits give the current position of the element whose destination is position n2-1, etc. 
        This word is just a quicker version of SHUFFLE, with the restriction that the number of elements to shuffle cannot be > 8.
        e.g. 23 65 78 12   HEX  4321  DECIMAL  4 QSHUFFLE
        results in
        12 78 65 23

 SPACE
        Outputs an ASCII space character

 -DUP  (n ... n\n) , n <> 0
       (n ... n) , n = 0
        Duplcates the top stack element if it is non-zero.

 TRAVERSE  (addr1\n ... addr2)
        Scans across then name field of a word. If n = 1, addr1 should be the nfa of the word, and addr2 is left as the address 
        of the last byte of the word name. If n = -1, addr1 should be the address of the last byte of the name, and the nfa is left as addr2.

 LATEST  ( ... n)
        Leaves the nfa of the most recently defined name in the CURRENT dictionary on the stack.

 LFA  (addr1 ... addr2)
        Converts the parameter field address (addr1) of a word to its name field address (addr2).

 CFA  (addr1 ... addr2)
        Converts the parameter field address (addr1) of a word to its code field address (addr2).

 PFA  (addr1 ... addr2)
        Converts the name field address (addr1) of a word to its parameter field address (addr2).

 !CSP
        Stores the stack pointer in user variable CSP. This is only used by internal words as an aid to compilation checking.

 ?ERROR  (f\n ... )
        Causes error n if the flag f is true.

 ?COMP
        Causes an error if not in compilation mode.

 ?EXEC
        Causes an error if not in execution mode.

 ?PAIRS  (n1\n2 ... )
        Causes an error if n1 <> n2. This word is used as part of compilation checking by loop-related words.

 ?CSP
        Causes an error if the stack pointer is not the same as that stored in user variable CSP.

 ?LOADING
        Causes an error if not loading a file.

 <?WKEY>  (n ... f)
        ?KEY for the wimp mode. The keyboard is checked, and if the key with internal key number n is pressed, a true flag is left on the stack, else a false flag is left.

 <?KEY>  (n ... f)
        ?KEY for the non-wimp mode.

 ?KEY  (n ... f)
        Vectored to execute <?WKEY> or <?KEY>.

 <?WKEYBOARD>  ( ... n)
        ?KEYBOARD for the wimp mode. The keyboard is scanned, and if a key is pressed its internal key number is left on the stack. Zero is left on the stack if no key is pressed.

 <?KEYBOARD>  ( ... n)
        ?KEYBOARD for the non-wimp mode.

 ?KEYBOARD
        Vectored to execute <?WKEYBOARD> or <?KEYBOARD>

 COMPILE
        During execution the cfa of the word following COMPILE is compiled into the dictionary.

 [
        During a colon definition, compilation mode is suspended and execution mode is entered.

 ]
        During a colon definition, execution mode is terminated and compilation mode is reentered.

 SMUDGE
        Toggles the smudge bit of the most recently defined word in the CURRENT dictionary.

 HEX
        Changes the base to hexadecimal.

 DECIMAL
        Changes the base to decimal.

 (;CODE)
        Runtime word compiled by ;CODE that changes the cfa of the most recently defined word to 
        point to the machine code following (;CODE).

 ;CODE
        Compilation of the current colon definition of a defining word is terminated, and 
        ASSEMBLER becomes the current vocabulary. 
        The assembly language following ;CODE is called initially by any word defined using this defining word. 
        This word is the machine code equivalent of DOES>.

 <BUILDS
        Used in the colon definition of a defining word, and used in cooperation with DOES>. A defining word created as shown

       : DEFWORD <BUILDS ......
                 DOES> ......
                 ;
    uses the code between <BUILDS and DOES> to build a dictionary entry for any words defined with DEFWORD. A word created as

       DEFWORD NEWWORD

    causes the code between <BUILDS and DOES> to be executed, which creates the dictionary entry for NEWWORD. 
    When NEWWORD is executed, the code following DOES> is executed, with the parameter field address of NEWWORD being on the stack.

 <IBUILDS  (str ... )
        Same as <BUILDS but the name of the word to be defined is a string on the stack.

 DOES>
        See <BUILDS

 COUNT  (addr1 ... addr2\n)
        Converts the address of the name length word of a string (addr1) into the address of the first character of 
       the string (addr2) along with the length of the string (n).

 <TYPE>  (addr\n ... )
        TYPE for the non-Wimp mode.

 TYPE  (addr\n ... )
        Vectored to perform <TYPE> or <WTYPE>. Expects to find the length and address of a group of characters to print.

 -TRAILING  (addr\n1 ... addr\n2)
        Changes the length count of a character string at addr so as not to include any trailing spaces.

 (.")
        Run-time word planted by ." which prints the following inline string.

 ."
        Prints the following string in the input stream (terminated by " or CR.

 EXPECT  (addr\n ... )
        Receives characters from the keyboard and places them at addr onwards, until either CR is pressed or n characters are entered. 
        At least one NULL character is planted at the end of the stored text.

 QUERY
        Allows up to 256 characters to be input and stores them in the Terminal Input Buffer (TIB).

 X
        Synonym for NULL word, which causes interpretation of text from the input buffer to cease.

 FILL  (addr\n\b ... )
        Fills n bytes of memory starting at address addr with the value b

 ERASE  (addr\n ... )
        Clears n bytes of memory starting at address addr to ASCII NULL.

 BLANKS
        Clears n bytes of memory starting at address addr to ASCII SPACE.

 HOLD  (c ... )
        Used between <# and #> during numeric conversion to insert character c into a numeric string.

 PAD  ( ... addr)
        Leaves the address of the text scratchpad buffer on the stack.

 WORD  (c ... addr)
        Takes characters from the input until character c is seen or the input is exhausted (e.g. CR pressed). 
        The characters are stored as a string in a buffer and the address of the count word of the string is left on the stack.

 <NUMBER>  (addr ... n)
        Normal NUMBER action.

 NUMBER  (addr ... n)
        Vectored to execute <NUMBER>. Converts the ASCII string representation of a number at address addr into its numeric format.

 -FIND  (addr1 ... addr2\n\tf)
        (addr1 ... ff)
        Searches the dictionary to find the string following in the input stream. 
        If the word is found, the cfa of the word along with its name header word are left on the stack below a TRUE flag. 
        If the name cannot be found a FALSE flag is left.

 -IFIND  (addr1 ... addr2\n\tf)
        Searches the dictionary to find the string whose name length word is at address addr1. 
        If the word is found, the cfa of the word along with its name header word are left on the stack below a TRUE flag. 
        If the name cannot be found a FALSE flag is left.

 ERROR  (n ... )
        Causes error message n to be given, and control passes back to the interpreter.

 ID.  (addr ...)
        Prints a word name from its nfa on the stack.

 <CREATE>
        Normal action of CREATE.

 CREATE
        Vectored to execute <CREATE>. Creates a new dictionary entry from the word following it in the input stream. 
        The code field initially contains a branch to the next instruction (which will contain garbage).

 <ICREATE>  (addr ... )
        Normal action of ICREATE.

 ICREATE  (addr ... )
        Vectored to execute <ICREATE>. Same as CREATE but the word to create is in the string on top of the stack.

 [COMPILE]
        Used in a colon definition to force the compilation of an immediate word following in the input stream which would otherwise execute.

 LITERAL  (n ... )
        During compilation the value on top of the stack is compiled into the dictionary along with some code to put that value on the stack 
        during execution of the word being defined.

 DLITERAL  (n ... )
        Same as LITERAL. Only included for compatiblity.

 ?STACK
        Causes an error if the stack pointer is invalid.

 ?PARAMS  (n ... f)
        Checks if at least n items are on the stack. If they are a TRUE flag is left, else a FALSE flag is left.

 INTERPRET
        The outer text interpreter of the FORTH system which accepts words from the input stream and executes or compiles them according 
        to the current system state.

 IMMEDIATE
        Causes the most recently defined word to become IMMEDIATE. i.e. it will always execute, even with a colon definition.

 VOCABULARY
        Causes a new vocabulary to be defined with the name of the word following in the input stream.

 FORTH
        Makes FORTH the context vocabulary. This is the root vocabulary which all other vocabularies ultimately link to.

 DEFINITIONS
        Makes the current vocabulary equal to the context vocabulary.

 (
        Introduces a comment. All text between ( and ) (up to a maximum of 256) is ignored by the system during interpretation.

 QUIT
        Clears the return stack, and causes a return to the FORTH command interpreter.

 <ABORT>
        Normal action of ABORT.

 ABORT
        Vectored to execute <ABORT>. The computation and return stacks are cleard, and control is returned to the FORTH command interpreter.

 WARM
        Causes a warm start. The current and context vocabularies are set to FORTH, and the base is set to decimal.

 COLD
        Causes a cold start. The boot-up parameters are loaded into the corresponding user variables, and the system is started by calling ABORT.

 <<  (n1\n2 ... n3)
        Shifts the second stack element left by the number of bits signified by the top stack element. 
        Zeros are placed in the exposed least significant bit positions. The result is placed on the stack.

 >>  (n1\n2 ... n3)
        Shifts the second stack element right by the number of bits signified by the top stack element. 
        Zeros are placed in the exposed most significant bit positions. The result is placed on the stack.

 >>>  (n1\n2 ... n3)
        Shifts the second stack element right by the number of bits signified by the top stack element. 
        The exposed most significant bit positions are filled with the sign bit of n1. The result is placed on the stack.

 >><< (n1 ... n2)
        The most significant 16 bits of the top stack item are swapped with the least significant 16 bits, placing the result on the stack.

 ><  (n1 ... n2)
        The top item on the stack is assumed to be a 16 bit quantity. 
        The most significant 8 bits of the top stack item are swapped with the least significant 8 bits, placing the result on the stack.

 +-  (n1\n2 ... n3)
        The top stack value has the sign of the second stack value applied to it, and the result is left on the stack.

 D+-  (n1\n2 ... n3)
        Same as +-. Included for compatibility.

 ABS  (n1 ... n2)
        The absolute value of the top stack item is placed on the stack.

 DABS  (n1 ... n2)
        Same as ABS. Included for compatibility.

 MIN  (n1\n2 ... n3)
        Leaves the minimum value of the top two stack items on the stack.

 MAX  (n1\n2 ... n3)
        Leaves the maximum value of the top two stack items on the stack.

 M*  (n1\n2 ... n3)
        Same as *. Included for compatibility.

 M/  (n1\n2 ... n3\n4)
        Divides the second stack item by the first stack item, and leaves the remainder below the quotient on the stack.

 *  (n1\n2 ... n3)
        Multiplies the top two stack values and leaves the answer on the stack.

 2*  (n1 ... n2)
        Multiplies the top stack item by 2.

 4*  (n1 ... n2)
        Multiplies the top stack item by 4.

 /MOD  (n1\n2 ... n3\n4)
        Same as M/. Included for compatibility.

 /  (n1\n2 ... n3)
        Divides the second stack element by the top stack element, and leaves the quotient on the stack.

 2/  (n1 ... n2)
        Divides the top stack item by 2.

 4/  (n1 ... n2)
        Divides the top stack item by 4.

 MOD  (n1\n2 ... n3)
        Divides the second stack item by the top stack item, and leaves the remainder on the stack, with the sign of n1.

 */MOD  (n1\n2\n3 ... n4\n5)
        Performs the equivalent of "n1 n2 * n3 /MOD".

 */  (n1\n2\n3 ... n4)
        Performs the equivalent of "n1 n2 * n3 /".

 M/MOD  (n1\n2 ... n3\n4)
        Same as U/. Included for compatibility.

 USE  ( ... addr)
        A variable holding the address of the mass storage buffer to use next.

 PREV  ( ... addr)
        A variable holding the address of the most recently used mass storage buffer.

 +BUF  (addr1 ... addr2\f)
        Changes the mass storage buffer address addr1 to the next mass storage buffer address addr2. 
        A flag is left above the address on the stack, which is FALSE if addr2 is the address of the most recently used mass storage buffer.

 <UPDATE>
        Vectored version of UPDATE. Marks the current editing screen as being updated. 
        This is used by the system when it determines whether to save the contents of a buffer before it can be reused.

 UPDATE
        Vectored word. Initially performs <UPDATE>

 EMPTY-BUFFERS
        Marks all mass storage buffers as being empty by filling them with zeros. No data is written to mass storage.

 BUFFER  (n ... addr)
        Get a free mass storage buffer, and assign it to screen n. 
        If the buffer chosen contains UPDATEd data, then that buffer is first written to mass storage. 
        The address of the first location in the buffer available for data is left on the stack.

 BLOCK  (n ... addr)
        Places on the stack the address of the first location of the buffer allocated to screen n available for data. 
        If the block is not in main storage it is first transferred there from mass storage into the buffer which 
        has been least recently accessed. Any UPDATEd data in that buffer is first written out to mass storage.

 (LINE)  (n1\n2 ... addr\n3)
        Leaves the start address and character count of the line n1 of screen number n2.

 .LINE  (n1\n2 ... )
        Outputs on the screen line n1 of screen number n2.

 <MESSAGE>  (n ... )
        Vectored version of MESSAGE. Displays an error message on the screen appropriate to error number n.

 MESSAGE  (n ... )
        Vectored word. Initially performs <MESSAGE>.

 LOAD  (n ... )
        Causes the input stream to come from screen n. 
        When interpretation of screen n is terminated, input resumes from its source before screen n was interpreted.

 -->
        Continues interpretation with the next screen from mass storage.

 <R/W>  (addr\n\f ... )
        Vectored version of R/W. Performs reads to/writes from mass storage. 
        The flag f is true for a read and false for a write. 
        n is the screen to be transferred to a mass storage buffer whose first byte of data is address addr.

 R/W  (addr\n\f ... )
        Vectored word. Initially performs <R/W>.

 FLOAD  (addr ... )
        Begins interpretation of the text contained in the file whose name is stored in the string at addr.

 <FLOAD>
        Runtime word to begin interpretation of the text file whose name is positioned inline with the code.

 FLOAD"
        Begins interpretation of the file whose name appears next in the input stream, terminated by a " or newline.

 '
        Leaves the cfa of the word which follows in the input stream.

 FORGET
        Deletes all the words defined after (and including) the word following in the input stream.

 BACK  (addr ... )
        Places a branch offset or a branch instruction in the dictionary, depending on the value of SPEED. 
        Used by the system branching words.

 BEGIN
        Initiates a BEGIN WHILE REPEAT or BEGIN UNTIL or BEGIN AGAIN loop.

 ENDIF
        Terminates an IF construct.

 THEN
        Same as ENDIF.

 DO
        Initiates a DO LOOP or DO +LOOP loop.

 LOOP
        Terminates a DO LOOP loop.

 +LOOP
        Terminates a DO +LOOP loop.

 UNTIL
        Terminates a BEGIN UNTIL loop.

 END
        Same as UNTIL.

 AGAIN
        Terminates a BEGIN AGAIN loop.

 REPEAT
        Terminates a BEGIN WHILE REPEAT loop.

 IF
        Starts an IF construct.

 ELSE
        Part of the IF ELSE THEN construct.

 WHILE
        Part of the BEGIN WHILE REPEAT loop.

 SPACES  (n ... )
        Prints n spaces to the screen.

 <#
        Initiates the system numeric output formatting sequence.

 #>  (n1 ... addr\n2)
        Terminates the system numeric output formatting sequence. 
        The top stack element is removed, and the address and count of the character representation of the converted number 
        is left on the stack in a form suitable for TYPE.

 SIGN  (n1\n2 ... n2)
        Stores a '-' character in the character representation of the number being converted, if n is negative. 
        The top stack element n2 is part of the converted number, and is left on the stack.

 #  (n1 ... n2)
        Converts the least significant digit of the number n1 into a character according to the current base, and stores 
        the character in the string at pad. The rest of the number is left on the stack.

 #S  (n1 ... n2)
        Converts the number n1 into its character representation, and leaves the text at PAD. n2 is always zero.

 .R  (n1\n2 ... )
        Prints the number n1 in the current base at the right of a field of size n2.

 .  (n ... )
        Prints the number n in the current base followed by one space.

 DEC.  (n ... )
        Prints the number n in base decimal followed by one space.

 H.  (n ... )
        Prints the number n in base hexadecimal followed by one space. Leading zeros are not printed.

 DEPTH  ( ... n)
        Leaves the number of items on the stack, not including n.

 ?  (addr ... )
        Prints the number at address addr.

 LIST  (n ... )
        Produces a listing of screen n on the screen. 
        If screen n is not in a mass storage buffer it is first loaded into one. The base is set to decimal.

 INDEX  (n1\n2 ... )
        Prints the first lines of screens n1 to n2 inclusive.

 TRIAD  (n ... )
        Lists the 3 screens starting at a multiple of three and including screen n. A form feed is first printed.

 VLIST
        Prints all words in the CONTEXT vocabulary, and all those vocabularies to which the CONTEXT vocabulary is chained. 
        Pressing the space bar pauses the listing. While paused, pressing the tab key abandons the listing, while any other key continues the listing.

 CREATE-SCREEN  (n ... )
        Creates space for screen n in mass storage. If a file containing this screen already exists a read/write error will be generated.

 .S
        Non-destructively prints the contents of the stack.

 (OSCLI)
        Sends the following inline string to the command line interpreter.

 <WOSCLI>  (addr\n ... )
        Sends the text at address addr and of length n to the command line interpreter.

 OSCLI
        Vectored to initially perform <WOSCLI>

 OSCLI"
        Sends the string following in the input stream and terminated with " or a newline to the command line interpreter.

 EXVEC:
        Starts the definition of a vectored word.

 ASSIGN
        Used in conjunction with TO-DO. A statement of the form

           ASSIGN vecword TO-DO actionword

        causes the vectored word vecword to perform actionword whenever it is executed from this point onwards.

 TO-DO
        See ASSIGN.

 CASE:
        Defines a word which, when executed, will cause one of a number of words to be executed depending on the value on the stack. 
        For example

            CASE caseword
                 ACTION0 ACTION1 ACTION2 ACTION3
            CASE;

        When caseword is executed it will execute either ACTION0, ACTION1, ACTION2 or ACTION3 depending on whether 
        the top stack value is 0, 1, 2, 3 respectively. A value out of range will cause an error to be signalled. 
        As many acions as are required can be indicated in the caseword definition, but the start index is always zero.

 CASE;
        Terminates the definition of a case word.

 PCASE:
        Starts the definition of a positional case word. 
        This allows the action to be performed to be dependent on an explicit stack value, not on the implicit number 
        starting from zero as in the CASE: word.
        The structure of a PCASE: definition is as follows.

              PCASE: caseword
                     5 ACTION1 62 ACTION2 19 ACTION3
              PCASE;

        When caseword is executed, the top stack value is examined. 
        If it is 5 then ACTION1 is executed, a value of 62 causes ACTION2 to be executed, and similarly for ACTION3. 
        An invalid stack value causes an error to be signalled.

 PCASE;
        Terminates a PCASE: definition.

 NOWIMPS
        Enters mode 0 and reconfigures some of the vectored words to perform the non-wimp function.

 WIMPS
        Enters the Wimp environment and reconfigures some of the vectored words to perform the Wimp function.

 .RS
        Non-destructively prints the contents of the return stack.

 HIDE
        Causes the word following it in the input stream to be excluded from a dictionary search from this point onwards.

 STRING  (n ... )
        Defines a string with the name following in the input stream, and of length n.

 STRING[]  (n1\n2 ... )
        Defines a two dimensional string with the name following in the input stream, with dimensions n1 and n2. 
        n1 is the number of strings in the array, and n2 is the length of each string.

 ARRAY  (n ... )
        Defines a numeric array with the name following in the input stream, and of length n.

 ARRAY[]  (n1\n2 ... )
        Defines a two dimensional numeric array with the name following in the input stream, with dimensions n1 and n2.

 .STR  (addr ... )
        Prints the string at address addr.

 STRLEN  (addr ... n)
        Leaves the length of the string at addr on the stack.

 STRCPY  (addr1\addr2 ... )
        Copies the string at addr2 into the string addr1. No length checking is performed.

 STRCPY"  (addr ... )
        Copies the string following in the input stream to the string addr.

 STRCAT  (addr1\addr2 ... )
        Concatenates the string at addr2 to the string addr1. No length checking is performed.

 STRCAT"  (addr ... )
        Concatenates the string following in the input stream to the string addr.

 STRCMP  (addr1\addr2 ... n)
        Compares the string at addr2 to the string addr1. If they are the same n is left as 0, else it is 1.

 STRCMP"  (addr ... n)
        Compares the string following in the input stream to the string addr. If they are the same n is left as 0, else it is 1.
