
.........1.........2.........3.........4.........5.........6.........7.........8


HISOFT
Presents

The Colt

FAST BASIC COMPILER


COLT ZX BASIC Compiler Manual

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

First Edition August 1985


= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =


CONTENTS
--------

Page	1	Introduction
Page	1	The compilation process
Page	2	Getting started with COLT
Page	4	COLT in detail
Page	5	Loading the compiler
Page	5	COLT statements
Page	9	Strings and arrays
Page	9	Error messages during compilation
Page	10	Run-time errors
Page	10	Saving compiled code
Page	11	Re-loading compiled code
Page	11	Trace facilities
Page	12	Compiling up to 32K
Page	12	Returning to Basic
Page	13	Fetching variables from Basic
Page	13	Taking COLT variables back to Basic
Page	14	Floating point?
Page	15	LOAD commands
Page	15	Speed
Page	16	Strange Errors
Page	16	COLT in Detail
Page	18	Changing these space allocations - some useful addresses
Page	18	Calls between Basic and COLT
Page	19	Compiling subroutines
Page	19	Re-entering code
Page	21	The Executive
Page	22	Using the Executive
Page	22	Quick access commands
Page	23	User-definable "soft" (function) keys
Page	24	Enhanced Basic Commands
Page	24	Window commands
Page	26	Sprite commands
Page	27	Reading the keyboard
Page	28	Other commands
Page	31	User-defined Basic
Page	32	Executive error messages
Page	33	Other disc/wafer interfaces


= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =


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 comparatively 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 command. 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 this 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 when 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 is 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 "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 appears, 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 there, 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 negligible.

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 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 names 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 in Basic,
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
Ar 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
		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.
GOSUB n		 'n' is a positive integer. The fast form of GO SUB.
GOSUB 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 GOSUB
GOTO e		 as GOSUB
IF e THEN
IN e
INK e
INKEY$
INKEY$ #e	for Interface 1
INPUT a		Editing exactly as in Basic. Colour
		operations and all three forms of INPUT may
INPUT a(v)	be intermixed. The suffix #e is allowed to
INPUT a$	enable reading from the RS232 or 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 a list 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 analogous 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 ready 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 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 GOSUB to go to a line number greater than
	32767. This can occur at run-time with computed GOTOs and
	GOSUBs.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


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 in to 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 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 to 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 'OLDPPC' (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 occasions 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	xx

	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    | |
         = Begin                                              | Ctop
                                                            Nmtop

'STKEND'	A Basic system variable (address 23653 and 4) which
		marks the end of the space occupied by Basic.
'RAMTOP'	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 'GOSUB', 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 all 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 means 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 effect 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 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 program 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 argument 1, 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 bracketed 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' tines. 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 home 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 n,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 as 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 areas 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' to 'n'.

*fx W(here) n
	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. If 'm' is
	2, the errors 'D' and 'L' are both 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 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 provide 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 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 nay 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 '*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 DF
	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 variable '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 temporarily to be disabled.

During development, we have experienced problems with the SAGA
Emperor keyboard, which would not type the exclamation 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 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.


.........1.........2.........3.........4.........5.........6.........7.........8
