changeset 24:01a6e267aa38

Added the Basic09 Reference Manual
author roug
date Sat, 06 Apr 2002 13:34:58 +0000
parents dac1f4e899fe
children ad78331ace28
files docs/basic09/basic09.docbook docs/basic09/makefile
diffstat 2 files changed, 7734 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/basic09/basic09.docbook	Sat Apr 06 13:34:58 2002 +0000
@@ -0,0 +1,7715 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
+  <!ENTITY b09 "BASIC09">
+  <!ENTITY minus "&#045;">
+]>
+<book id="basic09" lang="en">
+ <bookinfo>
+<title>&b09;</title>
+<subtitle>Programming Language Reference Manual</subtitle>
+<titleabbrev>&b09; Reference Manual</titleabbrev>
+
+<copyright>
+<year>1983</year>
+<holder>Dragon Data Ltd. and Microware Systems Corporation.
+All Rights Reserved.
+Basic 09 is a trademark of Microware Systems Corporation and Motorola Inc.
+</holder>
+
+</copyright>
+<revhistory>
+<revision>
+<revnumber>F</revnumber>
+<date>February 1983</date>
+</revision>
+</revhistory>
+</bookinfo>
+
+
+
+<chapter>
+<title>Introduction</title>
+<subtitle>Introduction to &b09; Programming</subtitle>
+<sect1>
+<title>Comments on &b09;</title>
+<para>
+&b09; is an enhanced structured Basic language programming
+system specially created for the 6809 Advanced Microprocessor
+used by the Dragon Computer.
+In addition to the standard BASIC language statements and functions,
+&b09; includes many of the useful elements of the PASCAL
+programming language so that programs can be modular,
+well-structured, and use sophisticated data structures.
+It also permits full access
+to almost all of the OS-9 Operating System commands and functions so it
+can be used as a systems programming language.
+These features make &b09; an ideal language for many applications:
+scientific, business, industrial control, education and more.
+</para>
+<para>
+&b09; is unusual in that it is an <emphasis>Interactive Compiler</emphasis> that
+has the best of both kinds of language system: it gives
+the fast execution speed typical of compiler languages plus the ease of use
+and memory space efficiency typical of interpreter languages.
+&b09; is a complete PROGRAMMING SYSTEM that
+includes a powerful text editor, multi-pass compiler,
+run-time interpreter, high-level interactive debugger, and a system
+executive. Each of these components was carefully integrated
+to give the user a
+friendly, highly interactive programming resource. that provides all the tools
+and helpful "extra" facilities needed for fast, accurate creation and testing of
+structured programs.
+</para>
+
+<highlights>
+<para>
+&b09; Features
+
+<itemizedlist mark="bullet">
+
+<listitem>
+  <para>
+  Structured, recursive BASIC with Pascal-type enhancements:
+  <itemizedlist mark="dash">
+    <listitem><para>allows multiple, independent, named procedures</para></listitem>
+    <listitem><para>procedures called by name with parameters</para></listitem>
+    <listitem><para>multi-character, upper or lower case identifiers</para></listitem>
+    <listitem><para>variables and line numbers local to procedures</para></listitem>
+    <listitem><para>line numbers optional</para></listitem>
+    <listitem><para>automatic linkage to ROM or RAM "library" procedures</para></listitem>
+    <listitem><para>PACK command compacts program and provides security</para></listitem>
+    <listitem><para>PRINT USING with FORTRAN-like format specifications</para></listitem>
+  </itemizedlist>
+  </para>
+</listitem>
+
+
+<listitem>
+<para>
+Extended data structures:
+  <itemizedlist mark="dash">
+    <listitem><para>Five Basic data types: BYTE, INTEGER, REAL, BOOLEAN, and STRING</para></listitem>
+    <listitem><para>One, two, or three dimensional arrays</para></listitem>
+    <listitem><para>User-defined complex structures and data types</para></listitem>
+  </itemizedlist>
+</para>
+</listitem>
+
+
+<listitem>
+<para>
+Extended Control Structures (with Unique Closure Elements):
+</para>
+</listitem>
+
+
+<listitem>
+<para>
+Graphics Interface Module for Access to Dragon Computer Colour
+Graphics Functions
+</para>
+</listitem>
+
+
+<listitem>
+<para>
+Powerful interactive debugging and editing features:
+  <itemizedlist mark="dash">
+    <listitem><para>Integral, full-featured text editor</para></listitem>
+    <listitem><para>Syntax error check upon line entry and procedure compile</para></listitem>
+    <listitem><para>Trace mode reproduces original source statements</para></listitem>
+    <listitem><para>Renumber command for line numbered procedures</para></listitem>
+  </itemizedlist>
+</para>
+</listitem>
+
+
+<listitem>
+<para>
+High-speed, high-accuracy math:
+  <itemizedlist mark="dash">
+    <listitem><para>9 decimal-digit 40 bit binary floating point</para></listitem>
+    <listitem><para>Full set of transcendentals (SIN, ASN, ACS, LOG, etc.)</para></listitem>
+  </itemizedlist>
+</para>
+</listitem>
+</itemizedlist>
+
+</para>
+</highlights>
+</sect1>
+<sect1>
+<title>The History of &b09;</title>
+<para>
+&b09; was conceived in 1978 as a high-performance
+programming language to demonstrate the capabilities of the 6809
+microprocessor to efficiently run high-level languages. &b09;
+was developed at the same time as the 6809 under the auspices of the
+architects of the 6809. The project covered
+almost two years, and incorporated the results of research in such areas as
+interactive compilation, fast floating point arithmetic algorithms, storage
+management, high-level symbolic debugging, and structured language
+design. These innovations give &b09; its speed, power, and
+unique flavor.
+</para><para>
+&b09; was commissioned by Motorola, Inc., Austin, Texas,
+and developed by Microware Systems Corporation, Des Moines, Iowa.
+Principal designers of &b09; were Larry Crane, Robert
+Doggett, Ken Kaplan, and Terry Ritter. The first release was in February,
+1980.
+</para><para>
+Excellent feedback, thoughtful suggestions, and carefully documented bug
+reports from &b09; users all over the world have been
+invaluable to the designers in their efforts to achieve the degree of
+sophistication and reliability &b09; has today.
+</para>
+</sect1>
+</chapter>
+
+
+
+<chapter>
+<title>Introduction to &b09; Programming</title>
+<para>
+
+This section is intended for persons who have not previously
+written computer programs. If you are familiar with programming in
+general or BASIC programming specifically, this section can give you
+a "feel" for the &b09; interactive environment.
+
+</para>
+<sect1><title>What is a Program?</title>
+<para>
+A computer works something like a pocket calulator. With a
+calculator you push a button, some calculation occurs, and the
+result is displayed. On some calculators you can write a program
+which is just a list of the buttons you want pushed, in the order
+you want them pushed. This is very similar to a computer program,
+but most computer languages use command names instead of buttons.
+</para>
+
+<para>
+To get results from a computer, you must first put into the
+computer the list of commands you want executed in the order you
+want them executed. Each command will mean "do this thing" or "do
+that thing", but the computer only has certain commands which it
+will understand. A computer can do things like "add" or "save the
+result into memory". Typing "get me a taco" to a computer won't
+get it; similarly, on a calculator you can't push buttons which
+aren't there. After you have stored a list of commands into the
+computer, you can tell it to perform those operations. This is like
+actually pushing the buttons on a hand calculator. Then, if you
+remembered to have the compuer display your results, you get to see
+them. Generaly, a computer does not automatically display results
+like a hand calculator. More calculations occur in a computer then
+in a calculator, and displaying all these results would simply be
+overwhelming.
+</para>
+
+<para>
+You enter a program into a computer by using the computer
+itself as a "text editor", to store the commands you type in. Some
+editors allow you to enter any text you want. Other editors will
+only store valid computer commands. Even if the computer does store
+all the text you type in, it can only execute those commands it
+knows. If during program execution, &b09; finds a word which does
+not correspond to a command it will probably stop and print out an
+"error message". Other editors check each command as you enter it
+(usually after the carriage-return ending each line) and print error
+messages immediately for invalid commands. After typing in your
+list of commands, there are ways to display that list, to modify the
+commands you have typed in, and to insert others. But simpy
+entering a computer program does not get results any more than
+thinking which buttons to push will get results on a calculator.
+You store your program by typing it into a computer, but no results
+are available until after you start the program running.
+</para>
+<para>
+Even though programming is conceptually simple, it is easy to
+misspell commands which &b09; will not interpret correctly.
+Unlike humans, &b09; does not infer anything: Every command must
+be perfectly spelled and punctuated or it is wrong. Even after
+spelling errors are eliminated, it is likely that the sequence of
+commands you have entered will not do the job you wanted it to do.
+The meaning of the program to &b09; is often quite different than
+was intended by the programmer, biut good intentions just don't push
+the right buttons. After you get the program to run without obvious
+error, you must test the program with sample input and see that it
+produces results which are known correct. If the results are incorrect,
+the program must be modified and tested until it does
+produce correct results. This is known as testing and
+debugging. Computer malfunctions are rare, and if the computer
+works to store the program, it is probably working perfectly. If the
+program does not work, you need to puzzle out how the computer is
+doing something hich you didn't realize that you told it to do.
+Programming can be frustrating, but if you enter the right commands,
+the computer will do the right things for you.
+</para></sect1>
+<sect1><title>A Simple &b09; Program</title>
+<para>
+Probably the easiest way to explain programming is by example.
+This simple program sometimes keeps kids happy for hours. First,
+the program asks the user for his name. Then the computer types out
+"Hi", then the name, then "see you later". This may not seem like
+much, but it is great fun to type in things which are not your name,
+and see if they will be printed out. They will, of course.
+</para>
+<para>
+When you turn on the &b09; computer it will print some heading
+information. If the prompt is "OS9:  ", enter the "basic09" (and
+a carriage-return) to get to the prompt "B:". When you have the
+prompt "B:", it means that the system is in the &b09; "command
+mode". While in the command mode, you can do several things, like:
+list, kill, or create programs (called "procedures" in &b09;).
+&b09; lets you keep several different programs in memory at the
+same time. Each procedure is identified by a name you give it when
+you create the procedure.</para>
+<para>
+To create a new procedure you command the system to enter the
+"edit mode" by typing a simpl "e" (in upper or lower case) and a
+carriage-return (the ENTER or RETURN key). The Editor lets you
+enter or change programs and actually checks for many common errors
+as you type in your program. This automatic checking feature is one
+of the nicest things about &b09;. Because it's always "looking
+over your shoulder" to catch mistakes, it saves a lot of debugging
+time! If you're not 100% sure about how something works - you can
+go ahead and try it instead of digging through this manual. If you
+guess wrong &b09; will usually show you where and why.
+</para>
+<para>
+Because you did not specify a particular procedure name,
+&b09; will automatically select the name "PROGRAM" for you, and
+will respond by printing out "PROCEDURE PROGRAM"; this means that
+you will be editing a procedure which is named PROGRAM. Later you
+will see that you can enter many different procedures and give them
+different names (just type the name you want to use for the program
+after the "e").
+</para>
+<para>
+The computer output so far is a follows:
+<programlisting>
+B:e
+PROCEDURE PROGRAM
+*
+E:
+</programlisting>
+The asterisk (*) indicates the "current edit line" in the procedure
+being edited. In this case the current line is empty since you have
+not yet entered anything. The asterisk is handy, since you will be
+moving back and forth between different lines to edit them. Later
+you will be "opening" existing procedures for modification, and the
+first line will be displayed automatically, helping identify that
+you are editing the correct program.
+</para>
+<para>
+When &b09; responds with the edit prompt "E:", it is in the
+edit mode. Now you can enter "edit commands" which help us enter
+the computer program. While in edit mode, &b09; ALWAYS TAKES THE
+FIRST CHARACTER OF EVERY LINE AS AN EDIT COMMAND. Some of the basic
+edit commands are:
+<programlisting>
+&lt;space> &lt;program statement> &lt;cr>  insert line
+? &lt;cr>  go to next line down (just &lt;cr> also does the same)
+- &lt;cr>  move back to previous line
+L &lt;cr>  list current line
+d &lt;cr>  delete current line
+</programlisting>
+The most-important edit command is the (invisible) space character;
+this means "save the following line of text", The "space" command
+is the way most text is entered into the system. you must type an
+edit command at the start of each line. If a line is to be entered,
+you must type a space before the rest of the line. If you forget to
+type an edit command, &b09; will respond with "WHAT?". Another
+useful edit command is "L*" (or "l*", since the editor accepts
+either upper or lower case) which will display the whole procedure.
+This allows you to watch the procedure develop as lines are entered.
+</para>
+<para>
+You use the "space" command to enter the following line:
+<programlisting>
+E: print "type your name"
+*
+</programlisting>
+When &b09; executes procedure PROGRAM, this line will tell it to
+print on the screen all of the characters between the quotes.
+</para>
+<para>
+As mentioned before, &b09; checks for errors at the end of
+each line and again when the edit is finished. These errors are, in
+general, anything &b09; cannot identify or things that don't
+conform to the rules of the language. An error could be a bad
+character, mismatched parenthesis, or one of many other things.
+&b09; will print out an "error code" to identify the error and
+print an up arrow character under the place in the line where it
+detected the error. The error codes are listed at the end of this
+manual. If the error was detected at the end of the edit session,
+the I-code location of the error will also be printed. This cryptic
+information is all &b09; knows about the problem, hopefully, it
+will help you to find and fix the error.
+</para>
+<para>
+In the same way that you entered the first line, enter the
+following lines.  Remember that the first character entered must be
+a space to get &b09; to save the rest of the line. Example:
+<programlisting>
+E: input name$
+*
+E: print "Hi ";name$;", see you later."
+*
+E: end
+*
+</programlisting>
+The second line ("input name$"), when executed, commands &b09; to
+wait for a line of text to come in from the keyboard (this will
+happen after the user reads the message printed out in the first
+line). &b09; will accumulate text from the keyboard character-by-character
+until a carriage-return ends the line. This text is
+placed in memory corresponding to the variable "name$". The dollar-sign
+($) on the end of the variable tells &b09; that you want to
+store a sequence of characters as opposed to a number.
+</para>
+<para>
+The third line of procedure PROGRAM (print "Hi ";name$;", see
+you later."), starts out like the first line. The command "print"
+causes &b09; to print out the various values which come after it.
+When this line is executed, the characters H, i, and "space" are
+printed out since the are enclosed in double-quotes. Next, without
+additional spaces, &b09; prints out the line which was typed in by
+the user and saved in the memory corresponding to "name$" and prints
+out " see you later". When a PRINT statement contains multiple values,
+it will print them out one after the other. If the separator
+is a comma, &b09; will move to the next 16-column "tab stop"
+before printing the next value. However, if the separator between
+print values is a semicolon, absolutely no space will separate the
+values. The last line of the procedure ("END") tells &b09; to
+stop executing the program and return to the command mode (B:).
+You have not yet EXECUTED the procedure, you are just EDITING. If
+you type in l* the whole program will be listed, as follows:
+<programlisting>
+E:l*
+PROCEDURE PROGRAM 
+ 0000      PRINT "type your name"
+ 0012      INPUT name$
+ 0017      PRINT "Hi ";name$;", see you later."
+ 0035      END
+*
+E:
+</programlisting>
+Notice that the editor has added some information which you did not
+type in. You can use this listing to show exactly what to type in
+to run this program, but the editor only wants the relevant
+information.
+</para>
+<para>
+The numbers to the left are "I-code addresses". These are the
+actual memory locations relative to the start of the procedure where
+each line begins. These numbers may look strange because they are in
+hexadecimal (base 16). These values are important, since the
+compiler may find errors at some I-code location and will try to
+convey that information it has to the programmer. I-code addresses
+are supplied automatically by &b09;.
+</para>
+<para>
+The space between the "I-code addresses" and the beginning of
+the program line is reserved for "line numbers". Line numbers are
+required in many versions of BASIC (although not in &b09;).
+Notice that although the program was typed in lower case some words
+are printed in upper case. &b09; identifies valid command
+"keywords" and converts them to upper case automatically.
+</para>
+<para>
+Now let's run it. First type "q" to quit the editor. We are
+nowback in "command mode" ( B:). Now type "run". &b09;
+remembers the procedure edited (PROGRAM) and starts to execute
+it.
+<screen>
+E:q
+READY
+B:run
+type your name
+? tex
+Hi tex, see you later.
+READY
+B:
+</screen>
+The question mark (?) is the normal input prompt to tell the user
+that the program is waiting for input.
+</para>
+<para>
+This program is extremely simple, but younger kids can get
+grat fun from it. Its action is especially amusing to young people
+who are learning a computer language for the first time because a
+machine is "responding" to them, and because the machine is too
+easily "fooled" if you do not type in a real name.
+</para></sect1>
+<sect1><title>Basic Programming Techniques: Loops and Arithmetic</title>
+<para>
+Another simple program that most of us can identify with is a
+program to print out multiplication tables.
+<programlisting>
+PROCEDURE multable
+  FOR i=1 TO 9
+    FOR j=1 TO 9
+      PRINT i*j; TAB(5*j);
+    NEXT j
+  NEXT i
+</programlisting>
+First, open the editor by typing "e multable", as follows:
+<screen>
+B: e multable
+PROCEDURE multable
+*
+E:
+</screen>
+Next, type in the program line-by-line staring with "FOR i=1 TO 9"
+(lower-case is perfectly fine). If you loose your way, type "L*" to
+see where you are. This will display the entire procedure and put
+an asterisk at the left of the current line. If you make a mistake,
+use "+" or "-" to mode to that line, use "d" to delete the line, and
+use the space command to enter the line over. Make sure that there
+are no errors and then type "q". When you have the program running,
+try adding a statement before "FOR i=1 TO 9" as follows: "DIM
+i,j:INTEGER".
+</para>
+<para>
+The FOR i=1 TO 9 and NEXT i constitute the start and end of a
+control structure or "loop". A control structure is used to cause
+repeated or conditional execution of the statement(s) it surrounds.
+A control structure usually has one entry at the top and one exit at
+the bottom. In this way, the entire structure take on the properties
+of a single statement. The beginning statement of the
+FOR...NEXT structure (FOR...) provides a "loop initialization", places
+the value 1 in the storage called "i", and sets up the operation of
+the following NEXT (every FOR must have a NEXT). When "NEXT i" is
+executed, the value in "i" is increased by 1 (which is the default
+STEP size) and compared to the value 9 (which is the ending value
+for this loop). If the resulting "i" is less than or equal to 9,
+the statement(s) following that FOR... is (are) executed.
+</para>
+<para>
+Loops can be "nested" to execute the enclosed statements even
+more times. For example, the PRINT statement in "multable" is
+executed 81 times; once for each of 9 values of "j" and this number
+(9 times) for each of 9 values of "i". The ability to tremendously
+increase the number of times some code is executed is at the heart
+of both computer programming and computer errors. It means that
+a vary small portion of a program can often be made to do the vast
+majority of the work. But a few remaining special cases may require
+individual handling and may consume more programming and code than
+that which "usually" works. Unfortunately, "usually" is not
+sufficient. A special case which occurs once in a thousand times
+may occur once a second, and if the error stops the program, further
+processing of normal values also stops. Experience has indicated
+that the programmer should know what is happening in the first and
+second pass, and the next-to-the-last and last pass through each
+loop in the program.
+</para></sect1>
+<sect1><title>Listing Procedure Names</title>
+<para>
+The "DIR" command causes &b09; to display the names and sizes
+of all procedures in memory. This command is used so frequently
+that there is a quick shorthand for DIR: a simple &lt;cr> when in
+command mode does the same thing. You will see
+a table of all procedure names and two numbers next to each
+name. The first column, "proc size", is the size of the corresponding
+procedure. The "data size" column shows the amount of memory that the
+procedure requires for its variables.
+On the last line this command shows the amount of free bytes of workspace memory
+remaining. You can use this information to estimate how much memory
+your program needs to run. You must have at least as much free memory as
+the <emphasis>data size</emphasis> of the procedure(s) to be run. If a data size number is
+followed by a question mark, you need more memory.
+</para>
+</sect1>
+<sect1>
+<title>Requesting More Memory</title>
+<para>
+&b09; automatically get 4K of workspace memory from
+OS-9 when it starts up. There is almost always more than this
+available, but &b09; does not grab it all so other tasks running
+on your computer can have memory too. If you are not multitasking
+and need more memory, the MEM command can get it if available.
+Just type MEM and the amount of memory you want. Depending on your
+computer and how it is configured, you can usually get at least 24K
+in OS-9 Level One Systems or 40K in OS-9 Level Two systems. For
+example:
+<programlisting>
+MEM 20000
+</programlisting>
+
+requests 20.000 (20K) bytes of memory. &b09; will always round the
+amount you request up to the next highest multiple of 256 bytes. If MEM
+responds with "WHAT?", this means that much memory is not
+available. There is another convenient way to do the same thing
+when you first call up &b09; from OS-9.  OS-9 has a
+"#" <emphasis>memory size option</emphasis> on command lines
+that let you specify how much memory to give the program.
+To call &b09; with 16K of memory to start with, you can type:
+<programlisting>
+OS9: basic #16k
+</programlisting>
+</para>
+</sect1>
+<sect1>
+<title>Storing and Recalling Programs</title>
+<para>
+Nobody wants to retype a whole program every time it is to be
+run. Two commands, SAVE and LOAD, are used to store programs and
+recall previously "SAVEd" programs to or from OS-9 disk files. The
+simples way to use SAVE is by itself. It will store the procedure
+last edited or run on a disk file having the same name. For
+example:
+<programlisting>
+B: save
+</programlisting>
+If our procedure name was the default name "PROGRAM", &b09; will
+create a file called "PROGRAM" to hold it. OS-9 won't let you have
+two files of the same name because unique names are necesary to
+identify the specific file you want. Therefore if a file called
+"PROGRAM" already exists, &b09; will ask you:
+<screen>
+Overwrite?
+</screen>
+If you respond "Y" for YES, it will replace the file previously
+stored on that file with the program to be saved. This is OK if
+what you want to save is a never version of the same program. But if
+not you will permanently erase another program you may have wanted
+to keep. If this is the case answer "N" for NO. Fortunately, there
+is a simple way to store the procedure on a file using a different
+name: just type SAVE, a ">", and a different file name of your
+choice. The file can consist of any combination of up to
+thirty-one letters, numbers, periods, or underscores ("_"). The only
+restriction is that the name must start with a letter A-Z or a-z.
+For example:
+<programlisting>
+save >newprogram5
+</programlisting>
+will save the program on a file called "newprogram5". There are
+several useful variations of the SAVE command that let you save
+various combinations of programs on the same file. See the SAVE
+command description for more information. You should also read
+Chapter 2 of the "OS-9 Users Manual" to learn about the OS-9
+commands that deal with disk files.
+</para>
+<para>
+If you exit from &b09;, it will not automatically save your
+programs. You must make sure to save them before you quit, or they
+will be lost unless the were saved at some time before!
+</para>
+<para>
+The LOAD command, as it's name implies, reads in a previously
+save program from a file. You must give the name of the file with 
+the command. For example:
+<informalexample>
+<programlisting>
+load program
+</programlisting>
+</informalexample>
+If you just started &b09; and have not created any procedures,
+the command is very straightforward. As the procedure(s) stored in
+the file are loaded, &b09; displays their name(s) as they are
+brought in. Once the program is loaded, you can edit and/or run
+it. But if you have a procedure in &b09; that has the same name
+as a procedure stored in the file, &b09; will replace it with the
+new version loaded from the file. If this kind of conflict exists
+you could loose your old program, so be sure to save or RENAME it
+before loading a new one (remember that &b09; can keep several
+procedures in memory at the same time as long as they have different
+names). If you want to permanently erase all other procedures
+before loading new ones, you can type:
+<programlisting>
+B: kill*
+</programlisting>
+This tells &b09; to "kill" all procedures in memory and has the
+same effect as completely resetting &b09;.
+</para>
+</sect1>
+<sect1>
+<title>How to Print Program Listings</title>
+<para>
+If your computer is equipped with a printer, you will want to
+make hard-copy listings of your programs. This is easy to do - just
+type:
+<programlisting>
+B: LIST* /p
+</programlisting>
+This tells &b09; to LIST all procedures in memory to the output
+device "/p" which is the printer device name in most OS-9 systems.
+Like the SAVE command, LIST has several useful variations. If you
+want to list just one procedure (if there are more than on in
+memory) you can type:
+<programlisting>
+B: LIST procedurename >/P
+</programlisting>
+If you want, you can put two or more procedure names (seperated by
+spaces) before the semicolon and those specific procedures will be
+listed.
+</para>
+<para>
+Notice that if you omit the "/p" or ">/p" from the commands above,
+the programs will be listed on your display instead of the printer.
+This is the same as the "L*" command in Edit Mode. You will also
+notice that the listing will be automatically "pretty-printed",
+e.g. program levels within loops are indented for easy reading.
+</para></sect1>
+<sect1><title>&b09;'s Four Modes:</title>
+<para>
+At any given time, &b09; is in one of four modes:
+
+<literallayout>
+SYSTEM MODE: Used for executing system commands.
+EDIT MODE: Used for creating/editing procedures.
+EXECUTION MODE: Used for running procedures.
+DEBUG MODE: Used for testing procedures for errors.
+</literallayout>
+So far, you have been exposed to System Mode (SAVE, LOAD, etc.),
+Edit Mode (the editor), and Execution Mode (RUN). A section of this
+manual is devoted to each mode. The chart below shows how various
+commands in each mode causes changes to other modes.
+
+<figure>
+<title>&b09; Mode Change Possibilities</title>
+<screen>
+   OS-9          SYSTEM MODE           EDIT MODE
+----------       ------------         ------------
+|        |       |          |         | +        |
+|        |       |  $       |         | -        |
+|        | &lt;-----+--&lt;eof>   |         | &lt;cr>     |
+|        | &lt;-----+--BYE     |         | &lt;line#>  |
+|        |       |  CHD     |         | &lt;space>  |
+|        |       |  CHX     |         | c        |
+|        |       |  DIR     |         | d        |
+|        |       |  EDIT----+-------> | l        |
+|        |       |  KILL    | &lt;-------+-q        |
+|        |       |  LIST    |         | r        |       ------------
+|BASIC09-+-----> |  LOAD    |         | s        |       | TRON     |
+|        |       |  MEM     |         ------------       | TROFF    |
+|        |       |  PACK    | &lt;--------------------------+ END or Q |
+|        |       |  RENAME  |                            | DEG/RAD  |
+|        |       |  RUN-----+-------> ------------       | STATE    |
+|        |       |  SAVE    | &lt;-------+-END      |       | $        |
+|        |       |          | &lt;-------+-&lt;CTRL Q> |       | BREAK    |
+|        |       ------------ &lt;-------+-STOP     | &lt;-----+-CONT     |
+|BASIC09 |                            | PAUSE----+-----> | DIR      |
+|AUTORUN-+--------------------------> | ERROR----+-----> | LET      |
+|        |                            | &lt;CTRL C>-+-----> | LIST     |
+|        | &lt;--------------------------+-BYE      |       | PRINT    |
+|        |                            | PROGRAM  | &lt;-----+-STEP     |
+----------                            ------------       ------------
+                                     EXECUTION MODE       DEBUG MODE
+</screen>
+</figure>
+</para>
+</sect1>
+<sect1><title>More about the Workspace...</title>
+<para>
+The workspace concept is important because &b09; and OS-9 are
+both highly modular systems, and the workspace is a way to logically
+group a set of procedures (i.e. modules) which are applicable to a 
+particular line of study or development. Modular software
+development lets the programmer divide a large and complex project
+into smaller, more manageable, and individually testable sections.
+Modularity also lets programmers accumulate and use libraries of
+commonly used routines.
+</para>
+<para>
+As the software is written and debugged, &b09; makes it easy
+to deal with the procedures that comprise an overall project, either
+individually or as a group. For example, you can save all procedures
+on the wrkspace to a single mass stoarage file or load a
+file containing multiple procedures. Usually all procedures
+associated witha project exists inside the workspace. However, you
+can also call library procedures which are "outside" the workspace
+in OS-9 memory module format. The library procedures can be written
+in &b09; or machine language, can be in RAM or ROM memory, and can
+even be shared by several users.
+</para>
+<para>
+&b09; always reserves approximately 1.2K bytes of the workspace
+for internal use. All remaining space is used for storage of
+procedures and for procedure variable storage during execution.
+&b09; will not run a procedure if there is not enough space for
+variables. If you run out of workspace area, you can use the MEM
+command to enlarge the workspace or you can kill procedures in the
+workspace that are not needed. The "MEM" command can be used at any
+time to change the size of the workspace. The size of the workspace
+can be increased (subject to availability of free memory) or
+decreased (but not below the minimal amount needed to store the
+present workspace).
+</para>
+</sect1>
+<sect1>
+<title>Where to go From Here?</title>
+<para>
+A good way to learn &b09; is to use it! Try typing in and
+running some of the example programs in the back of the book. Look
+at and study the function of each program statement. Read the chapters
+on the EDIT and DEBUG modes and experiment with more advanced
+commands. Also, &b09; and the OS-9 Operating System are so intimately
+connected, a basic understanding of OS-9 is important. See
+Chapter 2 of the "OS-9 User's Manual".
+</para>
+</sect1>
+</chapter>
+<chapter>
+<title>System Mode</title>
+<para>
+System mode includes commands to save, load, examine procedures;
+commands to interact with OS-9; and other commands to
+control the workspace environment. A complete list of system commands
+is given below.
+<table frame="none">
+<title>System Mode Commands</title>
+<tgroup cols="5">
+<tbody>
+<row>
+<entry>$</entry>
+<entry>CHX</entry>
+<entry>EDIT</entry>
+<entry>LOAD</entry>
+<entry>RENAME</entry>
+</row>
+<row>
+<entry>BYE</entry>
+<entry>DIR</entry>
+<entry>KILL</entry>
+<entry>MEM</entry>
+<entry>RUN</entry>
+</row>
+<row>
+<entry>CHD</entry>
+<entry>E</entry>
+<entry>LIST</entry>
+<entry>PACK</entry>
+<entry>SAVE</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+</para>
+<para>
+The system commands are processed by the &b09; "command interpreter"
+which always identifies itself with the "B:" prompt. It is entered
+automatically when &b09; is started up and
+whenever you exit any other mode. Commands can be entered in either upper or
+lower-case letters.
+Commands such as DIR, MEM, "$", and BYE don't operate on specific
+procedures, but may have optional or required parameters. Other commands
+(such as SAVE, LOAD, PACK, KILL, and LIST) can operate on a specific
+procedure or on ALL procedures within the workspace.
+If the command is used with a specific procedure name, the command is
+applied to only that procedure. For example:
+<informalexample>
+<programlisting>
+list pete
+</programlisting>
+</informalexample>
+will display the procedure named "pete".
+The asterisk is a special name that means "all procedures in the
+workspace". Therefore, if the command is given follwed by an asterisk it
+is applied to all procedures. For example:
+<programlisting>
+list*
+</programlisting>
+will display all of the procedures in the workspace.
+</para>
+<para>
+If the command is given without any name at all, the "current" working
+procedure is used. This means the name of the procedure
+last given in another command. The DIR command prints an asterisk
+before its name so it can be found at any time.
+If you have not yet given a name in any command, 
+the name "PROGRAM" is automatically used. Some commands that require a file
+name as well as (one or
+more) procedure names require that a ">"
+precede the file name so it is not mistaken for a procedure name. If
+you omit the file name, the name of the (first) procedure is used instead.
+In this manual, the phrase file name means an OS-9 "pathlist"
+which can describe either a file or device.
+</para>
+<para>
+Here are some examples:
+<programlisting>
+SAVE tom bill >myfile
+SAVE* big_file
+</programlisting>
+or
+<programlisting>
+SAVE tic tac toe
+</programlisting>
+which is exactly equivalent to
+<programlisting>
+SAVE tic,tac,toe >tic
+</programlisting>
+
+Another class of commands use only one procedure name, or the
+current working name if a name is omitted. These commands change
+the mode of &b09; by exiting the command mode and entering another mode.
+These commands are:
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="1in">
+<tbody>
+<row>
+<entry>RUN</entry>
+<entry>which enters Execution Mode to run a procedure</entry>
+</row>
+<row>
+<entry>EDIT</entry>
+<entry>which enters Edit Mode to create or change a procedure</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+The one other mode, Debug Mode, cannot be entered directly from the
+system mode &mdash; more on this later.
+</para>
+<bridgehead renderas="sect2">
+Syntax Notation Used in System Command Descriptions</bridgehead>
+<para>
+Individual descriptions of the available commands in each mode follow. In
+order to precisely describe their formats, the syntax notation shown below
+is used.
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="1.3in">
+<tbody>
+<row>
+<entry>[ ]</entry>
+<entry>things in brackets are optional.</entry>
+</row>
+<row>
+<entry>{ }</entry>
+<entry>things in braces can be optionally repeated.</entry>
+</row>
+<row>
+<entry>&lt;procname></entry>
+<entry>means a procedure name</entry>
+</row>
+<row>
+<entry>&lt;pathlist></entry>
+<entry>An OS-9 file name</entry>
+</row>
+<row>
+<entry>&lt;number></entry>
+<entry>A decimal or hex number</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</para>
+<sect1>
+<title>System Mode Commands</title>
+<para>
+<cmdsynopsis>
+<command>$ [&lt;text>]   ("Shell" Command)</command>
+</cmdsynopsis>
+This command calls the OS-9 Shell command interpreter to process an OS-9
+command or to run another program. Running the OS-9 command does not
+cause &b09; or its workspace to be disturbed.
+</para>
+<para>
+If the "$" is followed by text, the Shell is called to process the
+text as a single OS-9 command line. After the command is executed,
+&b09; is immediately re-entered.
+</para>
+<para>
+If no text is specified, &b09; is suspended, and the OS-9 Shell is called to
+process multiple command lines individually entered from the keyboard.
+Control is returned to &b09; when an end-of-file character (usually ESCAPE) is
+entered. The contents of the &b09; workspace is not affected. This is a
+convenient way to temporarily leave &b09; to manipulate files or perform
+other housekeeping tasks.
+</para>
+<para>
+This command is the "gateway" to OS-9 from inside &b09;. It allows access to
+any OS-9 command or to other programs. It also permits creation of
+concurrent processes and other real-time functions.
+</para>
+<para>
+Examples:
+<informalexample>
+<literallayout>
+B: $copy file1 file2                    Calls the OS-9 copy command
+B: $asm sourcefile&amp;                 Calls the assembler as a <emphasis>background</emphasis> task
+B: $basic09 fourier(20)&amp;            Starts <emphasis>another</emphasis> concurrent &b09; program
+</literallayout>
+</informalexample>
+</para>
+<cmdsynopsis><command>BYE (or ESCAPE character)</command>
+</cmdsynopsis>
+<para>
+Exits &b09; and returns to OS-9 or the program that called &b09;.
+Any procedures in the workspace are lost if not previously saved. The
+escape key (technically speaking, an end-of-file character condition on
+&b09;'s standard input path) does the same thing.
+</para>
+<cmdsynopsis><command>CHD &lt;pathlist> or CHX &lt;pathlist></command>
+</cmdsynopsis>
+<para>
+
+Changes the current OS-9 user Data 
+or Execution Directory to the specified pathlist
+which must be a directory file. &b09; uses the Data Directory to LOAD or
+SAVE procedures.  The Execution Directory is used to
+PACK or auto-load packed modules.
+</para>
+<para>
+Example:
+<informalexample>
+<programlisting>
+CHD /d1/joe/games
+</programlisting>
+</informalexample>
+
+
+</para>
+<cmdsynopsis><command>DIR [&lt;pathlist>]</command>
+</cmdsynopsis>
+<para>
+Displays the name, size, and variable storage requirement of each
+procedure presently in the workspace. The current working procedure has
+an asterisk before its name. All packed procedures have a dash before their
+name (see PACK). The available free memory within the workspace is also
+given. If a pathlist is specified, output is directed to that file or device.
+</para>
+<para>
+A question mark next to a data storage size means the workspace does not
+have enough free memory to run that procedure.
+</para>
+<para>
+Note: This command should not be confused with the OS-9 "DIR" command.
+They have completely different functions.
+</para>
+
+<cmdsynopsis>
+<command>EDIT [&lt;procname>]</command>
+<sbr>
+<command>E [&lt;procname>]</command>
+</cmdsynopsis>
+<para>
+
+Exits command mode and enters the text editor/compiler mode. If the specified
+procedure does not exist, a new one is created. See the Chapter 4 for a
+complete description of how edit mode works.
+</para>
+<para>
+Examples:
+<informalexample>
+<programlisting>
+E newprog
+EDIT printreport
+</programlisting>
+</informalexample>
+
+</para>
+<cmdsynopsis>
+<command>KILL [&lt;procname> {,&lt;procname>}]</command>
+<sbr>
+<command>KILL*</command>
+</cmdsynopsis>
+<para>
+Erases the procedure(s) specified. KILL* clears the
+entire workspace. The process may take some time if there are many
+procedures in the workspace.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+kill formulas
+kill prog1, prog2, prog7
+</programlisting>
+</informalexample>
+</para>
+
+<cmdsynopsis>
+<command>LIST [&lt;procname> {,&lt;procname>}] [> &lt;pathlist>]</command>
+<sbr>
+<command>LIST* [&lt;pathlist>]</command>
+</cmdsynopsis>
+<para>
+Prints a formatted "pretty printed" listing of one or more procedures.
+The listing includes
+the relative I-code storage addresses in hexadecimal format in the first
+column. The second column is reserved for program line numbers (if line
+numbers are used).
+</para>
+<para>
+If a pathlist is given, the listing is output to that file or device. This option
+is commonly used to print hard-copy listings of programs.
+
+The LIST, SAVE and PACK commands all have identical syntax, except
+that LIST prints on the OS-9 standard error path (#2) if no pathlist is given.
+The files produced are formatted differently, but the function is similar.
+
+<important>
+<para>
+If an "*" is used with LIST, SAVE or PACK, the file name
+immediately follows WITHOUT a greater-than sign ">" before it!
+</para>
+</important>
+
+Examples:
+
+<informalexample>
+<programlisting>
+list* /p
+list prog2,prog3 >/p
+list prog5 >temp
+</programlisting>
+</informalexample>
+
+</para>
+
+<cmdsynopsis>
+<command>LOAD &lt;pathlist></command>
+</cmdsynopsis>
+<para>
+Loads all procedures from the specified file into the workspace. As
+procedures are loaded, their names are displayed. If any of the procedures
+being loaded have the same name as a procedure already in the workspace,
+the existing procedures are erased and replaced with the procedure
+being loaded.
+</para>
+<para>
+If the workspace fills up before the last procedure in the file is loaded, an
+error (#32) is given. In this case, not all procedures may have been loaded,
+and the one being loaded when the workspace became full may not be
+completely loaded. You should KILL the last procedure, use the MEM
+command to get more memory or KILL unnecessary procedure(s) to free
+up space, and then LOAD the file again.
+</para>
+<para>
+Example:
+
+<informalexample>
+<programlisting>
+load quadratics
+</programlisting>
+</informalexample>
+
+</para>
+<cmdsynopsis>
+<command>MEM</command>
+<sbr>
+<command>MEM [&lt;number>]</command>
+</cmdsynopsis>
+<para>
+MEM used without a number displays the present total workspace size in
+(decimal) bytes. If a number is given, &b09; asks OS-9 to expand or
+contract the workspace to that size. A hex value can be used if preceded by
+a dollar sign. If MEM responds with What?, you either asked for more
+memory than is available, tried to give back too much memory (there has
+to be enough to store all procedures in the workspace), or gave an
+invalid number.
+</para>
+<para>
+Example:
+
+<informalexample>
+<programlisting>
+MEM 18000
+</programlisting>
+</informalexample>
+
+</para>
+<cmdsynopsis>
+<command>PACK [&lt;procname> {,&lt;procname>}] [> &lt;pathlist>]</command>
+<sbr>
+<command>PACK* [&lt;pathlist>]</command>
+</cmdsynopsis>
+<para>
+This command
+ causes an extra compiler pass on the procedure(s) specified, which
+removes names, line numbers, non-executable statements, etc. The result is
+a smaller, faster procedure(s) that CANNOT be edited or debugged but can be
+executed by &b09; or by the &b09; run-time-only program called "RunB".
+If a pathlist is not given, the name of the first procedure in the list will be
+used as a default pathname.
+The procedure is written to the file/device specified in OS-9 memory
+module format suitable for loading in ROM or RAM outside the
+workspace.
+THE RESULTING FILE CANNOT BE LOADED INTO THE WORKSPACE LATER ON,
+so you should always perform a regular SAVE before PACKing a procedure!
+</para>
+<para>
+&b09; will automatically load the packed procedure when you try
+to run it later. Here is an example sequence that demonstrates packing a
+procedure:
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="2in">
+<tbody>
+<row>
+<entry>pack sort</entry>
+<entry>packs procedure sort and creates a file</entry>
+</row>
+<row>
+<entry>kill sort</entry>
+<entry>kills procedure inside the workspace</entry>
+</row>
+<row>
+<entry>run sort</entry>
+<entry>run (sort is loaded outside of the workspace)</entry>
+</row>
+<row>
+<entry>kill sort</entry>
+<entry>done; delete "sort" from outside memory</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+The last step (kill) does not have to be done immediately if you will use the
+procedure again later, but you should kill it when you are done so its
+memory can be used for other purposes.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+pack proc1,proc2 >packed.programs
+
+pack* packedfile
+</programlisting>
+</informalexample>
+</para>
+
+<cmdsynopsis>
+<command>RENAME &lt;procname>,&lt;new procname></command>
+</cmdsynopsis>
+<para>
+
+Changes the name of a procedure. Can be used to allow two
+copies of the same procedure in the workspace under different names.
+</para>
+<para>
+Example:
+
+<informalexample>
+<programlisting>
+rename thisproc thatproc
+</programlisting>
+</informalexample>
+</para>
+
+<cmdsynopsis>
+<command>RUN [&lt;procname> [ ( &lt;expr> , {&lt;expr>} ) ]]</command>
+</cmdsynopsis>
+<para>
+Runs the procedure specified. Technically speaking, &b09; then
+leaves Command mode and enters Execution mode.
+</para>
+<para>
+A parameter list can be used to pass expected parameters to the procedure
+in the same way a RUN statement inside a
+procedure calls another procedure except for the restriction that all
+parameters must be constants or expressions without variables. See the
+PARAM statement description.
+Assembly language procedures cannot be run from command mode.
+</para>
+<para>
+The procedure called can be normal or "packed". If the procedure is not
+found inside &b09;'s workspace, &b09; will call OS-9 to attempt to LINK
+to an external (outside the workspace) module. If this fails, &b09;
+attempts to LOAD the procedure from a file of the same name.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+run getdata
+
+run invert("the string to be inverted")
+
+run power(12,354.06)
+
+run power($32, sin(pi/2))
+</programlisting>
+</informalexample>
+</para>
+
+<cmdsynopsis>
+<command>SAVE [&lt;procname> { &lt;procname>} [> &lt;pathlist>]]</command>
+<sbr>
+<command>SAVE* [&lt;pathlist>]</command>
+</cmdsynopsis>
+<para>
+Writes the procedure(s) (or all procedures) to an output
+file or device in source format. SAVE is similar to the LIST command
+except the output is not formatted and I-code addresses are not included. If
+a pathlist is not specified, it defaults to the name of the first
+procedure listed.
+</para>
+<para>
+If a file of the same name already exists, SAVE will prompt with:
+<screen>
+rewrite?
+</screen>
+You may answer "Y" for yes which causes the existing file to be rewritten
+with the new procedure(s); or "N" to cancel the SAVE command.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+save proc2 proc3 proc4 >monday.work
+
+save* newprogram
+
+save
+
+save  >testprogram
+</programlisting>
+</informalexample>
+</para>
+</sect1>
+</chapter>
+<chapter>
+<title>Edit Mode</title>
+<para>
+Edit Mode (also called "The Editor") is used to enter or modify
+&b09; procedures. It is entered from Command Mode by the EDIT (or E) command.
+As soon as Edit Mode is entered, prompts change from "B:" to "E:"
+If you have used a
+text editor before, you will find the &b09; editor similar to many others
+except for these two differences:
+
+<orderedlist  numeration="arabic">
+<listitem>
+<para>
+The editor is both "string" and "line number" oriented. The use of line numbers
+is optional and text can be corrected without re-typing the entire line.
+</para>
+</listitem>
+  
+<listitem>
+<para>
+The editor is interfaced to the &b09; compiler and "decompiler". This
+lets &b09; do continuous syntax error checking and permits
+programs to be stored in memory in a more compact, compiled form.
+</para>
+</listitem>
+</orderedlist>
+
+</para>
+<sect1><title>Overview of Edit Commands</title>
+<para>
+The Editor includes the following commands. Each command is described
+in detail later in this chapter.
+
+<table frame="none">
+<title>Edit Mode Commands</title>
+<tgroup cols="2">
+<colspec colwidth="2in">
+<tbody>
+<row>
+<entry>&lt;cr></entry>
+<entry>move edit pointer forward</entry>
+</row>
+<row>
+<entry>+</entry>
+<entry>move edit pointer forward</entry>
+</row>
+<row>
+<entry>+*</entry>
+<entry>move edit pointer to end of text</entry>
+</row>
+<row>
+<entry>&minus;</entry>
+<entry>move edit pointer backward</entry>
+</row>
+<row>
+<entry>&minus;*</entry>
+<entry>move edit pointer to beginning of text</entry>
+</row>
+<row>
+<entry>&lt;space> &lt;text></entry>
+<entry>insert unnumbered line</entry>
+</row>
+<row>
+<entry>&lt;line#> &lt;text></entry>
+<entry>insert or replace numbered line</entry>
+</row>
+<row>
+<entry>&lt;line#> &lt;cr></entry>
+<entry>find numbered line</entry>
+</row>
+<row>
+<entry>c</entry>
+<entry>change string</entry>
+</row>
+<row>
+<entry>c*</entry>
+<entry>change all occurence of string</entry>
+</row>
+<row>
+<entry>d</entry>
+<entry>delete line</entry>
+</row>
+<row>
+<entry>d*</entry>
+<entry>delete all lines</entry>
+</row>
+<row>
+<entry>l</entry>
+<entry>list line(s)</entry>
+</row>
+<row>
+<entry>l*</entry>
+<entry>list all lines</entry>
+</row>
+<row>
+<entry>q</entry>
+<entry>quit editing</entry>
+</row>
+<row>
+<entry>r</entry>
+<entry>renumber line</entry>
+</row>
+<row>
+<entry>r*</entry>
+<entry>renumber all lines</entry>
+</row>
+<row>
+<entry>s</entry>
+<entry>search for string</entry>
+</row>
+<row>
+<entry>s*</entry>
+<entry>search for all occurence of string</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+
+</para></sect1>
+<sect1><title>How the Editor Works</title>
+<para>
+In order to understand how the editor works it is helpful to
+have a general idea of what goes on inside &b09; while you are
+editing procedures.  &b09; programs are always stored in memory
+in a compiled form called
+"I-code" (short for "Intermediate Code"). I-code is a complex binary coding
+system for programs that lies between your original "source" program and
+the computer's native "machine language". I-code is relatively compact, can
+be executed rapidly, and most importantly, can be reconstructed almost exactly
+back to the original source program. The Editor is closely connected to the
+"compiler" and "decompiler" systems within &b09; that translate source code
+to I-Code and vice-versa.
+It is this innovative system that gives &b09; its most powerful and unusual
+abilities.
+</para>
+<para>
+Whenever you enter (or change) a program line and "return", the
+compiler instantly translates this text to the internal I-code form. When
+&b09; needs to display program lines back, it uses the decompiler to translate the
+I-code back to the original "source" format. These processes are completely
+automatic and do not require any special action on your part.
+</para>
+<para>
+This technique has several advantages. First,
+it allows the text editor to report many (syntax) errors immediately so
+you can correct them instantly. Secondly,
+the I-code representation of a program is more compact (by about 30%)
+than its original form, so you can have have larger programs in any
+given amount of available memory.
+</para>
+<para>
+When programs are listed by &b09;, it is possible they will have a
+slightly different appearance than the
+way they were originally typed in, but they will
+<emphasis>always</emphasis> be functionally
+identical to the original form. This can happen if the
+original program had extraneous spaces between keywords, unnecessary
+parentheses in expressions, etc. &b09; keywords are always automatically
+capitalized.
+</para>
+<para>
+When you have finished editing the procedure, use the "q" (for "quit")
+command to
+exit edit mode and return to the command mode. When you give the "q" command,
+the compiler performs another "pass" over the entire procedure again.
+At this time syntax
+that extends over multiple lines is checked and errors reported. Examples
+of these errors are: GOTO or GOSUB to a non-existent line,
+missing variable or array declarations, improperly constructed loops, etc.
+These errors are reported using an error code and the hexadecimal I-code
+address of the error. For example:
+<screen>
+01FC ERR #043
+</screen>
+This message means that error number 43 was detected in the line that
+included I-code address 01FC (hexadecimal). The LIST command gives
+the I-code addresses so you can locate lines with errors reported during the
+compiler's second pass.
+</para></sect1>
+<sect1><title>Line-Number Oriented Editing</title>
+<para>
+As mentioned previously, the editor has the capability to work
+on programs with or without line numbers (or both).
+Line numbers must be positive whole numbers in the range of 1 to 32767.
+</para>
+<para>
+If you have experience with another version of the BASIC language, this is the kind of
+editing you probably used. However, well-structured programs seldom
+really need line numbers. If you don't have to use line numbers, don't.
+Your programs will be shorter, faster, and easier to read.
+</para>
+<para>
+The line-number oriented commands are:
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="2in">
+<tbody>
+<row>
+<entry>&lt;line#> &lt;text></entry>
+<entry>insert or replace numbered line</entry>
+</row>
+<row>
+<entry>&lt;line#> &lt;cr></entry>
+<entry>find numbered line</entry>
+</row>
+<row>
+<entry>d</entry>
+<entry>delete line</entry>
+</row>
+<row>
+<entry>r</entry>
+<entry>renumber line</entry>
+</row>
+<row>
+<entry>r*</entry>
+<entry>renumber all lines</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</para>
+<para>
+To enter or replace a numbered line, simply type in the line
+number and statement. Numbered lines can be entered in any order, but will
+be automatically stored in ascending sequence. To move to a numbered
+line, type the line number followed by a carriage return. The editor will move
+to that line (or the line with the next higher number if the specified number
+is not found) and print it. The line may be deleted using the "d" command.
+</para>
+<para>
+The "r" renumber command will uniformly resequence all numbered lines and
+lines that refer to numbered lines. Its formats are:
+<programlisting>
+r [ &lt;beg line #>  [,&lt;incr> ] ] &lt;CR>
+r*[ &lt;beg line #>  [,&lt;incr> ] ] &lt;CR>
+</programlisting>
+
+The first format renumbers the program starting at the current line and
+forward. Lines are renumbered using
+&lt;beg line#> as the initial line number. &lt;incr> is added to the previous line
+number for the next line's number. For example,
+<programlisting>
+r 200,5
+</programlisting>
+will give the first line number 200, the second 205, the third 210, etc.
+If &lt;beg line#> and/or &lt;incr> are not
+specified, the values 100 and 10, respectively, are assumed.
+The second form of the command is identical exect it renumbers all lines in the procedure.
+
+</para></sect1>
+<sect1><title>String-Oriented Editing</title>
+<para>
+
+
+Most editor commands are string-oriented. This means that you can enter or
+change whole or partial lines without using line numbers at all.  You will
+find that string-oriented editing is generally faster and more convenient.
+</para>
+<para>
+Because line numbers are not used, there has to be another way
+to tell &b09; what place in the program to work on. To do this,
+the editor maintains an "edit pointer" that
+indicates which line is the present working location within the procedure,
+and commands start workin at this point.
+The editor shows you the location of the edit pointer by displaying an
+"*" at the left side of the program line where the edit pointer is
+presently located.
+</para>
+<sect2><title>Moving the Edit Pointer</title>
+<para>
+The "+" and "&minus;" are used to reposition the edit pointer:
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="2in">
+<tbody>
+<row>
+<entry>&minus;</entry>
+<entry>moves backward one line</entry>
+</row>
+<row>
+<entry>&minus; &lt;number></entry>
+<entry>moves backward n lines</entry>
+</row>
+<row>
+<entry>&minus;*</entry>
+<entry>moves to the beginning of the procedure</entry>
+</row>
+<row>
+<entry>+</entry>
+<entry>moves forward one line</entry>
+</row>
+<row>
+<entry>+ &lt;number></entry>
+<entry>moves forward N lines</entry>
+</row>
+<row>
+<entry>+*</entry>
+<entry>moves to the end of procedure</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+The number indicates how many lines to move. Backward means
+towards the first line of the procedure. If the number is omitted,
+a count of one is used (this is true of most edit commands).
+A line consisting of a carriage return only also moves the pointer forward one
+line, which makes it easy to step through a program one line at a time.
+Therefore, the following commands all do the same thing:
+
+<programlisting>
+&lt;CR>
++ &lt;CR>
++1 &lt;CR>
+</programlisting>
+
+
+</para></sect2>
+<sect2><title>Inserting Lines</title>
+<para>
+The Insert Line function consists of a "space" followed by a &b09; statement
+line. The statement is inserted just ahead of the edit pointer position. (the
+space itself is not inserted).
+</para></sect2>
+<sect2><title>Deleting Lines</title>
+<para>
+
+
+The "d" command is used to delete one or more lines. Its format is:
+
+<programlisting>
+d [&lt;number>] &lt;CR>
+d*
+</programlisting>
+
+The first form deletes the &lt;number> of lines starting at the current edit
+pointer location.
+The second form deletes ALL lines in the procedure (caution!).
+The editor accepts
+"+*" and "&minus;*" to mean to the end, or to the beginning of the procedure
+respectively. If the number is negative, that many lines BEFORE the
+current line is deleted.
+If a line number is omitted, only the current line is deleted.
+</para></sect2>
+<sect2><title>Listing Lines</title>
+<para>
+
+
+The "l" command is used to display one or more lines.
+It also has the forms:
+<programlisting>
+l [&lt;number>] &lt;CR>
+l*
+</programlisting>
+The first form will display the &lt;number> of lines starting at the current
+edit pointer position. If the number is NEGATIVE, previous lines
+will be listed.
+
+The second form displays the entire procedure. Neither change the
+edit pointer's position. The line that is the present position of the edit
+pointer is displayed with a leading asterisk.
+
+</para></sect2>
+<sect2><title>Search: Finding Strings</title>
+<para>
+What's a string?  A string is a sequence of one or more characters that
+can include letters, numbers, or punctuation in any combination. Strings
+are very usefull because they allow you to change or locate just part
+of a statement without having to type the whole thing.
+
+In the Editor, strings must be surrounded by two matching punctuation
+characters (called <emphasis>delimiters</emphasis>) so the editor
+knows where the string begins and ends.
+The characters used for delimiters are not considered part of the string
+and cannot also appear within the string.
+Strings used by the Editor should not be confused with &b09;'s data type
+which is also called STRING &mdash; they are different creatures.
+</para>
+<para>
+The "s" command may be used to locate the next occurrence or all
+occurrences of a string. The format for this command is:
+
+<programlisting>
+s &lt;delim> &lt;match str> [&lt;delim>] &lt;CR>
+s*&lt;delim> &lt;match str> [&lt;delim>] &lt;CR>
+</programlisting>
+
+The first format searches for the &lt;match str> starting on the current
+edit pointer line onward.  If any line at or following the edit pointer
+includes a sequence of characters that match the search string, the edit
+pointer is moved to that line and the line is displayed. If the string
+cannot be located, the message:
+
+<screen>
+CAN'T FIND: "&lt;match str>"
+</screen>
+will be displayed and the edit pointer will remain at its original
+position.  The "s*" variation searches for all occurrences of the string
+in the procedure starting at the present edit pointer and displays all
+lines it is found in.  The edit pointer ends up at the last line the
+string occurred in.
+</para>
+<para>
+Here are some examples:
+
+<informalexample>
+<programlisting>
+E:s/counter/             Looks for the string: counter
+
+E:s.1/2.                 Looks for the string: 1/2
+
+E:s?three blind mice?    Looks for the string: three blind mice
+</programlisting>
+</informalexample>
+</para></sect2>
+<sect2><title>Change: String Substitution</title>
+<para>
+The "c" change string function is a very handy tool that
+can eliminate a tremendous amount of typing.
+It allows strings within lines to be located, removed, and replaced by
+another string. This command is very commonly used for things like:
+fixing lines with errors
+without having to retype the entire line, changing a variable name
+throughout a program, etc. Its formats are:
+<programlisting>
+c &lt;delim> &lt;match str> &lt;delim> &lt;repl str> [&lt;delim>] &lt;CR>
+c*&lt;delim> &lt;match str> &lt;delim> &lt;repl str> [&lt;delim>] &lt;CR>
+</programlisting>
+In the first form, the editor looks for the first occurrence of the
+match string starting at the present edit pointer position. If found,
+the match string is removed from the line and the replacement string is
+inserted in its place.  The second form works the same way, but changes
+ALL occurrences of the match string in the procedure starting at the
+present edit pointer position.
+</para>
+<para>
+The "c*" command will stop anytime it finds or causes a line with an error.
+It cannot be used to find or change line numbers.
+</para>
+<para>
+A word of warning:
+sometimes you can inadvertently change a line you did't
+intend to change because the match string is imbedded in a longer string.
+For example, if you attempt to change "no" to "yes" and the word "normal"
+occurs before the "no" you are looking for, "normal" will change to "yesrmal".
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+c/xval/yval/
+c*,GOSUB 5300,GOSUB 5500
+</programlisting>
+</informalexample>
+</para>
+</sect2>
+</sect1>
+</chapter>
+
+
+<chapter>
+<title>Execution Mode</title>
+
+<sect1><title>Running Programs</title>
+<para>
+To run a &b09; procedure, enter:
+
+<programlisting>
+RUN &lt;procname>
+</programlisting>
+
+If the procedure you want to run was the last procedure edited, listed,
+saved, etc., you can type RUN without giving a procedure name (the
+"*" shown in the DIR command identifies this procedure).
+</para>
+<para>
+If the procedure expects <emphasis>parameters</emphasis> (see Chapter 7),
+they can be given on the same
+command line, however they must all be constant numbers or strings, as
+appropriate, and must be given in the correct order. For example:
+
+<programlisting>
+RUN add(4,7)
+</programlisting>
+
+is used to call a program that expects parameter, such as
+<programlisting>
+PROCEDURE add
+PARAMETER a,b                a,b will receive the values 4,7
+PRINT a+b
+END
+</programlisting>
+
+The ability to pass parameters to a program allows you to specifically
+initialize program variables. Sometimes certain procedures are parts of a
+larger software system and are designed to be called from other
+procedures. You can use this feature to individually test such procedures by
+passing them test values as parameters.
+</para>
+<para>
+The RUN statement causes &b09; to enter <emphasis>Execution Mode</emphasis>,
+causing the procedure to run until one of the these things happen:
+<orderedlist numeration="arabic">
+<listitem><para>an END or STOP statement is executed</para></listitem>
+<listitem><para>you type [Ctrl-E]</para></listitem>
+<listitem><para>a run-time error occurs</para></listitem>
+<listitem><para>you type [Ctrl-C] (keyboard interrupt)</para></listitem>
+</orderedlist>
+In cases 1 and 2, you will return to system mode. In 
+cases 3 and 4, you will enter DEBUG mode.
+</para></sect1>
+<sect1><title>Execution Mode: Technically Speaking</title>
+<para>
+
+
+The RUN statement is simple and normally you do not need to know what
+is happening inside &b09; when you use it. The technical description of
+execution mode that follows is given for the benefit of advanced
+&b09; programmers.
+</para>
+<para>
+Execution mode is &b09;'s state when you run any procedure. It involves
+executing the I-code of one or more procedures inside or outside the
+workspace. Many procedures can be in use because they can call each
+other (or themselves) and nest exactly like subroutines.
+
+You can enter execution mode in a number of ways:
+<orderedlist numeration="arabic">
+<listitem><para>By means of the RUN system command.</para></listitem>
+<listitem><para>By &b09;'s auto-run feature.</para></listitem>
+</orderedlist>
+The Auto-run feature allows &b09; to get the name of a file to load and
+run from the same command line used to call &b09;. The file loaded and run
+can be either a SAVED file (in the data directory), or a PACKED file (in the
+execution directory). The file may contain several procedures; the one
+executed is the one with the same name as the file. Parameters may be
+passed following the pathname specified. For
+example, the following OS-9 command lines use this feature:
+
+<programlisting>
+OS9: &b09; printreport("Past Due Accounts")
+OS9: &b09; evaluate(COS(7.8814)/12.075,&minus;22.5,129.055)
+</programlisting>
+
+</para>
+</sect1>
+</chapter>
+
+
+<chapter>
+<title>Debug Mode</title>
+<sect1><title>Overview of Debug Mode</title>
+<para>
+One of &b09;'s outstanding features is its set of powerful <emphasis>symbolic
+debugging</emphasis> commands. What is Symbolic Debugging? Simply
+stated, it is testing and manipulation of programs using the
+actual names and program statements used in the program.
+In this chapter you will learn how Debug Mode can let you watch your
+program run in slow motion you can observe each statement as
+it is executed. As a bonus, you will also learn how to use the Debug Mode as
+a calculator.
+</para>
+<para>
+Debug mode is entered from execution mode in one of three ways:
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+When an error occurs during execution of a procedure (that is not
+intercepted by an ON ERROR GOTO statement within the program).
+</para>
+</listitem>
+<listitem>
+<para>
+When a procedure executes a PAUSE statement.
+</para>
+</listitem>
+<listitem>
+<para>
+When a keyboard interrupt (control-C) occurs.
+</para>
+</listitem>
+</orderedlist>
+</para>
+<para>
+When any of the above happen, Debug Mode announces itself by
+displaying the suspended procedure name like this:
+<programlisting>
+BREAK: PROCEDURE test5
+D:
+</programlisting>
+</para>
+<para>
+Notice that 
+Debug Mode displays a "D:" prompt when it is awaiting a
+command. Any debug mode commands can the be used to examine or
+change variables, turn trace mode on/off, etc. Depending on which
+commands are used, execution of the program can be terminated, resumed,
+or executed one source line at a time.
+</para></sect1>
+<sect1><title>Debug Mode Commands</title>
+<para>
+<cmdsynopsis>
+<command>$ &lt;text></command>
+</cmdsynopsis>
+Calls OS-9's Shell command interpreter to run a program or OS-9
+command. Exactly the same as the System Mode "$" command.
+
+<cmdsynopsis>
+<command>BREAK &lt;proc name></command>
+</cmdsynopsis>
+Sets up a "breakpoint" at the procedure named. This command is used
+when procedures call each other, and provides a way to re-enter Debug
+Mode when returning to a specific procedure.
+To illustrate how BREAK works, suppose there are three procedures in the
+workspace: PROC1, PROC2, and PROC3. Assume that PROC1 calls PROC2, which in
+turn calls PROC3. While PROC3 is executing, you type Control-C to enter
+debug mode. You can now enter:
+<programlisting>
+D: BREAK proc1
+ok
+D:
+</programlisting>
+Notice that BREAK responds with "ok" if the procedure was found on the
+current RUN stack. If you wish you can use the STATE command to verify that the
+three procedures are "nested" as expected.
+Now, you can resume execution of PROC3 by typing CONT. After PROC3 terminates,
+control passes back to PROC2, which eventually returns to PROC1. As soon as
+this happens, the breakpoint you set is encountered, PROC1 is suspended,
+and Debug Mode is reentered.
+</para>
+<para>
+There are three characteristics of BREAK you should note:
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+The breakpoint is removed as soon as it occurs.
+</para>
+</listitem>
+
+<listitem>
+<para>
+You can use one breakpoint for each active procedure.
+</para>
+</listitem>
+
+<listitem>
+<para>
+You can't put a breakpoint on a procedure unless it has been called but
+not yet returned to. Hence, BREAK cannot be used on procedures
+that have not yet been run.
+</para>
+</listitem>
+</orderedlist>
+
+<cmdsynopsis>
+<command>CONT</command>
+</cmdsynopsis>
+The command causes program execution to continue at the next
+statement. It may resume
+programs suspended by Control-C, PAUSE statements, BREAK command
+breakpoints, or after non-fatal run-time errors.
+
+<cmdsynopsis>
+<command>DEG</command>
+<sbr>
+<command>RAD</command>
+</cmdsynopsis>
+These commands select either degrees or radians as the angle unit
+measure used by trigonometric functions. These commands only affect
+the procedure currently being debugged or run.
+
+<cmdsynopsis>
+<command>DIR [&lt;path>]</command>
+</cmdsynopsis>
+Displays the workspace procedure directory in exactly the same way as the
+System Mode DIR command.
+
+<cmdsynopsis>
+<command>END or Q</command>
+</cmdsynopsis>
+Termintes execution of all procedures and exits Debug Mode by
+returning to System Mode. Any open paths are closed at this point.
+
+
+<cmdsynopsis>
+<command>LET &lt;var> := &lt;expr></command>
+</cmdsynopsis>
+This command is essentially the same as the &b09; LET program statement,
+which allows the value of a procedure variable to be set to a new value
+using the result of the evaluated expression. The variable names used
+in this command must be the same as in the original "source" program;
+otherwise, an error is generated. LET does not work on user-defined
+data structures.
+
+
+<cmdsynopsis>
+<command>LIST</command>
+</cmdsynopsis>
+Displays a formatted source listing of the suspended procedure with I-code
+addresses. An asterisk is printed to the left of the statement where
+the procedure is suspended. Only list the current procedure may be listed.
+
+
+<cmdsynopsis>
+<command>PRINT [#&lt;expr>,] [USING &lt;expr>,] &lt;expr list></command>
+</cmdsynopsis>
+This is exactly the same as the &b09; PRINT statement and can be used
+to examine the present value of variables in the suspended program. All
+variable names must be the same as in the original program, and no
+new variable names can be used. User-defined data structures cannot
+be printed.
+
+
+<cmdsynopsis>
+<command>STATE</command>
+</cmdsynopsis>
+
+
+
+This command
+lists the calling ("nesting") order of all active procedures. The
+highest-level procedure is always shown at the bottom of the calling list,
+and the lowest-level procedure will always be the suspended procedure.
+An example:
+<informalexample>
+<programlisting>
+D:state
+PROCEDURE DELTA
+CALLED BY BETA
+CALLED BY ALPHA
+CALLED BY PROGRAM
+</programlisting>
+</informalexample>
+
+
+<cmdsynopsis>
+<command>STEP [&lt;number>]   or   &lt;CR></command>
+</cmdsynopsis>
+This command allows the suspended procedure to be executed one or
+more source statements at a time.
+For example, "STEP 5" would execute the equivalent of the next 5 source
+statements. A debug command line which is just a carriage return is
+considered the same as "STEP 1". The STEP command is most commonly
+used with the trace
+mode on, so the original source lines can be seen as they
+are executed.
+</para>
+<para>
+Note: because compiled I-code contains actual statement memory addresses,
+the "top" or "bottom" statements of loop structures are usually executed
+just once. For example, in FOR...NEXT loops the FOR statement is executed
+once, so the statement that appears to be the top of the loop is actually
+the one following the "FOR" statement.
+
+<cmdsynopsis>
+<command>TRON</command>
+<sbr>
+<command>TROFF</command>
+</cmdsynopsis>
+These commands turn the suspended procedure's trace mode on and off. In
+trace mode, the compiled code of each equivalent statement line is
+reconstructed to source statements and displayed before the statement
+is executed. If the statement causes the evaluation of one or more
+expressions, an equal sign and the expression result(s) are displayed
+on the following line(s).
+</para>
+<para>
+Trace mode is local to a procedure. If the suspended procedure calls
+another, no tracing occurs until control returns back
+(unless of course, other called procedure(s) have trace mode on).
+</para></sect1>
+<sect1><title>Debugging Techniques</title>
+<para>
+
+If your program does not do what you expect it to, it is bound to show
+one of two symptoms: incorrect results, or premature termination due to
+an error.  The second case will automatically send you into Debug Mode.
+In the first case, you have to force the program into Debug Mode either
+by hitting Control-C
+ (assuming you have time to do so), or by using Edit Mode to put
+one or more PAUSE statements in the program. Once you're in Debug Mode,
+you can bring its powerful commands to bear on the problem.
+</para>
+<para>
+Usually the first step after an error stops the program is to place
+a PAUSE statement at the beginning of the suspected procedure or at a place
+within it where you think things begin to go amiss, and the you
+rerun the program. When the program hits the PAUSE statement, and enters
+DEBUG mode, it is time to turn the trace mode on and actually
+watch your program run. To do so, just type:
+<programlisting>
+D: TRON
+</programlisting>
+
+After you have done this, you hit the carriage return key once for every
+statement.  You will see the original source statement, and if expressions
+are evaluated by the statement, Debug Mode will print an equal sign and
+the result of the expression.  Notice that some statements such as FOR
+and PRINT may cause more than one expression to be evaluated.  Using this
+technique, you can watch your program run one step at a time until you see
+where it goes wrong.  But what if in the process of tracing, you encounter
+a loop that works OK, but executes 200 statements repetitively? That's
+a lot of carriage returns.  In this case, turn the trace off (if you
+want) and use the STEP command to quickly run through the loop. Then,
+turn trace mode back on, and resume single-step debugging. The command
+sequence for this example is:
+
+<programlisting>
+D: TROFF
+D: STEP 200
+D: TRON
+</programlisting>
+</para>
+<para>
+Don't forget that trace mode is "local" to one procedure only. If the procedure
+under test returns to another procedure you need to use the BREAK
+command or put a PAUSE statement in the procedure to enter Debug Mode.
+If you call another procedure from the procedure being debugged, tracing will
+stop when it is called until it returns. If you also want to trace the called
+procedure, it will need its own PAUSE statement.
+
+</para></sect1>
+<sect1><title>Debug Mode as a Desk Calculator</title>
+<para>
+The simple program listed below turns Debug Mode into a powerful desk
+calculator. It's function is simple: it declares 26 working variables,
+then goes into Debug Mode so you can use interactive PRINT and LET statements.
+
+<programlisting>
+PROCEDURE Calculator
+DIM a,b,c,d,e,f,g,h,i,j,k,l,m
+DIM n,o,p,q,r,s,t,u,v,w,x,y,z
+PAUSE
+END
+</programlisting>
+
+Recall that while in debug mode, you cannot create new variables,
+hence the DIM statements that pre-define 26 working variables for you.
+If you wish yu can add more or fewer variables.
+The PAUSE statement causes Debug Mode to be entered. Here's a sample session:
+<programlisting>
+B: run calculator
+BREAK: PROCEDURE Calculator
+D:let x:=12.5
+D:print sin(pi/2)
+.7071606781
+D:let y:=exp(4+0.5)
+D:print x,y
+12.5   90.0171313
+D:Q
+B:
+</programlisting>
+</para>
+<para>
+Don't forget that
+the Debug Mode PRINT command can use PRINT USING to
+produce formatted output (including hexadecimal).
+</para>
+<para>
+By adding less than a dozen statements to the program, you can
+make it store its variables on a disk file so they're remembered
+from session to session. There are also many other enhancement
+possibilities
+</para>
+</sect1>
+</chapter>
+
+
+
+<chapter>
+<title>Data Types, Variables and Data Structures</title>
+
+<sect1><title>Why are there different data types?</title>
+<para>
+A computer program's primary function is to
+process data. The performance of the computer, and even
+sometimes whether or not a computer can handle a particular problem,
+depends on how the software stores data in memory and operates on it.
+&b09; offers many possibilities for organizing and manipulating data.
+</para>
+<para>
+Complicating matters somewhat is the fact that there are many kinds
+of data.  Some data are numbers used for counting or measuring. Another
+example is textual data composed of letters, punctuation, etc., such
+as your name.  Seldom can they be mixed (for example multiplication is
+meaningless to anything but numbers), and they have different storage
+size requirements.  Even within the same general kind of data, it is
+frequently advantageous to have different ways to represent data. For
+example, &b09; lets you chose from three different ways to represent
+numbers - each having its own advantages and disadvantages.  The decision
+to use one depends entirely on the specific program you are writing. In
+order for you to select the most appropiate way to store data variables,
+&b09; provides five different basic data types. &b09; also lets you create
+new customized data types based on combinations of the five basic types.
+A good analogy is to consider the five basic types to be atoms, and the
+new types you create as molecules. This is why the five basic types are
+called <emphasis>atomic data types</emphasis>.
+</para></sect1>
+<sect1><title>Data Structures</title>
+<para>
+A <emphasis>data structure</emphasis> refers to storage for
+more than one data item under a single name. Data
+structures are often the most practical and convenient way to organize large
+amounts of similar data.
+The simplest kind of data structure is the <emphasis>array</emphasis>,
+which is a table of values.
+The table has a single name, and the storage space for each individual
+value is numbered. Arrays are created by DIM statements.
+For example, to create an array having five storage spaces called "AGES",
+we can use the statement:
+
+<programlisting>
+DIM AGES(5):INTEGER
+</programlisting>
+"(5)" tells &b09; how many spaces to reserve. The ":INTEGER" part
+indicates the array's data type. To assign a value of 22 to the third
+storage space in the array we can use the statement:
+
+<programlisting>
+LET AGES(3):=22
+</programlisting>
+
+As you shall see, &b09; lets you create complex arrays and
+even arrays that have different data types combined.
+</para>
+<sect2><title>Atomic Data Types</title>
+<para>
+&b09; includes five atomic data types: BYTE, INTEGER, REAL,
+STRING and BOOLEAN. The first three types are used to represent
+numbers, The STRING type is used to represent character data, and
+the BOOLEAN type is used to represent the logical values of either
+TRUE or FALSE. Arrays of any of these data types can be created
+using one, two, or three dimensions. The table below gives an
+overview of the characteristics of each type:
+
+<table frame="none">
+<title>&b09; Atomic Data Type Summary</title>
+<tgroup cols="3">
+<colspec colwidth="1.2in">
+<colspec colwidth="2.1in">
+<thead>
+<row>
+<entry>Type:</entry>
+<entry>Allowable values:</entry>
+<entry>Memory requirement:</entry>
+</row>
+</thead>
+<tbody>
+<row>
+<entry>BYTE</entry>
+<entry>Whole Numbers 0 to 255</entry>
+<entry>One byte</entry>
+</row>
+<row>
+<entry>INTEGER</entry>
+<entry>Whole Numbers ­32768 to 32767</entry>
+<entry>Two bytes</entry>
+</row>
+<row>
+<entry>REAL</entry>
+<entry>Floating Point +/­ 1*10^38</entry>
+<entry>Five bytes</entry>
+</row>
+<row>
+<entry>STRING</entry>
+<entry>Letters, digits, punctuation</entry>
+<entry>One byte/character</entry>
+</row>
+<row>
+<entry>BOOLEAN</entry>
+<entry>True or False</entry>
+<entry>One byte</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+Why are there three different ways to represent numbers? Although REAL
+numbers appear to be the most versatile because they have the greatest
+range and are floating-point, arithmetic operations involving them are
+relatively slower (by a factor of about four) compared to the INTEGER
+or BYTE types.  Thus using INTEGER values for loop counters, indexing
+arrays, etc.  can significantly speed up your programs. The BYTE type
+is not appreciably faster than INTEGER, it conserves memory space in
+some cases and serves as a building block for complex data types in
+other cases.  If you neglect to specify the type of a variable, &b09;
+will automatically use the REAL data type.
+</para></sect2>
+<sect2><title>Type BYTE</title>
+<para>
+BYTE variables hold integer values in the range 0 through 255
+(unsigned 8-bit data) which are
+stored as a single byte. BYTE values are always converted to another type
+(16-bit integer
+values and/or real values) for computation, thus they have no speed
+advantage over other numeric types. However, BYTE variables require
+only half of the storage used by integers, and an 1/5 of that used by reals.
+Attempting to store an integer value outside the BYTE range to a BYTE
+variable results in the storage of the least-significant 8-bits (the value
+modulo 256) without error.
+
+</para></sect2>
+<sect2><title>Type INTEGER</title>
+<para>
+INTEGER variables consist of two bytes of storage, and hold a
+numeric value in the range ­32768 through 32767 as
+signed 16-bit data. Decimal points are not allowed. INTEGER constants
+may also be represented as hexadecimal values in the range $0000
+through $FFFF to facilitate address calculations. INTEGER values
+are printed without a decimal point. INTEGER arithmetic is faster and
+requires less storage than REAL values.
+</para>
+<para>
+Arithmetic which results in values outside the INTEGER range does not
+cause run-time errors but instead "wraps around" modulo 65536; i.e.,
+32767 + 1 yields &minus;32768. Division of an integer by another integer
+yields an integer result, and any remainder is discarded. The programmer
+should be aware that numeric comparisons made on values in the range
+32767 through 65535 will actually be dealing with negative numbers,
+so it may be desirable to limit such comparisons to tests for equality
+or non-equality.  Additionally, certain functions (LAND, LNOT, LOR, LXOR)
+use integer values, but produce results on a non-numeric bit-by-bit basis.
+</para></sect2>
+<sect2><title>Type REAL</title>
+<para>
+The REAL data type is the default type for undeclared variables. However,
+a variable may be explicitly typed REAL (for example, twopi:REAL) to
+improve a program's internal documentation. REAL-type values are
+always printed with a decimal point, and only those constants which
+include a decimal point are actually stored as REAL values.
+</para>
+<para>
+REAL numbers are stored in 5 consecutive memory bytes. The
+first byte is the (8-bit) exponent in binary two's-complement
+representation. The next four bytes are the binary sign-and-magnitude
+representation of the mantissa; the mantissa in the first 31 bits,
+and the sign of the mantissa in the last (least significant) bit of
+the last byte of the real quantity.
+<figure>
+<title>Internal Representation of REAL Numbers</title>
+
+<literallayout>
+      +--------+--------+--------+--------+--------+
+      |exponent|        |        |        |      |S| &lt;- mant. sign
+      +--------+--------+--------+--------+--------+
+byte:     +0       +1       +2       +3       +4
+</literallayout>
+</figure>
+
+</para>
+<para>
+The exponent covers the range 2.938735877 * 10^&minus;39 (2^&minus;128)
+through 1.701411835 * 10^38 (2^127) as powers of 2. Operations which
+result in values out of the representation range cause overflow or
+underflow errors (which may be handled automatically by the ON ERROR
+command).  The mantissa covers the range from 0.5 through .9999999995
+in steps of 2^-31. This means that REAL numbers can represent values
+on the number line about .0000000005 apart. Operations which cause
+results between the representable points are rounded to the nearest
+representable number.
+</para>
+<para>
+Floating point arithmetic is inherently inexact, thus a sequence of
+operations can produce a cumulative error. Proper rounding (as
+implemented in &b09;) reduces this effect but cannot eliminate it.
+Programmers using comparisons on REAL quantities should use caution
+with strict comparisons (i.e., = or &lt;>), since
+the exact desired value may not occur during program execution.
+
+</para></sect2>
+<sect2><title>Type STRING</title>
+<para>
+
+
+A STRING is a variable length  sequence of characters or nil (an empty
+string).  A variable may be defined as a STRING either explicitly (e.g.,
+DIM title:STRING) or implicitly by appending a dollar-sign character to
+the variable name (title$ := "My First Program.").  The default maximum
+length allocated to each string is 32 characters, but each string may
+be dimensioned less (e.g., DIM A:STRING [4]) for memory savings or more
+(e.g., DIM long:STRING [2880]) to allow long strings.  Notice that
+strings are inherently variable-length entities, and dimensioning the
+storage for a string only defines the maximum-length string which can
+be stored there.  When a STRING value is assigned to a STRING variable,
+the bytes composing the string are copied into the variable storage
+byte-by-byte. The beginning of a string is always character number one,
+and this is NOT affected by the BASE0 or BASE1 statements. Operations
+which result in strings too long to fit in the dimensioned storage
+truncate the string on the right and no error is generated.
+</para>
+<para>
+Normally the internal representation of the string is hidden. A string
+is stored in a fixed-size storage area and is represented by a sequence
+of bytes terminated by the value zero or by the maximum length allocated
+to the STRING variable. Any remaining "unused" storage after the zero
+byte allows the stored string to expand and contract during execution.
+
+The example below shows the internal storage of a variable dimensioned as
+STRING[6] and assigned a value of "SAM". Notice the byte at +3 contains
+the zero string terminator, and the two following bytes are not used.
+<informalfigure>
+<literallayout>
+      +--------+--------+--------+--------+--------+--------+
+      |   S    |    A   |    M   |   00   |        |        |
+      +--------+--------+--------+--------+--------+--------+
+byte:     +0       +1       +2       +3       +4       +5
+</literallayout>
+</informalfigure>
+If the value "ROBERT" is assigned to the variable, the zero byte terminator
+is not needed because the STRING fills the storage exactly:
+<informalfigure>
+<literallayout>
+      +--------+--------+--------+--------+--------+--------+
+      |   R    |    O   |    B   |    E   |    R   |    T   |
+      +--------+--------+--------+--------+--------+--------+
+byte:     +0       +1       +2       +3       +4       +5
+</literallayout>
+</informalfigure>
+</para></sect2>
+<sect2><title>Type BOOLEAN</title>
+<para>
+A BOOLEAN quantity can have only two values: TRUE or FALSE.  A variable
+may be typed BOOLEAN (e.g., DIM done_flag:BOOLEAN ).  BOOLEAN quantities
+are stored as single byte values, but they may not be used for numeric
+computation.  BOOLEAN values print out as the character strings: "TRUE"
+and "FALSE."
+
+BOOLEAN values result from comparisons (comparing two compatible types),
+and are appropriate for logical flags and expressions.  ( result:=a AND
+b AND c ).
+
+Do not confuse BOOLEAN operations AND, OR, XOR, and NOT (which operate
+on the Boolean values TRUA end FALSE) with the logical functions LAND,
+LOR, LXOR, and LNOT (which use integer values to produce results on a
+bit-by-bit basis).  Attempting to store a non-BOOLEAN value in a BOOLEAN
+variable (or the reverse) will cause a run-time error.
+</para></sect2>
+<sect2><title>Automatic Type Conversion</title>
+<para>
+Expressions that mix numeric data types (BYTE, INTEGER, or REAL) are
+automatically and temporarily converted to the largest type necessary to
+retain accuracy. In addition, certain &b09; functions also perform
+automatic type conversions as necessary. Thus, numeric quantities of
+mixed types may be used in most cases.
+Type-mismatch errors happen when an expression includes types that
+cannot legally be mixed. These errors are reported by the second compiler
+pass which automatically occurs when you leave EDIT mode. Type
+conversions can take time. Therefore, you should use expressions
+containing all values of a single type wherever possible.
+</para></sect2>
+</sect1>
+<sect1><title>Constants</title>
+<para>
+Constants are frequently used in program statements and in expressions to
+assign values to variables. &b09; has rules that allow you to specify
+constants that correspond to the five basic data types.
+</para>
+<sect2><title>Numeric Constants</title>
+<para>
+Numeric constants can be either REAL or INTEGER. If a number constant
+includes a decimal point or uses the "E format" exponential form,
+it forces &b09; to
+store the number in REAL format even if the value could have been
+stored in INTEGER or BYTE format.
+Thus, if you specifically want to specify a REAL constant,
+use a decimal point (for example, 12.0).
+This is sometimes done if all other values in an expression are of type
+REAL so &b09; does not have to do a time-consuming type conversion
+at run-time.
+
+Numbers that do not have a decimal point but are too large to be
+represented as integers are also stored in REAL format. The following are
+examples of REAL values:
+
+<informaltable frame="none">
+<tgroup cols="2">
+<tbody>
+<row>
+<entry>1.0</entry>
+<entry>9.8433218</entry>
+</row>
+<row>
+<entry>&minus;.01</entry>
+<entry>&minus;999.000099</entry>
+</row>
+<row>
+<entry>100000000</entry>
+<entry>5655.34532</entry>
+</row>
+<row>
+<entry>1.95E+12</entry>
+<entry>&minus;99999.9E-33</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+
+</para>
+<para>
+
+Numbers that do not have a decimal point and are in the range of
+­32768 to +32767 are treated as INTEGER numbers.
+&b09; will also accept integer constants in hexadecimal in the range 0 to
+$FFFF. Hex numbers must have a leading dollar sign. Here are some
+examples of INTEGER constants:
+
+<informaltable frame="none">
+<tgroup cols="3">
+<tbody>
+<row>
+<entry>12</entry>
+<entry>&minus;3000</entry>
+<entry>64000</entry>
+</row>
+<row>
+<entry>$20</entry>
+<entry>$FFFE</entry>
+<entry>$0</entry>
+</row>
+<row>
+<entry>0</entry>
+<entry>&minus;12</entry>
+<entry>&minus;32768</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+</para></sect2>
+<sect2><title>Boolean Constants</title>
+<para>
+The two legal boolean constants are "TRUE" and "FALSE".
+</para>
+<para>
+Example:
+<programlisting>
+DIM flag, state: BOOLEAN
+flag := TRUE
+state := FALSE
+</programlisting>
+
+</para></sect2>
+<sect2><title>String Constants</title>
+<para>
+String constants consist of a sequence of any characters enclosed in
+double quote characters. The binary value of each character byte can be
+1 to 255.  Double quote characters to be included in the string use two
+characters in a row to represent one double quote.
+
+The null string "" is important because it represents a string having no
+characters. It is analogous to the numeric zero.  Here are some examples
+of string constants:
+
+<programlisting>
+"&b09; is a new microcomputer language"
+"AABBCCDD"
+""   (a null string)
+"An ""older man"" is wiser"
+</programlisting>
+
+</para></sect2>
+</sect1>
+<sect1><title>Variables</title>
+<para>
+Each &b09; variable is "local" to the procedure where it is defined. This
+means that it is only known to the program statements within that
+procedure. You can use the same variable name in several procedures and
+the variables will be completely independent. If you want other procedures
+to be able to share a variable, you must use the RUN and PARAM statements
+to pass the variable when a procedure calls another procedure.
+</para>
+<para>
+Storage for variables is allocated from the &b09; workspace when
+the procedure is called. It is not possible to force a variable to
+occupy a particular absolute address in memory. When the procedure
+is exited, variable storage is given back and the values stored in
+it are lost. Procedures can call themselves (this is referred to as
+<emphasis>recursion</emphasis>) which causes another separate
+storage space for variables to be allocated.
+
+
+<warning>
+<para>
+&b09; does not automatically initialize
+variables. When a procedure is run, all variables, arrays, and
+structures will have random values. Your program must assign
+any initial value if needed.
+</para>
+</warning>
+
+</para></sect1>
+<sect1><title>Parameter Variables</title>
+<para>
+Procedures may pass variables to other procedures. When this occurs, the
+variables passed to the called procedure are called "parameters".
+Parameters may be passed either "by reference",
+allowing values to be returned from the called procedure, or
+"by value", which protects the values in the calling procedure such
+that they may not be changed by the procdure which is called.
+</para>
+<para>
+Parameters are usually passed "by reference"; this is done by enclosing
+the names of the variables to be sent to the called procedure in
+parentheses as part of the RUN statement. The storage address of each
+parameter variable is evaluated and sent to the called procedure, which
+then associates those addresses with names in a local PARAM statement.
+The called procedure uses this storage as if it had been created locally
+(although it may have a new name) and can change the values stored there.
+Parameters passed by reference allow called procedures to return values
+to their callers.
+</para>
+<para>
+Parameters may be passed "by value" by writing the value to be passed
+as an expression which is evaluated at the time of the call. Useful
+expression-generators that do not alter values are +0 for numbers or +""
+for strings. For example:
+
+<informalexample>
+<programlisting>
+RUN inverse(x)                              passes x by reference. 
+RUN inverse(x+0)                            passes x by value. 
+RUN translate(word$)                        passes word$ by reference. 
+RUN translate(word$+"")                     passes word$ by value.
+</programlisting>
+</informalexample>
+</para>
+<para>
+When parameters are passed by value, a temporary variable is created
+when the expression is evaluated. The result is placed in this new temporary
+storage. The address of this temporary storage is sent to the called
+procedure. Therefore, the value actually given to the called procedure is a
+<emphasis>copy</emphasis> of the result, and the called procedure can't
+accidentially (or otherwise) change the variable(s) in the calling program.
+</para>
+<para>
+Notice that expressions containing numeric constants are either of type
+INTEGER or of type REAL; there is no type BYTE constant. Thus, BYTE-type
+VARIABLES may be sent to a procedure as parameters; but expressions will
+be of types INTEGER or REAL. For example, a RUN statement may evaluate
+an INTEGER as a parameter and send it to the called procedure. If the
+called procedure is expecting a BYTE-type variable, it uses only the
+high-order byte of the (two-byte) INTEGER (which, if the value was
+intended to be in BYTE-range, will probably be zero!).
+</para></sect1>
+<sect1><title>Arrays</title>
+<para>
+The DIM statement can create arrays of from 1 to 3 dimensions
+(a one-dimensional array is often called a "vector", while a 2 or 3
+dimensional array is called a "matrix" ).  The sizes of each dimension are
+defined when the array is typed (e.g., DIM plot(24,80):BYTE) by including
+the number of elements in each dimension.  Thus, a table dimensioned
+(24,80) has 24 rows (1-24) of 80 columns (1 - 80) when accessed in the
+default (BASE 1) mode. You may elect to access the elements of an array
+starting at zero (BASE 0), in which case there are still 24 rows (now
+0-23) and 80 columns (now 0-79). Arrays may be composed of atomic data
+types, complex data types, or other arrays.
+</para></sect1>
+<sect1><title>Complex Data Types</title>
+<para>
+The TYPE statement can be used to define a new data type as a "vector" (a
+one-dimensional array) of any atomic or previously-defined types.
+For example:
+
+<informalexample>
+<programlisting>
+TYPE employee_rec = name:STRING; number(2):INTEGER; malesex:BOOLEAN
+</programlisting>
+</informalexample>
+
+This structure differs from an array in that the various elements may be of
+mixed types, and the elements are accessed by a <emphasis>field name</emphasis>
+instead of an array index. For example:
+
+<informalexample>
+<programlisting>
+DIM employee_file(250): employee_rec
+employee_file(1).name := "Tex"
+employee_file(20).number(2) := 115
+</programlisting>
+</informalexample>
+</para>
+<para>
+The complex structure gives the programmer the ability to store and
+manipulate related values that are of many types, to create "new"
+types in addition to the five atomic data types, or to create data
+structures of unusual "shape" or size.  Additionally, the position of
+the desired element in complex-type storage is known and defined at
+"compile time" and need not be calculated at "run time". Therefore,
+complex structure accesses may be slightly faster than array accesses.
+The elements of a complex structure may be copied to another similar
+structure using a single assignment operator (:= ). An entire structure
+may be written to or read from mass storage as a single entity (e.g.,
+PUT #2, employee_file).  Arrays or complex structures may be elements
+of subsequent complex structures or arrays.
+</para>
+</sect1>
+</chapter>
+
+
+<chapter>
+<title>Expressions, Operators, and Functions</title>
+
+<sect1>
+<title>Evaluation of Expressions</title>
+<para>
+Many &b09; statements evaluate <emphasis>expressions</emphasis>. The
+result of an evaluation is just a value of some atomi type (e.g., REAL,
+INTEGER, STRING, or BOOLEAN). The expression itself may consist of values
+and operators. For example, the expression "5+5" results in an integer
+with a value of ten.
+</para>
+<para>
+A "value" can be a constant value (e.g, 5.0, 5 , "5" , or TRUE), a
+variable name, or a function (e.g, SIN(x) ) which "returns" the result as
+a value. An <emphasis>operator</emphasis> combines values (typically,
+those adjacent to the operator) and also returns a result.
+</para>
+<para>
+In the course of evaluating an expression, each value is copied to an
+"expression stack" where functions and operators take their input values
+and return results. If (as is often the case) the expression is to be
+used in an assignment statement, only when the result of the entire
+expression has been found is the assignment made.  This allows
+the variable which is being modified (assigned to) to be one of the
+values in the expression. The same principles apply for numeric, string,
+and boolean operators. These principles make assignment statements such
+as "X=X+1" legal in all cases, even though it would not make sense in a
+mathematical context.
+</para>
+<para>
+Any expression evaluates to one of the five "atomic" data types, i.e.,
+real, integer, byte, boolean, or string. This does not mean, however,
+that all the operators and operands in expressions have to be of an
+identical type. Often types are mixed in expressions because the RESULT
+of some operator or function has a different type than its operands.
+An example is the "less than" operator. Here is an example:
+
+<informalexample>
+<programlisting>
+24 &lt; 100
+</programlisting>
+</informalexample>
+
+The "&lt;" operator compares two numeric operands. The result of the
+comparison is of type BOOLEAN; in this case, the value TRUE.
+</para>
+<para>
+&b09; allows intermixing of the three numeric types because it performs
+automatic type conversion of operands. If different types are used in an
+expression, the "result" will be  the same type as the operand(s)
+having the largest representation. As a rule, any numeric type operand
+may be used in a expression that is expected to produce a result of
+type REAL. Expressions that must produce BYTE or INTEGER results must
+evaluate to a value that is small enough to fit the representation. &b09;
+has a complete set of functions that can perform compatible type
+conversion. Type-mismatch errors are reported by the second compiler
+pass when leaving Edit mode.
+</para>
+</sect1>
+<sect1>
+<title>Operators</title>
+<para>
+Operators take two operands (except negation) and cause some operation
+to be performed producing a result, which is generally the same type
+as the operands (except comparisons).  The table below lists the operators
+available and the types they accept and produce.
+"NUMERIC" refers to either BYTE, INTEGER, or REAL types.
+<table frame="none">
+<title>&b09; Expression Operators</title>
+<tgroup cols="4">
+<colspec colwidth="0.8in">
+<thead>
+<row rowsep="1">
+<entry>Operator</entry>
+<entry>Function</entry>
+<entry>Operand type</entry>
+<entry>Result type</entry>
+</row>
+</thead>
+<tbody>
+<row>
+<entry>&minus;</entry>
+<entry>Negation</entry>
+<entry>NUMERIC</entry>
+<entry>NUMERIC</entry>
+</row>
+<row>
+<entry>^ or  **</entry>
+<entry>Exponentiation</entry>
+<entry>NUMERIC (positive)</entry>
+<entry>NUMERIC</entry>
+</row>
+<row>
+<entry>*</entry>
+<entry>Multiplication</entry>
+<entry>NUMERIC</entry>
+<entry>NUMERIC</entry>
+</row>
+<row>
+<entry>/</entry>
+<entry>Division</entry>
+<entry>NUMERIC</entry>
+<entry>NUMERIC</entry>
+</row>
+<row>
+<entry>+</entry>
+<entry>Addition</entry>
+<entry>NUMERIC</entry>
+<entry>NUMERIC</entry>
+</row>
+<row>
+<entry>­</entry>
+<entry>Subtraction</entry>
+<entry>NUMERIC</entry>
+<entry>NUMERIC</entry>
+</row>
+<row>
+<entry>NOT</entry>
+<entry>Logical Negation</entry>
+<entry>BOOLEAN</entry>
+<entry>BOOLEAN</entry>
+</row>
+<row>
+<entry>AND</entry>
+<entry>Logical AND</entry>
+<entry>BOOLEAN</entry>
+<entry>BOOLEAN</entry>
+</row>
+<row>
+<entry>OR</entry>
+<entry>Logical OR</entry>
+<entry>BOOLEAN</entry>
+<entry>BOOLEAN</entry>
+</row>
+<row>
+<entry>XOR</entry>
+<entry>Logical EXCLUSIVE OR</entry>
+<entry>BOOLEAN</entry>
+<entry>BOOLEAN</entry>
+</row>
+<row>
+<entry>+</entry>
+<entry>Concatenation</entry>
+<entry>STRING</entry>
+<entry>STRING</entry>
+</row>
+<row>
+<entry>=</entry>
+<entry>Equal to</entry>
+<entry>ANY</entry>
+<entry>BOOLEAN</entry>
+</row>
+<row>
+<entry>&lt;> or >&lt;</entry>
+<entry>Not equal to</entry>
+<entry>ANY</entry>
+<entry>BOOLEAN</entry>
+</row>
+<row>
+<entry>&lt;</entry>
+<entry>Less than</entry>
+<entry>NUMERIC, STRING*</entry>
+<entry>BOOLEAN</entry>
+</row>
+<row>
+<entry>&lt;= or =&lt;</entry>
+<entry>Less than or Equal</entry>
+<entry>NUMERIC, STRING*</entry>
+<entry>BOOLEAN</entry>
+</row>
+<row>
+<entry>></entry>
+<entry>Greater than</entry>
+<entry>NUMERIC, STRING*</entry>
+<entry>BOOLEAN</entry>
+</row>
+<row>
+<entry>>= or =></entry>
+<entry>Greater than or Equal</entry>
+<entry>NUMERIC, STRING*</entry>
+<entry>BOOLEAN</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+When comparing strings, the ASCII collating sequence is used, so that
+0 &lt; 1 &lt; ... &lt; 9 &lt; A &lt; B&lt; ... &lt; Z &lt; a &lt; b&lt;
+... &lt; z
+</para>
+<sect2>
+<title>Operator Precedence</title>
+<para>
+Operators have "precedence". This means they are evaluated in a specific
+order. (i.e., multiplications performed before addition).  Parentheses can
+be used to override natural precedence, however, extraneous parentheses
+may be removed by the compiler. The legal operators are listed below,
+in precedence order from highest to lowest.
+
+<informaltable frame="none">
+<tgroup cols="7">
+<colspec colname="c1">
+<colspec colname="c2">
+<colspec colname="c3">
+<colspec colnum=7 colname="c7">
+<spanspec spanname="firstop" namest="c2" nameend="c2">
+<spanspec spanname="secondop" namest="c3" nameend="c7">
+<spanspec spanname="onlyop" namest="c2" nameend="c7">
+<spanspec spanname="all" namest="c1" nameend="c7">
+<tbody>
+<row>
+<entry spanname="all">Highest Precedence</entry>
+</row>
+<row>
+<entry spanname="firstop">NOT</entry>
+<entry spanname="secondop">­(negate)</entry>
+</row>
+<row>
+<entry spanname="firstop">^</entry>
+<entry spanname="secondop">**</entry>
+</row>
+<row>
+<entry spanname="firstop">*</entry>
+<entry spanname="secondop">/</entry>
+</row>
+<row>
+<entry spanname="firstop">+</entry>
+<entry spanname="secondop">­</entry>
+</row>
+<row>
+<entry spanname="firstop">></entry>
+<entry>&lt;</entry>
+<entry>&lt;></entry>
+<entry>=</entry>
+<entry>>=</entry>
+<entry>&lt;=</entry>
+</row>
+<row>
+<entry spanname="onlyop">AND</entry>
+</row>
+<row>
+<entry spanname="firstop">OR</entry>
+<entry spanname="secondop">XOR</entry>
+</row>
+<row>
+<entry spanname="all">Lowest Precedence</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</para>
+<para>
+Operators of equal precedence are shown on the same line, and are
+evaluated left to right in expressions. The only exception to this rule is
+exponentiation, which is evaluated right to left. Raising a negative number
+to a power is not legal in &b09;.
+</para>
+<para>
+In the examples below, &b09; expressions on the left are evaluated as
+indicated on the right. Either form may be entered,
+but the simpler form on the left will always be generated by the decompiler.
+<informaltable frame="none">
+<tgroup cols="2">
+<tbody>
+<row>
+<entry>&b09; representation</entry>
+<entry>Equivalent form</entry>
+</row>
+<row>
+<entry>a:= b+c**2/d</entry>
+<entry>a:= b+((c**2)/d)</entry>
+</row>
+<row>
+<entry>a:= b>c AND d>e OR c=e</entry>
+<entry>a:= ((b>c) AND (d>e)) OR (c=e)</entry>
+</row>
+<row>
+<entry>a:= (b+c+d)/e</entry>
+<entry>a:= ((b+c)+d)/e</entry>
+</row>
+<row>
+<entry>a:= b**c**d/e</entry>
+<entry>a:= (b**(c**d))/e</entry>
+</row>
+<row>
+<entry>a:= ­(b)**2</entry>
+<entry>a:= (­b)**2</entry>
+</row>
+<row>
+<entry>a:=b=c</entry>
+<entry>a:= (b=c) (returns BOOLEAN value)</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+
+</para></sect2></sect1>
+<sect1><title>Functions</title>
+<para>
+Functions take one or more <emphasis>arguments</emphasis> enclosed in
+parentheses, perform some operation, and return a value. They may be used
+as operands in expressions. Functions expect that the arguments passed
+to them be expressions, constants, or variables of a certain type and
+return a result of a certain type. Giving a function, an argument of an
+incompatible type will result in an error.
+</para>
+<para>
+In the descriptions of functions that follow, the following notation
+describes the type required for the parameter expressions:
+
+<informaltable frame="none">
+<tgroup cols="2">
+<tbody>
+<row>
+<entry>&lt;num></entry>
+<entry>means any numeric-result expression.</entry>
+</row>
+<row>
+<entry>&lt;str></entry>
+<entry>means any string-result expression.</entry>
+</row>
+<row>
+<entry>&lt;int></entry>
+<entry>means any integer-result expression.</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+The functions below return REAL results. Accuracy of transcendental
+functions is 8+ decimal digits. Angles can be either degrees or radians (see
+DEG/RAD statement descriptions).
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="1.5in">
+<tbody>
+<row>
+<entry>SIN(&lt;num>)</entry>
+<entry>trigonometric sine of &lt;num></entry>
+</row>
+<row>
+<entry>COS(&lt;num>)</entry>
+<entry>trigonometric cosine of &lt;num></entry>
+</row>
+<row>
+<entry>TAN(&lt;num>)</entry>
+<entry>trigonometric tangent of &lt;num></entry>
+</row>
+<row>
+<entry>ASN(&lt;num>)</entry>
+<entry>trigonometric arcsine of &lt;num></entry>
+</row>
+<row>
+<entry>ACS(&lt;num>)</entry>
+<entry>trigonometric arcosine of &lt;num></entry>
+</row>
+<row>
+<entry>ATN(&lt;num>)</entry>
+<entry>trigonometric arctangent of &lt;num></entry>
+</row>
+<row>
+<entry>LOG(&lt;num>)</entry>
+<entry>natural logarithm (base e) of &lt;num></entry>
+</row>
+<row>
+<entry>LOG10(&lt;num>)</entry>
+<entry>logarithm (base 10) of &lt;num></entry>
+</row>
+<row>
+<entry>EXP(&lt;num>)</entry>
+<entry>e (2.71828183) raised to the power &lt;num>, which must be a
+positive number</entry>
+</row>
+<row>
+<entry>FLOAT(&lt;num>)</entry>
+<entry>&lt;num> converted to type REAL (from BYTE or INTEGER)</entry>
+</row>
+<row>
+<entry>INT(&lt;num>)</entry>
+<entry>truncates all digits to the right of
+the decimal point of a REAL &lt;num></entry>
+</row>
+<row>
+<entry>PI</entry>
+<entry>the constant 3.14159265.</entry>
+</row>
+<row>
+<entry>SQR(&lt;num>)</entry>
+<entry>square root of &lt;num>, which must be positive.</entry>
+</row>
+<row>
+<entry>SQRT(&lt;num>)</entry>
+<entry>square root of &lt;num>; same as SQR.</entry>
+</row>
+<row>
+<entry morerows="2">RND(&lt;num>)</entry>
+<entry>if &lt;num>=0, returns random x, 0 &lt;= x &lt; 1.</entry>
+</row>
+<row>
+<entry>if &lt;num>>0, returns random x, 0 &lt;= x &lt; &lt;num>.</entry>
+</row>
+<row>
+<entry>if &lt;num>&lt;0, use ABS(&lt;num>) as new random number seed.</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+The following functions can return any numeric type, depending on the
+type of the input parameter(s).
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="1.5in">
+<tbody>
+<row>
+<entry>ABS(&lt;num>)</entry>
+<entry>absolute value of &lt;num></entry>
+</row>
+<row>
+<entry>SGN(&lt;num>)</entry>
+<entry>signum of &lt;num>: ­1 if &lt;num> &lt; 0; 0 if &lt;num> = 0; or 1 if &lt;num> > 0</entry>
+</row>
+<row>
+<entry>SQ(&lt;num>)</entry>
+<entry>&lt;num> squared</entry>
+</row>
+<row>
+<entry>VAL(&lt;str>)</entry>
+<entry>convert type string to type numeric</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+
+The following functions can return results of type INTEGER or BYTE:
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="1.5in">
+<tbody>
+<row>
+<entry>FIX(&lt;num>)</entry>
+<entry>round REAL &lt;num> and convert to type INTEGER.</entry>
+</row>
+<row>
+<entry>MOD(&lt;num1>,&lt;num2>)</entry>
+<entry>modulus (remainder) function. &lt;num1> mod &lt;num2>.</entry>
+</row>
+<row>
+<entry>ADDR(&lt;name>)</entry>
+<entry>absolute memory address of variable, array, or structure named &lt;name>.</entry>
+</row>
+<row>
+<entry>SIZE(&lt;name>)</entry>
+<entry>storage size in bytes of variable, array, or structure named &lt;name>.</entry>
+</row>
+<row>
+<entry>ERR</entry>
+<entry>error code of most recent error, automatically resets to zero when referenced.</entry>
+</row>
+<row>
+<entry>PEEK(&lt;int>)</entry>
+<entry>value of byte at memory address &lt;int>.</entry>
+</row>
+<row>
+<entry>POS</entry>
+<entry>current character position of PRINT buffer.</entry>
+</row>
+<row>
+<entry>ASC(&lt;str>)</entry>
+<entry>numeric value of first character of &lt;str>.</entry>
+</row>
+<row>
+<entry>LEN(&lt;str>)</entry>
+<entry>length of string &lt;str>.</entry>
+</row>
+<row>
+<entry>SUBSTR(&lt;str1>,&lt;str2>)</entry>
+<entry>substring search: returns starting position of first occurrence of &lt;str1> in
+&lt;str2>, or 0 if not found.</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+The following functions perform bit-by-bit logical operations on integer
+or byte data types and return integer results. They should NOT be confused
+with the BOOLEAN-type operators.
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="1.5in">
+<tbody>
+<row>
+<entry>LAND(&lt;num>,&lt;num>)</entry>
+<entry>Logical AND</entry>
+</row>
+<row>
+<entry>LOR(&lt;num>,&lt;num>)</entry>
+<entry>Logical OR</entry>
+</row>
+<row>
+<entry>LXOR(&lt;num>,&lt;num>)</entry>
+<entry>Logical EXCLUSIVE OR</entry>
+</row>
+<row>
+<entry>LNOT(&lt;num>)</entry>
+<entry>Logical NOT</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+These functions return a result of type STRING:
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="1.7in">
+<tbody>
+<row>
+<entry>CHR$(&lt;int>)</entry>
+<entry>ASCII char. equivalent of &lt;int></entry>
+</row>
+<row>
+<entry>DATE$</entry>
+<entry>date and time, format: "yy/mm/dd hh:mm:ss"</entry>
+</row>
+<row>
+<entry>LEFT$(&lt;str>,&lt;int>)</entry>
+<entry>leftmost &lt;int> characters of &lt;str>.</entry>
+</row>
+<row>
+<entry>RIGHT$(&lt;str>,&lt;int>)</entry>
+<entry>rightmost &lt;int> characters of &lt;str>.</entry>
+</row>
+<row>
+<entry>MID$(&lt;str>,&lt;int1>,&lt;int2>)</entry>
+<entry>middle &lt;int2> characters of &lt;str> starting at
+character position &lt;int1>.</entry>
+</row>
+<row>
+<entry>STR$(&lt;num>)</entry>
+<entry>converts numeric type &lt;num> to displayable characters of type
+STRING representing the number converted.</entry>
+</row>
+<row>
+<entry>TRIM$(&lt;str>)</entry>
+<entry>&lt;str> with trailing spaces removed.</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+The following functions return BOOLEAN values:
+
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="1.5in">
+<tbody>
+<row>
+<entry>TRUE</entry>
+<entry>always returns TRUE.</entry>
+</row>
+<row>
+<entry>FALSE</entry>
+<entry>always returns FALSE.</entry>
+</row>
+<row>
+<entry>EOF(#&lt;num>)</entry>
+<entry>End-of-file test on disk file path &lt;num>, returns TRUE if
+end-of-file condition</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+</para>
+</sect1>
+</chapter>
+<chapter>
+<title>Program Statements and Structure</title>
+<sect1><title>Program Structure</title>
+<para>
+Each &b09; can be a complete program in itself, or several procedures
+that call each other can be used to create an application program. It is
+up to the programmer to decide which approach to take. One procedure
+may suffice for small programs but large programs are easier to write
+and test if divided into separate modules (procedures) according to the
+program's natural flow. These suggestions reflect sound structured
+programming practice. Nonetheless, you can use a single large procedure
+for your program if you so desire.
+</para>
+<para>
+A procedure consists of any number of program statement lines. Each line
+can have an optional line number, and more than one program statement can be
+placed on the same line if separated by "\" characters. For
+example, the following statements are equivalent:
+
+<informaltable frame="none">
+<tgroup cols="2">
+<tbody>
+<row>
+<entry>GOSUB 550 \ PRINT X,Y \ RETURN</entry>
+<entry><literallayout>GOSUB 550
+PRINT X,Y
+RETURN
+</literallayout></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+The maximum input line length is 255 characters. Line feeds can
+be used to make a single long line into shorter lines to fit display
+screens better. This is especially useful when working on hard-copy
+terminals.
+</para>
+<para>
+Program statements can be in any order consistent with program logic
+Progra readability is improved if all variables are declared with
+DIM statements at the beginning of the procedure, but this is not mandatory.
+The program can be terminated with END or STOP statements, which are also
+optional.
+</para></sect1>
+<sect1><title>Line Numbers</title>
+<para>
+Line numbers are optional. They can be any integer number in the range of
+1 to 32767. Only use line numbers where absolutely necessary (such as
+with GOSUB). They make programs harder to understand, use additional
+memory space, and increase compile time considerably. Line numbers are
+local to procedures. That is, the same line number can be used in different
+procedures without conflict.
+</para></sect1>
+<sect1><title>Assignment Statements</title>
+<para>
+Assignment statements are used for computing or initializing of variables.
+</para>
+<sect2><title>LET Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>[LET] &lt;var> := &lt;expr></command>
+<sbr>
+<command>[LET] &lt;var> = &lt;expr></command>
+<sbr>
+<command>[LET] &lt;struct> := &lt;struct></command>
+<sbr>
+<command>[LET] &lt;struct> = &lt;struct></command>
+</cmdsynopsis>
+
+</para>
+<para>
+This statement
+ evaluates an expression and stores the result in &lt;var> which may be a
+simple variable or data structure element. The result of the expression
+must be of the same or compatible type as &lt;var>.
+&b09; will accept either "=" or ":=" as an assignment operator, however, the
+second form ( := ) is preferred because it distinguishes the assignment
+operation from a comparison (the test for equality). The ":="  operator is
+the same as used in PASCAL.
+</para>
+<para>
+Another use of the assignment statement is to copy the entire value
+of an array or complex data structure to another array or complex
+data structure.  The data structures do not have to have the same type
+or "shape". The only restriction is that the size of the destination
+structure be the same or larger than the source structure.  In fact this
+type of assignment can be used to perform unusual type conversions.
+For example, a string variable of 80 characters can be copied to a
+one-dimensional array of 80 bytes.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+A := 0.1
+
+value := temp/sin(x)
+
+DIM array1(100), array2(100)
+array1 := array2
+
+LET AUTHOR$ := FIRST_NAME$ + LAST_NAME$
+
+DIM truth,lie:BOOLEAN
+lie := 100 &lt; 1
+truth := NOT lie
+
+count = total-adjustment
+matrix(2).coefficient(n+2) := matrix(1).coefficient(n)
+</programlisting>
+</informalexample>
+
+</para></sect2>
+<sect2><title>POKE Statement</title>
+<para>
+
+Syntax:
+<cmdsynopsis>
+<command>POKE &lt;integer expr> , &lt;byte expr></command>
+</cmdsynopsis>
+This statement allows a program to store data at a specific memory
+address. The first expression is used as the absolute address to store
+the type BYTE result of the second expression. This statement can alter
+any memory address so care must be taken when using it.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+POKE ADDR(buffer)+5,ASC("A")
+
+POKE 1200,14
+
+POKE $1C00,$FF
+
+POKE pointer,PEEK(pointer+1)
+
+(* alternative to: alphabet$ := "ABCDEFGHIJKLMNOPQRSTUVWXYZ" *)
+FOR i=0 to 25
+  POKE ADDR(alphabet$)+i,$40+i
+NEXT i
+POKE ADDR(alphabet$)+26,$FF
+</programlisting>
+</informalexample>
+
+</para></sect2></sect1>
+
+<sect1><title>Control Statements</title>
+<para>
+This class of statements affect the (usually) sequential execution of
+program statements.  They are used to construct loops or make decisions
+that alter program flow.  &b09; provides a selection of looping statements
+that allow you to create any kind of loop using sound structured
+programming style.
+</para>
+<sect2><title>IF Statement: Type 1</title>
+<para>
+Syntax:
+
+<cmdsynopsis>
+<command>IF &lt;bool expr> THEN &lt;line #></command>
+</cmdsynopsis>
+This form of the if statement causes execution to be transferred
+to the statement having the line number specified if the
+result of the expression is TRUE, otherwise the next sequential
+statement is executed. For example:
+<programlisting>
+IF payment &lt; balance then 400
+</programlisting>
+</para>
+</sect2>
+<sect2><title>IF Statement: Type 2</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>IF &lt;bool expr> THEN &lt;statements></command>
+<sbr>
+<command>[ ELSE &lt;statements> ]</command>
+<sbr>
+<command>ENDIF</command>
+</cmdsynopsis>
+This kind of IF structure evaluates the expression to a BOOLEAN
+value. If the result is TRUE the statement(s) immediately following
+the THEN are executed. If an ELSE clause exists, statements between
+the ELSE and ENDIF are skipped. If the expression is evaluated to
+FALSE control is transferred to the first statement following the
+ELSE, if present, or otherwise to the statement following the ENDIF.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+IF a &lt; b THEN
+  PRINT "a is less than b"
+  PRINT "a:";a;" b:";b
+ENDIF
+
+IF a &lt; b THEN
+  PRINT "a is less than b"
+ELSE
+  IF a=b THEN
+    PRINT "a equals b"
+  ELSE
+    PRINT "a is greater than b"
+  ENDIF
+ENDIF
+</programlisting>
+</informalexample>
+
+</para></sect2>
+<sect2><title>FOR/NEXT Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>FOR &lt;var> = &lt;expr> TO &lt;expr> [ STEP &lt;expr> ]</command>
+<sbr>
+<command>NEXT &lt;var></command>
+</cmdsynopsis>
+Creates a loop that usually executes a specified number of times
+while automatically increasing or decreasing a specified counter variable.
+The first expression is evaluated and the result is stored in &lt;var> which
+must be a simple integer or real variable. The second expression is
+evaluated and stored in a temporary variable.
+If the STEP clause is used, the expression following is evaluated
+and used as the loop increment. If it is negative, the loop will count down.
+</para>
+<para>
+The "body" of the loop (i.e. statements between the "FOR" and "NEXT" are
+executed until the counter variable is larger than the terminating
+expression value. For negative STEP values, the loop will execute until the
+loop counter is less than the termination value. If the initial value of &lt;var>
+is beyond the terminating value the body of the loop is never executed.
+It is legal to jump out of FOR/NEXT loops. The is no limit to the nesting
+of FOR/NEXT loops.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+FOR counter = 1 to 100 step .5
+  PRINT counter
+NEXT counter
+
+
+FOR var = min­1 TO min+max STEP increment-adjustment
+  PRINT var
+NEXT var
+
+
+FOR x = 1000 TO 1 STEP ­1
+  PRINT x
+NEXT x
+</programlisting>
+</informalexample>
+</para></sect2>
+<sect2><title>WHILE..DO Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>WHILE &lt;bool expr> DO</command>
+<sbr>
+<command>ENDWHILE</command>
+</cmdsynopsis>
+This is a loop construct with the test at the "top" of the
+loop. Statements within the loop are executed as long as &lt;bool
+expr> is TRUE. The body of the loop will not be executed if the
+boolean expression evaluates to FALSE when first executed.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+WHILE a&lt;b DO     is equivalent to     100 IF a>=b THEN 500
+  PRINT a                                 PRINT a
+  a := a+1                                a := a+1
+ENDWHILE                                  GOTO 100
+                                         500 REM
+
+DIM yes:BOOLEAN
+yes=TRUE
+WHILE yes DO
+  PRINT "yes!  ";
+  yes := POS&lt;50
+ENDWHILE
+
+REM reverse the letters in word$
+backward$ := ""
+INPUT word$
+WHILE LEN(word$) > 0 DO
+  backward$ := backward$ + RIGHT$(word$,1)
+  word$ := LEFT$(word$,LEN(word$)­1)
+ENDWHILE
+word$ := backward$
+PRINT word$
+</programlisting>
+</informalexample>
+
+</para></sect2>
+<sect2><title>REPEAT..UNTIL Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>REPEAT</command>
+<sbr>
+<command>UNTIL &lt;bool expr></command>
+</cmdsynopsis>
+This is a loop that has its test at the bottom of the loop. The
+statement(s) within the loop are executed until the result of &lt;bool expr> is
+TRUE. The body of the loop is always executed at least one time.
+</para>
+<para>
+Examples:
+<informalexample>
+<programlisting>
+x = 0            is the same as        x=0
+REPEAT                             100 PRINT x
+  PRINT x                              x=x+1
+  x=x+1                                IF X &lt;= 10 THEN 100
+UNTIL x>10
+
+(* compute factorial: n! *)
+temp := 1.
+INPUT "Factorial of what number? ",n
+REPEAT
+  temp := temp * n
+  n := n­1
+UNTIL n &lt;= 1.0
+PRINT "The factorial is "; temp
+</programlisting>
+</informalexample>
+</para></sect2>
+<sect2><title>LOOP and ENDLOOP/EXITIF and ENDEXIT Statements</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>LOOP</command>
+<sbr>
+<command>ENDLOOP</command>
+</cmdsynopsis>
+
+<cmdsynopsis>
+<command>EXITIF &lt;bool expr> THEN &lt;statements></command>
+<sbr>
+<command>ENDEXIT</command>
+</cmdsynopsis>
+These related types of statements can be used to construct
+loops with test(s) located anywhere in the body of the loop.
+The LOOP and ENDLOOP statements define the body of the loop.
+EXITIF clauses can be inserted anywhere inside the loop to leave the loop
+if the result of its test is true.
+Note that if there is no EXITIF clause, you will create a loop that never ends.
+</para>
+<para>
+The EXITIF clause evaluates an expression to a boolean result. If the
+result is FALSE, the statement following the ENDEXIT is executed next.
+Otherwise, the statement(s) between the EXITIF AND ENDEXIT are
+executed, then control is transferred to the statement following 
+the body of the loop.  This exit clause
+is often used to perform some specific function upon termination of the
+loop which depends on where the loop terminated.
+</para>
+<para>
+EXITIF statements are almost always used when LOOP..ENDLOOP is
+used, but they can also be useful in ANY type of &b09; loop 
+construct (e.g., FOR/NEXT, REPEAT... UNTIL, etc.). Examples:
+
+<informalexample>
+<programlisting>
+LOOP                 is equivalent to   100 REM top of loop
+  count=count+1                             count=count+1
+EXITIF count >100 THEN                      IF COUNT &lt;= 100 then 200
+  done = TRUE                               done = TRUE
+ENDEXIT                                     GOTO 300
+  PRINT count                           200 PRINT count
+  x = count/2                               x = count/2
+ENDLOOP                                     GOTO 100
+                                        300  REM out of loop
+
+INPUT x,y
+LOOP
+  PRINT
+EXITIF x &lt; 0 THEN
+  PRINT "x became zero first"
+ENDEXIT
+  x := x­1
+EXITIF y &lt; 0 THEN PRINT "y became zero first"
+ENDEXIT
+  y := y­1
+ENDLOOP
+</programlisting>
+</informalexample>
+
+</para></sect2>
+<sect2><title>GOTO Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>GOTO &lt;line #></command>
+</cmdsynopsis>
+The GOTO unconditionally transfers execution flow to the line having the
+specified number. Note that the line number is a constant, not an expression
+or a variable.
+</para>
+<para>
+Example:
+<informalexample>
+<programlisting>
+GOTO 1000
+</programlisting>
+</informalexample>
+
+</para></sect2>
+<sect2><title>GOSUB/RETURN Statements</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>GOSUB &lt;line #></command>
+<sbr>
+<command>RETURN</command>
+</cmdsynopsis>
+The GOSUB statement
+ transfers program execution to a subroutine starting at the specified
+line number. The subroutine is executed until a RETURN statement is
+encountered, which causes execution to resume at the statement following
+the calling GOSUB. Subroutines may be "nested" to any depth.
+</para>
+<para>
+Example:
+<informalexample>
+<programlisting>
+    FOR n := 1 to 10
+      x := SIN(n)
+      GOSUB 100
+    NEXT n
+    FOR m := 1 TO 10
+      x := COS(m)
+      GOSUB 100
+    NEXT m
+    STOP
+
+100 x := x/2
+    PRINT x
+    RETURN
+</programlisting>
+</informalexample>
+</para></sect2>
+<sect2><title>ON GOTO/GOSUB Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>ON &lt;int expr> GOTO &lt;line #> {,&lt;line #>}</command>
+<sbr>
+<command>ON &lt;int expr> GOSUB &lt;line #> {,&lt;line #>}</command>
+</cmdsynopsis>
+These statements evaluate an integer expression and use the result to select
+a corresponding line number from an ordered list. Control is then
+transferred to that line number unconditionally in ON GOTO statements or
+as a subroutine in ON GOSUB statements.
+These statements are similar to CASE statements in other languages.
+</para>
+<para>
+The expression must evaluate to a positive INTEGER-type result
+having a value between 1 and n, n being the amount of line numbers in the
+list. If the result has any other result, no line number is selected
+and the next sequential statement is executed.
+</para>
+<para>
+Example:
+
+<informalexample>
+<programlisting>
+   (* spell out the digits 0 to 9 *)
+   DIM digit:INTEGER
+   A$="one digit only, please"
+   INPUT "type in a digit"; digit
+   ON digit+1 GOSUB  10,11,12,13,14,15,16,17,18,19
+   PRINT A$
+   STOP
+
+   (* names of digits *)
+10 A$ := "ZERO"
+   RETURN
+11 A$ := "ONE"
+   RETURN
+12 A$ := "TWO"
+   RETURN
+13 A$ := "THREE"
+   RETURN
+14 A$ := "FOUR"
+   RETURN
+15 A$ := "FIVE"
+   RETURN
+16 A$ := "SIX"
+   RETURN
+17 A$ := "SEVEN"
+   RETURN
+18 A$ := "EIGHT"
+   RETURN
+19 A$ := "NINE"
+   RETURN
+</programlisting>
+</informalexample>
+</para></sect2>
+<sect2><title>ON ERROR GOTO Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>ON ERROR [ GOTO &lt;line #> ]</command>
+</cmdsynopsis>
+This statement sets a "trap" that transfers control to the line
+number given when a non-fatal run-time error occurs. If no ON ERROR GOTO has
+been executed in a procedure before an error occurs, the procedure will stop
+and enter DEBUG mode. The error trap can be turned of by executing ON
+ERROR without a GOTO.
+</para>
+<para>
+This statement is often used in conjunction with the ERR function,
+which returns the specific error code, and the ERROR statement
+which artificially generates "errors". Note: the ERR function
+automatically resets to zero any time it is called.
+</para>
+<para>
+Example:
+<informalexample>
+<programlisting>
+   (* List a file *)
+
+   DIM path,errnum: INTEGER, name: STRING[45], line: STRING[80]
+   ON ERROR GOTO 10
+   INPUT "File name? "; name
+   OPEN #path,name:READ
+   LOOP
+     READ #path, line
+     PRINT line
+   ENDLOOP
+
+10 errnum=ERR
+   IF errnum = 211 THEN
+     (* end-of-file *)
+     PRINT "Listing complete."
+     CLOSE #path
+     END
+   ELSE
+     (* other errors *)
+     PRINT "Error number "; errnum
+     END
+   ENDIF
+</programlisting>
+</informalexample>
+</para></sect2></sect1>
+<sect1><title>Execution Statements</title>
+<para>
+Execution statements run procedures, stop execution of procedures, create
+shells, or affect the current execution of the procedure.
+</para>
+<sect2><title>Run Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>RUN &lt;proc name> [ ( &lt;param> {,&lt;param>} ) ]</command>
+<sbr>
+<command>RUN &lt;string var> [ ( &lt;param> {,&lt;param>} ) ]</command>
+</cmdsynopsis>
+This statement
+ calls a procedure by name; when that procedure ends, control will pass
+to the next statement after the RUN. It is most often used to call a
+procedure inside the workspace, but it can also be used to call a previously
+compiled (by the PACK command) procedure or a 6809 machine language
+procedure outside the
+workspace. The name can be optionally taken from a string variable.
+</para></sect2>
+<sect2><title>Parameter Passing</title>
+<para>
+The RUN statement
+ can include a list of parameters enclosed in parentheses to be passed to
+the called procedure. The called procedure must have PARAM statements
+of the same size and order to match the parameters passed to it by the
+calling procedure.
+</para>
+<para>
+The parameters can be variables, constants, or the names of entire arrays or
+data structures. They can be of any type, (EXCEPT variable of type BYTE
+but BYTE arrays are O.K.).
+If a parameter is a constant or expression, it is passed "by value", i.e.,
+it is evaluated and placed in a temporary storage
+location, and the address of the temporary storage is passed to the called
+procedure. Parameters passed by value can be changed by the receiving
+procedure, but the changes are not reflected in the calling procedure.
+</para>
+<para>
+If the parameter is the name of a variable, array, or data structure, it is
+passed by "reference", i.e., the address of that storage
+is sent to the called procedure and thus the value in that storage may be
+changed by the receiving procedure. These changes are reflected in the
+calling procedure.
+</para></sect2>
+<sect2><title>Calling External Procedures</title>
+<para>
+If the procedure named by RUN can't be found in the workspace, &b09;
+will check to see if it was loaded by OS-9 outside the workspace. If it isn't
+found there, &b09; will try to find a disk file having the same name in the
+current execution directory, load it, and run it.
+In either case, &b09; checks to see if the called procedure is a &b09;
+I-code module or a 6809 machine language module, and executes it
+accordingly. If it is a 6809 machine language module, &b09; executes a
+JSR instruction to its entry point and the module is executed as 6809
+native code. The machine language routine can return to the original
+calling procedure by executing an RTS instruction. The diagram on the
+next page shows what the stack frame passed to machine-language
+subroutines looks like.
+</para>
+<para>
+After an external procedure has been called but is no longer needed, the
+KILL statement should be used to get rid of it so its memory space can be
+used for other purposes.
+<figure>
+<title>Stack Frame Passed to Machine Language Procedures</title>
+<literallayout>
++----------------------+         ^
+|                      |         |
+                          higher addresses
+
+|  more parameters     |
+
+|                      |
++----------------------+        ---
+|                      |         |
+|  size of 1st param   |         |
++  -  -  -  -  -  -  - +      4 bytes
+|  addr  of 1st param  |         |
+|                      |         |
++----------------------+        ---
+|                      |         |
+|  parameter count     |      2 bytes
+|                      |         |
++----------------------+        ---
+|                      |         |
+|  return address      |      2 bytes
+|                      |         |
++----------------------+        ---  &lt;- 6809 Stack Pointer
+                                        Register value
+</literallayout>
+</figure>
+</para>
+<para>
+Machine language modules return error status by setting the "C"
+bit of the MPU condition codes register, and by setting the B
+register to the appropiate error code. For an example of a machine
+language subroutine ("INKEY"), See Appendix A.
+</para>
+<para>
+Example of use of the RUN statement:
+
+<informalexample>
+<programlisting>
+PROCEDURE trig_table
+num1 := 0 \ num2 := 0
+REPEAT
+  RUN display(num1,SIN(num1))
+  RUN display(num2,COS(num2))
+  PRINT
+UNTIL num1 > 1
+END
+
+PROCEDURE display
+PARAM passed,funcval
+PRINT passed;":";funcval,
+passed := passed + 0.1
+END
+</programlisting>
+</informalexample>
+
+</para></sect2>
+<sect2><title>KILL Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+  <command>KILL &lt;str expr></command>
+</cmdsynopsis>
+
+This statement is used to
+"unlink" an external procedure, possibly returning system memory,
+and remove it from &b09;'s procedure directory. If the procedure is
+inside the workspace, nothing happens and no error is generated. KILL can
+be used with auto-loading PACKed procedures as an alternative to CHAIN
+when program overlay is desired.
+<warning>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+It can be fatal to OS-9 to KILL a procedure that is still "active".
+</para>
+</listitem>
+<listitem>
+<para>
+When KILL is used together with a RUN statement, the RUN statement MUST use the
+same string variable which contains the name of the procedure.
+See the first example below:
+</para>
+</listitem>
+</orderedlist>
+</warning>
+Examples:
+<informalexample>
+<programlisting>
+LET procname$="average"
+RUN procname$
+KILL procname$
+
+INPUT "Which test do you want to run? ",test$
+RUN test$
+KILL test$
+</programlisting>
+</informalexample>
+</para></sect2>
+<sect2><title>CHAIN Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>CHAIN &lt;str expr></command>
+</cmdsynopsis>
+The CHAIN statement
+ performs an OS-9 "chain" operation on the SHELL, passing the specified
+string as an argument. This causes &b09; to be exited, unlinked,
+and its memory returned to OS-9. The string should evaluate to the
+name of an executable module (such as &b09;), passing parameters if
+appropriate.
+</para>
+<para>
+CHAIN
+ can begin execution of any module, not just &b09;. It executes the
+module indirectly through the Shell in order to take advantage of Shell's
+parameter processing. This has the side-effect of
+leaving an extra "incarnation" of the Shell active. Programs that
+repeatedly chain to each other eventually find all of memory filled with
+waiting shells. This can be prevented by using the "ex" option of the Shell.
+Consult the OS-9 User's Guide for more details on the capabilities of the shell.
+</para>
+<para>
+Files that are open when a CHAIN occurs are not closed.
+However, the OS-9 Fork call will only pass the standard I/O paths
+(0,1,2) to a child process. Therefore, if it is necesary to pass
+an open path to another program segment, the "ex" option of Shell
+must be used.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+CHAIN "ex &b09; menu"
+
+CHAIN "&b09; #10k sort (""datafile"",""tempfile"")"
+
+CHAIN "DIR /D0"
+
+CHAIN "Dir; Echo *** Copying Directory ***; ex basic09 copydir"
+</programlisting>
+</informalexample>
+
+</para></sect2>
+<sect2><title>SHELL Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>SHELL &lt;str expr></command>
+</cmdsynopsis>
+This statement
+allows &b09; programs to run any OS-9 command or program.
+This gives access to virtually any OS-9 function including
+multiprogramming, utility commands, terminal, and I/O control,
+and more.
+Consult the "OS-9 User's Guide" for a detailed
+discussion of OS-9 standard commands.
+</para>
+<para>
+The SHELL statement requests OS-9 to create a new process, initially
+executing the "shell", which is the OS-9 command interpreter. The
+shell can then call any program in the system (subject to the normal
+security functions). The string expression is evaluated and passed to the
+shell to be executed as a command line. (just as if it had
+been typed in).  If the string is null, &b09; is temporarily
+suspended and the shell process displays prompts
+and accepts commands in its normal manner. When the shell process
+terminates, &b09; becomes active again and resumes execution at the
+statement following the SHELL statement.
+</para>
+<para>
+Here are a few examples of using the shell from &b09;:
+
+<informalexample>
+<programlisting>
+SHELL "copy file1 file2"         sequential execution
+
+SHELL "copy file1 file2&amp;"       concurrent execution
+
+SHELL "edit document"             calling text editor
+
+SHELL "asm source o=obj ! spool &amp;"        concurrent assembly
+
+N:=5
+SHELL "kill "+STR$(N)
+
+file$ := "/d1/batch_jobs"         concurrent execution of a
+SHELL file$ + " -p >/p &amp;"       batch procedure file
+</programlisting>
+</informalexample>
+</para></sect2>
+<sect2><title>END Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>END [&lt;output list>]</command>
+</cmdsynopsis>
+This statement
+ends execution of the procedure and returns to the calling procedure,
+or to &b09; command mode if it was the highest level procedure. If an
+output list is given, it also works the same as the PRINT statement.
+END is an executable statement and can be used several times in the same
+procedure. END is optional: it is not required at the "bottom" of a procedure.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+END
+
+END "I have finished execution"
+</programlisting>
+</informalexample>
+</para></sect2>
+<sect2><title>Stop Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>STOP [&lt;output list>]</command>
+</cmdsynopsis>
+This statement
+immediately terminates execution of all procedures and returns to the
+command mode. If an output list is given it also works like a
+PRINT statement.
+</para></sect2>
+<sect2><title>BYE Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>BYE</command>
+</cmdsynopsis>
+
+This statement
+ends execution of the procedure and terminates &b09;. Any open files
+are closed, and any unsaved procedures or data in the workspace will be lost.
+This command is especially useful for creating PACKed programs and/or
+programs to be called from OS-9 procedure files.
+<warning>
+<para>
+This command causes &b09; to abort.
+It should only be used if the program has been saved before it is tested!
+</para>
+</warning>
+</para></sect2>
+<sect2><title>ERROR Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>ERROR(&lt;integer expr>)</command>
+</cmdsynopsis>
+This statement
+generates an error having the error code specified by the result of
+evaluation of the expression. ERROR is often used for testing error routines.
+For details on error handling see the ON ERROR GOTO statement description.
+</para></sect2>
+<sect2><title>PAUSE Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>PAUSE [&lt;output list>]</command>
+</cmdsynopsis>
+PAUSE suspends execution of the procedure and causes &b09; to enter
+Debug Mode. If an output list is given it also works like a PRINT
+statement.
+<programlisting>
+&lt;output> BREAK IN PROCEDURE &lt;procedure name>
+</programlisting>
+The Debug Mode "CONT" command can be used to resume procedure
+execution at the following statement.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+PAUSE
+
+PAUSE "now outside main loop"
+</programlisting>
+</informalexample>
+
+</para></sect2>
+<sect2><title>CHD and CHX Statements</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>CHD &lt;str expr></command>
+<sbr>
+<command>CHX &lt;str expr></command>
+</cmdsynopsis>
+These statements
+change the current default Data or Execution directory,
+respectively. The string must specify the pathlist of a file
+which has the DIR attribute.
+For more information on the OS-9 directory structure, consult
+the OS-9 User's Guide.
+</para></sect2>
+<sect2><title>DEG and RAD Statements</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>DEG</command>
+<sbr>
+<command>RAD</command>
+</cmdsynopsis>
+These statements
+set the procedure's state flag to assume angles stated in
+degrees or radians in SIN, COS, TAN, ACS, ASN, and ATN functions.
+This flag applies only to the currently active procedure. The default state
+is radians.
+</para></sect2>
+<sect2><title>BASE 0 and BASE 1 Statements</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>BASE 0</command>
+<sbr>
+<command>BASE 1</command>
+</cmdsynopsis>
+
+These statements indicate whether a particular procedure's lowest array
+or data structure index (subscript) is zero or one. The
+default is one. These statements do not affect the string operations
+(e.g., MID$, RIGHT$, OR LEFT$) where the beginning character of a string
+is always index one.
+</para></sect2>
+<sect2><title>TRON and TROFF Statements</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>TRON</command>
+<sbr>
+<command>TROFF</command>
+</cmdsynopsis>
+These statements turn the trace mode on or off, and are useful for debugging.
+When trace mode is turned on, each statement is decompiled and printed
+before execution. Also, the result of each expression evaluation is printed as
+it occurs.
+</para></sect2>
+<sect2><title>Comment Statements</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>REM &lt;chars></command>
+<sbr>
+<command>(* &lt;chars> [ *) ]</command>
+</cmdsynopsis>
+These statements are used to put comments in programs. The second form
+of the statement is for compatibility with PASCAL programs. Comments
+are retained in the I-code but are removed by the PACK compile command.
+The "!" character can be typed in place of the keyword
+REM when editing programs. The compiler trims away extra spaces
+following REM to conserve memory space.
+</para>
+<para>
+Examples:
+<informalexample>
+<programlisting>
+REM this is a comment
+
+(* This is also a comment *)
+
+(* This is another kind of comment
+</programlisting>
+</informalexample>
+</para></sect2></sect1>
+<sect1><title>Declarative Statements</title>
+<para>
+The DIM, PARAM, and TYPE statements are called
+<emphasis>declarative statements</emphasis> because
+they are used to define and/or declare variables, arrays, and complex data
+structures. The DIM and PARAM statements
+are almost identical, the difference being that DIM are used to
+declare storage used exclusively within the procedure, and the PARAM statement
+is used to declare variables <emphasis>received</emphasis> from another calling procedure.
+</para>
+<para>
+When do you need to use the DIM statement?
+You don't need to for simple variables of type REAL because
+this is the default format for undeclared variables. You also don't need to
+for 32-character STRING type variables (any name ending with a
+"$" is automatically assigned this type). Even though you don't have to
+declare variables in these two cases, you may want to anyway to
+improve your program's internal documentation. Those
+things you <emphasis>must</emphasis> declare are:
+<orderedlist numeration="arabic">
+<listitem>
+<para>Any simple variables of type BYTE, INTEGER, or BOOLEAN.</para>
+</listitem>
+<listitem>
+<para>Any simple STRING variables shorter or longer than 32 characters.</para>
+</listitem>
+<listitem>
+<para>Arrays of any type.</para>
+</listitem>
+<listitem>
+<para>Complex data structures of any type.</para>
+</listitem>
+</orderedlist>
+</para>
+<para>
+The TYPE statement does not really create variable storage. Its purpose is to
+describe a <emphasis>new</emphasis> data structure type that can be used
+in DIM or PARAM statements in addition to the five atomic data
+types built-in to &b09;.
+Therefore, TYPE is only used in programs that use complex data structures.
+</para>
+<sect2><title>DIM Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>DIM &lt;decl seq> {; &lt;decl seq>}</command>
+<sbr>
+<command>&lt;decl seq> := &lt;decl> {, &lt;decl>} : &lt;type>}</command>
+<sbr>
+<command>&lt;decl> := &lt;name> [, &lt;subscript> ]</command>
+<sbr>
+<command>&lt;subscr> := ( &lt;const> [,&lt;const> [,&lt;const>]] )</command>
+<sbr>
+<command>&lt;type> := BYTE | INTEGER | REAL | BOOLEAN |
+ STRING | STRING &lt;max len> | &lt;user defined type></command>
+<sbr>
+<command>&lt;user def> := user defined by TYPE statement</command>
+</cmdsynopsis>
+The DIM statement is used to declare simple variables,
+arrays, or complex data structures of the five
+atomic types or any user-defined type. During compilation, &b09; assigns
+storage required for all variables declared in DIM statements.
+</para>
+<sect3><title>Declaring Simple Variables</title>
+<para>
+Simple variables are declared by using the variable name in a DIM
+statement without a subscript. If variables are not explicitly declared, they
+are automatically assumed to be REAL, or tpe STRING[32]
+if the variable name ends with a
+"$" character. Therefore all simple variables of other types
+must be explicitly declared. For example:
+
+<informalexample>
+<programlisting>
+DIM logical:BOOLEAN
+</programlisting>
+</informalexample>
+
+Several variables can be declared in sequence with a :&lt;type>
+following a group of the same type:
+<informalexample>
+<programlisting>
+DIM a,b,c: STRING
+</programlisting>
+</informalexample>
+In addition, several different types can be declared in a single DIM
+statement by using a semicolon ";" to separate different types:
+
+<informalexample>
+<programlisting>
+DIM a,b,c:INTEGER; n,m:decimal; x,y,z:BOOLEAN
+</programlisting>
+</informalexample>
+
+In this example a, b, and c are type INTEGER, n and m are type "decimal" (a
+user-defined type), and x, y, and z are type BOOLEAN.
+String variables are declared the same way except an optional
+maximum string length can be specified. If a length is not explicitly
+given, 32 characters are assumed:
+
+<informalexample>
+<programlisting>
+DIM name:STRING[40]; address,city:STRING; zip:REAL
+</programlisting>
+</informalexample>
+
+In this case, "name" is a string variable of 40 characters maximum, "address"
+and "city" are string variables of 32 characters each, and "zip" is a
+real variable.
+</para></sect3>
+<sect3><title>Array Declarations</title>
+<para>
+Arrays can have one, two, or three dimensions. The DIM statement format
+(including type grouping)
+is the same as for simple variables except each name is followed by
+subscript(s) to indicate its size. The maximum subscript size is
+32767. Simple variable and array declarations can be mixed
+in the same DIM statement:
+
+<informalexample>
+<programlisting>
+DIM a(10),b(20,30),c:INTEGER; x(5,5,5):STRING[12]
+</programlisting>
+</informalexample>
+
+In the example above, "a" is an array of 10 integers, "b" is a 20 by 30
+matrix of integers, "c" is a simple integer variable, and "x" is a
+three-dimensional array of 12-character strings.
+</para>
+<para>
+Arrays can be any atomic or user-defined type. By declaring arrays of
+user-defined types, structures of arbitrary complexity and shape can
+be generated.
+Here's an example declaration that generates a doubly-linked list
+of character strings. Each element of the array consists of the string
+containing the data and two integer "pointers".
+
+<informalexample>
+<programlisting>
+TYPE link_pointers = fwd,back: INTEGER
+TYPE element = data: STRING[64]; ptr: link_pointers
+DIM list(100): element
+
+(* make a circular list *)
+BASE0
+FOR index := 0 TO 99
+  list(index).data := "secret message " + STR$(index)
+  list(index).ptr.fwd := index+1
+  list(index).ptr.back := index­1
+NEXT index
+(* fix the ends *)
+list(0).ptr.back := 99
+list(99).ptr.fwd := 0
+
+(* Print the list *)
+index=0
+REPEAT
+  PRINT list(index).data
+  index := list(index).ptr.fwd
+UNTIL index=0
+END
+</programlisting>
+</informalexample>
+</para></sect3></sect2>
+<sect2><title>PARAM Statement</title>
+<para>
+Syntax: Same as DIM statement
+</para>
+<para>
+PARAM is identical to the DIM statement, but it does not create
+variable storage. Instead, it describes what parameters the "called" procedure
+expects to receive from the "calling" procedure.
+</para>
+<para>
+The programmer must insure that the total size of each
+parameter (as evaluated by the RUN statement in the calling procedure)
+conforms to the
+amount of storage expected for each parameter in the called procedure as
+specified by the PARAM statement.
+&b09; checks the size of each parameter (to prevent
+accidental access to storage other than the parameter)
+but DOES NOT CHECK TYPE. However, in most cases the programmer
+should ensure that the parameters evaluated in the RUN statement and
+sent to the called procedure agree exactly with the PARAM statement
+specification with respect to: the number of parameters, their order, size,
+shape, and type.
+</para>
+<para>
+Because type-checking is not performed, if you really know what you are
+doing you can make the parameter passing operation perform useful but
+normally illegal type conversions of identically-sized data structures. For
+example, passing a string of 80 characters to a procedure expecting a
+BYTE array having 80 elements assigns the numeric value of each
+character in the string to the corresponding element of the byte array.
+</para></sect2>
+<sect2><title>TYPE Statement</title>
+<para>
+Syntax:
+
+<cmdsynopsis>
+<command>TYPE &lt;type decl> {; &lt;type decl>}</command>
+<sbr>
+<command>&lt;type decl> := &lt;field name> . &lt;decl> : &lt;type>}</command>
+<sbr>
+<command>&lt;decl> := &lt;name> [, &lt;subscript> ]</command>
+<sbr>
+<command>&lt;subscript> := ( &lt;const> [,&lt;const> [,&lt;const>]] )</command>
+<sbr>
+<command>&lt;type> := BYTE | INTEGER | REAL | BOOLEAN |
+ STRING | STRING [&lt;max len>] | &lt;user defined></command>
+<sbr>
+<command>&lt;user defined> := user defined by TYPE statement</command>
+</cmdsynopsis>
+
+This statement is used to define new data types. New data types are
+defined as a "vector" (a one-dimensional array) of previously
+defined types. This structure differs from an array in that the
+various elements may be of different types, and the elements are
+accessed by field name instead of an array index.
+Here's an example:
+<informalexample>
+<programlisting>
+TYPE cust_recd := name,address(3):STRING; balance
+</programlisting>
+</informalexample>
+
+This example creates a new data type called "cust_recd" which has three
+named fields: a field called "name" which is a string, a field
+called "address" which is a vector of three strings; and
+a field called "balance" which is a (default) REAL value
+</para>
+<para>
+The TYPE statement can include previously-defined types so very
+complex non-rectangular data structures can be created such as
+lists, trees, etc. This statement  does not create any variable storage
+itself; the storage is created when the newly-defined type is used in a
+DIM statement.
+The example show below creates an array having 250 elements of type
+"cust_recd" that was defined above:
+
+<programlisting>
+DIM customer_file(250):cust_recd
+</programlisting>
+To access elements of the array in assignment statements, the field name
+is used as well as the index:
+<programlisting>
+name$ = customer_file(35).name
+customer_file(N+1).address(3) = "New York, NY"
+customer_file(X).balance= 125.98
+</programlisting>
+
+The complex structure allows creation of data types appropriate to
+the job at hand by providing more natural organization and
+association of data. Additionally, the position of the desired
+element is known and defined at compilation-time and need not be
+calculated at run time, unlike arrays, and can therefore be accessed
+faster than arrays.
+</para>
+</sect2></sect1>
+</chapter>
+
+
+<chapter>
+<title>Input and Output Operations</title>
+
+
+<sect1><title>Files and Unified Input/Output</title>
+<para>
+A file is a logical concept for a sequence of data which is
+saved for convenience in use and storage. File data may be pure
+binary data, textual data (ASCII characters), or any other useful
+information. Hardware input/output ("I/O") devices used by OS-9
+also work like files, so you can generally use any I/O facility
+regardless of whether you are
+working with disk files or I/O devices such as printers. This single
+interface standard for any device and simple communication facilities allow
+any device to be used with any other device. This concept is known as
+"unified I/O". Note that
+unified I/O can benefit routine programming. For example:
+file operations can be debugged by communicating with a terminal or
+printer instead of a storage device, and procedures which normally
+communicate with a terminal can be tested with data coming from and sent
+to a storage device.
+</para>
+<para>
+&b09; normally works with two types of files:
+sequential files and random-access files.
+</para>
+<para>
+A sequential file sends or receives (WRITE/READ) textual data only in
+order. It is not generally possible to start over at the beginning of
+a sequential file once a number of bytes have been accessed (many I/O
+devices such as printers are necessarily sequential).  A sequential
+file contains only valid ASCII characters; the READ and WRITE commands
+perform format conversion similar to that done automatically in INPUT and
+PRINT commands. A sequential file contains record-delimiter characters
+(carriage return) which separate the data created by different WRITE
+operations. Each WRITE command will send a complete sequential-file
+record, which is an arbitrary number of characters terminated by a
+carriage return. Each READ reads all characters up to the next carriage
+return.
+</para>
+<para>
+A random-access file sends and receives (PUT/GET) data in binary form
+exactly as it is internally represented in &b09;. This minimizes both the
+time involved in converting the data to and from ASCII representation,
+as well as reducing the file space required to store the data.  It is
+possible to PUT and GET individual bytes, or a substructure of many
+bytes (in a complex structure).  The GET structure statement merely
+recovers the number of bytes associated with that type of structure.
+It is possible to move to a particular byte in a random-access file
+(using SEEK) and to begin to PUT or GET sequentially from that point (in
+general, "SEEK #path,0" is equivalent to the REWIND used in some forms
+of BASIC). Since the random-access file contains no record-separators
+to indicate the size of particular elements of the file, the programmer
+should use the SIZE function to determine the size of a single element,
+then use SEEK to move to the desired element within the file.
+</para>
+<para>
+A new file is made on a storage device by executing CREATE. Once a file
+exists, the OPEN command is used to notify the operating system to set up
+a channel to the desired device and return that path number to the &b09;
+program. This channel number is then used in file-access operations (e.g.,
+READ, WRITE, GET, PUT, SEEK, etc.). When the programmer is finished with
+the file, it should be terminated by CLOSE to assure that the file system
+has updated all data back onto magnetic media.
+</para></sect1>
+<sect1><title>I/O Paths</title>
+<para>
+A "path" is a description of a "channel" through which data flows from a
+given program outward or from some device inward.  In order for data to
+flow to or from a device, there must be an associated OS-9 device driver
+&mdash; see the OS9 Users Manual.  When a path is created, OS-9 returns
+a unique number to identify the path in subsequent file operations. This
+"path number" is used by the I/O statements to specify the file to be
+used. Three path numbers have special meanings because they are "standard
+I/O paths" representing &b09;'s interactive input/output (your terminal).
+These are automatically "opened" for you and should not be closed except
+in very special circumstances. The standard I/O path numbers are:
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="0.3in">
+<tbody>
+<row>
+<entry>0</entry>
+<entry>Standard Input (Keyboard)</entry>
+</row>
+<row>
+<entry>1</entry>
+<entry>Standard Output (Display)</entry>
+</row>
+<row>
+<entry>2</entry>
+<entry>Standard Error/Status (Display)</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</para>
+<para>
+The table below is a summary of the I/O statements within &b09; and their
+general usage. This reflects typical usage; most statements can be used
+with any I/O device or file. Sometimes certain statements are used in
+unusual ways by advanced programmers to achieve certain special effects.
+<informaltable frame="none">
+<tgroup cols="3">
+<colspec colwidth="0.8in">
+<thead>
+<row>
+<entry>Statement</entry>
+<entry>Generally Used With</entry>
+<entry>Data Format (File Type)</entry>
+</row>
+</thead>
+<tbody>
+<row>
+<entry>INPUT</entry>
+<entry>Keyboard (interactive input)</entry>
+<entry>Text (Sequential)</entry>
+</row>
+<row>
+<entry>PRINT</entry>
+<entry>Terminals, Printers</entry>
+<entry>Text (Sequential)</entry>
+</row>
+<row>
+<entry>OPEN</entry>
+<entry>Disk Files and I/O Devices</entry>
+<entry>Any</entry>
+</row>
+<row>
+<entry>CREATE</entry>
+<entry>Disk Files and I/O Devices</entry>
+<entry>Any</entry>
+</row>
+<row>
+<entry>CLOSE</entry>
+<entry>Disk Files and I/O Devices</entry>
+<entry>Any</entry>
+</row>
+<row>
+<entry>DELETE</entry>
+<entry>Disk Files</entry>
+<entry>Any</entry>
+</row>
+<row>
+<entry>SEEK</entry>
+<entry>Disk Files</entry>
+<entry>Binary (Random)</entry>
+</row>
+<row>
+<entry>READ</entry>
+<entry>Disk Files</entry>
+<entry>Text (Sequential)</entry>
+</row>
+<row>
+<entry>WRITE</entry>
+<entry>Disk Files</entry>
+<entry>Text (Sequential)</entry>
+</row>
+<row>
+<entry>GET</entry>
+<entry>Disk Files and I/O Devices</entry>
+<entry>Binary (Random)</entry>
+</row>
+<row>
+<entry>PUT</entry>
+<entry>Disk Files and I/O Devices</entry>
+<entry>Binary (Random)</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+</para>
+<sect2><title>INPUT Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>INPUT [#&lt;int expr>,] ["&lt;prompt>",] &lt;input list></command>
+</cmdsynopsis>
+This statement accepts input during the execution of a program. The
+input is normally read from the standard input device (terminal)
+unless an optional path number is given. When the INPUT statement
+is encountered, program execution is suspended and a "?" prompt is
+displayed.  If the optional prompt string is given, it is displayed
+instead of the normal "?" prompt.  This means that the INPUT statement
+is really <emphasis>both</emphasis>
+an input and outout statement.  Therefore, if a path other than the
+default standard input path is used, the path should be open in UPDATE
+mode. This makes INPUT dangerous if used on disk files, unless you like
+prompts in your data (use READ).
+</para>
+<para>
+The data entered is assigned in order to the variable names in the order
+they appear in the input list. The variables can be of any atomic type,
+and the input data must be of the same (or compatible) type. The line
+is terminated by a carriage return. There must be at least as many input
+items given as variables in the input list. The length of the input line
+cannot exceed 256 characters.
+</para>
+<para>
+If any error occurs (type mismatch, insufficient amount of data, etc.), 
+the message:
+<screen>
+**INPUT ERROR ­ RETYPE**
+</screen>
+is displayed, followed by a new prompt. The entire input line must
+then be reentered.
+</para>
+<para>
+The INPUT statement
+uses OS-9's line input function (READLN) which performs line
+editing such as backspace, delete, end-of-file, etc. To perform input
+WITHOUT editing (i.e., to read pure binary data), use the GET statement.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+INPUT number,name$,location
+
+INPUT #14, "What is your selection", choice
+
+INPUT "What's your name? ",name$
+</programlisting>
+</informalexample>
+Here's how to read a single character (without editing) from the terminal
+(path #0):
+<informalexample>
+<programlisting>
+DIM char:STRING[1]
+GET #0,char
+</programlisting>
+</informalexample>
+For a function to test if data is available from the keyboard without
+"hanging" the program, see the "INKEY" assembly language program included
+in Appendix A.
+</para></sect2>
+<sect2><title>PRINT Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>PRINT &lt;output list></command>
+<sbr>
+<command>PRINT #&lt;int expr>, &lt;output list></command>
+<sbr>
+<command>PRINT USING &lt;str expr>, &lt;output list></command>
+<sbr>
+<command>PRINT #&lt;int expr>, USING &lt;str expr>, &lt;output list></command>
+</cmdsynopsis>
+This statement outputs the values of the items given in the output list
+to the standard output device (path #1, the terminal) unless another
+path number is specified.
+</para>
+<para>
+The output list consists of one or more items separated by commas or
+semicolon characters. Each item can be a constant, variable, or expression
+of any atomic type. The PRINT statement evaluates each item and converts
+the result to corresponding ASCII characters which are then displayed.
+If the separator character following the item is a semicolon, the
+next item will be displayed without any spacing in between. If a comma
+is used, spaces are output so the next item starts at the next "tab"
+zone. The tab zones are 16 characters long starting at the beginning of
+the line. If the line is terminated by a semicolon, the usual carriage
+return following the output line is inhibited.
+</para>
+<para>
+The "TAB(expr)" function can be used as an item in the output list, which
+outputs the correct number of spaces to cause the next item to start
+in the print column specified by the result of the expression. If the
+output line is already past the desired tab position, the TAB is ignored.
+A related function, "POS", can be used in the program to determine
+the output position at any given time. The output columns are numbered
+from one to a maximum of 255. The size of &b09;'s output buffer varies
+according to stack size at the moment.  A prectical values is at least
+512 characters.
+</para>
+<para>
+The PRINT USING form of this statement is described at the end of
+this chapter.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+PRINT value,temp+(n/2.5),location$
+
+PRINT #printer_path,"The result is "; n
+
+PRINT "what is " + name$ + "'s age? ";
+
+PRINT "index: ";i;TAB(25);"value:  ";value
+
+PRINT USING "R10.2,X2,R5.3",x,y
+
+PRINT #outpath USING fmt$,count,value
+
+(* print an 80­character line of all dashes *)
+REPEAT
+  PRINT "­";
+UNTIL POS >= 80
+PRINT
+</programlisting>
+</informalexample>
+
+</para></sect2>
+<sect2><title>OPEN Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>OPEN #&lt;int var>,"&lt;str expr>" [ : &lt;access mode> ]</command>
+<sbr>
+<command>&lt;access mode> := &lt;mode> ! &lt;mode> + &lt;access mode></command>
+<sbr>
+<command>&lt;mode> := READ ! WRITE ! UPDATE ! EXEC ! DIR</command>
+</cmdsynopsis>
+This statement issues a request to OS-9 to open an I/O path to an existing
+file or device.  The STRING expression is evaluated and passed to OS-9 as
+the descriptive pathlist.The variable name specified must be DIMensioned
+as type INTEGER or BYTE and is used "receive" the "path number" assigned
+to the path by OS-9. This path number is used to reference the specific
+file/device in subsequent input/output statements.
+</para>
+<para>
+The OPEN statement may also specify the path's desired "access mode" which
+can be READ, WRITE, UPDATE, EXEC, or DIR. This defines which direction I/O
+transfers will occur. If no access mode is specified, UPDATE is assumed
+and both reading and writing are permitted. The DIR mode allows OS-9
+directory type-files to be accessed but should NOT be used in combination
+with WRITE or UPDATE modes. The EXEC mode causes the current execution
+directory to be used instead of the current data directory.  Refer to the
+"OS-9 User's Guide" for more information on how files access modes.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+DIM printer_path:BYTE; name:STRING[24]
+name="/p"
+OPEN #printer_path,name:WRITE
+PRINT #printer_path,"Mary had a little lamb"
+CLOSE #printer_path
+
+DIM inpath:INTEGER
+dev$="/winchester/"
+INPUT name$
+OPEN #inpath,dev$+name$:READ
+
+OPEN #path:userdir$:READ+DIR
+
+OPEN #path,name$:WRITE+EXEC
+</programlisting>
+</informalexample>
+
+</para></sect2>
+<sect2><title>CREATE Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>CREATE #&lt;int var>,"&lt;str expr>" [ : &lt;access mode> ]</command>
+<sbr>
+<command>&lt;access mode> := &lt;mode> ! &lt;mode> + &lt;access mode></command>
+<sbr>
+<command>&lt;mode> := WRITE ! UPDATE ! EXEC</command>
+</cmdsynopsis>
+The CREATE statement is used to create a new file on a multifile mass storage
+device such as disk or tape. If the device is not of multifile type,
+this statement works like an "OPEN" statement.
+The variable name is used to receive the path number assigned by
+OS-9 and must be of BYTE or INTEGER type.  The STRING expression is
+evaluated and passed to OS-9 to be used as the descriptive pathlist.
+</para>
+<para>
+The "access mode" defines the direction of subsequent I/O transfers and
+should be either WRITE or UPDATE. "UPDATE" mode allows the file to be
+either read or written.
+</para>
+<para>
+OS-9 has a single file type that can be accessed both sequentially OR at
+random. Files are byte-addressed, so no explicit "record" length need be
+given (see GET and PUT statements). When a new file is created, it has an
+initial length of zero. Files are expanded automatically by PRINT, WRITE,
+or PUT statements that write beyond the current "end of file".
+File size may be set explicitly using the OS9 statement.
+</para>
+<para>
+Examples:
+<informalexample>
+<programlisting>
+CREATE #trans,"transactions":UPDATE
+
+CREATE #spool,"/user4/report":WRITE
+
+CREATE #outpath,name$:UPDATE+EXEC
+</programlisting>
+</informalexample>
+</para></sect2>
+<sect2><title>Close Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>CLOSE #&lt;int expr> {,#&lt;int expr>}</command>
+</cmdsynopsis>
+The CLOSE statement notifies OS-9 that one or more I/O paths are no longer
+needed. The paths are specified by their number(s). If the path closed
+used a non-sharable device (such as a printer), the device is released
+and can be assigned to another user. The path must have been previously
+established by means of the OPEN or CREATE statements.
+</para>
+<para>
+Paths #0, #1, and #2 (the standard I/O paths) should never be closed
+unless the user immediately opens a new path to take over the Standard
+Path number.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+CLOSE #master,#trans,#new_master
+
+CLOSE #5,#6,#9
+
+CLOSE  #1          \(* closes standard output path *)
+OPEN #path,"/T1"   \(* Permanently redirects Std Output *)
+
+CLOSE #0            \(* closes standard input path *)
+OPEN #path,"/TERM"  \(* Permanently redirects Std Input *)
+</programlisting>
+</informalexample>
+</para></sect2>
+<sect2><title>DELETE Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>DELETE &lt;str expr></command>
+</cmdsynopsis>
+This statement is used to delete a mass storage file. The file's name
+is removed from the directory and all its storage is deallocated, so any
+data on the file is permanently lost. The string expression is evaluated
+and passed to OS-9 as the descriptive pathlist of the file.
+</para>
+<para>
+The user must have write permission for the file to be deleted. See
+the "OS-9 User's Guide" for more information.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+DELETE "/D0/old_junk"
+
+name$="file55"
+DELETE name$
+DELETE "/D2/"+name$      (deletes file named "/D2/file55")
+</programlisting>
+</informalexample>
+
+
+</para></sect2>
+<sect2><title>SEEK Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>SEEK #&lt;int expr num>,&lt;real expr></command>
+</cmdsynopsis>
+SEEK changes the file pointer address of a mass storage file,
+which is the address of the next data byte(s) that are to be read or
+written next. Therefore, this statement is essential for random access
+of data on files using the GET and PUT statements.
+</para>
+<para>
+The first expression specifies the path number of
+the file and must evaluate to a byte value. The second expression specifies
+the desired file pointer address, and must evaluate to a REAL
+value in the range 0 &lt;= result &lt;= 2,147,483,648. Any fractional
+part of the result is truncated. Of course, the actual maximum file size
+depends on the capacity of the device.
+</para>
+<para>
+Although SEEK is normally used with random-access files, it can be used
+to "rewind" sequential files. For example:
+
+<programlisting>
+SEEK #path,0
+</programlisting>
+is the same as a "rewind" or "restore" function. This is the only form of
+the SEEK statement that is generally useful for files accessed by READ
+and WRITE statements. These statements use variable-length records, so
+it is difficult to know the address of any particular record in the file.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+SEEK #fileone,filptr*2
+
+SEEK #outfile,208894
+
+SEEK #inventory,(part_num ­ 1) * SIZE(inv_rcd)
+</programlisting>
+</informalexample>
+
+</para></sect2>
+<sect2><title>WRITE Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>WRITE #&lt;int expr>,&lt;output list></command>
+</cmdsynopsis>
+This statement writes data in ASCII character format on a file/device. The
+first expression specifies the number of a path that was previously
+opened by a OPEN or CREATE statement in WRITE or UPDATE mode.
+</para>
+<para>
+The output list consists of one or more expressions separated by commas.
+Each expression can evaluate to any expression type. The result is then
+converted to an ASCII character string and written on the specified path
+beginning at the present file pointer which is updated as data is written.
+</para>
+<para>
+If the output list has more than one item, ASCII null characters ($00)
+are written between each output string. The last item is followed by a
+carriage return character.
+</para>
+<para>
+Note that this statement creates variable-length ASCII records.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+WRITE #outpath,cat,dog,mouse
+
+WRITE #xfile,LEFT$(A$,n),count/2
+</programlisting>
+</informalexample>
+</para></sect2>
+<sect2><title>READ Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>READ #&lt;int expr num>,&lt;input list></command>
+</cmdsynopsis>
+This statement causes input data in ASCII character format to be read
+from a file or device.  The first expression specifies a path number.
+The path number which must have been previously opened by an OPEN or CREATE
+statement in READ or UPDATE access mode (except the standard input path #0).
+Data is read starting at the path's current file pointer address which
+is updated as data is read.
+</para>
+<para>
+This statement calls OS-9 to read a variable length ASCII
+record. Individual data items within the record are converted to &b09;'s
+internal binary format.  These results are assigned in order to the
+variables given in the input list. The input data must match the
+number and type of the variables in the input list.
+</para>
+<para>
+The individual data items in the input record are separated by ASCII
+null characters. Numeric items can also be delimited by commas or space
+characters. The input record is terminated by a carriage return character.
+</para>
+<para>
+Examples:
+
+<informalexample>
+<programlisting>
+READ #inpath,name$,address$,city$,state$,zip
+
+PRINT #1,"height,weight? "
+READ #0,height,weight
+</programlisting>
+</informalexample>
+
+<note>
+<para>
+READ is also used to read lists of expressions in the program.
+See the DATA statement section for details.
+</para>
+</note>
+</para></sect2>
+<sect2><title>GET/PUT Statement</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>GET #&lt;expr>,&lt;struct name></command>
+<sbr>
+<command>PUT #&lt;expr>,&lt;struct name></command>
+</cmdsynopsis>
+The GET and PUT statements read and write fixed-size binary data records
+to files or devices. These are the primary I/O statements
+used for random access input and output.
+</para>
+<para>
+The first expression is evaluated and used as the number of the
+I/O path which must have previously been opened by an OPEN or CREATE
+statement. Paths used by PUT statements must have been opened in WRITE
+or UPDATE access modes, and paths used by GET statements must be in READ
+or UPDATE mode.
+</para>
+<para>
+The statement uses exactly one name which can be the name of a variable,
+array, or complex data structure. Data is written from, or read into, the
+variable or structure named. The data is transferred in &b09;'s internal
+binary format without conversion which affords very high throughput
+compared to READ and WRITE statements. Data is transferred beginning
+at the current position of the path's file pointer (see SEEK statement)
+which is automatically updated.
+</para>
+<para>
+OS-9's file system does not inherently impose record structures on
+random-access files. All files are considered to be continuous sequences of
+addressable binary bytes. A byte or group of bytes located anywhere in the
+file can be read or written in any order. Therefore the
+<emphasis>programmer</emphasis> is free to use the basic file access
+system to create any record structure desired.
+</para>
+<para>
+Record I/O in &b09; is associated with data structures defined by DIM
+and TYPE statements. The GET and PUT statements write entire data
+structures or parts of data structures. A PUT statement, for example,
+can write a simple variable, an entire array, or a complex data structure
+in one operation.  To illustrate how this works, here is an example
+based on a simple inventory system that requires a random access file
+having 100 records.  Each record must include the following information:
+the name of the item (a 25-byte character string), the item's list price
+and cost (both real numbers), and the quantity on hand (an integer).
+</para>
+<para>
+First it is necesary to use the TYPE statement to define a new
+data type that describes such a record. For example:
+<informalexample>
+<programlisting>
+TYPE inv_item=name:STRING[25];list,cost:REAL;qty:INTEGER
+</programlisting>
+</informalexample>
+This statement describes a new record type called "inv_item" but does not
+cause variable storage to be assigned for it. The next step is to create
+two data structures: an array of 100 "records" of type "inv_item" to be called
+"inv_array" and a single working record called "work_rec":
+<programlisting>
+DIM inv_array(100):inv_item
+DIM work_rec:inv_item
+</programlisting>
+You can manually count the number of bytes assigned for each type to
+calculate the total size of each record. Sometimes these can become
+complicated and error-prone. Also, any change in a TYPE definition
+could require recalculation. Fortunately, &b09; has a built-in
+function:
+
+<programlisting>
+SIZE(&lt;name>)
+</programlisting>
+that returns the number of bytes assigned to any variable, array, or
+complex data structure. In our example, SIZE(work_rec) will return the number
+37, and SIZE(inv_array) will return 3700. The size function is often
+used in conjunction with the SEEK statement to position a file pointer
+to a specific record's address.
+</para>
+<para>
+The procedure below creates a file called "inventory" and initializes it
+with zeroes and nulls:
+
+<programlisting>
+PROCEDURE makefile
+TYPE inv_item = name:STRING[25]; list,cost:REAL; qty:INTEGER
+DIM inv_array(100):inv_item
+DIM work_rec:inv_item
+DIM path:byte
+CREATE #path,"inventory"
+work_rec.name = ""
+work_rec.list := 0.
+work_rec.cost := 0.
+work_rec.qty := 0
+FOR n = 1 TO 100
+  PUT #path,work_rec
+NEXT n
+END
+</programlisting>
+
+Notice that the assignment statements referenced each named "field" of
+work_rec by name, but PUT referenced the record as a whole.
+</para>
+<para>
+The subroutine below asks for a record number, then asks for data, and
+writes it in the file at the specified record:
+
+<programlisting>
+INPUT "Record number ?",recnum
+INPUT "Item name? ",work_rec.name
+INPUT "List price? ",work_rec.list
+INPUT "Cost price? ",work_rec.cost
+INPUT "Quantity? ",work_rec.qty
+SEEK #path, (recnum ­ 1) * SIZE(work_rec)
+PUT #path,work_rec
+</programlisting>
+This routine below uses a loop to read the entire file into the array
+"inv_array":
+
+<programlisting>
+SEEK #path,0 \ (* "rewind" the file *)
+FOR k = 1 TO 100
+  GET #path,inv_array(k)
+NEXT k
+</programlisting>
+
+Because ENTIRE STRUCTURES can be read, we can eliminate the FOR/NEXT
+loop and do exactly the same thing by:
+
+<programlisting>
+SEEK #path,0
+GET #path,inv_array
+</programlisting>
+
+The above example is a very simple case, but it illustrates the combined
+power of &b09; complex data structures and the random access I/O
+statements. When fully exploited, this system has the following important
+characteristics:
+<orderedlist  numeration="arabic">
+<listitem>
+<para>
+It is self-documenting. You can clearly see what a program does because
+structures have descriptive, named sub-structures.
+</para>
+</listitem>
+
+<listitem>
+<para>
+It is extremely fast.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Programs are simplified and require fewer statements to perform I/O
+functions than in other BASICs.
+</para>
+</listitem>
+
+<listitem>
+<para>
+It is versatile. By creating appropriate data structures you can read
+or write almost any kind of data in any file, including files created by
+other programs or languages.
+</para>
+</listitem>
+</orderedlist>
+
+These advantages are possible because a single GET or PUT statement can
+move any amount of data, organized any way you want.
+</para></sect2></sect1>
+<sect1><title>Internal Data Statements</title>
+<sect2><title>DATA/READ/RESTORE Statements</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>READ &lt;input list></command>
+<sbr>
+<command>DATA &lt;expr> , { &lt;expr> }</command>
+<sbr>
+<command>RESTORE [ &lt;line number> ]</command>
+</cmdsynopsis>
+These statements provide an efficient way to build constant tables
+within a program.  DATA statements provide values, the READ statement
+assign the values to variables, and RESTORE statements can be used to
+set which data statement is to be read next.
+</para>
+<para>
+The DATA statements have one or more expressions separated by commas.
+They can be located anywhere in a program. The expressions are evaluated
+each time the data statements are read and can evaluate to any type.
+Here are some examples:
+<informalexample>
+<programlisting>
+DATA 1.1,1.5,9999,"CAT","DOG"
+DATA SIN(temp/25), COS(temp*PI)
+DATA TRUE,FALSE,TRUE,TRUE,FALSE
+</programlisting>
+</informalexample>
+</para>
+<para>
+The READ statement has a list of one or more variable names. When
+executed, it gets "input" by evaluating the current expression in the
+current data statement. The result must match the type of the variable. When
+all the expressions in a DATA statement have been evaluated, the next
+DATA statement (in sequential order) is used. If there are no more DATA
+statements following, processing "wraps around" to the first data statement
+in the program.
+</para>
+<para>
+The RESTORE statement used without a line number causes the first DATA
+statement in the program to be used next. If it is used with a line
+number, the data statement having that line number is used next.
+</para>
+<para>
+Examples:
+<informalexample>
+<programlisting>
+    DATA 1,2,3,4
+    DATA 5,6,7,8
+100 DATA 9,10,11,12
+    FOR N := 1 TO X
+      READ ARRAY(N)
+    NEXT N
+    RESTORE 100
+    READ A,B,C,D
+</programlisting>
+</informalexample>
+</para></sect2></sect1>
+<sect1><title>Formatted Output: The Print Using Statement</title>
+<para>
+&b09; has a powerful output editing capability useful for report generation
+and other applications where formatted output is required. The
+output editing uses the PRINT USING statement which has the following
+syntax:
+<cmdsynopsis>
+<command>PRINT [&lt;expr#>,] USING &lt;str expr> , &lt;output list></command>
+</cmdsynopsis>
+The optional path number expression can be used to specify the path
+number of any output file or device. If it is omitted, the output is
+written to the standard output path (usually the terminal).
+</para>
+<para>
+The string expression is evaluated and used as a "format specification"
+which contains specific formatting directives for each item in the "output
+list".  The items in the output list can be constants, variables, or
+expressions of any atomic type. BLANKS ARE NOT ALLOWED IN FORMAT STRINGS!
+As each output item is processed, it is matched up with a specification
+in the format list. The type of each expression result must be compatible
+with the corresponding format specification. If there are fewer format
+specifications than items in the output list, the format specification
+list is repeated again from its beginning as many times as necessary.
+</para>
+<para>
+A format string has one or more format specifications which are separated
+by commas. There are two kinds of specifications: ones that control
+output editing of an item from the output list, and ones that cause an
+output function by themselves (such as tabbing and spacing).  There are
+six basic output editing directives. Each has a corresponding one-letter
+identifier:
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="0.6in">
+<tbody>
+<row>
+<entry>R</entry>
+<entry>real format</entry>
+</row>
+<row>
+<entry>E</entry>
+<entry>exponential format</entry>
+</row>
+<row>
+<entry>I</entry>
+<entry>integer format</entry>
+</row>
+<row>
+<entry>H</entry>
+<entry>hexadecimal format</entry>
+</row>
+<row>
+<entry>S</entry>
+<entry>string format</entry>
+</row>
+<row>
+<entry>B</entry>
+<entry>boolean format</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+The identifier letter is followed by a constant number called the "field
+width". This number indicates the exact number of print columns the
+output is to occupy and must allow for the data AND "overhead" character
+positions such as sign characters, decimal points, exponents, etc.
+Some formats have additional mandatory or optional parameters that
+control subfields or select editing options. One of these options is
+"justification" which specifies whether the output is to "line up" on
+the left, right side, or center of the output field. Fields are commonly
+right-justified in reports because it arranges them into neat columns
+with decimal points aligned in the same position.
+</para>
+<para>
+The abbreviations and symbols used in the syntax specifications are:
+
+<informaltable frame="none">
+<tgroup cols="3">
+<colspec colwidth="0.4in">
+<tbody>
+<row>
+<entry>w</entry>
+<entry>Total field width</entry>
+<entry>1 &lt;= w &lt;= 255</entry>
+</row>
+<row>
+<entry>f</entry>
+<entry>Fraction field</entry>
+<entry>1 &lt;= w &lt;= 9</entry>
+</row>
+<row>
+<entry>j</entry>
+<entry>OPTIONAL justification</entry>
+<entry>&lt; (left) > (right) ^ (center)</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+</para>
+<sect2><title>Real Format</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>Rw.fj</command>
+</cmdsynopsis>
+This format can be used for numbers of types REAL, INTEGER, or
+BYTE. The total field width specification must include two overhead
+positions for the sign and decimal point. The "f" specifies how many
+fractional digits to the right of the decimal point are to be
+displayed. If the number has more significant digits than the field
+allows for, the undisplayed places are used to round the displayed digits. For
+example:
+
+<programlisting>
+PRINT USING "R8.2", 12.349  gives    12.35
+</programlisting>
+
+The justification modes are:
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="0.3in">
+<tbody>
+<row>
+<entry>&lt;</entry>
+<entry>Left justify with leading sign and trailing spaces. (default if
+justification mode omitted)</entry>
+</row>
+<row>
+<entry>></entry>
+<entry>right justify with leading spaces and sign.</entry>
+</row>
+<row>
+<entry>^</entry>
+<entry>right justify with leading spaces and trailing sign
+(financial format)</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+
+Examples:
+
+<informalexample>
+<programlisting>
+PRINT USING "R8.2&lt;",5678.123          5678.12
+PRINT USING "R8.2>",12.3                   12.30
+PRINT USING "R8.2&lt;",­555.9            ­555.90
+PRINT USING "10.2^",­6722.4599            6722.46­
+PRINT USING "R5.1","9999999"            *****
+</programlisting>
+</informalexample>
+</para></sect2>
+<sect2><title>Exponential Format</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>Ew.fj</command>
+</cmdsynopsis>
+This format prints numbers of types REAL, INTEGER, or BYTE
+in the scientific notation format using a mantissa and decimal exponent.
+The syntax and behavior of this format is similar to the REAL format
+except the "w" field width must allow for eight overhead positions for the
+mantissa sign, decimal point, and exponent characters.
+The "&lt;" and "&gt;" justification modes are allowed and work the same way.
+</para>
+<para>
+Example:
+
+<informalexample>
+<programlisting>
+PRINT USING "E12.3",1234.567               1.235E+03
+
+PRINT USING "E12.6>",­0.001234            ­1.234000E-3
+</programlisting>
+</informalexample>
+
+</para></sect2>
+<sect2><title>Integer Format</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>Iwj</command>
+</cmdsynopsis>
+This format is used to display numbers of types INTEGER or BYTE,
+and REAL numbers that are within range for automatic type conversion.
+The "w" field width must allow for one position overhead for the sign.
+The justification modes are:
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="0.3in">
+<tbody>
+<row>
+<entry>&lt;</entry>
+<entry>left justify with leading sign and trailing spaces (default)</entry>
+</row>
+<row>
+<entry>></entry>
+<entry>right justify with leading spaces and sign</entry>
+</row>
+<row>
+<entry>^</entry>
+<entry>right justify with leading spaces and zeroes</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+Example:
+<informalexample>
+<programlisting>
+PRINT USING "I4&lt;",10         10
+
+PRINT USING "I4>",10             10
+
+PRINT USING "I4^",10             010
+</programlisting>
+</informalexample>
+
+
+</para></sect2>
+<sect2><title>Hexadecimal Format</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>Hwj</command>
+</cmdsynopsis>
+This format can be used to display the internal binary representation
+of ANY data type, using hexadecimal characters. The "w" field width
+specification determines the number of hexadecimal characters to
+output. Justification modes are:
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="0.3in">
+<tbody>
+<row>
+<entry>&lt;</entry>
+<entry>left justify with trailing spaces</entry>
+</row>
+<row>
+<entry>></entry>
+<entry>right justify, leading spaces</entry>
+</row>
+<row>
+<entry>^</entry>
+<entry>center justify</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+Because the number of bytes of memory used to represent data varies
+according to type, the following specification make the most sense for
+each data type:
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="0.5in">
+<tbody>
+<row>
+<entry>H2</entry>
+<entry>boolean, byte (one byte)</entry>
+</row>
+<row>
+<entry>H4</entry>
+<entry>integer (two bytes)</entry>
+</row>
+<row>
+<entry>H10</entry>
+<entry>real (five bytes)</entry>
+</row>
+<row>
+<entry>Hn*2</entry>
+<entry>string of length n</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+
+Examples:
+
+<informalexample>
+<programlisting>
+PRINT USING "H4",100               00C4
+
+PRINT USING "H4",-1                FFFF
+
+PRINT USING "H10",1.5              01D0000000
+
+PRINT USING "H8","ABC"             414243
+</programlisting>
+</informalexample>
+</para></sect2>
+<sect2><title>String Format</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>Swj</command>
+</cmdsynopsis>
+This format is used to display string data of any length. The "w" field
+width specifies the total field size. If the string to be displayed is
+shorter than the field size, it is padded with spaces according to the
+justification mode.  If it is too long, it will be truncated on the right side.
+The format specifications are:
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="0.3in">
+<tbody>
+<row>
+<entry>&lt;</entry>
+<entry>Left justify (default if mode omitted)</entry>
+</row>
+<row>
+<entry>></entry>
+<entry>right justify</entry>
+</row>
+<row>
+<entry>^</entry>
+<entry>Center justify</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+Examples:
+
+<informalexample>
+<programlisting>
+PRINT USING "S8&lt;","HELLO"         HELLO
+
+PRINT USING "S8>","HELLO"               HELLO
+
+PRINT USING "S8^","HELLO"             HELLO
+</programlisting>
+</informalexample>
+
+
+</para></sect2>
+<sect2><title>Boolean Format</title>
+<para>
+Syntax:
+<cmdsynopsis>
+<command>Bwj</command>
+</cmdsynopsis>
+This format is used to display boolean data. The result of the boolean
+expression is converted to the strings "TRUE" and "FALSE".
+The specification is otherwise identical to the STRING format.
+</para></sect2>
+<sect2><title>Control Specifications</title>
+<para>
+Control specifications are useful for horizontal formatting of the output
+line. They are not matched with items in the output list and can be used
+freely. The control formats are
+
+<informaltable frame="none">
+<tgroup cols="2">
+<colspec colwidth="0.5in">
+<tbody>
+<row>
+<entry>Tn</entry>
+<entry>Tab to column n</entry>
+</row>
+<row>
+<entry>Xn</entry>
+<entry>Space n columns</entry>
+</row>
+<row>
+<entry>'str'</entry>
+<entry>Include constant string. The string must not include single or
+double quotes, backslash or carriage return characters.</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+Warning: Control specifications at the end of the format
+specification list will NOT be processed if all output items have
+been exhausted.
+</para>
+<para>
+Example
+
+<informalexample>
+<programlisting>
+PRINT USING "'addr',X2,H4,X2,'data',X2,H2",1000,100     prints
+
+addr  03E8  data  C4
+</programlisting>
+</informalexample>
+</para></sect2>
+<sect2><title>Repeat Groups</title>
+<para>
+Many times identical sequences of specifications are repeated in format
+specification lists. The repeated groups can be enclosed in parentheses and
+preceded by a repeat count. These repeat groups can be nested.
+Here are some examples:
+
+<informalexample>
+<programlisting>
+"2(X2,R10.5)" is the same as  "X2,R10.5,X2,R10.5"
+
+"2(I2,2(X1,S4))" is the same as "I2,X1,S4,X1,S4,I2,X1,S4,X1,S4"
+ </programlisting>
+ </informalexample>
+</para>
+</sect2>
+</sect1>
+</chapter>
+
+<chapter>
+<title>Program Optimization</title>
+<sect1><title>General Execution Performance of &b09;</title>
+<para>
+The &b09; multipass compiler produces a compressed and
+optimized low-level "I-code" for execution. Compared to other BASIC
+languages program storage is greatly decreased and execution speed
+is increased.
+</para>
+<para>
+High-level language interpreters have a general reputation for slowness
+which is probably not deserved.  Because the &b09; I-code is kept at
+a powerful level, a single, fast I-code interpretation will so that
+there is often result in many MPU instruction cycles (such as execution
+of floating-point arithmetic operations). Thus, for complex programs
+there is little performance difference between execution of I-code and
+straight machine-language instructions.  This is generally not the case
+with traditional BASIC interpreters that have to "compile" from text as
+they run or even "tokenized" BASICs that must perform table-searching
+during execution.  &b09; I-code instructions that reference variable
+storage, statements, labels, etc., contain the actual memory addresses
+so no table searching is ever required.  Off course, &b09; fully exploits
+the power of the 6809's instruction set which was optimized for efficient
+execution of compiler-produced code.
+</para>
+<para>
+Because the &b09; I-code is interpreted, a variety of entry-time
+tests and run-time tests and development aids are available to help
+in program development; aids not available on most compilers.
+The editor reports errors immediately when they are entered,
+the debugger allows debugging using the original program source
+statements and names, and
+the I-code interpreter performs run-time error checking of things such
+as array bound errors, subroutine nesting, arithmetic errors, and other
+errors that are not detected (and usually crash) native-compiler-generated
+code.
+
+</para></sect1>
+<sect1><title>Optimum Use of Numeric Data Types</title>
+<para>
+Because &b09; includes several different numeric representations
+(i.e., REAL, INTEGER, and BYTE) and does "automatic type conversions"
+between them, it is easy to write expressions or loops that take at
+least ten times longer to execute than is necessary. Some particular
+&b09; numeric operators (+, ­, *, /) and control structures (FOR..NEXT)
+include versions for both REAL and INTEGER values. The INTEGER versions,
+off course, are much faster and may have slightly different properties
+(e.g., INTEGER divides discard any remainder). Type conversions takes
+time so expressions whose operands and operators are of the same type
+are more efficient.
+</para>
+<para>
+&b09;'s REAL (floaing point) math package provides excellent
+performance. A special 40-bit binary floating point representation
+designed for speed and accuracy was developed especially for &b09;
+after exhaustive research. The new CORDIC technique is used to derive
+all transcendental functions (SIN, TAN, LOG, EXP, etc.).  This integer
+shit-and-add technique is faster and more consistantly accurate than
+the commonly used series-expansion approximations.
+</para>
+<para>
+Nonetheless, INTEGER operations are faster because they generally have
+corresponding 6809 machine-language instructions. Overall program speed
+will increase and storage requirements will decrease if INTEGERs are used
+whenever possible. INTEGER arithmetic operations use the same symbols as
+REAL but &b09; automatically selects the INTEGER operations when working
+with an integer-value result. Only if all operands of an expression are
+of types BYTE or INTEGER will the result also be INTEGER.
+</para>
+<para>
+Sometimes, similar or identical results can be obtained in a number
+of different ways at various execution speeds. For example, if the
+variable "value" is an integer, then "value*2" will be a fast integer
+operation. However, if the expression is "value*2.0" the value "2.0"
+will be represented as a REAL number, and the multiplication will be a
+REAL multiplication. This will also require that the variable "value"
+will have to be transformed into a REAL value, and finally the result of
+the expression will have to be transformed back to an INTEGER value if
+it is to be assigned to a variable of that type. Thus a single decimal
+point will slow this particular operation down by about ten times!
+<table frame="none">
+<title>Arithmetic Functions Ranked by Speed</title>
+<tgroup cols="2">
+<colspec colwidth="3in">
+<colspec colwidth="2in">
+<thead>
+<row>
+<entry>Operation</entry>
+<entry>Typical Speed (MPU Cycles)</entry>
+</row>
+</thead>
+<tbody>
+<row>
+<entry>INTEGER ADD OR SUBTRACT</entry>
+<entry>150</entry>
+</row>
+<row>
+<entry>INTEGER MULTIPLY</entry>
+<entry>240</entry>
+</row>
+<row>
+<entry>REAL ADD</entry>
+<entry>440</entry>
+</row>
+<row>
+<entry>REAL SUBTRACT</entry>
+<entry>540</entry>
+</row>
+<row>
+<entry>INTEGER DIVIDE</entry>
+<entry>960</entry>
+</row>
+<row>
+<entry>REAL MULTIPLY</entry>
+<entry>990</entry>
+</row>
+<row>
+<entry>REAL DIVIDE</entry>
+<entry>3870</entry>
+</row>
+<row>
+<entry>REAL SQUARE ROOT</entry>
+<entry>7360</entry>
+</row>
+<row>
+<entry>REAL LOGARITM OR EXPONENTIAL</entry>
+<entry>20400</entry>
+</row>
+<row>
+<entry>REAL SINE OR COSINE</entry>
+<entry>32500</entry>
+</row>
+<row>
+<entry>REAL POWER (^)</entry>
+<entry>39200</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+</para>
+<para>
+This table can be used to deduce some interesting points. For
+example, "value*2" is not optimum - "value+value" can produce the
+same result in less time because multiplication takes longer than
+addition. Similarly, "value*value" or "SQ(value)" is MUCH faster
+than the equivalent "value^2". Another interesting case is "x/2.0".
+The REAL divide will cost 3870 cycles, but REAL multiplcation takes
+only 990 cycles. The mathematical equivalent to division by a
+constant is multiplication by the inverse of the constant.
+Therefore, using "X*0.5" instead is almost four times faster!
+</para></sect1>
+
+<sect1><title>Looping Quickly</title>
+<para>
+When &b09; identifies a FOR..NEXT loop structure with an INTEGER
+loop counter variable, it uses a special integer version of the FOR..NEXT
+loop. This is much faster than the REAL-type version and is generally
+preferable. Other kinds of loops also run faster if INTEGER type variables
+are used for loop counters.
+</para>
+<para>
+When writing program loops, remember that statements INSIDE the loop
+may be executed many times for each single execution OUTSIDE the loop.
+Thus, any value which can be computed before entering a loop will increase
+program speed.
+</para></sect1>
+<sect1><title>Optimum Use of Arrays and Data Structures</title>
+<para>
+&b09; internally uses INTEGER numbers to index arrays and complex data
+structures. If the program uses subscripts that are REAL type variables
+or expressions, &b09; has to convert them to INTEGERs before they can
+be used. This takes additional time, so use INTEGER expressions for
+subscripts whenever you can.
+</para>
+<para>
+Note that the assignment statement (LET) can copy identically sized data
+structures. This feature is much faster than copying arrays or structures
+element-by-element inside a loop.
+</para></sect1>
+<sect1><title>The PACK Command</title>
+<para>
+The PACK command produces a compressed version of a &b09;
+procedure. Depending on the number of comments, line numbers, etc.,
+programs will execute from 10% to 30% faster after being packed. Minimizing
+use of line numbers will even speed up procedures that are unPACKed.
+</para></sect1>
+<sect1><title>Eliminating Constant Expressions and Sub-Expressions</title>
+<para>
+Consider the expression:
+<programlisting>
+x = x+SQRT(100)/2
+</programlisting>
+
+is exactly the same as the expression:
+<programlisting>
+x = x+5
+</programlisting>
+The subexpression "SQRT(100)/2" consists of constants only, so its result
+will not vary regardless of the rest of the program. But every time the
+program is run, the computer must evaluate it. This time can be significant,
+especially if the statement is within a loop. Constant expressions or
+subexpressions should be calculated by the programmer while writing the program
+(using DEBUG mode or a pocket calculator).
+</para></sect1>
+<sect1><title>Fast Input and Output Functions</title>
+<para>
+Reading or writing data a line or record at a time is much faster than a
+character at a time. Also, the GET and PUT statements are much faster
+than READ and WRITE statements when dealing with disk files. This is
+because GET and PUT use the exact binary format used internally by
+&b09;. READ, WRITE, PRINT, and INPUT must perform binary-to-ASCII or
+ASCII-to-binary conversions which take time.
+</para></sect1>
+<sect1><title>Professional Programming Techniques</title>
+<para>
+One sure way to make a program faster is to use the most
+efficient algorithms possible. There are many good programming
+"cookbooks" that explain useful algorithms with examples in BASIC or PASCAL.
+Thanks to &b09;'s rich vocabulary you can use algorithms written in either
+language with little or no adaptation.
+</para>
+<para>
+&b09; also eliminates any possible excuse for not using good
+structured programming style that produces
+efficient, reliable, readable, and maintainable software. &b09; generates
+optimized code to be executed by the 6809 which is the most
+powerful 8-bit processor in existence at the time of this writing.
+But a computer can only execute what
+it is told to execute, and no language implementation can make up for an
+inefficient program. An inefficient program is evidence of a lack of
+understanding of the problem. The result is likely to be hard to understand
+and hard to update if program specifications change (they always do). The
+identification of efficient algorithms and their clear, structured
+expression is indicative of professionalism in software design and is a goal
+in itself.
+</para>
+</sect1>
+</chapter>
+
+
+
+<appendix>
+<title>Sample Programs</title>
+<para>
+<programlisting>
+PROCEDURE fibonacci
+  REM computes the first ten Fibonacci numbers
+  DIM x,y,i,temp:INTEGER
+
+  x:=0 \y:=0
+  FOR i=0 TO 10
+    temp:=y
+
+    IF i&lt;>0 THEN
+    y:=y+x
+    ELSE y:=1
+    ENDIF
+
+    x:=temp
+    PRINT i,y
+  NEXT i
+</programlisting>
+
+<programlisting>
+PROCEDURE fractions
+  REM by T.F. Ritter
+  REM finds increasingly­close rational approximations
+  REM to the desired real value
+  DIM m:INTEGER
+
+  desired:=PI
+  last:=0
+
+  FOR m=1 TO 30000
+    n:=INT(.5+m*desired)
+    trial:=n/m
+    IF ABS(trial­desired)&lt;ABS(last­desired) THEN
+      PRINT n; "/"; m; " = "; trial,
+      PRINT "difference = "; trial­desired;
+      PRINT
+      last:=trial
+    ENDIF
+  NEXT m
+</programlisting>
+
+<programlisting>
+PROCEDURE prinbi
+   REM by T.F. Ritter
+   REM prints the integer parameter value in binary
+   PARAM n:INTEGER
+   DIM i:INTEGER
+
+   FOR i=15 TO 0 STEP ­1
+     IF n&lt;0 THEN
+       PRINT "1";
+     ELSE PRINT "0";
+     ENDIF
+     n:=n+n
+   NEXT i
+   PRINT
+
+  END
+</programlisting>
+
+<programlisting>
+PROCEDURE hanoi
+  REM by T.F. Ritter
+  REM move n discs in Tower of Hanoi game
+  REM See BYTE Magazine, Oct 1980, pg. 279
+
+  PARAM n:INTEGER; from,to_,other:STRING[8]
+
+  IF n=1 THEN
+     PRINT "move #"; n; " from "; from; " to "; to_
+  ELSE
+    RUN hanoi(n­1,from,other,to_)
+    PRINT "move #"; n; " from "; from; " to "; to_
+    RUN hanoi(n­1,other,to_,from)
+  ENDIF
+
+  END
+</programlisting>
+
+<programlisting>
+PROCEDURE roman
+  REM prints integer parameter as Roman Numeral
+  PARAM x:INTEGER
+  DIM value,svalu,i:INTEGER
+  DIM char,subs:STRING
+
+  char:="MDCLXVI"
+  subs:="CCXXII "
+  DATA 1000,100,500,100,100,10,50,10,10,1,5,1,1,0
+
+  FOR i=1 TO 7
+    READ value
+    READ svalu
+
+    WHILE x>=value DO
+      PRINT MID$(char,i,1);
+      x:=x­value
+    ENDWHILE
+
+    IF x>=value­svalu THEN
+      PRINT MID$(subs,i,1); MID$(char,i,1);
+      x:=x­value+svalu
+    ENDIF
+
+  NEXT i
+  END
+</programlisting>
+
+<programlisting>
+PROCEDURE eightqueens
+  REM originally by N. Wirth; here re­coded from Pascal
+  REM finds the arrangements by which eight queens
+  REM can be placed on a chess board without conflict
+  DIM n,k,x(8):INTEGER
+  DIM col(8),up(15),down(15):BOOLEAN
+  BASE 0
+
+  (* initialize empty board *)
+  n:=0
+  FOR k:=0 TO 7 \col(k):=TRUE \NEXT k
+  FOR k:=0 TO 14 \up(k):=TRUE \down(k):=TRUE \NEXT k
+  RUN generate(n,x,col,up,down)
+  END
+
+PROCEDURE generate
+  PARAM n,x(8):INTEGER
+  PARAM col(8),up(15),down(15):BOOLEAN
+  DIM h,k:INTEGER \h:=0
+  BASE 0
+
+  REPEAT
+    IF col(h) AND up(n­h+7) AND down(n+h) THEN
+      (* set queen on square [n,h] *)
+      x(n):=h
+      col(h):=FALSE \up(n­h+7):=FALSE \down(n+h) := FALSE
+      n:=n+1
+      IF n=8 THEN
+        (* board full; print configuration *)
+        FOR k=0 TO 7
+          PRINT x(k); "   ";
+        NEXT k
+        PRINT
+      ELSE RUN generate(n,x,col,up,down)
+      ENDIF
+
+      (* remove queen from square [n,h] *)
+      n:=n­1
+      col(h):=TRUE \up(n­h+7):=TRUE \down(n+h):=TRUE
+    ENDIF
+    h:=h+1
+  UNTIL h=8
+  END
+</programlisting>
+
+<programlisting>
+PROCEDURE electric
+     REM re­programmed from "ELECTRIC"
+     REM by Dwyer and Critchfield
+     REM Basic and the Personal Computer (Addison­Wesley, 1978)
+     REM provides a pictorial representation of the
+     REM resultant electrical field around charged points
+     DIM a(10),b(10),c(10)
+     DIM x,y,i,j:INTEGER
+     xscale:=50./78.
+     yscale:=50./32.
+
+     INPUT "How many charges do you have? ",n
+     PRINT "The field of view is 0­50,0­50 (x,y)"
+     FOR i=1 TO n
+       PRINT "type in the x and y positions of charge ";
+       PRINT i;
+       INPUT a(i),b(i)
+     NEXT i
+     PRINT "type in the size of each charge:"
+     FOR i=1 TO n
+       PRINT "charge "; i;
+       INPUT c(i)
+     NEXT i
+
+     REM visit each screen position
+     FOR y=32 TO 0 STEP ­1
+       FOR x=0 TO 78
+         REM compute field strength into v
+         GOSUB 10
+         z:=v*50.
+         REM map z to valid ASCII in b$
+         GOSUB 20
+         REM print char (proportional to field)
+         PRINT b$;
+       NEXT x
+       PRINT
+     NEXT y
+     END
+
+10   v=1.
+     FOR i=1 TO n
+       r:=SQRT(SQ(xscale*x­a(i))+SQ(yscale*y­b(i)))
+       EXITIF r=.0 THEN
+         v:=99999.
+       ENDEXIT
+       v:=v+c(i)/r
+     NEXT i
+     RETURN
+
+20   IF z&lt;32 THEN b$:=" "
+     ELSE
+       IF z>57 THEN z:=z+8
+       ENDIF
+       IF z>90 THEN b$:="*"
+       ELSE
+         IF z>INT(z)+.5 THEN b$:=" "
+         ELSE b$:=CHR$(z)
+           ENDIF
+         ENDIF
+       ENDIF
+     RETURN
+</programlisting>
+
+<programlisting>
+PROCEDURE qsort1
+  REM quicksort, by T.F. Ritter
+  PARAM bot,top,d(1000):INTEGER
+  DIM n,m:INTEGER; btemp:BOOLEAN
+
+  n:=bot
+  m:=top
+
+  LOOP  \REM each element gets the once over
+    REPEAT  \REM this is a post­inc instruction
+      btemp:=d(n)&lt;d(top)
+      n:=n+1
+    UNTIL NOT (btemp)
+    n:=n­1 \REM point at the tested element
+    EXITIF n=m THEN
+    ENDEXIT
+
+    REPEAT  \REM this is a post­dec instruction
+      m:=m­1
+    UNTIL d(m)&lt;=d(top) OR m=n
+    EXITIF n=m THEN
+    ENDEXIT
+
+    RUN exchange(d(m),d(n))
+    n:=n+1 \REM prepare for post­inc
+    EXITIF n=m THEN
+    ENDEXIT
+
+  ENDLOOP
+
+  IF n&lt;>top THEN
+    IF d(n)&lt;>d(top) THEN
+      RUN exchange(d(n),d(top))
+    ENDIF
+  ENDIF
+
+  IF bot&lt;n­1 THEN
+    RUN qsort1(bot,n­1,d)
+  ENDIF
+  IF n+1&lt;top THEN
+    RUN qsort1(n+1,top,d)
+  ENDIF
+
+  END
+
+PROCEDURE exchange
+  PARAM a,b:INTEGER
+  DIM temp:INTEGER
+
+  temp:=a
+  a:=b
+  b:=temp
+
+  END
+
+PROCEDURE prin
+  PARAM n,m,d(1000):INTEGER
+  DIM i:INTEGER
+
+  FOR i=n TO m
+    PRINT d(i);
+  NEXT i
+  PRINT
+
+  END
+
+PROCEDURE sortest
+  REM This procedure is used to test Quicksort
+  REM It fills the array "d" with randomly generated
+  REM numbers and sorts them.
+  DIM i,d(1000):INTEGER
+
+  FOR i=1 TO 1000
+    d(i):=INT(RND(100))
+  NEXT i
+
+  RUN prin(1,1000,d)
+
+  RUN qsort1(1,1000,d)
+
+  RUN prin(1,1000,d)
+
+  END
+</programlisting>
+
+<programlisting>
+PROCEDURE structst
+
+  REM example of intermixed array and record structures
+  REM note that structure d contains 200 real elements
+
+  TYPE a=one(2):REAL
+  TYPE b=two(10):a
+  TYPE c=three(10):b
+  DIM d,e:c
+
+  FOR i=1 TO 10
+    FOR j=1 TO 10
+      FOR k=1 TO 2
+        PRINT d.three(i).two(j).one(k)
+        d.three(i).two(j).one(k):=0.
+        PRINT e.three(i).two(j).one(k)
+        PRINT
+      NEXT k
+    NEXT j
+  NEXT i
+
+  REM this is a complete structure assignment
+  e:=d
+
+  FOR i=1 TO 10
+    FOR j=1 TO 10
+      FOR k=1 TO 2
+        PRINT e.three(i).two(j).one(k);
+      NEXT k
+      PRINT
+    NEXT j
+  NEXT i
+
+  END
+</programlisting>
+
+<programlisting>
+PROCEDURE pialook
+  REM display PIA at address (T.F. Ritte)
+  REM made understandable by K. Kaplan
+
+  DIM address:INTEGER
+  INPUT "Enter PIA address:  "; address
+  RUN side(address)
+  RUN side(adress+2)
+  END
+
+PROCEDURE side
+  REM display side of PIA at address
+  PARAM address:INTEGER
+  DIM data:INTEGER
+
+  (* loop until control register input strobe
+  (* flag (bit 7) is set
+  REPEAT \ UNTIL LAND(PEEK(address+1),$80) &lt;> 0
+  (* now read the data register
+  data := PEEK(address)
+  (* display data in binary
+  RUN prinbyte(data)
+  END
+
+PROCEDURE prinbyte
+  REM print a byte as binary
+  PARAM n: INTEGER
+  DIM i: INTEGER
+
+  n:= n*256
+  FOR i = 7 TO 0 STEP ­1
+    IF n &lt; 0 THEN PRINT "1";
+    ELSE PRINT "0";
+    ENDIF
+    n:= n + 1
+  NEXT i
+
+  PRINT
+  END
+</programlisting>
+
+</para>
+<para>
+The following procedures demonstrate multiple-precision arithmetic, in
+this case using five integers to represent a twenty decimal digit number, with
+four fractional places.
+</para>
+<para>
+
+
+<programlisting>
+PROCEDURE mpadd
+  REM a+b=>c:five_integer_number (T.F. Ritter)
+  PARAM a(5),b(5),c(5):INTEGER
+  DIM i,carry:INTEGER
+
+  carry:=0
+  FOR i=5 TO 1 STEP ­1
+    c(i):=a(i)+b(i)+carry
+    IF c(i)>=10000 THEN
+      c(i):=c(i)­10000
+      carry:=1
+    ELSE carry:=0
+    ENDIF
+  NEXT i
+</programlisting>
+
+<programlisting>
+
+PROCEDURE mpsub
+  PARAM a(5),b(5),c(5):INTEGER
+  DIM i,borrow:INTEGER
+
+  borrow:=0
+  FOR i=5 TO 1 STEP ­1
+    c(i):=a(i)­b(i)­borrow
+    IF c(i)&lt;0 THEN
+      c(i):=c(i)+10000
+      borrow:=1
+    ELSE borrow:=0
+    ENDIF
+  NEXT i
+</programlisting>
+
+<programlisting>
+
+PROCEDURE mprint
+  PARAM a(5):INTEGER
+  DIM i:INTEGER; s:STRING
+
+  FOR i=1 TO 5
+    IF i=5 THEN PRINT ".";
+    ENDIF
+    s:=STR$(a(i))
+    PRINT MID$("0000"+s,LEN(s)+1,4);
+  NEXT i
+</programlisting>
+
+<programlisting>
+PROCEDURE mpinput
+  PARAM a(5):INTEGER
+  DIM n,i:INTEGER
+
+  INPUT "input ultra­precision number: ",b$
+  n:=SUBSTR(".",b$)
+
+  IF n&lt;>0 THEN
+    a(5):=VAL(MID$(b$+"0000",n+1,4))
+    b$:=LEFT$(b$,n­1)
+  ELSE a(5):=0
+  ENDIF
+
+  b$:="00000000000000000000"+b$
+  n:=1+LEN(b$)
+  FOR i=4 TO 1 STEP ­1
+    n:=n­4
+    a(i):=VAL(MID$(b$,n,4))
+  NEXT i
+</programlisting>
+
+<programlisting>
+
+PROCEDURE mptoreal
+  PARAM a(5):INTEGER; b:REAL
+  DIM i:INTEGER
+
+  b:=a(1)
+  FOR i=2 TO 4
+    b:=b*10000
+    b:=b+a(i)
+  NEXT i
+  b:=b+a(5)*.0001
+</programlisting>
+
+<programlisting>
+PROCEDURE Patch
+  (* Program to examine and patch any byte of a disk file *)
+  (* Written by L. Crane *)
+  DIM buffer(256):BYTE
+  DIM path,offset,modloc:INTEGER; loc:REAL
+  DIM rewrite:STRING
+  INPUT "pathlist? ",rewrite
+  OPEN #path,rewrite:UPDATE
+  LOOP
+    INPUT "sector number? ",rewrite
+  EXITIF rewrite="" THEN ENDEXIT
+    loc=VAL(rewrite)*256
+    SEEK #path,loc
+    GET #path,buffer
+    RUN DumpBuffer(loc,buffer)
+    LOOP
+      INPUT "change (sector offset)? ",rewrite
+    EXITIF rewrite="" THEN
+      RUN DumpBuffer(loc,buffer)
+    ENDEXIT
+    EXITIF rewrite="S" OR rewrite="s" THEN ENDEXIT
+      offset=VAL(rewrite)+1
+      LOOP
+      EXITIF offset>256 THEN ENDEXIT
+        modloc=loc+offset­1
+        PRINT USING "h4,' ­ ',h2",modloc,buffer(offset);
+        INPUT ":",rewrite
+      EXITIF rewrite="" THEN ENDEXIT
+        IF rewrite&lt;>" " THEN
+          buffer(offset)=VAL(rewrite)
+        ENDIF
+        offset=offset+1
+      ENDLOOP
+    ENDLOOP
+    INPUT "rewrite sector? ",rewrite
+    IF LEFT$(rewrite,1)="Y" OR LEFT$(rewrite,1)="y" THEN
+      SEEK #path,loc
+      PUT #path,buffer
+    ENDIF
+  ENDLOOP
+  CLOSE #path
+  BYE
+
+PROCEDURE DumpBuffer
+  (* Called by PATCH *)
+  TYPE buffer=char(8):INTEGER
+  PARAM loc:REAL; line(16):buffer
+  DIM i,j:INTEGER
+  WHILE loc>65535. DO
+    loc=loc­65536.
+  ENDWHILE
+  FOR j=1 TO 16
+    PRINT USING "h4",FIX(INT(loc))+(j­1)*16;
+    PRINT ":";
+    FOR i=1 TO 8
+      PRINT USING "X1,H4",line(j).char(i);
+    NEXT i
+    RUN printascii(line(j))
+    PRINT
+  NEXT j
+
+PROCEDURE PrintASCII
+  TYPE buffer=char(16):BYTE
+  PARAM line:buffer
+  DIM ascii:STRING; nextchar:BYTE; i:INTEGER
+  ascii=""
+  FOR i=1 TO 16
+    nextchar=line.char(i)
+    IF nextchar>127 THEN
+      nextchar=nextchar­128
+    ENDIF
+    IF nextchar&lt;32 OR nextchar>125 THEN
+      ascii=ascii+" "
+    ELSE
+      ascii=ascii+CHR$(nextchar)
+    ENDIF
+  NEXT i
+  PRINT "  "; ascii;
+</programlisting>
+
+<programlisting>
+     PROCEDURE MakeProc
+     (* Generates an OS­9 command file to apply a command *)
+     (* Such as copy, del, etc., to all files in a directory *)
+     (* or directory system.  Author: L. Crane *)
+
+     DIM DirPath,ProcPath,i,j,k:INTEGER
+     DIM CopyAll,CopyFile:BOOLEAN
+     DIM ProcName,FileName,ReInput,ReOutput,response:STRING
+     DIM SrcDir,DestDir,DirLine:STRING[80]
+     DIM Function,Options:STRING[60]
+     DIM ProcLine:STRING[160]
+
+     ProcName="CopyDir"
+     Function="Copy"
+     Options="#32k"
+     REPEAT
+       PRINT "Proc name ("; ProcName; ")";
+       INPUT response
+       IF response&lt;>"" THEN
+         ProcName=TRIM$(response)
+       ENDIF
+
+       ON ERROR GOTO 100
+       SHELL "del "+ProcName
+100    ON ERROR
+       INPUT "Source Directory? ",SrcDir
+       SrcDir=TRIM$(SrcDir)
+       ON ERROR GOTO 200
+       SHELL "del procmaker...dir"
+200    ON ERROR
+       SHELL "dir "+SrcDir+" >procmaker...dir"
+       OPEN #DirPath,"procmaker...dir":READ
+       CREATE #ProcPath,ProcName:WRITE
+       PRINT "Function ("; Function; ")";
+       INPUT response
+       IF response&lt;>"" THEN
+         Function=TRIM$(response)
+       ENDIF
+       INPUT "Redirect Input? ",response
+       IF response="y" OR response="Y" THEN
+	    ReInput="&lt;" \ ELSE  \ReInput=""
+       ENDIF
+       INPUT "Redirect Output? ",response
+       IF response="y" OR response="Y" THEN
+	 ReOutput=">" \ ELSE  \ReOutput=""
+       ENDIF
+       PRINT "Options ("; Options; ")";
+       INPUT response
+       IF response&lt;>"" THEN
+	 Options=TRIM$(response)
+       ENDIF
+       INPUT "Destination Directory? ",DestDir
+       DestDir=TRIM$(DestDir)
+       WRITE #ProcPath,"t"
+       WRITE #ProcPath,"TMode .1 ­pause"
+       READ #DirPath,DirLine
+       INPUT "Use all files? ",response
+       CopyAll=response="y" OR response="Y"
+       WHILE NOT(EOF(#DirPath)) DO
+	 READ #DirPath,DirLine
+	 i=LEN(TRIM$(DirLine))
+	 IF i>0 THEN
+	   j=1
+	   REPEAT
+	     k=j
+	     WHILE j&lt;=i AND MID$(DirLine,j,1)&lt;>" " DO
+	       j=j+1
+	     ENDWHILE
+	     FileName=MID$(DirLine,k,j­k)
+	     IF NOT(CopyAll) THEN
+	       PRINT "Use "; FileName;
+	       INPUT response
+	       CopyFile=response="y" OR response="Y"
+	     ENDIF
+	     IF CopyAll OR CopyFile THEN
+	       ProcLine=Function+" "+ReInput+SrcDir+"/"+FileName
+	       IF DestDir&lt;>"" THEN
+		 ProcLine=ProcLine+" "+ReOutput+DestDir+"/"+FileName
+	       ENDIF
+	       ProcLine=ProcLine+" "+Options
+	       WRITE #ProcPath,ProcLine
+	     ENDIF
+	     WHILE j&lt;i AND MID$(DirLine,j,1)=" " DO
+	       j=j+1
+	     ENDWHILE
+	   UNTIL j>=i
+	 ENDIF
+       ENDWHILE
+       WRITE #ProcPath,"TMode .1 pause"
+       WRITE #ProcPath,"Dir e "+SrcDir
+       IF DestDir&lt;>"" THEN
+	 WRITE #ProcPath,"Dir e "+DestDir
+       ENDIF
+       CLOSE #DirPath
+       CLOSE #ProcPath
+       SHELL "del procmaker...dir"
+       PRINT
+       INPUT "Another ? ",response
+     UNTIL response&lt;>"Y" AND response&lt;>"y"
+     IF response&lt;>"B" AND response&lt;>"b" THEN
+       BYE
+     ENDIF
+</programlisting>
+
+<programlisting>
+***************
+* INKEY - a subroutine for BASIC09 by Robert Doggett
+
+* Called by: RUN INKEY(StrVar)
+*            RUN INKEY(Path, StrVar)
+* Inkey determines if a key has been typed on the given path
+* (Standard Input if not specified), and if so, returns the next
+* character in the String Variable.  If no key has been type, the
+* null string is returned. If a path is specified, it must be
+* either type BYTE or INTEGER.
+
+  0021             TYPE     set   SBRTN+OBJCT
+  0081             REVS     set   REENT+1
+
+  0000 87CD005E             mod   InKeyEnd,InKeyNam,TYPE,REVS
+                                  ,InKeyEnt,0
+  000D 496E6B65    InKeyNam fcs   "Inkey"
+D 0000                      org   0          Parameters
+D 0000             Return   rmb   2          Return addr of caller
+D 0002             PCount   rmb   2          Num of params following
+D 0004             Param1   rmb   2          1st param addr
+D 0006             Length1  rmb   2          size
+D 0008             Param2   rmb   2          2nd param addr
+D 000A             Length2  rmb   2          size
+  0012 3064        InKeyEnt leax  Param1,S
+  0014 EC62                 ldd   PCount,S   Get parameter count
+  0016 10830001             cmpd  #1         just one parameter?
+  001A 2717                 beq   InKey20    ..Yes; default path A=0
+  001C 10830002             cmpd  #2         Are there two params?
+  0020 2635                 bne   ParamErr   No, abort
+  0022 ECF804               ldd   [Param1,S] Get path number
+  0025 AE66                 ldx   Length1,S
+  0027 301F                 leax  -1,X       byte available?
+  0029 2706                 beq   InKey10    ..Yes; (A)=Path number
+  002B 301F                 leax  -1,X       Integer?
+  002D 2628                 bne   ParamErr   ..No; abort
+  002F 1F98                 tfr   B,A
+  0031 3068        InKey10  leax  Param2,S
+  0033 EE02        InKey20  ldu   2,X        length of string
+  0035 AE84                 ldx   0,X        addr of string
+  0037 C6FF                 ldb   #$FF
+  0039 E784                 stb   0,X        Initialize to null str
+  003B 11830002             cmpu  #2         at least two-byte str?
+  003F 2502                 blo   InKey30    ..No
+  0041 E701                 stb   1,X        put str terminator
+  0043 C601        InKey30  ldb   #SS.Ready
+  0045 103F8D               OS9   I$GetStt   is there an data ready?
+  0048 2508                 bcs   InKey90    ..No; exit
+  004A 108E0001             ldy   #1
+  004E 103F89               OS9   I$Read     Read one byte
+  0051 39                   rts
+  0052 C1F6        InKey90  cmpb  #E$NotRdy
+  0054 2603                 bne   InKeyErr
+  0056 39                   rts              (carry clear)
+  0057 C638        ParamErr ldb   #E$Param   Parameter Error
+  0059 43          InKeyErr coma
+  005A 39                   rts
+  005B 1A6926               emod
+  005E             InKeyEnd equ   *
+</programlisting>
+
+</para>
+</appendix>
+<appendix>
+<title>Quick Reference</title>
+<para>
+
+
+<table frame="none">
+<title>System Mode Commands</title>
+<tgroup cols="5">
+<tbody>
+<row>
+<entry>$</entry>
+<entry>CHX</entry>
+<entry>EDIT</entry>
+<entry>LOAD</entry>
+<entry>RENAME</entry>
+</row>
+<row>
+<entry>BYE</entry>
+<entry>DIR</entry>
+<entry>KILL</entry>
+<entry>MEM</entry>
+<entry>RUN</entry>
+</row>
+<row>
+<entry>CHD</entry>
+<entry>E</entry>
+<entry>LIST</entry>
+<entry>PACK</entry>
+<entry>SAVE</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+
+
+<table frame="none">
+<title>Edit Mode Commands</title>
+<tgroup cols="5">
+<tbody>
+<row>
+<entry>+</entry>
+<entry>&lt;cr></entry>
+<entry>c*</entry>
+<entry>l*</entry>
+<entry>r*</entry>
+</row>
+<row>
+<entry>+*</entry>
+<entry>&lt;line #></entry>
+<entry>d</entry>
+<entry>q</entry>
+<entry>s</entry>
+</row>
+<row>
+<entry>-</entry>
+<entry>&lt;space></entry>
+<entry>d*</entry>
+<entry>r</entry>
+<entry>s*</entry>
+</row>
+<row>
+<entry>-*</entry>
+<entry>c</entry>
+<entry>l</entry>
+<entry></entry>
+<entry></entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+
+
+<table frame="none">
+<title>Debug Mode Commands</title>
+<tgroup cols="5">
+<tbody>
+<row>
+<entry>$</entry>
+<entry>DEG</entry>
+<entry>LET</entry>
+<entry>Q</entry>
+<entry>STEP</entry>
+</row>
+<row>
+<entry>BREAK</entry>
+<entry>DIR</entry>
+<entry>LIST</entry>
+<entry>RAD</entry>
+<entry>TROFF</entry>
+</row>
+<row>
+<entry>CONT</entry>
+<entry>END</entry>
+<entry>PRINT</entry>
+<entry>STATE</entry>
+<entry>TRON</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+
+
+
+<table frame="none">
+<title>Program Reserved Words</title>
+<tgroup cols=5>
+<tbody>
+<row>
+<entry>ABS</entry>
+<entry>DIR</entry>
+<entry>INT</entry>
+<entry>PEEK</entry>
+<entry>SQR</entry>
+</row>
+<row>
+<entry>ACS</entry>
+<entry>DO</entry>
+<entry>INTEGER</entry>
+<entry>PI</entry>
+<entry>SQRT</entry>
+</row>
+<row>
+<entry>ADDR</entry>
+<entry>ELSE</entry>
+<entry>KILL</entry>
+<entry>POKE</entry>
+<entry>STEP</entry>
+</row>
+<row>
+<entry>AND</entry>
+<entry>END</entry>
+<entry>LAND</entry>
+<entry>POS</entry>
+<entry>STOP</entry>
+</row>
+<row>
+<entry>ASC</entry>
+<entry>ENDEXIT</entry>
+<entry>LEFT$</entry>
+<entry>PRINT</entry>
+<entry>STR$</entry>
+</row>
+<row>
+<entry>ASN</entry>
+<entry>ENDIF</entry>
+<entry>LEN</entry>
+<entry>PROCEDURE</entry>
+<entry>STRING</entry>
+</row>
+<row>
+<entry>ATN</entry>
+<entry>ENDLOOP</entry>
+<entry>LET</entry>
+<entry>PUT</entry>
+<entry>SUBSTR</entry>
+</row>
+<row>
+<entry>BASE</entry>
+<entry>ENDWHILE</entry>
+<entry>LNOT</entry>
+<entry>RAD</entry>
+<entry>TAB</entry>
+</row>
+<row>
+<entry>BOOLEAN</entry>
+<entry>EOF</entry>
+<entry>LOG</entry>
+<entry>READ</entry>
+<entry>TAN</entry>
+</row>
+<row>
+<entry>BYE</entry>
+<entry>ERR</entry>
+<entry>LOG10</entry>
+<entry>REAL</entry>
+<entry>THEN</entry>
+</row>
+<row>
+<entry>BYTE</entry>
+<entry>ERROR</entry>
+<entry>LOOP</entry>
+<entry>REM</entry>
+<entry>TO</entry>
+</row>
+<row>
+<entry>CHAIN</entry>
+<entry>EXEC</entry>
+<entry>LOR</entry>
+<entry>REPEAT</entry>
+<entry>TRIM$</entry>
+</row>
+<row>
+<entry>CHD</entry>
+<entry>EXITIF</entry>
+<entry>LXOR</entry>
+<entry>RESTORE</entry>
+<entry>TROFF</entry>
+</row>
+<row>
+<entry>CHR$</entry>
+<entry>EXP</entry>
+<entry>MID$</entry>
+<entry>RETURN</entry>
+<entry>TRON</entry>
+</row>
+<row>
+<entry>CHX</entry>
+<entry>FALSE</entry>
+<entry>MOD</entry>
+<entry>RIGHT$</entry>
+<entry>TRUE</entry>
+</row>
+<row>
+<entry>CLOSE</entry>
+<entry>FIX</entry>
+<entry>NEXT</entry>
+<entry>RND</entry>
+<entry>TYPE</entry>
+</row>
+<row>
+<entry>COS</entry>
+<entry>FLOAT</entry>
+<entry>NOT</entry>
+<entry>RUN</entry>
+<entry>UNTIL</entry>
+</row>
+<row>
+<entry>CREATE</entry>
+<entry>FOR</entry>
+<entry>ON</entry>
+<entry>SEEK</entry>
+<entry>UPDATE</entry>
+</row>
+<row>
+<entry>DATA</entry>
+<entry>GET</entry>
+<entry>OPEN</entry>
+<entry>SGN</entry>
+<entry>USING</entry>
+</row>
+<row>
+<entry>DATE$</entry>
+<entry>GOSUB</entry>
+<entry>OR</entry>
+<entry>SHELL</entry>
+<entry>VAL</entry>
+</row>
+<row>
+<entry>DEG</entry>
+<entry>GOTO</entry>
+<entry>PARAM</entry>
+<entry>SIN</entry>
+<entry>WHILE</entry>
+</row>
+<row>
+<entry>DELETE</entry>
+<entry>IF</entry>
+<entry>PAUSE</entry>
+<entry>SIZE</entry>
+<entry>WRITE</entry>
+</row>
+<row>
+<entry>DIM</entry>
+<entry>INPUT</entry>
+<entry></entry>
+<entry>SQ</entry>
+<entry>XOR</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+
+
+<table frame="none">
+<title>&b09; Statements</title>
+<tgroup cols="5">
+<tbody>
+<row>
+<entry>BASE 0</entry>
+<entry>ELSE</entry>
+<entry>GOTO</entry>
+<entry>OPEN</entry>
+<entry>RETURN</entry>
+</row>
+<row>
+<entry>BASE 1</entry>
+<entry>END</entry>
+<entry>IF/THEN</entry>
+<entry>PARAM</entry>
+<entry>RUN</entry>
+</row>
+<row>
+<entry>BYE</entry>
+<entry>ENDEXIT</entry>
+<entry>INPUT</entry>
+<entry>PAUSE</entry>
+<entry>SEEK</entry>
+</row>
+<row>
+<entry>CHAIN</entry>
+<entry>ENDIF</entry>
+<entry>KILL</entry>
+<entry>POKE</entry>
+<entry>SHELL</entry>
+</row>
+<row>
+<entry>CHD</entry>
+<entry>ENDLOOP</entry>
+<entry>LET</entry>
+<entry>PRINT</entry>
+<entry>STOP</entry>
+</row>
+<row>
+<entry>CHX</entry>
+<entry>ENDWHILE</entry>
+<entry>LOOP</entry>
+<entry>PUT</entry>
+<entry>TROFF</entry>
+</row>
+<row>
+<entry>CLOSE</entry>
+<entry>ERROR</entry>
+<entry>NEXT</entry>
+<entry>RAD</entry>
+<entry>TRON</entry>
+</row>
+<row>
+<entry>CREATE</entry>
+<entry>EXITIF/THEN</entry>
+<entry>ON ERROR GOTO</entry>
+<entry>READ</entry>
+<entry>TYPE</entry>
+</row>
+<row>
+<entry>DATA</entry>
+<entry>FOR/TO/STEP</entry>
+<entry>ON/GOSUB</entry>
+<entry>REM</entry>
+<entry>UNTIL</entry>
+</row>
+<row>
+<entry>DEG</entry>
+<entry>GET</entry>
+<entry>ON/GOTO</entry>
+<entry>REPEAT</entry>
+<entry>WHILE/DO</entry>
+</row>
+<row>
+<entry>DELETE</entry>
+<entry>GOSUB</entry>
+<entry></entry>
+<entry>RESTORE</entry>
+<entry>WRITE</entry>
+</row>
+<row>
+<entry>DIM</entry>
+<entry></entry>
+<entry></entry>
+<entry></entry>
+<entry></entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+
+
+<table frame="none">
+<title>Transcendental Functions</title>
+<tgroup cols="4">
+<tbody>
+<row>
+<entry>ACS (x)</entry>
+<entry>COS (x)</entry>
+<entry>LOG10 (x)</entry>
+<entry>SIN (x)</entry>
+</row>
+<row>
+<entry>ASN (x)</entry>
+<entry>EXP (x)</entry>
+<entry>PI</entry>
+<entry>TAN (x)</entry>
+</row>
+<row>
+<entry>ATN (x)</entry>
+<entry>LOG (x)</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+
+
+<table frame="none">
+<title>Numeric Functions</title>
+<tgroup cols="4">
+<tbody>
+<row>
+<entry>ABS (x)</entry>
+<entry>LAND (m,n)</entry>
+<entry>MOD (m,n)</entry>
+<entry>SQ (x)</entry>
+</row>
+<row>
+<entry>FIX (x)</entry>
+<entry>LNOT (m,n)</entry>
+<entry>RND (x)</entry>
+<entry>SQR (x)</entry>
+</row>
+<row>
+<entry>FLOAT (m)</entry>
+<entry>LOR (m,n)</entry>
+<entry>SGN (x)</entry>
+<entry>SQRT (x)</entry>
+</row>
+<row>
+<entry>INT (x)</entry>
+<entry>LXOR (m,n)</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+
+<table frame="none">
+<title>String Functions</title>
+<tgroup cols="4">
+<tbody>
+<row>
+<entry>ASC (char$)</entry>
+<entry>LEFT$ (str$,m)</entry>
+<entry>RIGHT$ (str$,m)</entry>
+<entry>TRIM$ (str$)</entry>
+</row>
+<row>
+<entry>CHR$ (m)</entry>
+<entry>LEN (str$)</entry>
+<entry>STR$ (x)</entry>
+<entry>VAL(str$)</entry>
+</row>
+<row>
+<entry>DATE$</entry>
+<entry>MID$ (str$,m,n)</entry>
+<entry>SUBSTR(st1$,st2$)</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+
+<table frame="none">
+<title>Miscellaneous Functions</title>
+<tgroup cols="4">
+<tbody>
+<row>
+<entry>ADDR (var)</entry>
+<entry>FALSE</entry>
+<entry>POS</entry>
+<entry>TAB (m)</entry>
+</row>
+<row>
+<entry>EOF (#path)</entry>
+<entry>PEEK (addr)</entry>
+<entry>SIZE (var)</entry>
+<entry>TRUE</entry>
+</row>
+<row>
+<entry>ERR</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+
+<table frame="none">
+<title>Operator Precedence</title>
+<tgroup cols="7">
+<colspec colname="c1">
+<colspec colname="c2">
+<colspec colname="c3">
+<colspec colnum=7 colname="c7">
+<spanspec spanname="firstop" namest="c2" nameend="c2">
+<spanspec spanname="secondop" namest="c3" nameend="c7">
+<spanspec spanname="onlyop" namest="c2" nameend="c7">
+<spanspec spanname="all" namest="c1" nameend="c7">
+<tbody>
+<row>
+<entry>highest -></entry>
+<entry spanname="firstop">NOT</entry>
+<entry spanname="secondop">­(negate)</entry>
+</row>
+<row>
+<entry spanname="firstop">^</entry>
+<entry spanname="secondop">**</entry>
+</row>
+<row>
+<entry spanname="firstop">*</entry>
+<entry spanname="secondop">/</entry>
+</row>
+<row>
+<entry spanname="firstop">+</entry>
+<entry spanname="secondop">­</entry>
+</row>
+<row>
+<entry spanname="firstop">></entry>
+<entry>&lt;</entry>
+<entry>&lt;></entry>
+<entry>=</entry>
+<entry>>=</entry>
+<entry>&lt;=</entry>
+</row>
+<row>
+<entry spanname="onlyop">AND</entry>
+</row>
+<row>
+<entry>lowest -></entry>
+<entry spanname="firstop">OR</entry>
+<entry spanname="secondop">XOR</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+
+
+</para>
+</appendix>
+<appendix>
+<title>&b09; Error Codes</title>
+<para>
+<literallayout>
+10 ­ Unrecognized Symbol
+11 ­ Excessive Verbage (too many keywords or symbols)
+12 ­ Illegal Statement Construction
+13 ­ I-code Overflow (need more workspace memory)
+14 ­ Illegal Channel Reference (bad path number given)
+15 ­ Illegal Mode (Read/Write/Update/Dir only)
+16 ­ Illegal Number
+17 ­ Illegal Prefix
+18 ­ Illegal Operand
+19 ­ Illegal Operator
+
+20 ­ Illegal Record Field Name
+21 ­ Illegal Dimension
+22 ­ Illegal Literal
+23 ­ Illegal Relational
+24 ­ Illegal Type Suffix
+25 ­ Too-Large Dimension
+26 ­ Too-Large Line Number
+27 ­ Missing Assignment Statement
+28 ­ Missing Path Number
+29 ­ Missing Comma
+
+30 ­ Missing Dimension
+31 ­ Missing DO Statement
+32 ­ Memory Full (need more workspace memory)
+33 ­ Missing GOTO
+34 ­ Missing Left Parenthesis
+35 ­ Missing Line Reference
+36 ­ Missing Operand
+37 ­ Missing Right Parenthesis
+38 ­ Missing THEN statement
+39 ­ Missing TO
+
+40 ­ Missing Variable Reference
+41 ­ No Ending Quote
+42 ­ Too Many Subscripts
+43 ­ Unknown Procedure
+44 ­ Multiply-Defined Procedure
+45 ­ Divide by Zero
+46 ­ Operand Type Mismatch
+47 ­ String Stack Overflow
+48 ­ Unimplemented Routine
+49 ­ Undefined Variable
+
+50 ­ Floating Overflow
+51 ­ Line with Compiler Error
+52 ­ Value out of Range for Destination
+53 ­ Subroutine Stack Overflow
+54 ­ Subroutine Stack Underflow
+55 ­ Subscript out of Range
+56 ­ Parameter Error
+57 ­ System Stack Overflow
+58 ­ I/O Type Mismatch
+59 ­ I/O Numeric Input Format Bad
+
+60 ­ I/O Conversion: Number out of Range
+61 ­ Illegal Input Format
+62 ­ I/O Format Repeat Error
+63 ­ I/O Format Syntax Error
+64 ­ Illegal Path Number
+65 ­ Wrong Number of Subscripts
+66 ­ Non-Record-Type Operand
+67 ­ Illegal Argument
+68 ­ Illegal Control Structure
+69 ­ Unmatched Control Structure
+
+70 ­ Illegal FOR Variable
+71 ­ Illegal Expression Type
+72 ­ Illegal Declarative Statement
+73 ­ Array Size Overflow
+74 ­ Undefined Line Number
+75 ­ Multiply-Defined Line Number
+76 ­ Multiply-Defined Variable
+77 ­ Illegal Input Variable
+78 ­ Seek Out of Range
+79 ­ Missing Data Statement
+80 ­ Print Buffer Overflow
+</literallayout>
+
+Error codes above 80 are those used by OS-9 or other external programs.
+Consult the "OS-9 User's Guide" for a list of error codes and explanations.
+</para>
+</appendix>
+
+
+<appendix>
+<title>The &b09; Graphics Interface Module</title>
+<para>
+The Graphics Interface module provides a simple and convenient
+way to access the colour graphics and joystick functions of the
+Dragon Computer from &b09; programs. The module is a program
+written in assembly language and stored in a file called "GFX". It
+can be loaded into memory using the OS-9 "LOAD" command prior to or
+after called &b09;, or it will be automatically called by &b09;
+the first time it is referenced in a program if the "GFX" file is
+located in the execution ("CMDS") directory.
+</para>
+<para>
+"GFX" is called using the &b09; "RUN" statement. The first
+parameter passed is the name of the graphics function desired.
+Other parameters are used to pass coordinates, colour modes, etc.
+</para>
+<para>
+The are two basic graphics modes: 4-colour having 128 by 192
+pixel resolution, and 2-colour having 256 by 192 pixel resolution.
+The display is treated as a 256 by 192 point grid with coordinates
+0,0 in the lower left-hand corner. X (horizontal) coordinates in
+either mode must be in the range of 0 to 255. An X-coordinate
+greater than 255 will cause a run-time error. Y coordinates
+(vertical) must be in the range of 0 to 191. A number greater than
+191 will be replaced by 191. Some of the graphics functions require
+or optionally accept a colour mode which controls the foreground
+colour and colour set. The mode and colour codes are given in the
+table on the next page.
+</para>
+<beginpage>
+<table frame="none">
+ <title>Colour Graphics Modes and Colour Codes</title>
+<tgroup cols="6">
+<colspec colname="c1">
+<colspec colname="c2">
+<colspec colname="c3">
+<colspec colname="c4">
+<colspec colname="c5">
+<colspec colname="c6">
+<thead>
+<row>
+<entry morerows=1 namest="c2">Colour Code</entry>
+<entry align="center" nameend="c4">Two Colour Format</entry>
+<entry align="center" nameend="c6">Four Colour Format</entry>
+</row>
+<row>
+<entry namest="c3">Background</entry>
+<entry namest="c4">Foreground</entry>
+<entry namest="c5">Background</entry>
+<entry namest="c6">Foreground</entry>
+</row>
+</thead>
+<tbody>
+<row>
+<entry morerows=3 valign=middle>Colour Set 1</entry>
+<entry align="center">00</entry>
+<entry align="left">Black</entry>
+<entry align="left">Black</entry>
+<entry align="left">Green</entry>
+<entry align="left">Green</entry>
+</row>
+<row>
+<entry align="center">01</entry>
+<entry align="left">Black</entry>
+<entry align="left">Green</entry>
+<entry align="left">Green</entry>
+<entry align="left">Yellow</entry>
+</row>
+<row>
+<entry align="center">02</entry>
+<entry namest="c5" align="left">Green</entry>
+<entry align="left">Blue</entry>
+</row>
+<row rowsep=1>
+<entry align="center">03</entry>
+<entry namest="c5" align="left">Green</entry>
+<entry align="left">Red</entry>
+</row>
+<row>
+<entry morerows=3 valign=middle>Colour Set 2</entry>
+<entry align="center">04</entry>
+<entry align="left">Black</entry>
+<entry align="left">Black</entry>
+<entry align="left">Buff</entry>
+<entry align="left">Buff</entry>
+</row>
+<row>
+<entry align="center" namest="c2">05</entry>
+<entry align="left">Black</entry>
+<entry align="left">Buff</entry>
+<entry align="left">Buff</entry>
+<entry align="left">Cyan</entry>
+</row>
+<row>
+<entry align="center" namest="c2">06</entry>
+<entry namest="c5" align="left">Buff</entry>
+<entry align="left">Magenta</entry>
+</row>
+<row rowsep=1>
+<entry align="center" namest="c2">07</entry>
+<entry namest="c5" align="left">Buff</entry>
+<entry align="left">Orange</entry>
+</row>
+<row>
+<entry morerows=3 valign=middle>Colour Set 3*</entry>
+<entry align="center">08</entry>
+<entry namest="c5" align="left">Black</entry>
+<entry align="left">Black</entry>
+</row>
+<row>
+<entry align="center" namest="c2">09</entry>
+<entry namest="c5" align="left">Black</entry>
+<entry align="left">Dark Green</entry>
+</row>
+<row>
+<entry align="center" namest="c2">10</entry>
+<entry namest="c5" align="left">Black</entry>
+<entry align="left">Med. Green</entry>
+</row>
+<row rowsep=1>
+<entry align="center" namest="c2">11</entry>
+<entry namest="c5" align="left">Black</entry>
+<entry align="left">Light Green</entry>
+</row>
+<row>
+<entry morerows=3 valign=middle>Colour Set 4*</entry>
+<entry align="center">12</entry>
+<entry namest="c5" align="left">Black</entry>
+<entry align="left">Black</entry>
+</row>
+<row>
+<entry align="center" namest="c2">13</entry>
+<entry namest="c5" align="left">Black</entry>
+<entry align="left">Green</entry>
+</row>
+<row>
+<entry align="center" namest="c2">14</entry>
+<entry namest="c5" align="left">Black</entry>
+<entry align="left">Red</entry>
+</row>
+<row>
+<entry align="center" namest="c2">15</entry>
+<entry namest="c5" align="left">Black</entry>
+<entry align="left">Buff</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+<note>
+<para>
+Colour Sets 3 and 4 are not available on PAL video system
+(U.K. and European) models.
+</para>
+</note>
+<bridgehead renderas="sect2">MODE</bridgehead>
+<cmdsynopsis>
+<command>Calling Syntax: RUN GFX("Mode",Format,Colour)</command>
+</cmdsynopsis>
+<para>
+MODE switches the screen from alphanumeric to graphics display mode,
+and selects the screen mode and colour mode. "Format" determines
+between two-colour (Format = 0), or four-colour (Format = 1)
+graphics modes. "Colour" is the initial colour code that specifies
+the foreground colour and colour set.
+</para>
+<para>
+This command must be given before aby other graphics command is
+used. The first time MODE is called, it requests 6K bytres of memory
+from OS-9 for use as the graphics display memory. MODE will return
+an error if sufficient free memory is not available.
+</para>
+<para>
+An example:
+<programlisting>
+RUN GFX("Mode",1,3)
+</programlisting>
+selects four-colour mode graphics is used, and the initial
+foreground colour is red.
+</para>
+<bridgehead renderas="sect2">MOVE</bridgehead>
+<cmdsynopsis>
+<command>Calling Syntax: RUN GFX("Move",X,Y)</command>
+</cmdsynopsis>
+<para>
+MOVE positions the (invisible) graphics cursor to the specified
+location without changing the display. X and Y are the coordinates
+of the new position.
+</para>
+<para>
+Example:
+<programlisting>
+RUN GFX("Move",0,0)
+</programlisting>
+This example positions the cursor in the lower left-hand corner.
+</para>
+<bridgehead renderas="sect2">COLOR</bridgehead>
+<cmdsynopsis>
+<command>Calling Syntax: RUN GFX("Color",Colour)</command>
+</cmdsynopsis>
+<para>
+COLOR changes the current foreground colour (and possibly the colour
+set). The current graphics mode and cursor position are not
+changed. For example:
+<programlisting>
+RUN GFX("Color",0)
+</programlisting>
+changes the foreground colour to green in four-colour format (or
+black in two-colour format).
+</para>
+<bridgehead renderas="sect2">POINT</bridgehead>
+<cmdsynopsis>
+<command>Calling Syntax: RUN GFX("Point",X,Y) or</command><sbr>
+<command>RUN GFX("Point",X,Y,Colour)</command>
+</cmdsynopsis>
+<para>
+POINT moves the graphics cursor to the specified X.Y coordinate and
+sets the pixel at that coordinate to the current foreground colour.
+If the optional "Colour" is specified, the current foreground colour
+is set to the given "Colour". For example:
+<programlisting>
+RUN GFX("Point",0,192,1)
+</programlisting>
+Point moves the cursor to the upper left-hand corner and changes
+the foreground colour to green in two-colour format, or it changes
+the colour to yellow in the four-colour format.
+</para>
+<bridgehead renderas="sect2">CLEAR</bridgehead>
+<cmdsynopsis>
+<command>Calling Syntax: RUN GFX("Clear") or</command><sbr>
+<command>RUN GFX("Clear",Colour)</command>
+</cmdsynopsis>
+<para>
+CLEAR resets all points on the screen to the background colour, or
+if the optional colour is given presets the screen to that colour.
+The current graphics cursor is reset to (0,0).
+</para>
+<bridgehead renderas="sect2">LINE</bridgehead>
+<cmdsynopsis>
+<command>Calling Syntax: RUN GFX("Line",x2,y2)</command><sbr>
+<command>RUN GFX("Line",x2,y2,Colour)</command><sbr>
+<command>RUN GFX("Line",x1,y1,x2,y2)</command><sbr>
+<command>RUN GFX("Line",x1,y1,x2,y2,Colour)</command>
+</cmdsynopsis>
+<para>
+LINE draw lines in various ways. If one coordinate is given, the
+line will be drawn from the current graphics cursor position to the
+coordinates specified. If two sets of coordinates are given, they
+are used as the start and end points of the line. The line will be
+drawn in the current foreground colour unless a new colour is given
+as a parameter. After the line is drawn the graphics cursor will be
+positioned at x2,y2. For example
+<programlisting>
+RUN GFX("Line",0,0,0,192)
+</programlisting>
+draws a line from (0,0) to (0,192).
+<programlisting>
+RUN GFX("line",24,65,2)
+</programlisting>
+draws a blue line (4-colour mode) to point 24,65.
+</para>
+<bridgehead renderas="sect2">CIRCLE</bridgehead>
+<cmdsynopsis>
+<command>Calling Syntax: RUN GFX("Circle",Radius)</command><sbr>
+<command>RUN GFX("Circle",Radius,Colour)</command><sbr>
+<command>RUN GFX("Circle",X,Y,Radius)</command><sbr>
+<command>RUN GFX("Circle",X,Y,Radius,Colour)</command>
+</cmdsynopsis>
+<para>
+CIRCLE draws a circle of the given radius. The current graphics
+cursor position is assumed if no X,Y value is given. The current
+foreground colour is assumed if the Colour parameter is not used.
+The center of the circle must be on the screen.
+</para>
+<bridgehead renderas="sect2">ALPHA</bridgehead>
+<cmdsynopsis>
+<command>Calling Syntax: RUN GFX("Alpha")</command>
+</cmdsynopsis>
+<para>
+Alpha is a quick convenient way of getting the screen back to
+alphanumeric mode. When graphics mode is entered again, the screen
+will show the previous unchanged graphics display.
+</para>
+<bridgehead renderas="sect2">QUIT</bridgehead>
+<cmdsynopsis>
+<command>Calling Syntax: RUN GFX("Quit")</command>
+</cmdsynopsis>
+<para>
+QUIT switches the screen back to alpha mode and returns the 6K byte
+graphics display memory to OS-9.
+</para>
+<bridgehead renderas="sect2">GLOC</bridgehead>
+<cmdsynopsis>
+<command>Calling Syntax: RUN GFX("Gloc",Vdisp)</command>
+</cmdsynopsis>
+<para>
+GLOC returns the address of the video display RAM as an integer number.
+This address may be used in subsequent PEEK and POKE
+operations to access the video display directly. GLOC can be used
+to create special functions that are not available in the Graphics
+Module.
+</para>
+<bridgehead renderas="sect2">GCOLR</bridgehead>
+<cmdsynopsis>
+<command>Calling Syntax: RUN GFX("Gcolr",Colour)</command><sbr>
+<command>RUN GFX("Gcolr",X,Y,Colour)</command>
+</cmdsynopsis>
+<para>
+GCOLR is used to read the colour of the pixel at the current
+graphics cursor position, or from the coordinates X,Y. The
+parameter "Colour" may be an integer or a byte variable in which the
+colour code is returned.
+</para>
+<bridgehead renderas="sect2">JOYSTK</bridgehead>
+<cmdsynopsis>
+<command>Calling Syntax: RUN GFX("Joystk",Stick,Fire,X,Y)</command>
+</cmdsynopsis>
+<para>
+JOYSTK returns the status of the specified joystick's Fire button,
+and returns the X,Y position of the joystick. The Fire button may
+be read as a BYTE, INTEGER, or a BOOLEAN value. Non-zero (TRUE)
+means the button was pressed. The X,Y values returned may be BYTE
+or INTEGER variables, and they will be in the range 0 to 63. The
+Stick parameter may be BYTE or INTEGER, and should be 0 for
+RIGHT, or 1 for LEFT, depending on whether the RIGHT or the LEFT
+joystick is to be tested.
+</para>
+<para>
+Example:
+<programlisting>
+RUN GRX("Joystk",1,leftfire,leftx,lefty)
+</programlisting>
+</para>
+<bridgehead renderas="sect1">A Sample Graphics Program</bridgehead>
+<para>
+The program on the next page illustrates how the GFX module is
+called and used. It creates an analog clock on the graphics
+display.
+</para>
+<para>
+<programlisting>
+PROCEDURE clk
+ 0000      (* Simple Clock Simulator *)
+ 001C      DIM time(4),last(4),xx(3),yy(3):INTEGER
+ 0043      DIM x0,y0,radius,bkg:INTEGER
+ 0056      DIM i,j,x1,y1,x2,y2:INTEGER
+ 0071      DEG
+ 0073      bkg=0
+ 007A      x0=128
+ 0081      y0=96
+ 0088      radius=95
+ 008F      RUN GFX("MODE",1,bkg+1)
+ 00A5      RUN GFX("CLEAR")
+ 00B2      RUN GFX("CIRCLE",x0,y0,radius)
+ 00CF      FOR i=0 to 89 STEP 6
+ 00E4        x2=SIN(i)*radius
+ 00F4        y2=COS(i)*radius
+ 0104        x1=x2*.9
+ 0115        y1=y2*.9
+ 0126        j=MOD(i/30,3)+bkg+1
+ 013B        RUN GFX("LINE",x0+x1,y0+y1,x0+x2,y0+y2,j)
+ 016C        RUN GFX("LINE",x0-x1,y0-y1,x0-x2,y0-y2,j)
+ 019D        RUN GFX("LINE",x0+y1,y0-x1,x0+y2,y0-x2,j)
+ 01CE        RUN GFX("LINE",x0-y1,y0+x1,x0-y2,y0+x2,j)
+ 01FF      NEXT i
+ 020A      FOR i=1 TO 3
+ 021A        time(i)=0
+ 0225        xx(i)=x0
+ 0231        yy(i)=y0
+ 023D      NEXT i
+ 0248      LOOP
+ 024A        time$=DATE$
+ 0250        last=time
+ 0258        time(3)=VAL(MID$(time$,16,2))*6
+ 026E        time(2)=VAL(MID$(time$(13,2))*6
+ 0284        time(1)=MOD(VAL(MID$(time$,10,2))*30+time/2)/12,360)
+ 02A9        j=last(3)
+ 02B3        FOR i=3 TO 1 STEP -1
+ 02C9          IF i=3 OR j=0 OR ABS(time(i)-last(i+1))&lt;6 OR
+               ABS(time(i)-j)&lt;6 THEN
+ 0300            RUN GFX("LINE",x0,y0,xx(i),yy(i),bkg)
+ 032B            xx(i)=x0+SIN(time(i))*radius*(.3+i*.2)
+ 035A            yy(i)=y0+COS(time(i))*radius*(.3+i*.2)
+ 0389            RUN GFX("LINE",x0,y0,xx(i),yy(i),bkg+i)
+ 03B7          ENDIF
+ 03B9        NEXT i
+ 03C4        WHILE time$=DATE$ DO
+ 03CF        ENDWHILE
+ 03D3      ENDLOOP
+</programlisting>
+</para>
+
+</appendix>
+
+</book>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/basic09/makefile	Sat Apr 06 13:34:58 2002 +0000
@@ -0,0 +1,19 @@
+OBJ=basic09
+STYLESHEET=docbook-utils.dsl
+
+all: book1.htm
+
+$(OBJ).pdf: $(OBJ).docbook $(STYLESHEET)
+	 docbook2pdf -d $(STYLESHEET) $(OBJ).docbook
+
+$(OBJ).ps: $(OBJ).docbook $(STYLESHEET)
+	 docbook2ps -d $(STYLESHEET) $(OBJ).docbook
+
+book1.htm: $(OBJ).docbook $(STYLESHEET)
+	rm -f *.htm *.html
+#	jade -t sgml -V html-index -d /usr/share/sgml/docbook/dsssl-stylesheets-1.64/html/docbook.dsl $(OBJ).docbook
+#	collateindex.pl -p -o index.docbook HTML.index
+	docbook2html -d $(STYLESHEET) $(OBJ).docbook
+
+print:
+	psnup -2 $(OBJ).ps | lpr