HISOFT PRESENTS

THE COLT

FAST BASIC COMPILER



COLT ZX BASIC Compiler Manual

Copyright Threlfall and Hodgson 1985
Published by Hisoft
             180 High Street North
             Dunstable     LU6 1AT

First Edition August 1985

All Rights Reserved Worldwide. No part of this publication may be
reproduced or transmitted in any form or by any means, including
photocopying and recording, without the written permission of the
copyright holder. Such written permission must also be obtained before
any part of this publication is stored in a retrieval system of any
nature.

It is an infringement of the copyright pertaining to HiSoft COLT and its
associated documentation to copy, by any means whatsoever, any part of
HiSoft COLT (the Compiler and/or the Executive) for any reason other
than for the purposes of making a security back-up copy of the object
code.

Please buy, don't steal.


INTRODUCTION
------------
Welcome to the world of fast programs and easy development given to you
and your ZX Spectrum with Hisoft's COLT Basic compiler. COLT is a
totally new product which transforms your Spectrum Basic programs into
pure Z80 machine code, making them run between 2 and 800 times faster!

COLT is easy to use and is small enough to allow most programs to be
compiled. Before we start to use it, we'll look into the process of
compilation to see why having a program such as COLT is so handy.


THE COMPILATION PROCESS
-----------------------
When you write a Basic program on your Spectrum, you're taking advantage
of the machine's in-built 'interactive' features. This means that you
can write part of a program, run it and correct any errors. This can be
done because the Basic system used by the Spectrum is known as an
'interpreter'. It takes each line of Basic which you type in, and if the
line makes sense it is added to the Basic program in memory. The 'syntax
checker' which prints a flashing '?' whenever you attempt to enter an
incorrect line, can detect only what is known as a 'syntax error'. A
syntax error is a programming error which cannot form part of a Basic
program because it does not conform to the 'syntax rules' of the
language. For example, just as we cannot sensibly say

	'Time four half past is the'

in English, we cannot assign a string to a numeric variable in Spectrum
Basic :

	10 LET a = "This will cause a syntax error"

The syntax checker cannot detect 'algorithmic' errors, which are
programming errors that, although perfectly valid Basic, do not really
do what you expect or require. You may have a line which adds 10 to a
variable, for instance, when in fact you are supposed to be adding 5.
These are always the hardest errors to find!

Once you have a valid Basic program in the Spectrum's memory, you can
execute the program by typing 'RUN' and pressing the ENTER key. Errors
can still occur, of course, if you miss out lines or perform incorrect
calculations. The program will then stop with an 'error report', telling
you at which line the error occurred. This is why the system is known as
'interactive', as it allows you to correct errors as they occur, rather
than having to run the program, find all the errors, and correct them
all before running the program again.

Interaction is a feature of interpreters, as they run programs in a
particular way. When you RUN a program, the interpreter finds the first
line of the program, which is stored in the computer as Basic, and works
out what it is supposed to do with the line. This may involve continuing
on to other lines, it may involve calling subroutines, or it may just
print something on the screen and finish. It doesn't matter what it
does, but how it does it. Interpreted programs are automatically much
slower than the computer is truly capable of because each individual
line has to be examined by the interpreter program every time it is met.
A FOR .. NEXT loop is not automatically converted into a machine code
loop which ends after a certain number of iterations, but is examined
each time the line containing the NEXT is encountered, and a check is
made to see if the end of the loop has been reached. The Spectrum Basic
interpreter lives in the ROM (read-only memory) inside the machine and
cannot easily be removed. COLT supplants this interpreter with a program
known as a 'compiler'.

A compiler is a program which converts another program written in a
particular language to machine code (in this case), so that the computer
can run this program directly rather than having to go through an
interpreter. In the case of the COLT compiler, the language which it
converts from is Spectrum Basic. The end result is a comparitively short
machine code program which will do exactly what the Basic program does,
but considerably faster. As it is now in machine code, we cannot run our
program by typing 'RUN', as this is an interpreter comman. Instead, we
need to 'call' it using an address given to us by the compiler. We can
call machine code programs with the RANDOMIZE USR <address> statement,
where <address> is the address which we want to call.

There are a very few Basic features which the COLT compiler cannot
handle, but we needn't consider them until later. To see how the whole
system works, let's start from the beginning.


GETTING STARTED WITH COLT
-------------------------
The COLT compiler is supplied on a cassette tape which incorporates a
short BASIC loader to get the compiler into memory and initialise it.
Make sure that the cassette is fully rewound and then place it in your
cassette player ready to be loaded. Type

	LOAD "" <ENTER>

(press the 'J' key followed by two presses of the SYMBOL-SHIFT 'P'
combination) and press PLAY on your cassette recorder. After a few
seconds the familiar tape loading stripes should appear on the screen
and the program name will be printed :

	Program: COLT

If this doesn't happen, rewind the cassette recorder and try again. If,
after numerous attempts, you still cannot get the tape to load, return
it to Hisoft and we will be pleased to send you a free replacement.

Eventually, the BASIC program will have loaded and started running. The
first thing it does it to automatically load the compiler machine code
into the computer. When the whole process has finished, you will be
asked if you want to make a backup (working) copy of the compiler. If
this is the first time that you have used the compiler, we strongly
recommend that you answer 'Y' to this question. Hisoft licences you to
make one working copy of the compiler on either cassette tape or 
microdrive cartridge. If you do answer 'Y', you will then be asked if
you want to save the copy to cassette tape or microdrive. If you have a
microdrive it is obviously sensible to save your working copy on a
cartridge as it will subsequently load much faster.

Next you are asked whether you want to change the start address of the
compiled program from 40000. Answer 'N' to this at the moment, as you
won't need to do this until you are compiling large programs. You'll see
the screen clear and a clock appear in the top right of the screen,
ticking away happily. This clock is part of the 'Executive' program,
which we'll be examining in greater detail later. Now type in this
program in the normal way :

	 10 LET h$="0123456789ABCDEF"
	 20 FOR a=0 TO 255
	 30 LET d$="  " : REM TWO spaces inside the string
	 40 GO SUB 100
	 50 POKE 23692,255
	 60 PRINT a;" = ";d$
	 70 NEXT A
	 80 STOP
	100 LET x= INT (a/16): LET y = a-16*x
	110 LET d$(1)=h$(x+1)
	120 LET d$(2)=h$(y+1)
	130 RETURN

When you run this program, you will see the numbers from 0 to 255
printed out along with their hexadecimal (base 16) equivalents. The
'POKE 23692,255' statement on line 50 simply stops the computer asking
for 'Scroll?' each time the screen is filled up. If you time this
program, you'll find that it takes just over 30 seconds to complete.

To compile the program type 

	RANDOMIZE USR 60000

and press ENTER. After a very short time, you should see this
information printed on the screen :

			      00:00:00:0
	HISOFT COLT Integer Compiler 1.0
	(c) 1985 THRELFALL and HODGSON

	Compiling Line  140
	Compiled OK

	Begin  End    Vars   Lines
	40000  40384  51517  51999

	Names  Nmtop   Ctop  Nvars
	52059  52191  52460   80

	To run RANDOMIZE USR 40000

(some of the numbers and messages may be different, but don't worry)

All these numbers will be useful to advanced programmers, but the rest
of us can ignore them. All we need to know is that the 'Compiled OK'
message appeared. If a line cannot be compiled (either because it
doesn't make sense or because it is one of the things which COLT cannot
deal with) then the dubious line is reproduced on the screen with a
flashing '?' mark next to the offending part of the line. This program,
if typed in correctly, will not cause any errors.

When the screen display above clears, run the compiled program by typing

	RANDOMIZE USR 40000	(and press ENTER)

You can see the difference immediately! Although our example turns out
only to be about twice as fast as interpreted Basic, other programs can
achieve as much as 70 times greater execution speed. When the compiled
program finishes, you can type LIST and find that the original program
is still ther, ready to be altered and re-compiled at once. By allowing
us to do this, the COLT compiler maintains the interactivity provided by
the standard Basic interpreter. Now we can look at each feature of COLT
and describe its operation in more detail.


COLT IN DETAIL
--------------
COLT is a fully microdrive and Interface 1 compatible integer Basic
compiler for the ZX Spectrum and Spectrum+. It will compile nearly all
ZX Basic code including strings, all the microdrive commands, tape
commands, RS232 commands, networking commands and finally the commands
associated with the EXECUTIVE.

COLT is an 'integer' Basic, which means that it can deal only with whole
numbers between -32768 and 32767. This has been done so that the maximum
speed can be attained, making COLT ideal for writing high-quality
arcade-style games. COLT has been written to not use floating point
arithmetic as the increase in speed over the Spectrum's own interpreter
would be negligable.

COLT includes many special features to maintain compatibility with
Spectrum Basic. There are no special commands which cannot be tested in
the normal interactive environment.

Here is a full list of some of the features of COLT :

	Full string handling

	Up to 26 one-dimensional arrays and 26 one-dimensional string
	arrays.

	Fully microdrive / interface 1 compatible

	All microdrive commands except DATA can be compiled

	Full variable names

	Access to Basic variables

	Basic access to COLT variables

	INPUT with full line editing

	Computed GOTOs

	VAL and VAL$ may be used

	Break key can be permanently enabled

	Compiles up to 32K of Basic, producing very fast code

	Very fast compilation (maximum 2 seconds per 1K of Basic) with
	precise error reporting


LOADING THE COMPILER
--------------------
You should load the compiler by typing the command LOAD "". This will
load a Basic program which gives some information on the compiler. You
will be offered the opportunity of making a working copy to tape or
microdrive. This will enable you to treat the copy you have just
received as a MASTER BACKUP. In addition, you will be given the chance
to change the point at which the compiler places the compiled code. This
is RAMTOP, and for the compiler alone may be between 26000 and 59000. If
you use the Executive as well then the upper limit is 52000.


COLT STATEMENTS
---------------
Variable nmames may be of any length but may contain only the characters
'A' to 'Z', 'a' to 'z' and '0' to '9' (but a digit cannot be the first
character of a variable's name). As inBasic, upper and lower case are
treated as being the same. There must not be any colour codes embedded
in the name or the compiler will object. In the list below,

	'e'	represents an arbitrary expression
	'N'	represents a positive integer
	'a$'	represents any string variable or sliced string
		 expression (as in 'x$(1 TO 4)')
	'a'	represents any simple or loop variable
	'a(e)'	represents any one-dimensional array or array element

Colour codes and other control codes must not appear in the middle of
lines, except within quotes: '"'.

When 'x', 'y' and 'z' are given as arguments to a function then floating
point evaluation is possible. The expression 'n/m' may replace 'x', 'y'
or 'z' and 'n/m' is calculated to give a floating point result .'n' and
'm' may be integer variables or integer bracketed expressions, e.g.
'BEEP 1/3,5' sounds the beeper for 1/3 of a second. 'BEEP (1+2)/(3+4),5'
sounds it for 3/7ths of a second. A division sign is the only operator
which is allowed outside of brackets, and there may be one only per
argument (x, y or z).

String expressions should not contain brackets (e.g. a$=(b$+c$)) as they
are unnecessary and tend to confuse the compiler. In PRINT statements
string comparisons must be in parentheses (brackets); e.g. use 'PRINT
("x" < "y")' rather than 'PRINT "x" < "y"'.

Unless otherwise stated, the functions below work exactly as in Basic
(remembering that all arithmetic is done in integer form). This table
should be examined in conjunction with the Spectrum manual.

AND			boolean 'AND'. Cannot be used to mix strings and
			numbers: e.g. 'b$=a$ AND 2' will not compile
ABS e
AT e,e
ATTR(e,e)
BEEP x,y		see comments about floating point above
BIN e
BORDER e
BRIGHT e
CIRCLE x,y,z
CHR$ e
CLS			both this and the special interface 1 form CLS#
			are handled
CAT			all forms are supported
CLEAR			clear compiled code variables only. The
			interface 1 form 'CLEAR#' to reset the channels
			is supported. The form 'CLEAR 12345' is NOT
			supported
CLOSE			all forms are supported
CODE a$
CONTINUE		this is not useful in a program and may be used
			to mark the end of the code to be compiled. It
			must be the first sub-statement in a multiple
			statement line
COPY
DATA list		'list' must be a list of integers or strings in
			quotes and may not contain expressions. It must
			be the first and only statement in a line
DEF FN			user-defined functions are NOT supported!
DIM a(v)		only one-dimensional arrays are available in COLT
DIM a$(v)		the storage of both arrays and strings is
			discussed later.
			Run-time array bound checking is minimal to make
			the speed of execution as high as possible. All
			arrays, strings and variables are erased when
			you re-enter a COLT program
DRAW x,y
DRAW x,y,z
ERASE
FLASH e
FN			user-defined functions are NOT supported!
FORMAT			all forms supported
FOR a=u TO v STEP w	'STEP' is optional. Note that the difference
			between 'u' and 'v' cannot exceed 32767 and the
			loop is always traversed at least once
GO SUB n		'n' is a positive integer. The fast form of GO SUB
GO SUB e		the expression must begin with a non-numeric
			(i.e. not a digit) and this is then evaluated at
			run-time. This option is relatively slow and
			should be used only when absolutely necessary
GOTO n			as GO SUB
GOTO e			as GO SUB
IF e THEN
IN e
INK e
INKEY$
INKEY$#e		for interface 1
INPUT a			editing exactly as in Basic. Colour operations
INPUT a(v)		and all three forms of INPUT may be intermixed.
INPUT a$		The suffix #e is allowed to enable reading from
			microdrive files
INT e			helps testing within the interactive environment
INVERSE e
LEN a$			a$ cannot be sliced
LET a=e
LET a$=a$
LINE
LOAD			all forms including the microdrive derivatives
			may be used with the exception of 'LOAD .. DATA'.
			See "LOAD commands" below
LPRINT			with or without the addition of #e
MERGE
MOVE			all forms are supported
NEW
NEXT a			see 'FOR'. Note that COLT expects that the
			'NEXT' will follow the 'FOR' when the code is
			read from top to bottom
OPEN 			all forms supported
OR
OUT e,e
OVER e
PAPER e
PAUSE e
PEEK e
PLOT e,e
POKE e,e
POINT(e,e)
PRINT			with or without #e
RANDOMIZE
RANDOMIZE e
READ a			reads alist of integers from DATA statements.
			Only minimal checking is performed to ensure
			that types are correct
READ a$			as for 'READ a', except that the data read are
			strings
REM			see special type below. Used for testing BREAK
			key
RESTORE e		restores the data pointer to line e. Line e must
			exist and be a DATA statement
RESTORE			initialises the DATA pointer to the start of the
			program
RETURN
RND			returns a random integer between 0 and 32767
			(this is not quite the same as Basic). To obtain
			the same effect under Basic use USR 59997
SAVE			all forms, including microdrive versions (except
			'LOAD .. DATA') are allowed
SCREEN$(e,e)
SGN e
STOP
STR$ e			see comments on strings and the section called
			'Floating Point?' below
TAB e
TO			all forms a$(m TO n), a$( TO n) and a$(m TO )
			are allowed
USR e
USR "string"
VAL a$			if a$ contains a reference to a variable then
			the Basic variable of that name is used. See
			"Fetching from Basic" below
VAL$ a$			see VAL
VERIFY			all forms except 'VERIFY .. DATA' allowed. All
			Executive commands of this form are compiled.
			Note, however, that '*fx Goto e' always returns
			to Basic line 'e', not compiled line 'e'


STRINGS AND ARRAYS
------------------
Strings and arrays are stored within the Basic variable space (i.e. in
the space pointed to by the system variable 'VARS' (location 23627)) and
are at the front of this space. The space needed for strings and arrays
is allocated dynamically as the need arises at run-time, just as in
Sinclair Basic. There is one minor difference: if a string or array gets
smaller, the space allocated to it does not decrease. This results in
code which is about 5 times faster than that which would result if
strings were made exactly the correct size. In general, string handling
is roughly 20 to 25 times faster than Basic. The fact that the space is
not handed back is invisible to the user as an enquiry like 'LEN a$'
will give the expected result. One side effect is that you may run out
of space slightly earlier than usual. However, this process results in
faster code for string handling than any other Spectrum Basic compiler.

Arrays work in an exactly analagous fashion and get longer, but not
shorter, if they are re-allocated. The old array space is reused.

The only space used between 'STKEND' and 'RAMTOP' (Basic system
variables) at run-time is temporary space used in forming string
expressions and is built up from 256 bytes above STKEND (the end of
normal Basic space). Note that as this gap is only 256 bytes long, no
string should change in length by more than 255 bytes (characters) in
one go.


ERROR MESSAGES DURING COMPILATION
---------------------------------
Any error will result in the offending line becoming the current
(editing) line. Simply press EDIT (CAPS-SHIFT and 1 simultaneously) to
bring the line down to the bottom of the screen to be edited.

Error reports :

1 Next without For
	A 'NEXT' statement uses a variable which has not been seen so
	far in a 'FOR' statement

2 Variable not found
	The maximum number of variables (255) has been exceeded. There
	is no cure except to use fewer variables

4 Out of memory
	The table length for the variable names is not long enough
	(change locations 59991 and 2 - see "Technical Information"
	below)

8 End of file
	No code to compile

C Nonsense in Basic
	This means that the compiler can't compile this particular
	statement

G No room for line
	The space allocated to the code is too small; try decreasing
	RAMTOP with a 'CLEAR n' with n less than 40000

M RAMTOP no good
	No room for tables. There must be enough room for the names,
	lines and variables above RAMTOP for compilation to begin, even
	when compiling 32K of code

N Statement not found
	Using GOTO or GO SUB to go to a line number greater than 32767.
	This can occur at run-time with computed GOTOs and GO SUBs


RUN-TIME ERRORS
---------------

3 Subscript wrong
	Only very rudimentary array bound checking is performed to speed
	up the code

6 Number too big
	Usually due to dividing by zero

B Integer out of range
	A number greater than 32767 or less than -32768 has been used

D and L BREAK into program
	The BREAK key has been pressed

E Out of data
	A READ has been attempted after all the DATA statements have
	been exhausted

H STOP in INPUT
	The keyword 'STOP' was entered in response to an INPUT statement

P FN without DEF
	An EXECUTIVE routine has been called but the Executive is not
	present


SAVING COMPILED CODE
--------------------
If you wish to save your compiled code you must save both the compiled
code and the compiler. It is easiest to save from RAMTOP (usually 40000)
to 65535 (the physical top of RAM) as this will also save any
user-defined graphics. 'E!k' in the EXECUTIVE will do this
automatically, otherwise the command is :

	LET rt=USR 59200:SAVE "name" CODE rt,65535-rt:LET rt=USR 59200

Do not BREAK into this SAVE or the compiler will be corrupted.

To minimise the amount of code to be saved try to make "Vars" only just
larger than "End" (see "Technical Information"). This may be
accomplished by the following action :

	CLEAR (PEEK 23730+256*PEEK 23731)+(Vars-End-5)

where "Vars" and "End" are read from the screen at the end of a
compilation. The code must then be recompiled and the new entry point
noted.


RE-LOADING COMPILED CODE
------------------------
It is extremely important that before re-loading compiled code into a
'clean' machine you should 'CLEAR n', where 'n' is the address to which
your code was compiled (normally 40000). Failure to do this will usually
crash the machine. If the compiled code which you re-load contains
Executive commands, then the Executive must be re-started with RANDOMIZE
USR 55020. This is not necessary for sprite or window functions.


TRACE FACILITIES
----------------
A very helpful feature of COLT is that you can use it with or without
the BREAK key enabled, and, in addition, in association with the
Executive, a trace of each line being executed can be seen.

This is achieved by three different 'REM' statements, each of the form
'REM #n':

REM #0
	Break is disabled except at 'Scroll?', INPUT and during tape and
microdrive commands. This results in the fastest, smallest and most
secure code. Programs can be broken into with the Executive

REM #1
	BREAK enabled. This produces longer code than REM #0, but BREAK
works as usual

REM #2
	When used in association with the Executive '*fx line' command,
the current line number is displayed every 50th of a second. This
clearly is a very powerful feature when debugging. It will cause the
line number (but not the statement number) to be printed if there is an
error


COMPILING UP TO 32K
-------------------
Usually, it is possible only to compile about 16K or so of Basic in a
48K machine (a little less if you are using the Executive). This is
because the machine must hold both your source code (i.e. the Basic
program) and the resulting compiled code. The latter is much the same
size as the former.

When working to and from cassette tape this is clearly a good method, as
you still have the Basic present to try again if your code does not work
as intended.

With the advent of the microdrives the position has changed. Provided
that you have saved your Basic code, you are unlikely to mind if the
compiler removes it from memory during the compilation process.. This
fact is used in COLT to allow you to compile 30 to 34K of Basic, as
follows :

	1) SAVE your Basic code
	2) With a 'CLEAR n' set RAMTOP so that there is room for the
	area from 'Vars' to 'Ctop' (see "Technical Information"). For a
	32K program this will need to be about 5K, so use CLEAR 55000.
	3) POKE the COLT variable at 59987 (a two-byte integer) with the
	final RAMTOP address at which you wish the code to be compiled.
	For example, to make it 32767 (=127 * 256 +255), you should

		POKE 59987,255: POKE 59988,127

	4) Compile. If the compilation is successful then the Basic area
	will be empty. If any compilation error occurs, the Basic should
	still be there. Error messages are produced as usual.
	5) During compilation, the machine stack has been moved from
	your original choice to location 65535 (so over-writing the last
	few UDGs) and then to your new chosen value.
	6) Before re-loading any files you should re-execute step 2
	above or there will not be room for the Basic.
	7) Note that if you have the Executive present then about 25K
	only of Basic can be compiled, and the first CLEAR (step 2)
	should be about 48000. To turn off the Executive to make more
	space, type

		RANDOMIZE USR 59190

	and press ENTER.


RETURNING TO BASIC
------------------
A section of compiled code will return automatically to Basic when it
finishes. STOP will cause a normal error 9 report. If the compiled code
was called by an immediate mode command (typed at the bottom), then no
statements after the 'RANDOMIZE USR n' will be executed. If the code is
called by a line in another program then it will return to the next
statement. This is carried out by the compiled code executing a
CONTINUE, so if you wish to return to some other point in Basic, you
should POKE 'OLDPC' (location 23662) with the line number and 'OSPPC'
(location 23664) with the statement number. This will over-ride the
values put there by the compiler and must be in the compiled code.

This method may also be used to chain programs. If the compiled code
contains a line 'LOAD "fred"', and the compiled code is invoked from
line 10, first statement, then the compiler will return to the second
statement in line 10 (if it exists) or the next line in "fred". Hence,
you may chain Basic and compiled code. Note however that the LOAD
command will destroy the compiled code's arrays and strings.


FETCHING VARIABLES FROM BASIC
-----------------------------
There will be many occassions when you wish to pick up the value of a
Basic variable for use in a COLT program. For this reason, if the
argument to the VAL function contains a reference to a variable, it uses
the Basic variable rather than the COLT variable. This allows you to
write statements like

	LET fred=VAL "fred"

which would take the Basic variable 'fred' and transfer its value into
the COLT variable 'fred'. The same applies to members of an array :

	LET b(10)=VAL "b(10)"

The 'VAL$' function may be used to get Basic strings into COLT, like
this:

	LET a$=VAL$ "a$"

which gets the Basic string variable 'a$' into the COLT string variable
'a$'.


TAKING COLT VARIABLES BACK TO BASIC
-----------------------------------
This is not quite as easy as the converse, so a special function has
been provided to help :

	LET fred=USR 59227: PRINT "john"

will set Basic variable 'fred' to be equal to COLT variable 'john'. THis
can be extended to arrays and strings :

	LET point=USR 59227: PRINT "b(n)"

will set 'point' to be an integer pointer to the FIRST member of the
COLT array 'b'. 'n' may take any value but the pointer is always to the
first member. To access the first element of the array 'b', a Basic line
like

	LET b(1)=PEEK point + 256*PEEK(point+1)

would suffice. To get at the 'nth' member, use :

	LET b(n)=PEEK (point+2*(n-1)) + 256*PEEK (point+2*(n-1)+1)

the factor of two allows for the fact that there are 2 bytes per array
member.

To access a string we would type 

	LET point=USR 59227: PRINT "a$"

where 'point' points to the first member of the COLT string 'a$', (i.e.
a$(1)), 'point+1' points to the second member (a$(2)), and so on.


FLOATING POINT?
---------------
We said at the beginning that COLT used only integer arithmetic, as
floating point mathematics is prohibitively expensive in computer time.
Exceptions to this rule have been seen already in the DRAW and BEEP
commands.

The VAL and STR$ functions give access to full floating point
arithmetic. Try

	PRINT STR$ VAL "SQR 3"

You will see that a floating point number is printed out. The VAL
function can be used to make available all the floating point functions,
such as SIN, COS and TAN. Using the function VAL by itself always
returns the result of the floating point operation as an integer. For
example,

	LET a=VAL "100*SQR 20"

will set 'a' to be 447.

However, 'STR$ VAL' has been set to return the floating point result
into the string :

	LET a$=STR$ VAL "100/3"

will set a$ to be the string "33.333333". This string can then be
manipulated further by repeated use of these functions :

	LET b$=a$+"*2"
	LET c$=STR$ VAL b$

sets c$ to be two times the value of the number held in a$: "66.666666".
This process can be continued indefinitely.

Note also that any variables used in quotes, like "a*b", refer to the
Basic variables 'a' and 'b', not the COLT ones. This form of arithmetic
is useful but will run at much the same speed as Basic.

Here are a few examples :

	10 LET a=VAL "SIN(.523598775)*100+100*.01"
	20 PRINT a

gives 51 both in Basic and compiled code. Note that the expression did
not contain any variables. This may be accomplished like this :

	10 LET b=100
	20 LET a=VAL ("SIN(.523598775)*100+0.01*"+STR$ b)
	30 PRINT b

which uses the compiled variable 'b'. However, if line 20 was replaced
by

	20 LET a=VAL("SIN(.523598775)*100+0.01*b)

the Basic variable 'b' would be used.

All the above return integer values, but by using strings we may obtain
floating point ones :

	10 LET a$="100/LN 12+ EXP 2"
	20 LET b$="SIN 1+COS 2+TAN 3+0.01"
	30 LET c$=VAL(a$+"2.34973+"+b$)
	40 PRINT c$

which gives 300 both in Basic and compiled code. It must be admitted
that it is rather cumbersome, but it works!


LOAD COMMANDS
-------------
If you wish to compile these a word of warning is necessary : 'LOAD
CODE' will work correctly, but loading Basic is dangerous. It will work
successfully, but in doing so will wipe out all the COLT arrays and
strings from the 'VARS' area of Basic. If you are not using any, then
this won't matter, but otherwise strange results will ensue.


SPEED
-----
Speed is the main reason that most people buy a compiler, and COLT
produces very fast code. Although some functions, such as DRAW, CIRCLE
and tape commands are no faster than Basic, others are very fast indeed.
A FOR .. NEXT loop at the bottom of a 16K program takes nearly 800 times
longer in Basic than when compiled under COLT. In general, though, an
improvement of about 50 times is to be expected, the ratio improving
with larger programs.

Executive commands vary considerably in the amount they are speeded up.
A simple command will be much faster, while a typical sprite MOVE
command may be only 2 to 4 times faster as the Executive commands are
already very efficient.

On the standard 'KILOBAUD' tests as used in most magazines, the average
improvement over Spectrum Basic is about 75 times.


STRANGE ERRORS
--------------
On most occasions when COLT appears to give strange results the problem
can be attributed usually to problems with integers. Remember that a
calculation which would normally yield a fractional result will be
rounded to an integer with COLT, and that the maximum range of numbers
which can be operated on is -32768 to 32767.


COLT IN DETAIL
--------------
This section gives details of the more advanced operations of COLT,
together with the internal workings of the system and ways to enhance
it.

The compiler is invoked with the command

	RANDOMIZE USR 60000

If any Basic command is found which cannot be compiled, the line up to
that point followed by a flashing cursor will be shown. A return to
Basic will be made with the offending line being made the 'current line'
(it will have the '>' listing marker after its line number).

After an initial pass of the code during which any errors should show
up, a second pass is made immediately. During both passes the message

	Compiling line xxxx

will appear. This is followed immediately by a table of useful
information about the layout of your compiled code in the machine. The
table appears as shown over the page :

	Begin   End   Vars   Lines
	xxxxx  xxxxx  xxxxx  xxxxx

	Names  Nmtop   Ctop  Nvars
	xxxxx  xxxxx  xxxxx  xxxxx

	To run type RANDOMIZE USR xxxxx


To explain these numbers, we'll use a diagram :

------|-------|---------------|--------|------|-------|-------|-|--------
Basic | Spare | Compiled Code | Unused | Vars | Lines | Names | | COLT
------|-------|---------------|--------|------|-------|-------|-|--------
                              |        |      |       |       | |
  STKEND RAMTOP              End     Vars   Lines   Names     | Ctop
         =Begin                                             Nmtop


'STKEND'	is a Basic system variable (address 23653 and 4) which
		marks the end of the space occupied by Basic
'RAMTOP'	is a Basic system variable which marks the highest point
		that Basic is allowed to reach. This is set by 'CLEAR n'
		in Basic, and defaults to 40000 under COLT
'Begin'		usually this is the same as the original RAMTOP, but
		when compiling 32K, it changes (see below)
'End'		marks the end of the compiled code. From here to 'Vars'
		is free for more program
'Vars'		the variables used by COLT are not the same as
		similarly-named Basic variables. They are stored here.
		The space needed is 2 bytes per new variable after the
		initial ones. All variables have an entry in this table.
		The 26 single-letter variables are first, containing
		space for the value, the loop end and the step. Strings
		are next (26 of them), and here the table contains a
		pointer to the string, its length, and its absolute
		maximum length. The 26 arrays are last, with similar
		pointers
'Lines'		in order to compile 'GOTO' and 'GO SUB', etc., a table
		of line numbers and addresses is built here. It is kept
		for use in computed GOTOs. This space is four times the
		number of lines
'Names'		you may have up to 255 variables in COLT. The first two
		are system variables, the next 78 are the string
		variables, array variables and FOR-loop variables
		(single letters). These are pre-defined to make the code
		as fast as possible. The space from 'Names' to 'Ctop' is
		reserved for the names of your variables. By default, a
		few hundred bytes are allocated, but you may change this
		(see below)
'Nmtop'		the last location used between 'Names' and 'Ctop' for
		variable names
'Nvars'		the number of variable names you have used. This will
		never be less than 80
'Ctop'		The last space which may be used during the compilation
		of code. This is normally just before the start of COLT
		(or the Executive if you are using it). This value may
		be changed (see below). The bottom of the compiler is at
		59200, and the bottom of the Executive is at 52000


CHANGING THESE SPACE ALLOCATIONS - SOME USEFUL ADDRESSES
--------------------------------------------------------
All numbers are stored as two-byte integers in normal Z-80 (i.e.
reversed) format. The locations of interest are :

59987		Normally this is set to zero, but if it is made non-zero
		then this is the address of the new RAMTOP to be adopted
		when the Basic code is erased during a 32K compilation
59991		the space allocated to variable names
59993		the address of 'Ctop' above. You may wish to change this
		if you are compiling subroutines
59997		use 'RANDOMIZE USR 59997' to access COLT's random number
		generator from Basic


CALLS BETWEEN BASIC AND COLT
----------------------------
When you have finished your program and compiled it, you will usually
delete all the Basic code and treat the compiled code as a subroutine
(i.e. you will call it with 'RANDOMIZE USR xxxxx'). Note that it is a
true subroutine and the variables used in COLT are not the same as the
Basic ones and vice versa. The easiest way to delete all the Basic code
is to type 'NEW'. This clears the machine up to RAMTOP. The compiled
code is above RAMTOP, and is safe from deletion.

You can now call your compiled code with the simple statement

	RANDOMIZE USR n

where 'n' is the value of RAMTOP you chose, usually 40000. This
statement may be issued either in immediate mode or in a program line.
Note that in either case any further statements on that line will not be
executed.

Another slight restriction is that while Basic can call as many compiled
sections as you wish (see "Compiling subroutines"), you should not call
one COLT section from another. This is because entering a compiled
section always clears any old COLT arrays and strings from the Basic
variables area. In addition, when you reach the end of a section of
compiled code, there is not a simple return to Basic but a jump to the
next statement of Basic after the one which called the compiled code.
This is necessary due to the uncertain state of the machine stack after
certain ROM routines. See the section on returning to Basic.

For the same reason, you cannot call compiled code from your own machine
code.


COMPILING SUBROUTINES
---------------------
It is possible to compile several sections of Basic to be treated as
totally independent subroutines. The procedure is as follows :

1) Compile the first section. Now make a note of the variables 'End' and
'Vars', which are given on the screen following compilation. Subtract
the smaller from the larger and adjust RAMTOP (by a 'CLEAR n') so that
it is increased by this amount minus one (i.e. End - Vars - 1). For
example, if RAMTOP was 40000 (='Begin'), 'End' was 54000 and 'Vars' was
57000, then you should issue the command

	CLEAR 42999

2) Recompile to this new RAMTOP and make a note of the variable 'Begin'
which is displayed. This will be the USR call for the first section of
code

3) Modify the COLT variable 'Ctop', which is location 59993, so that the
value is the old value of RAMTOP (= old value of 'Begin') minus one.
This protects the code you have just generated from being overwritten

4) Load or type the next section of Basic and issue a 'CLEAR n', where
'n' is the location at which you wish the second section of code to be
compiled

5) Now follow the instructions 1 to 4 as many times as required

6) Save from the last RAMTOP you have used to 65535 (this will include
the UDGs as well). You would be well advised to do this step after each
section of compilation

7) Note that while there may be variables in several sections with the
same names, they are NOT the same variables. When you re-enter a section
at the beginning, all variables are set to zero.


RE-ENTERING CODE
----------------
It may occasionally be useful to re-enter a piece of compiled code
without resetting all the variables; for example after a trapped error
under the Executive. This is possible if you enter the code 19 locations
on from the normal entry point. For example, if your code is at 40000,
then

	RANDOMIZE USR 40019

will enter the compiled code without clearing or destroying arrays,
strings or variables. However, there are a few points which should be
borne in mind if this process is to be totally successful :

1) You should not re-enter if you have used RUN or CLEAR since the last
time the code was entered at the normal entry point

2) You must enter at the normal point at least once before using the
alternative point

3) You must not alter your Basic area at all between calls, for instance
by adding or altering lines of code or by opening or closing streams

4) You can only re-enter the last section of code you ran


Here is an example of how this might be carried out :

	 1 IF A=1 THEN GOTO 10
	 2 DIM A(10)
	 3 FOR K=1 TO 10: LET A(K)=K
	 4 NEXT K
	10 LET A=1

The first time the program is run, lines 1 to 10 will be executed (use
'RANDOMIZE USR n'). If the program is subsequently re-run with
'RANDOMIZE USR (n+19)', then only lines 1 and 10 will be executed.


THE EXECUTIVE
-------------
The Executive is an integral part of the COLT program which allows
numerous extra commands to be used in both standard Spectrum Basic and
COLT-compiled programs. The Executive is automatically loaded and
activated at the same time as COLT (it's responsible for the clock at
the top of the screen), but it can be turned off and even removed if the
space it takes up is required for use with COLT. Obviously,
de-activating or removing the Executive seems that no Executive commands
must be issued in either interpreted or compiled Basic programs. Some of
the features of the Executive are :

	* Sprite graphics for sophisticated moving pictures and objects
	
	* Window functions, including individual window scrolling and
	  attribute setting

	* On-screen user-defined graphics generation

	* Machine code programs and subroutines may be called with
	  parameters

	* ON ERROR GOTO statement

	* Two-byte PEEK and POKE

	* Decimal to binary / hexadecimal and hexadecimal to decimal
	  conversions

	* Free space calculator to tell you how much memory is available

	* No 'USR' calls once the Executive is started. Every command
	  looks like Basic and is syntax-checked on entry as usual

	* All Executive commands may be executed in immediate mode or
	  intermixed with normal Basic commands

	* All commands will compile under COLT

	* User-defined Basic commands

	* Multiple line delete

	* Fully microdrive compatible

	* Programmable keys - ideal for those tortuous microdrive
	  commands

	* On-screen clock with stopwatch facilities

	* On-screen trace of the line number being executed

	* Function key command to invoke the COLT compiler

	* Function key command to run program at RAMTOP (for COLT)

	* 'Repeat last command' key



USING THE EXECUTIVE
-------------------
The Executive code starts at address 52470 and finishes at 59200. If you
want to save code which includes the Executive you should stop the
Executive first, otherwise it will fail to verify on tape.

If you do not wish to use the Executive and require the extra space for
compiled code then the command

	RANDOMIZE USR 59190

will erase it and allow a further 7K of Basic to be compiled. The
compiled code must not call any Executive routines if you do this.

The Executive uses interrupt mode 2, so it cannot be used with other
programs using interrupts. It is inactivated (but not erased) by 'New',
so you should use

	*fx d 1,9999: CLEAR

to have the same effects as 'New', but without disabling the Executive.

The Executive is started with 

	RANDOMIZE USR 55020

and can be stopped with

	RANDOMIZE USR 55010

Note that with the Executive operating, programs will run about 10%
slower than usual, due to the use of interrupts.


QUICK ACCESS COMMANDS
---------------------
The quick access commands allow you to use certain Executive commands
with a very small number of keystrokes. In the table which follows, the
symbols 'E!' mean 'press SPACE and the letter, release SPACE then
release the letter key'. ENTER does not need to be pressed.

	E!t	switches the clock on.
	E!l	switches the line trace facility on.
	E!o	switches the clock or line trace off.
	E!s	stops the clock display but does not switch the clock
		off.
	E!z	zero the clock display.
	E!i	initialize the clock - any key toggles a digit, and
		ENTER moves on to the next digit in the sequence.
	E!r	return last command issued to the command line.
	E!c	call the COLT compiler (this command actually executes a
		'RANDOMIZE USR 60000' command).
	E!p	executes the program at RAMTOP+1 (correct for COLT).
	E!k	save code. This generates the command to KEEP the
		compiled code plus compiler and UDGs to tape. The
		command presented may be edited to save to microdrive.
		The copy saved to tape may be reloaded with 
		'CLEAR n:LOAD "name" CODE' where 'n' is the value of
		'RAMTOP' to which the code was compiled. Unless you have
		changed it, this will be 40000. Note that when the code
		is reloaded the compiler is disabled, and 'E!c' should
		not be used. However, this does not mean that you may
		give copies of your compiled programs to your friends.
		Do not break into the SAVE as the compiler will be
		disabled.
	E!x	breaks into and stops (exits) almost any program. Also
		returns display to normal black ink on white paper.


USER-DEFINABLE 'SOFT' (FUNCTION) KEYS
-------------------------------------
Now that Sinclair has released the microdrives, the ability to press one
or two keys to save or load programs is definitely an advantage. The
microdrive commands can only be described as devilish, requiring several
shifted characters.

The 'soft' or 'programmable' key function provided by the Executive
allows you to have your own special expressions pre-defined for access
with only two key strokes.

There are nine user-definable keys ('1' to '9'). Execution of the
commands they represent is simplicity itself : just press 'E!number'.
Here is how you define the keys :

You should have a line

	1 REM

in which you type the command or characters you wish to have inserted in
the input area. This may include keywords such as THEN, IF and so on
(you may need a ':' before them to be able to enter them). Each
definition is separated by either a '^' (SYMBOL-SHIFT H) or a '|'
(Extended mode then SYMBOL-SHIFT S). If you use '^' then an ENTER
character is automatically added on to the end of the function key
string. If '|' is used, the machine returns to accept more input.

Examples :

 	1 REM PRINT "Mary had a little lamb"| PRINT "its fleece was
	white as snow"^

Pressing 'E!1' would add 

	PRINT "Mary had a little lamb"

to the input line, and wait for you to press ENTER or type some more.
'E!2' would print 

	"its fleece was white as snow"

straight away.


ENHANCED BASIC COMMANDS
-----------------------
Executive commands must be entered with the Executive running and are
just like Basic commands. They may be freely inter-mixed with Basic
commands and are all of the form :

	*fx token/letter argument1, argument2.....

Each argument is any valid expression and there may be up to 16 of them.
Excess arguments will be ignored, and no error message will be given.
Note that all arguments are treated as integers.

An upper-case letter plus a bracketted series of letters following '*fx'
means that you can type the first letter in upper or lower case. The
letters in brackets may be omitted.

Words totally in upper-case are Basic 'tokens' and are entered by a
single keystroke, such as 'FN', 'FORMAT' and 'ERASE'.

The result of an Executive command is in some cases an 8-bit integer (up
to a value of 255), and sometimes a 16-bit integer. It should be obvious
which is applicable.


WINDOW COMMANDS
---------------
The Executive allows you to define a window on the Spectrum screen which
is smaller than the normal screen size of 32 columns by 24 lines. Within
this window there are many special functions which may be carried out,
such as high-resolution scrolling and colour changes.

*fx FN a,b,c,d
	defines a window (we're using 'FN' to stand for FeNetre!) which
	has its top left corner at (line a, column b), is c lines deep
	and d columns wide. The default is the whole screen, and the
	minimum window size is 2x2.

*fx PAPER n
	changes the colour of the paper in the window to colour 'n'
	immediately ('n' is between 0 and 7). No error is reported if
	'n' is outside this range, but 'n' is taken modulus 8 (so that 9
	becomes 1, 10 is 2 and so on).

*fx PAPER n,1
	changes the colour of the paper in the window only for those
	character locations matching the present attributes exactly in
	ink, paper, flash and bright.

*fx INK n
	as PAPER but for INK colour

*fx INK n,1
	as PAPER but for INK colour

*fx FLASH 0
	turns flashing off over the whole window

*fx FLASH n
	where 'n' is greater than 0 turns flashing on over the whole
	window

*fx FLASH n,1
	as for PAPER but for FLASH attribute

*fx BRIGHT 0
	as for FLASH but controls the BRIGHT attribute

*fx BRIGHT n
	as for FLASH but controls the BRIGHT attribute

*fx BRIGHT n,1
	as for FLASH but controls the BRIGHT attribute

*fx INVERSE 0
	inverts the window's attributes (the paper colour becomes the
	ink colour, and the ink colour is used for the paper)

*fx INVERSE 0,1
	as FLASH

*fx SCREEN$ n,p,q
	moves the window ink in the direction 'n' (5, 6, 7 or 8, going
	in the direction indicated by the arrows on those keys) by 1
	pixel 'p' times. 'q' defines the wraparound :

		q = 2  : wrap from one side to the other
		q = 1  : fill side with ink-coloured pixels
		q = 0  : fill side with paper-coloured pixels
		q = -1 : wrap and invert

*fx ATTR n
	moves window attributes in direction 'n'. This scrolls in the
	current attributes

*fx LINE n,p,r,q
	moves character line 'r' in direction 'n' (5 for left or 8 for
	right) by 1 pixel 'p' times. Wraparound is given by 'q' as above
	in SCREEN$. Line 'r' must be within the current window for
	predictable results.



SPRITE COMMANDS
---------------
Sprites add a new dimension to Basic graphics on the Spectrum. They are
user-defined characters of up to 32 pixels by 24 pixels which may be
positioned anywhere on the screen. When a sprite is moved the background
which was there before the sprite arrived is re-instated. Try that from
ordinary Basic! There are commands which allow you to access the
easy-to-use on-screen sprite definer as well as to make sprites visible
and invisible at will. You can have up to 16 sprites.

There are a few restrictions. You should not scroll the area of the
screen containing a sprite if you wish to move it again, as it will be
erased from its old homer rather than the new one. On some machines (not
the Spectrum!), this process is controlled by hardware and is then
totally successful.

*fx FORMAT n,a,b,c,d,m,e
	Sprite 'n' (where 'n' may be from 1 to 16) is defined to be at
	screen position (a,b) and to be 'c' pixels wide and 'd' deep.
	(Subject to the space limitation given above). The UDGs defining
	it start at address 'm' and successive bytes read across then
	down the sprite. The UDGs may be stored wherever you please.

	A sprite is always made visible after being formatted, its ink
	colour being that current when the sprite was defined, and the
	paper colour is 9. Only pixels which are ink are plotted, so if
	a character is only 2 pixels wide, make bits 0 to 5 zeros.

	To aid in defining sprites and UDGs in general, an on-screen
	character definition system is provided. If parameter 'e' is 1
	in the *fx FORMAT command, then an 8 times full-size picture of
	the sprite or UDG will be shown on the screen. The cursor may be
	moved to change the character using the keys as follows :

	0 - clear current pixel
	1 - set current pixel
	3 - clear the entire grid
	4 - set the entire grid
	5 - left
	6 - down
	7 - up
	8 - right
	9 - restore grid to the last-shown correct size
	ENTER - return to next command
	CAPS-SHIFT - show sprite at (a,b) full size

	For example, to define an ordinary UDG (say UDG letter 'A'),
	issue a command similar to this :

	*fx FORMAT 1,100,100,8,8,65368,USR "A"

	Note that using the sprite definer will turn the clock/trace
	off.

*fx MOVE m,a,b,e
	move sprite 'n' to pixel location (a,b). If parameter 'e' is
	given then the address of the UDG is changed to 'e'. This allows
	you to alternate UDGs to 'animate' a sprite. When a sprite is
	moved it is always visible (if it is on the screen) afterwards.

*fx ERASE n
	temporarily remove sprite 'n' but leave defined

*fx ERASE
	Sets all sprites to erased, although they stay on the screen.
	You should do this after a 'CLS' command, otherwise the next
	'MOVE' will re-draw the background you have just erased! Colours
	will become confused if you don't use this instruction. The best
	advice is to use this at the start of your program and after
	every CLS.

*fx VERIFY n
	This provides collision detection. It looks to see if sprite 'n'
	is overlapping any other sprite and sets location 54983
	accordingly. If this is 0 after a 'VERIFY' command then sprite
	'n' is not touching any other sprite. Otherwise it is set to the
	highest-numbered sprite it touches.

*fx RESTORE n
	restore an erased sprite to its last location.


To use sprites, first FORMAT each one, using the sprite definer if
necessary. This identifies each sprite and gives the initial position.
It also gives the sprite its shape and tells it where the bytes defining
it are (don't forget to save the area where you have stored your
characters). Now MOVE, ERASE and RESTORE as desired.


READING THE KEYBOARD
--------------------
'INKEY$' will read the keyboard successfully only if just one key is
pressed at a time. As this is no good for a game, it is better to use
the 'IN' command. For example, if 'IN 254' does not equal 255 then one
or more keys are being pressed. If 'IN 65278' does not equal 255 then
one or more of CAPS-SHIFT, Z, X, C or V are being pressed. The full use
of 'IN' to read the keyboard can be found in Chapter 23 of the (old)
Spectrum manual.


OTHER COMMANDS
--------------
*fx T(ime)
	turns on the clock. Note that the clock stops during 'BEEP' and
	tape or microdrive commands. The clock value may be PEEKed from
	Basic and is held at locations 54986, 7, 8 and 9

*fx L(ine)
	line numbers. The number of the line currently being executed is
	displayed at the top-right of the screen. In Basic, the
	statement is also shown. If you use this command in association
	with 'REM #2' in COLT, the line number of the compiled code
	being run is shown, but not the statement number. This is
	updated every 50th of a second

*fx O(ff)
	turns off L or T. Does not stop the clock or the Executive

*fx Z(ero)
	zero the clock

*fx I(nitialize)
	sets the time on the clock. The form '*fx I h,m,s' sets the
	clock.

*fx S(top)
	stops display of the clock or line trace, leaving them at their
	current values (the clock continues internally)

*fx F(ree)
	prints the amount of free space between 'STKEND' and 'RAMTOP'

*fx P(rog)
	run the program at RAMTOP+1 (correct for COLT)

*fx LEN
	print the end address of Basic (this is equal to the value of
	the system variable 'STKEND')

*fx USR m,a,b,c...
	call location 'm'. The HL register pair points to argument 'a'
	(2 bytes long). This means that you can take parameters to a
	machine code routine

*fx BIN n
	print 'n' (a decimal number) in 16-bit binary (base 2)

*fx CODE n
	print hexadecimal value (base 16) of 'n' (a decimal number)

*fx H(ex)
	goes into input mode to accept a hexadecimal (base 16) number.
	After ENTER has been pressed, it prints the decimal equivalent.
	Illegal keys are ignored and deletion is not allowed

*fx D(elete) m,n
	delete lines 'm' tp 'n'

*fx W(here)
	print location in memory of program line 'n'. The address given
	is that of the higher byte of the line number

*fx G(oto) n,m
	if an error occurs which would normally give an error report
	then execution continues at line 'n'. If 'm' is zero or not
	given then BREAK (errors 'D' or 'L') still give an error report.
	If 'm' is 1 then error 'L' is trapped (dangerous as it includes
	E!E!). If the code is compiled, it transfers command to the
	Basic line 'n', not that in the compiled code. If 'n' = 0 then
	the error trapping is turned off. The error number is stored in
	location 54982 before control is passed to line 'm'

	The interface 1 errors and numbers are as follows :

	100 Nonsense in Basic
	101 Invalid stream number
	102 Invalid device expression
	103 Invalid name
	104 Invalid drive number
	105 Invalid station number
	106 Missing name
	107 Missing station number
	108 Missing drive number
	109 Missing baud rate
	111 Stream already open
	112 Writing to a 'read' file
	113 Reading to a 'write' file
	114 Drive 'write' protected
	115 Microdrive full
	116 Microdrive not present
	117 File not found
	118 Hook code error
	119 CODE error
	120 MERGE error
	121 Verification failed
	122 Wrong file type

Error trapping is turned off once an error occurs (even for BREAK), so
if you wish error trapping to continue you should re-enable it.


*fx STOP n
	stop with error report 'n'. This will be trapped by '*fx GOTO'
	above unless 'n' is zero

*fx DATA m,n
	this is a two-byte POKE. The 16-bit integer 'n' is put into
	locations 'm' and 'm+1' in normal Z-80 fashion

*fx PEEK m
	this is a two-byte PEEK. The 16-bit (unsigned) integer in memory
	locations 'm' and 'm+1' is returned

*fx LN m,n,p
	this provides a 'logging' function which enables you to see
	which part of your program (whether it's Basic or machine code)
	is absorbing all the program time. This means that you can
	devote your effort to improving the small percentage of your
	code which takes the longest. The general maxim is that 10% of
	the code is used for 90% of the time. Now you can find which
	part that 10% is :

	BASIC
	-----
	The parameters are 'm' (the start line number), 'n' (the
	increment in 'm') and 'p', which is 2. There are 10 'bins' for
	the information which is returned. The first holds the use of
	all lines up to and including 'm'. The next, 'm+1' to 'm+n', the
	third 'm+n+1' to 'm+2*n' etc. The last bin holds all occurrences
	greater than 'm+9*n'.

	For example,
		*fx LN 100,10,2

	would log the activity in the line range starting at 100 with a
	resolution of 10 lines.

	MACHINE CODE
	------------
	As for Basic except that the parameters are now 'm' (the
	starting address), n (the increment in m), and 'p' is 1. This
	will report the next location at which code is to be executed.

	The logging for both Basic and machine code is carried out every
	50th of a second, so if too small a number is given for 'n' in
	machine code logging, very misleading results can be produced
	from synchronism with the sampling process.

	If 'p' is made zero the logging process is turned off. A new
	'*fx LN' always clears the data accumulated from previous runs.


*fx LLIST
	This command causes the logging data started by '*fx LN' to be
	printed on the screen as a table. The results are
	self-explanatory. This command does not stop or reset the
	logging process.


USER-DEFINED BASIC
------------------
You may have your own user-defined statements by using or re-defining
existing Executive commands. You should put the address of your machine
code routine (in the form 'JP address') in locations 55001, 2 and 3.
'JP' is 'C3' in hexadecimal. Your routine will be passed the token or
first letter after the '*fx' in the A register. The HL register pair
holds the address of the first two-byte argument.

If bit 7 of the system variable 'FLAGS' is zero then you should treat
this as syntax checking, and return zero in the A register (and the zero
flag reset) if the character or token is yours. Otherwise return without
altering anything.

If bit 7 of 'FLAGS' is set, Basic is running and you should execute your
code, returning zero in the A register. For example, to define a new

	'*fx SQR'

function to print a character on the current stream, you could use code
like this :

	CP 187		; 187 is the token 'SQR'
	RET NZ		; return if not SQR
	XOR A		; clear A and zero flag
	BIT 7,(IY+1)	; test bit 7 of 'FLAGS'
	RET Z		; return if in syntax phase
	LD A,(HL)	; get first argument in A
	RST 16		; print on current stream via ROM
	XOR A		; clear A
	RET		; and return

The Basic code to print the letter 'A' (ASCII value 65) would then be

	*fx SQR 65


EXECUTIVE ERROR MESSAGES
------------------------
A flashing cursor during syntax checking (i.e. when you press the ENTER
key to enter a line into a Basic program) means that the syntax of a
statement is wrong or something is out of context. The messages reported
by the Executive are :

Q Parameter error
	You have used more than 16 parameters.

P FN without DEF
	An invalid *fx command has been issued from a compiled piece of
	code. This shouldn't happen unless the versions of COLT and the
	Executive are incompatible.

A Invalid argument
	The line numbers used in a DELETE command are not sensible.

B Integer out of range
	All arguments must be in the normal integer range of -32768 to
	32767. This error is also caused if you attempt to define too
	large a window or to manipulate a line which is off the screen.

5 Out of screen
	This means that the screen is not large enough for the FORMAT
	command.


The Executive uses interrupt mode 2 to maintain the clock, trace, etc.
and is called automatically every 50th of a second. The system variables
'FRAMES' (locations 23672, 3 and 4) is modified by this process. The
overhead of doing this is that all programs slow down by between 10% and
15%. In addition, the clock will stop during tape, microdrive and
certain other operations which cause interrupts to be temporarily
disabled.

During development, we have experienced problems with the SAGA Emperor
keyboard, which would not type the exclaimation mark, '!' (SYMBOL-SHIFT
1). SAGA was extremely helpful in sorting out this problem with its
product, and the cure is very simple. It should only be attempted if it
is necessary. The keyboard is connected to the computer by two cables.
One is an 8-way cable and the other is a 5-way. At the computer end of
the 5-way cable is a small printed circuit board with 5 tracks at one
end. You should solder a 10K resistor between the first and fifth tracks
to cure the fault. The problem has been experienced on several other
programs. If your keyboard does have this fault, but is not manufactured
by SAGA, we suggest you contact its manufacturer.


OTHER DISC/WAFER INTERFACES
---------------------------
We believe that other storage media interfaces which use the commands
FORMAT, CAT, MOVE, ERASE, OPEN, CLOSE, MERGE or VERIFY will function
perfectly correctly with COLT due to the unique compilation process used
for these statements. Please let us know what success you have.



HISOFT
180 High Street North
Dunstable LU6 1AT
(0582) 696421
