BBC BASIC Reference Manual
BBC BASIC Reference Manual
Reference Manual
Copyright © 1992 Acorn Computers Limited. All rights reserved.
Updates and changes copyright © 2017 RISC OS Open Ltd. All rights reserved.
Issue 1 published by Acorn Computers Technical Publications Department.
Issues 2 and 3 published by RISC OS Open Ltd.
No part of this publication may be reproduced or transmitted, in any form or by
any means, electronic, mechanical, photocopying, recording or otherwise, or
stored in any retrieval system of any nature, without the written permission of the
copyright holder and the publisher, application for which shall be made to the
publisher.
The product described in this manual is not intended for use as a critical
component in life support devices or any system in which failure could be expected
to result in personal injury.
The product described in this manual is subject to continuous development and
improvement. All information of a technical nature and particulars of the product
and its use (including the information and particulars in this manual) are given by
the publisher in good faith. However, the publisher cannot accept any liability for
any loss or damage arising from the use of any information or particulars in this
manual.
If you have any comments on this manual, please complete the form at the back of
the manual and send it to the address given there.
Within this publication, the term ‘BBC’ is used as an abbreviation for ‘British
Broadcasting Corporation’, however the BBC is not affiliated in any way with this
manual.
All trademarks are acknowledged as belonging to their respective owners.
ii
Contents
Part 1 – Overview 1
About the BBC BASIC Reference Manual 3
Intended readership 3
Structure of the manual 3
Conventions used in this manual 4
Simple programming 15
Entering a program 15
Altering a program 16
Deleting whole programs 19
Numbering lines in a program 20
Listing long programs 21
Comments 22
Multiple statements 23
Saving and recalling programs 24
Variables 27
Types of variables 27
Naming variables 27
iii
Contents
Numeric expressions 29
Integers and floating point numbers 29
Special integer variables 31
Arithmetic operators 31
String expressions 39
Assigning values to string variables 39
Joining strings together 40
Splitting strings 40
How characters are represented 43
Converting between strings and numbers 43
Arrays 47
The DIM statement 47
Two dimensional arrays 47
Finding the size of an array 49
Operating on whole arrays 49
Array operations 52
Outputting text 55
Print formatting 55
The text cursor 58
Defining your own characters 60
Inputting data 63
Inputting data from the keyboard 63
Including data as part of a program 65
Programming the keyboard 67
Using the mouse in programs 69
Programming function keys 71
iv
Contents
Control statements 73
IF... THEN... ELSE 73
Operators 74
IF... THEN... ELSE... ENDIF 75
FOR... NEXT 77
REPEAT... UNTIL 80
WHILE... ENDWHILE 81
CASE... OF... WHEN... OTHERWISE... ENDCASE 82
GOTO 84
GOSUB... RETURN 84
ON... GOTO/GOSUB 85
v
Contents
Viewports 147
Text viewports 147
Graphics viewports 149
Sprites 151
Loading a user sprite 151
Plotting a user sprite 152
vi
Contents
Sound 159
Activating the sound system 159
Selecting sound channels 159
Allocating a wave-form to each channel 159
Setting the stereo position 160
Creating a note 161
Synchronising the channels 162
Finding the value of the current beat 163
Finding the current tempo 163
Executing a sound on a beat 164
vii
Contents
Index 503
viii
Part 1 – Overview
1
2
1 About the BBC BASIC Reference
Manual
B BC BASIC is one of the most popular and widely-used versions of the BASIC
programming language. This manual provides a complete description of BBC
BASIC for users of computers running RISC OS version 3.10 or later.
Intended readership
You should read this manual if you are
● a computer user who has never used BBC BASIC before, who wants an
introduction to a new computer language;
● an experienced programmer in other computer languages, who wants an
insight into BBC BASIC’s features without having to resort to a lengthy
tutorial-type manual;
● an experienced BBC BASIC programmer, who needs specific information about
the structure of BBC BASIC, and the use of its commands.
3
Conventions used in this manual
4
2 About BBC BASIC
5
BASIC versions
● BASIC V is the most commonly used interpreter. Each real number is stored
using 5 bytes of memory, and all real arithmetic is performed in software. This
version of BASIC is provided by the “BASIC” module.
● BASIC VI is an alternative interpreter that performs calculations involving real
numbers with greater accuracy. Real numbers are stored using 8 bytes of
memory, and arithmetic is performed in accordance with the IEEE 754 floating
point standard. Apart from increased accuracy, this also makes for easier data
interchange with other languages like C. There are in fact two different variants
of the BASIC VI interpreter, to cater for the two main floating point instruction
sets which ARM processors have supported over the years:
● The first variant of BASIC VI, provided by the “BASIC64” module, was
released with RISC OS 3.10 and is designed around the FPA instruction
set.
● The second variant of BASIC VI, provided by the “BASICVFP” module, was
released with RISC OS 5.24 and is designed around the VFP instruction
set.
If you do need to know more about real numbers, Appendix A – Numeric implementation
explains in detail how they are stored and manipulated, and gives details of the
differences between the FPA and VFP variants of BASIC VI.
BASIC versions
Different versions of the BBC BASIC interpreter provide different features. This
manual describes the features present in version 1.75 of the interpreter, as
included in RISC OS 5.24.
If you have an older version than this then you will need to obtain the latest
version from the RISC OS Open web site (http://www.riscosopen.org) as part of the
“System resources” archive. Open the archive and follow the instructions in the
ReadMe file to merge these updates with your !System.
To load the newer version of the BASIC V interpreter in place of the one in the
RISC OS ROM you will need to execute the following * Command:
RMEnsure BASIC 1.75 RMLoad System:Modules.BASIC
This should only be done once after the machine has started, and before entering
the desktop, because BASIC programs that run inside the desktop will stop working
if the BASIC interpreter changes whilst they are using it.
The recommended method for doing this is to create a file containing this
command, set its file type to ‘Obey’, and add it to the Choices:Boot.PreDesk
directory. Further information on the !Boot application and the PreDesk directory
can be found in the RISC OS User Guide.
6
About BBC BASIC
You will find a list of the differences between each released version of the BASIC
interpreter in Appendix I – BBC BASIC’s history.
Instructions to avoid
If you do decide to write a window managed program you must be careful to avoid
instructions in BASIC which will either interfere with the running of other programs
under the Wimp, or simply not work at all. These include:
7
Window managed programs
8
Part 2 – Programming techniques
9
10
3 Command mode
T his chapter describes how to enter and leave BASIC, and how command mode
works while within BASIC.
Entering BASIC
BASIC V
To start BASIC V, press F12 to access the command line and type the following:
BASIC
Press Return, and BASIC will start with a message of the form:
ARM BBC BASIC V (C) Acorn 1989
Starting with 651516 bytes free
BASIC VI
RISC OS 5 includes BASIC VI in ROM, whereas previous versions of RISC OS
supplied it on disc. This is in contrast to BASIC V which has always been supplied
in ROM.
To start BASIC VI, press F12 to access the command line and then type BASIC64.
Press Return, and BASIC will start with a message similar to:
ARM BBC BASIC VI (FPA) (C) Acorn 1989
Starting with 581628 bytes free.
If you get the error message Module BASIC64 not found or Module
BASICVFP not found on RISC OS 5 it suggests that the named module has
been unplugged from ROM; consult the RISC OS User Guide for details on how to
correct this.
On versions of RISC OS where BASIC VI is not in ROM, you will get the following
error message if BASIC VI is not loaded and you are using a version of BASIC V
older than version 1.75:
File 'BASIC64' not found
11
Leaving BASIC
If you get this message then you should download and install the latest version of
!System from the RISC OS Open web site (http://www.riscosopen.org) and ensure
that the updated BASIC module is loaded before the desktop starts, as described
in the section entitled BASIC versions on page 6.
If you get the error message
File 'System:Modules.BASIC64' not found
then your !System does not contain a copy of BASIC64 and in this case too you
should update to the latest version of !System.
BASIC files saved from both BASIC V and BASIC VI are the same and can be run
using either BASIC, although the difference in arithmetic precision may give
slightly different results for calculations using real numbers. Note also that
differences in the lower-level interfaces to BASIC may cause compatibility issues
for some advanced programs; consult the later chapters for details.
Leaving BASIC
To leave BASIC, type QUIT, then press Return twice to get back to the desktop.
Command mode
When you enter BASIC it is in command or interactive mode (sometimes this is termed
immediate mode). This means that you can type commands and the computer
responds straight away. For example, if you type
PRINT "Hello"
the computer displays the following on the screen:
Hello
PRINT is an example of a keyword which the computer recognises. It instructs the
computer to display on the screen whatever follows the PRINT statement enclosed
in quotation marks. Keywords are always written in upper case letters (capitals).
If you make a mistake, the computer may not be able to make sense of what you
have typed. For example, if you type:
PRINT "Hello
the computer responds with the message:
Missing "
12
Command mode
This is an error message. It indicates that the computer cannot obey your
command because it does not follow the rules of BASIC (in this case because the
computer could not find a second quotation mark).
If PRINT is followed by any series of characters enclosed in quotation marks, then
these characters are displayed on the screen exactly as you typed them. Thus:
PRINT "12 - 3"
produces the output:
12 - 3
PRINT, however, can also be used to give the result of a calculation. For example,
typing
PRINT 12 - 3
produces the output:
9
In this case, because the sum was not enclosed in quotation marks, the computer
performed the calculation and displayed the result.
Similarly, multiplication and division can be performed using the symbols * and /.
For example:
PRINT 12 * 13
PRINT 111 / 11
Some commands, although they have an effect on the computer, do not give
evidence that anything has changed. If, for example, you type
LET FRED = 12
nothing obvious happens. Nevertheless, the computer now knows about the
existence of a variable called FRED which has the value 12. A variable is a name
which can have different values assigned to it. It is described in more detail later in
this manual.
Now if you type
PRINT FRED / 3
the computer responds by displaying the number 4.
The program below illustrates how you can give commands to produce some
graphics on the screen:
CLS
CIRCLE FILL 600,500,100
13
Command mode
14
4 Simple programming
Entering a program
Once you have entered BASIC you can begin to type in programs. Each line of a
program is numbered so that it can be referred to more easily. Note that you must
press Return at the end of each line you type in. For example, type the following:
10 PRINT "Hello"
Note that nothing happens (but all must be well as no error message was printed).
Now type
RUN
The Hello message is displayed on the screen. The number 10 at the start of the
line is called the line number, and identifies the text after it as a program
statement to be stored in memory, rather than as a command to be executed
immediately.
You can type spaces either between the start of the line and the line number, or
between the line number and the instruction without affecting the execution of the
program.
10 PRINT "Hello"
and
10PRINT "Hello"
are equally valid.
One of the advantages of programs is that they can be executed repeatedly: Typing
RUN again here causes Hello to be displayed a second time – there is no need to
type the complete PRINT "Hello" statement again.
The following is a simple program demonstrating the use of a variable and the
INPUT statement:
15
Altering a program
Altering a program
Once you have entered a program, you may wish to make changes to it.
You can of course type in a whole new version of the program, but there are quicker
methods available.
To see the program which is currently stored in memory, type
LIST
Lines 10, 20 and 30 are listed on the screen.
16
Simple programming
Note that these two extra lines are added to the program in such a way that the line
numbers are listed in numerical order:
5 PRINT "Hello"
10 PRINT "Can you give me a number ";
20 INPUT number
30 PRINT "The number you typed was ";number
40 PRINT "Twice "; number " is "; 2*number
To replace lines, enter the new line with the line number of the one which is to be
replaced. For example:
40 PRINT number;" squared is ";number*number
Now when you type
LIST
the following is displayed:
5 PRINT "Hello"
10 PRINT "Can you give me a number ";
20 INPUT number
30 PRINT "The number you typed was ";number
40 PRINT number;" squared is "; number*number
17
Altering a program
5 PRINT "Hello"
10 PRINT "Can you give me a number ";
20 INPUT number
30 PRINT "The number you typed_was ";number
40 PRINT number;" squared is "; number*number
30 PRINT "The number you typed
Press Backspace until the word typed is deleted from the new line 30. The cursor
on the old line 30 does not move:
5 PRINT "Hello"
10 PRINT "Can you give me a number ";
20 INPUT number
30 PRINT "The number you typed_was ";number
40 PRINT number;" squared is "; number*number
30 PRINT "The number you
Type the word
entered
and press End to copy the rest of line 30 to your new version.
Press Return. The square disappears and the cursor moves to the start of a new
line. Now type
LIST
to produce the following:
5 PRINT "Hello"
10 PRINT "Can you give me a number ";
20 INPUT number
30 PRINT "The number you entered was ";number
40 PRINT number;" squared is "; number*number
There are no restrictions on how much you move the cursor around when you are
copying. Note when the cursor reaches the end of the screen it will wrap-around to
the other side of the screen. You can use the right and left arrow keys to miss out
parts of lines or to repeat them. You can also copy from several different lines on to
your new line as you go.
Deleting lines
You can either delete lines one at a time, or delete a group of lines at once using
the DELETE command.
18
Simple programming
To delete a single line, you just type the line number followed by Return. To delete
line number 5, for example, type
5
To check that line 5 is deleted, type
LIST
and the computer displays the following:
10 PRINT "Can you give me a number ";
20 INPUT number
30 PRINT "The number you entered was ";number
40 PRINT number;" squared is "; number*number
The DELETE command allows you to delete a number of consecutive lines in three
different ways:
● By deleting a block of lines. To delete all line numbers between 10 and 30
inclusive, type
DELETE 10,30
● By deleting from the beginning of a program. To delete all lines from the
beginning of the program to line 30, type
DELETE 0,30
The number zero is the minimum line number that can be used in a program.
Therefore, all lines from the start of the program to line 30 are deleted.
● By deleting from a line to the end of the program. To delete all lines from line
20 to the end of the program, for example, type
DELETE 20,65279
The number 65279 is the maximum line number that can be used in a program,
so in this case all lines from line 20 to the end of the program are deleted. Of
course, you can use any other number which is higher than the last line of the
program, so something like 60000 will usually work just as well, and is
somewhat quicker to type!
19
Numbering lines in a program
This tells the computer to forget about any existing program, and to be ready to
accept a new one.
Although the DELETE and LIST commands combined with cursor editing are fine
for making small changes to a BASIC program, it is usually easier to edit programs
using the desktop Edit application. In addition, the BASIC Editor provides an
alternative way to edit BASIC programs outside of the desktop environment. See
the chapter entitled Editing BASIC files on page 191 for details of using this program.
20
Simple programming
Typing
RENUMBER
without including a number after the command, means that your program lines are
renumbered 10, 20, 30, 40 and so on.
21
Comments
LIST 20,40
To see from the beginning of the program up to a particular line type, for example,
LIST ,30
To display from a particular line to the end of the program type, for example,
LIST 20,
Comments
When writing programs, especially long or complex ones, you should insert
comments to remind you what each part of the program is doing. This is done by
using the REM keyword which is short for ‘remark’.
REM tells the computer to ignore the rest of the line when it executes the program.
For example, to add comments to the following program:
10 PRINT "Can you give me a number ";
20 INPUT number
30 PRINT "The number you typed was ";number
40 PRINT number;" squared is "; number*number
type
22
Simple programming
Multiple statements
A line of BASIC can contain up to 238 characters and can be spread over several
lines on the screen. In all the programs given so far, each line of BASIC contains a
single statement. Several statements, however, may be placed on one line
separated by colons (:). For example:
10 PRINT "Can you give me a number ";:INPUT number
30 PRINT "The number you typed was ";number: REM print out
the number
40 PRINT number;" squared is "; number*number: REM and its
square
23
Saving and recalling programs
Note that REM statements must only be placed at the end of a line since the whole
of the rest of the line is ignored. If you alter the program so that line 30 reads as
follows:
30 REM print out the number: PRINT "the number you typed
was ";number
you will prevent the PRINT statement being executed.
The lines above illustrate that lines with more than one statement can overflow
onto the next screen line very easily, making the program hard to read. You should
therefore try to avoid too many multi-statement lines.
24
Simple programming
The LOAD operation replaces the current program with the one from the disc (so
you should be sure that you don’t mind losing the current program before you load
a new one). You can check this by listing the program currently in memory.
In addition to loading a program, you can add a program to the end of the current
one using the APPEND command. The appended program is renumbered to ensure
that its line numbers start after those of the initial program. The statements
LIBRARY and OVERLAY may be used to add libraries of procedures and functions
to the current program (see the chapter entitled Procedures and functions on page 87
for details).
25
Saving and recalling programs
26
5 Variables
A variable has a name and a value associated with it. The name, for example,
FRED or a single letter such as x, allows the variable to be identified and its
value to be accessed. This value can be changed and retrieved as many times as
required.
Types of variables
There are three different types of variables used to store different types of
information. These are:
● Integer variables which can only store whole numbers
● Floating point variables, which can store either whole numbers or fractions
● String variables which store characters.
Each type is distinguished by the last character of the variable name. A name by
itself, like Fred, signifies a floating point variable; Fred% is an integer variable,
and Fred$ is a string variable.
Naming variables
The rules for naming variables are as follows:
● they can contain digits, unaccented upper- and lower-case letters, the
underscore character (_) and the grave character (`), also known as a backtick
● there must be no spaces within the name but they can be divided into multiple
words using the underscore character (_)
● they must not start with a digit
● they must not start with most BASIC keywords.
27
Naming variables
28
6 Numeric expressions
T his chapter tells you how to perform arithmetic operations using numeric
variables. If you want to know more about the different types of numeric
variable which BBC BASIC uses, and how they are represented, see Appendix A –
Numeric implementation.
29
Integers and floating point numbers
30
Numeric expressions
In BBC BASIC, it is usual not to use LET at all; it is principally allowed to provide
compatibility with other BASICs which require its presence.
An alternative way of expressing an addition in an assignment is to use:
x += 1
This means ‘let x become equal to itself with one added to it’.
Similarly,
x –= 3
means ‘let x become equal to itself with three subtracted from it’.
Arithmetic operators
The full list of arithmetic operators and logical operators is given in the following
table. Each operator is assigned a priority. When an expression is being evaluated,
this priority determines the order in which the operators are executed. Priority 1
operators are acted upon first, and priority 7 last.
31
Arithmetic operators
32
7 Binary and logic
Hexadecimal numbers
The computer treats any number which is preceded by an & sign as a hexadecimal
(hex) number.
Whereas decimal numbers can contain ten separate digits, from 0 to 9,
hexadecimal numbers can contain sixteen separate digits, 0 to 9 and A to F. The
first 16 hexadecimal numbers and their decimal equivalents are given below:
33
Shift operators
Shift operators
There are three operators which act upon the 32 bits of an integer, shifting it either
left or right by a given number of places.
Shift left
The simplest shift is <<. This shifts the bits of an integer to the left by a given
number of places and inserts zeros in the righthand bits. For example:
A% = 10
B% = A% << 1
C% = A% << 2
D% = A% << 3
This leaves the variables with the following values:
Variable Value
A% 10 (%00000000000000000000000000001010)
B% 20 (%00000000000000000000000000010100)
C% 40 (%00000000000000000000000000101000)
D% 80 (%00000000000000000000000001010000)
34
Binary and logic
35
AND, OR and EOR
36
Binary and logic
With AND
TRUE AND TRUE gives TRUE (-1 AND -1 = -1)
TRUE AND FALSE gives FALSE (-1 AND 0 = 0)
FALSE AND FALSE gives FALSE ( 0 AND 0 = 0)
With OR
TRUE OR TRUE gives TRUE (-1 OR -1 = -1)
TRUE OR FALSE gives TRUE (-1 OR 0 = -1)
FALSE OR FALSE gives FALSE ( 0 OR 0 = 0)
With EOR
TRUE EOR TRUE gives FALSE (-1 EOR -1 = 0)
TRUE EOR FALSE gives TRUE (-1 EOR 0 = -1)
FALSE EOR FALSE gives FALSE ( 0 EOR 0 = 0)
37
TRUE and FALSE
38
8 String expressions
39
Joining strings together
Splitting strings
As well as joining two strings together, BASIC can split a string into smaller
sequences of characters. Three functions are provided for doing this.
● LEFT$(A$,n) which gives the first (lefthand end) n characters of a string.
● RIGHT$(A$,n) which gives the last (righthand end) n characters of a string.
● MID$(A$,m,n) which gives n characters from the middle, beginning at the
mth character.
For example,
PRINT LEFT$("HELLO",2),RIGHT$("THERE",2),MID$("GORDON",3,2)
gives
HE RE RD
and
40
String expressions
41
Splitting strings
produces:
Hello Susan.
Howdy Susan.
Howdy Susan!
Alternatively, you can give the maximum number of characters to be replaced.
Then, if the length of the replacement string is less than the given value, all of it is
used. Otherwise only the first designated number of characters have an effect. For
example,
10 A$ = "ABCDEFGHIJ"
20 RIGHT$(A$,3) = "KL"
30 PRINT A$
40 LEFT$(A$,4) = "MNOPQR"
50 PRINT A$
60 MID$(A$,4,3) = "STUVW"
70 PRINT A$
produces:
ABCDEFGHKL
MNOPEFGHKL
MNOSTUGHKL
42
String expressions
43
Converting between strings and numbers
VAL
VAL returns the value of a string, up to the first non-numeric character.
For example:
PRINT VAL("10to10")
prints the value 10, since all the characters after the t are ignored. The string may,
however, begin with a + or -. Thus,
number = VAL("-5")
assigns the value -5 to number. If, however, the string does not start with a digit
or a plus or minus sign, VAL returns 0.
EVAL
EVAL however, considers the whole string as an expression, allowing operators and
variable names to occur within it. Variables must be assigned values beforehand.
10 radius = 5
20 area = EVAL("PI*radius^2")
30 PRINT area
When this program is run the value printed is 78.5398163, which is the value PI
(3.141592653) multiplied by 5 squared.
STR$
STR$ performs the opposite conversion to the above two functions. It takes the
number given and returns a string containing the digits in the number.
For example,
10 A = 45
20 B = 30.5
30 A$ = STR$(A)
40 B$ = STR$(B)
50 PRINT A + B
60 PRINT A$ + B$
produces the following when it is run:
75.5
4530.5
44
String expressions
45
Converting between strings and numbers
46
9 Arrays
A rrays are groups of variables. An array has a name which applies to all
variables in the group. The individual members, known as the elements of the
array, are identified by a subscript. This is a whole number (zero or greater)
indicating the element’s position within the array. For example, A(0) is the first
element in the array named A(), and A(1) is the second element, and so on.
47
Two dimensional arrays
This allocates space for nine elements, each called B() in this case, and each
identified by two subscripts as shown in the following table:
B(0,0) B(0,1) B(0,2)
48
Arrays
When you DIM a string array, the elements are initialised, just as they are for
numeric arrays. Each element in the array is set to the null string, "". No space is
allocated for the characters of each string element until they are assigned a value.
The operators += and –= are particularly useful with arrays, as they remove the
need to evaluate the subscript expressions twice. For example, suppose you had
the assignment:
a(100*(SINRADangle+1))=a(100*(SINRADangle+1))+increment
The expression 100*(SINRADangle+1) must be calculated twice, which could
be quite time-consuming. On the other hand, if you used
a(100*(SINRADangle+1)) += increment
the complex subscript expression would only be used once, saving time. It is also
easier to write and read!
49
Operating on whole arrays
It is possible to set every element in an array to any given value using a single
assignment as follows:
10 DIM A(10), B(10)
20 n% = 2
30 A() = (3*n%)
40 B() = A()
Line 10 dimensions two arrays of the same size. Line 30 sets all of the elements of
A() to 3*n%, i.e. 6. Then line 40 sets all of the elements of B() from the
corresponding elements in A().
Note: You may be wondering why the righthand side of the assignment in line
30 is in brackets, i.e. why couldn’t we have written
20 A() = 3*n%
The answer is that the righthand side of an array assignment must be a single
item (number, single variable or expression in brackets) to avoid possible
confusion with a more complex array operation, for example
20 A() = 3*n%()
as described below.
Instead of setting all of the elements of an array to one value, you can set them to
different values by giving a list of values after the =. For example:
10 DIM a(5), b(2,2)
20 a() = 1,2,3,4
30 b() = 6,5,4,3,2,1
Any elements omitted from the list are not changed in the array (for example, a(4)
and a(5) above wouldn’t be assigned). In the case of multi-dimensional arrays, the
elements are assigned so that the last subscript changes quickest. For example, in
the case of b() above the six values listed would be assigned to b(0,0), b(0,1),
b(0,2), b(1,0),… , b(2,1), b(2,2) respectively.
In addition, all the elements in an array can be increased, decreased, multiplied or
divided by a given amount:
10 DIM A(2,2), B(2,2)
20 A(0,0) = 4
30 A(1,1) = 5
40 A(2,2) = 6
50 n% = 2: m% = 3
60 A() = A() + (n%*n%)
70 A() = A() - m%
80 B() = A() * 6
90 B() = B() / n%
50
Arrays
When you RUN this program, the elements of the arrays A() and B() are assigned
the following values:
Array Value Array Value Array Value
A(0,0) 5 A(0,1) 1 A(0,2) 1
A(1,0) 1 A(1,1) 6 A(1,2) 1
A(2,0) 1 A(2,1) 1 A(2,2) 7
51
Array operations
Note that the second dimension of the first array must be identical to the first
dimension of the second array.
Also, the matrix multiplication operation can multiply a vector (a one-dimensional
array) by a two dimensional matrix to yield a vector. There are two possible cases:
row().matrix()
This gives a row vector as the result. The number of elements is equal to the
number of columns in the matrix.
matrix().column()
This gives a column vector as the result. The number of elements is equal to the
number of rows in the matrix. For example:
10 i = 2: j = 3
20 DIM row(i), column(j)
30 DIM matrix(i,j)
40:
Array operations
Arithmetic operations on arrays are not quite as general as those on simple
numbers. Although you can say a=b*b+c, you cannot use the equivalent array
expression a()=b()*b()+c(). Instead, you would have to split it into two
assignments:
a() = b()*b()
a() = a()+c()
Also, the only place these array operations may appear is on the righthand side of
an assignment to another array. You cannot say
PRINT a()*2
for example (or, indeed, PRINT a()).
52
Arrays
53
Array operations
90 mod=MODa()
then to perform the same operation without the MOD operator, you would
have to say:
10 DIM a(100), b(100)
20 ...
90 b()=a()*a()
100 mod=SQR(SUM(b())
54
10 Outputting text
Y ou can output text, including special characters defined by yourself, using the
PRINT statement.
Print formatting
The PRINT statement provides a number of ways of formatting the printed output.
Printing numbers
Numbers are printed right justified in the print field, unless preceded by a
semicolon, which causes them to be left justified. Print fields are discussed below.
In the example below, the first number is right justified in the default field of ten
characters; the second number is left justified because a semicolon comes before
it:
10 A% = 4
20 PRINT 4;" ";A%
55
Print formatting
Defining fields
The columns controlled by commas are called fields. By default a field is ten
characters wide. Each string which is printed following a comma starts at the
lefthand side of the next field. In other words, using commas is a convenient
method of left-justifying text. Numbers, on the other hand, are displayed to the
right of the next field, so that the units of integers, or the least significant decimal
places of floating point numbers, line up.
Thus,
10 FOR N% = 1 TO 5
20 A$ = LEFT$("Hello",N%)
30 B% = N%*10^(N%-1)
40 PRINT A$,A$,A$,A$'B%,B%,B%,B%
50 NEXT N%
produces the following when RUN:
56
Outputting text
H H H H
1 1 1 1
He He He He
20 20 20 20
Hel Hel Hel Hel
300 300 300 300
Hell Hell Hell Hell
4000 4000 4000 4000
Hello Hello Hello Hello
50000 50000 50000 50000
57
The text cursor
In each case x is the field width, y is the number of digits and the dot or comma
between them is used as the decimal point.
58
Outputting text
Initially, the text cursor is at the top lefthand corner of the screen, which is position
(0,0). The number of possible positions for the cursor depends on the screen
mode. For example, in a screen mode which has 80 characters across the screen
and 32 rows, the coordinates it can have vary as follows:
(0,0) (79,0)
(0,31 (79,31)
59
Defining your own characters
60
Outputting text
To do this, use the VDU 23 command, followed by the code of the character you
wish to define and then eight integers, each representing one row of the character,
from top to bottom. The bit pattern of each integer defines the sequence of dots
and spaces: one gives a dot and zero gives a space.
128 64 32 16 8 4 2 1
24
60
126
219
126
36
66
129
To set up character 128 to be the shape shown above, use the following:
VDU 23,128,24,60,126,219,126,36,66,129
Then, to display this character, type
PRINT CHR$(128)
Note that characters 129-133 and 136-139 can be redefined by the Wimp and so
should be avoided in window managed programs.
61
Defining your own characters
62
11 Inputting data
T his chapter describes several methods by which you can input data into your
BASIC program:
● from the keyboard
● from predefined data within your program
● by programming keys on the keyboard
● from a mouse.
INPUT
The INPUT statement allows a program to request information from the user.
The following program gives an example:
10 PRINT "Give me a number and I'll double it";
20 INPUT X
30 PRINT "Twice ";X " is ";X*2
When you run this program, the INPUT command on line 20 displays a question
mark on the screen and waits for you to enter data. The number you type is
assigned to the variable X. If you do not type anything, or type letters or symbols
instead, X is assigned the value 0.
63
Inputting data from the keyboard
64
Inputting data
65
Including data as part of a program
You may use as many DATA statements as you like, but you must make sure that
the type of each item of data matches the type of the variable into which it is being
read. Each DATA statement can be followed by one or more items of data
separated by commas.
You can usually leave out the quotation marks around strings, but they are needed
if you want to include leading or trailing spaces, commas or quotation marks in the
string.
For example,
10 DATA Hello, my name is
20 DATA Marvin
30 READ A$,B$
40 PRINT A$;B$
produces:
Hellomy name is
To obtain the sentence Hello, my name is Marvin, change the program as
follows:
10 DATA "Hello, my name is"
20 DATA " Marvin"
30 READ A$,B$
40 PRINT A$;B$
A DATA statement must appear as the first statement on a line, otherwise it will not
be found. If BASIC encounters a DATA statement while executing a program, it
ignores it and goes on to the next line.
When it attempts to READ the first item of data, it scans through the lines of the
program from the start until it finds the first DATA statement and uses the first
item of data on this line. The next READ uses the second item and so on until the
DATA statement has no more items left, at which point the next DATA statement is
searched for and used.
If there is insufficient data, the computer produces an error message, such as:
Out of data at line 20
This indicates that it has tried to READ an item of data, but that all items have
already been read.
You might have a lot of different sections of DATA, and want to start reading from a
certain point. You can do this using the RESTORE statement. It is followed by a
line number. BASIC will start subsequent searches for DATA from that line instead
of from the start of the program. For example, the program below
66
Inputting data
10 RESTORE 60
20 READ A$
30 PRINT A$
40 END
50 DATA First line of data
60 DATA Second line of data
will print out
Second line of data
because the RESTORE causes BASIC to start the search for DATA statements at
line 60.
Because line numbers can’t be used in procedure libraries, a special form of
RESTORE is provided so that you can still include data in them. If you say
RESTORE +offset, BASIC will start searching for DATA statements at offset+1
lines from where the RESTORE statement is located. For example, if you had the
following lines:
1000 RESTORE +0
1010 DATA ...
1020 DATA ...
the next READ would read data from line 1010. If line 1000 was RESTORE +1, then
data would be read next from line 1020, and so on.
A further useful feature is the ability to remember where data is currently being
read from (LOCAL DATA), read data from another part of the program, then restore
the original place (RESTORE DATA). This is mainly useful in functions and
procedures, so is explained in the section dealing with them.
A note about line numbers. In general, if you use line numbers anywhere in a
program (and there should be very few situations where you have to), they should
be simple numbers in the range 0 to 65279, not expressions like start%+10*n%.
Otherwise, if the program is renumbered, it will stop working since BASIC does not
know how to change the expression in the right way.
67
Programming the keyboard
The GET and GET$ instructions look in the keyboard buffer for a key. Hence they
take note of keys which were pressed before the input instructions were executed.
If, for instance, you want to ensure that you only read keys pressed after a prompt
has been displayed, you can empty or flush the buffer before using these
instructions. Then you can be sure that the key obtained is in response to the
prompt and not just an accidental press of the keyboard a few moments before. To
do this, use the operating system command:
*FX 15,1
68
Inputting data
10 MODE MODE
20 *FX 4,1
30 x = 600 : y = 492
40 oldx = x : oldy = y
50 RECTANGLE FILL x,y,80,40
60 REPEAT
70 *FX 15,1
80 key = GET
90 CASE key OF
100 WHEN 135 : END
110 WHEN 136 : x -= 20
120 WHEN 137 : x += 20
130 WHEN 138 : y -= 20
140 WHEN 139 : y += 20
150 ENDCASE
160 RECTANGLE FILL oldx,oldy,80,40 TO x,y
170 oldx = x : oldy = y
180 UNTIL FALSE
69
Using the mouse in programs
70
Inputting data
10 MODE MODE
20 MOUSE ON
30 MOVE 0,0
40 REPEAT
50 REPEAT
60 MOUSE x,y,button%
70 UNTIL button% <> 0
80 DRAW x,y
90 UNTIL FALSE
For more details about the MOUSE statement see the chapter entitled Keywords on
page 215.
71
Programming function keys
72
12 Control statements
N ormally, lines in a BASIC program are executed in sequence, one after the
other. However, the language includes two types of structure which alter this
sequence:
● Conditional structures allow statements to be executed only if certain
conditions are met.
● Loop structures allow statements to be executed repeatedly, either for a fixed
number of times, or until a certain condition is met.
In all cases, the code is easier to read if it is clear which statements are in the loop
and which are conditional on certain factors. This clarity can be achieved by use of
the LISTO command before listing the programs, to indent the conditional and
loop structures in the listing. All programs included in this chapter are listed as if
the command:
LISTO 3
had been typed beforehand; this gives a space after the line number and indents
structures.
73
Operators
For example:
10 PRINT "What is 2 * 4"
20 INPUT ans%
30 IF ans% = 8 THEN PRINT "Well done" ELSE PRINT "Wrong"
Line 30 contains a conditional expression. In the example shown the expression is
TRUE (i.e. has a non-zero value) when ans% is equal to 8, and is FALSE (i.e. has a
zero value) otherwise. Note that in an IF statement, either the THEN part or the
ELSE part (if present) is executed, never both.
Any non-zero number is treated as TRUE in an IF statement, however, the
comparison operators described in the following section return a particular value
meaning TRUE: –1. They return 0 for FALSE, of course. In addition, there are two
functions called FALSE and TRUE which return 0 and –1 respectively.
Operators
Two kinds of operators may be used in expressions:
● relational operators
● logical operators (on TRUE and FALSE values).
Relational operators
Relational operators can be used to evaluate numbers or strings:
Numbers
In the following, A and B can be integers or floating point numbers.
Operator Meaning
A = B TRUE when A is equal to B
A < B TRUE when A is less than B
A > B TRUE when A is greater than B
A <= B TRUE when A is less than or equal to B
A >= B TRUE when A is greater than or equal to B
A <> B TRUE when A is not equal to B
74
Control statements
Strings
Operator Meaning
A$ = B$ TRUE when A$ and B$ are the same
A$ <> B$ TRUE when A$ and B$ are different
A$ < B$ String comparisons; see below:
A$ > B$
A$ <= B$
A$ >= B$
When strings are compared, corresponding characters of each string are examined
until either they are different, or the end of a string is reached. If the strings are the
same length, and the corresponding characters are the same, the strings are said to
be equal; otherwise, the shorter string is ‘less than’ the longer one.
In the case where the two corresponding characters differ, the relationship between
the strings is the same as that between the ASCII codes of the mismatched
characters. For example, "HI" < "Hi" yields TRUE, because the ASCII code of
upper case I is less than that of lower case i. Similarly, "SIX" > "FIFTEEN" is
TRUE because "SIX" starts with S, and the ASCII value of S is larger than that of F.
75
IF... THEN... ELSE... ENDIF
10 n% = RND(10)
20 m% = RND(10)
30 PRINT "What is ";n% " * "m%;
40 INPUT ans%
50 IF ans% = n%*m% THEN
60 PRINT "Well done"
70 ELSE
80 PRINT "Wrong"
90 PRINT n%;" * ";m% " = ";n%*m%
100 ENDIF
The ENDIF on line 90 terminates the statement. It indicates that execution of the
following statements is not dependent on the outcome of the conditional
expression on line 50, so these statements are executed as normal. Without the
ENDIF the computer has no way of knowing whether or not the statements on line
100 belongs to the ELSE part.
There are certain rules which must be obeyed when using IF… THEN… [ELSE…]
ENDIF constructions:
● The first line must take the form:
IF condition THEN
with THEN being the last item on the line.
● The ELSE part need not be present, but if it is, the ELSE must be the first thing
on a line (excluding spaces).
● The ENDIF statement must be the first thing on a line (excluding spaces).
● IF… THEN … [ELSE …] ENDIF statements may be nested: one may occur
inside another. For example:
10 DIM A%(10)
20 count% = 0
30 PRINT "Give me an integer between 0 and 9 ";
40 INPUT number%
50 IF number% >= 0 AND number% <= 9 THEN
60 IF A%(number%) = 0 THEN
70 PRINT "Thank you"
80 A%(number%) = 1 : count% = count% + 1
90 ELSE
100 PRINT "You've already had that number"
110 ENDIF
120 ELSE
130 PRINT number% " is not between 0 and 9 !"
140 ENDIF
150 IF count% < 10 GOTO 30
76
Control statements
FOR... NEXT
The FOR and NEXT statements are used to specify the number of times a block of
a program is executed. These statements are placed so that they surround the
block to be repeated:
10 FOR N% = 1 TO 6
20 PRINT N%
30 NEXT N%
Type RUN and the following is produced:
1
2
3
4
5
6
The variable N% is called the control variable. It is used to control the number of
times the block of code is executed. The control variable can be started at any
number you choose, and you may alter the step size; the amount by which it
changes each time round the loop.
10 FOR N% = -5 TO 5 STEP 2
20 PRINT N%
30 NEXT N%
This program produces:
-5
-3
-1
1
3
5
The step size can be negative so that the control variable is decreased each time. It
does not have to be an integer value. You can also use a decimal step size,
although this is not generally advisable. The reason is that numbers such as 0.1 are
not exactly representable in the internal format used by the computer. This means
that when the step is added to the looping variable several times, small errors may
accumulate. You can see this by typing the following program:
10 FOR i=0 TO 100 STEP 0.1
20 PRINT i
30 NEXT i
77
FOR... NEXT
78
Control statements
Loops must be nested totally within each other: they must not cross. In the above
example, the N and M loops are incorrectly nested. BASIC tries to run the program,
but when line 50 is reached, it gives an error message indicating that it cannot
match the FOR statements with the NEXT statements.
Note: The reason the error wasn’t given sooner, i.e. as soon as the mismatched
NEXT was met, was that it is actually legal, though not advisable, to close more
than one loop with a single NEXT. When BASIC meets a NEXT var statement, it
terminates all open FOR loops until it meets one which started FOR var. Thus the
NEXT N in the example above closed the FOR M loop before performing the NEXT
N.
A FOR loop is ended when the control variable is:
● greater than the terminating value (value in the FOR statement) when a
positive step size is used.
● less than the terminating value (value in the FOR statement) when a negative
step size is used.
The loop is performed in the following sequence:
1 Assign the initial value to the control variable.
2 Execute the block of code.
3 Add the step to the control variable.
4 Test against terminating value, and if it is to be performed again, go back to
step 2.
The initial and terminating values and the step size are calculated only once, at the
start of the loop.
One of the consequences of the way in which the loop is performed is that the
block of code is always executed at least once. Thus,
10 FOR N = 6 TO 0
20 PRINT N
30 NEXT
produces:
6
FOR … NEXT loops are very versatile, since the initial and terminating values and
the step size can be assigned any arithmetic expression containing variables or
functions. For example:
79
REPEAT... UNTIL
REPEAT... UNTIL
The REPEAT … UNTIL loop repeats a block of code until a given condition is
fulfilled. For example:
10 REM Input a number in a given range
20 REPEAT
30 PRINT "Please give me a number between 0 and 9 "
40 INPUT N
50 UNTIL N >= 0 AND N <= 9
60 PRINT "Thank You"
If the result of the conditional expression following the UNTIL is TRUE, then the
loop is ended and the statement following the UNTIL is executed. If, however, the
result of the expression is FALSE, the block of code after the REPEAT is executed
again and the conditional expression is re-evaluated.
REPEAT … UNTIL loops may be nested in the same way as FOR … NEXT loops.
They are also similar to FOR loops in that the body of the loop is always executed
once, since no test is performed until the end of the loop is reached.
10 REM Repeat questions until answered right first time
20 REPEAT
30 tries% = 0
40 REPEAT
50 PRINT "What is 20 * 23 + 14 * 11 ";
60 INPUT ans%
70 tries% += 1
80 UNTIL ans% = 20 * 23 + 14 * 11
90 REPEAT
100 PRINT "What is 12 + 23 * 14 + 6 / 3 ";
110 INPUT ans%
120 tries% += 1
130 UNTIL ans% = 12 + 23 * 14 + 6 / 3
140 UNTIL tries% = 2;
80
Control statements
WHILE... ENDWHILE
The WHILE … ENDWHILE loop repeats a block of code while a given condition
holds true. For example:
10 X = 0
20 WHILE X < 100
30 PRINT X
40 X += RND(5)
50 ENDWHILE
The WHILE … ENDWHILE loop has a conditional expression at the start of it. If
this expression returns TRUE, the block of statements following the WHILE, down
to the matching ENDWHILE statement, is executed. This is repeated until the
expression returns FALSE, in which case execution jumps to the statement
following the matching ENDWHILE. We say ‘matching’ ENDWHILE because
WHILE loops may be nested. This means that when BASIC is looking for an
ENDWHILE to terminate a loop, it might skip nested WHILE … ENDWHILE loops.
Here is an example of nested WHILE loops:
10 A%=256
20 WHILE A%<>0
30 B%=1
40 WHILE B%<8
50 PRINT A%,B%
60 B%=B%*2
70 ENDWHILE
80 A%=A% DIV 2
90 ENDWHILE
WHILE … ENDWHILE is similar to REPEAT … UNTIL except that the conditional
expression is evaluated at the beginning of the loop (so the body of the loop may
never be executed if the condition is initially FALSE) and the loop repeats if the
result is TRUE. The following program demonstrates the fact that REPEAT …
UNTIL loops are always executed at least once, whereas the WHILE … ENDWHILE
loops need not be executed at all.
81
CASE... OF... WHEN... OTHERWISE... ENDCASE
10 REPEAT
20 PRINT "Repeat"
30 UNTIL TRUE
40
50 WHILE FALSE
60 PRINT "While"
70 ENDWHILE
80
90 PRINT "All done"
This program produces the following output:
Repeat
All done
82
Control statements
Like all the other BASIC structures, CASE statements may be nested.
83
GOTO
GOTO
The GOTO instruction may be used to specify a line number from which the
computer is to continue executing the program. For example:
10 PRINT "Hello"
20 GOTO 10
Whenever the computer executes line 20 it is sent back to line 10 once again. Left
on its own, this program never ends. To stop it, press Esc.
GOTO instructions send the control of the program either forwards or backwards.
The specified line number may be given as an expression. For example:
10 start% = 100
20 GOTO (start%+10)
30 PRINT "This line should not be executed"
100 REM start of the action
110 PRINT "Hello"
120 END
Using a variable, however, as the destination for a GOTO is not recommended
because while RENUMBER changes the line numbers, it does not alter GOTO
destinations that are given as anything other than a simple number. If you must
use an expression, it is best to put in inside brackets, since BASIC may get
confused if the expression starts with a number.
If you wish to make your programs easy to read, especially for other people, use as
few GOTOs as possible. They make a program very difficult to follow. It is far better
to use one of the loop constructs like REPEAT … UNTIL which have been described
above.
GOSUB... RETURN
GOSUB stands for ‘go to subroutine’ and is another variation of GOTO. Instead of
continuing indefinitely from the line number which is jumped to, the lines are
executed until a RETURN statement is reached. Control then passes back to the
instruction which comes after the GOSUB. For example,
10 GOSUB 100
20 PRINT "This is printed after the first GOSUB returns"
30 GOSUB 100
40 PRINT "This is printed after the second GOSUB returns"
50 END
100 PRINT "This is printed in the GOSUB"
110 RETURN
84
Control statements
produces:
This is printed in the GOSUB
This is printed after the first GOSUB returns
This is printed in the GOSUB
This is printed after the second GOSUB returns
Like GOTO, GOSUB should be used sparingly, if at all. It is provided in this version
of BASIC for compatibility with weaker dialects of the language. Better methods of
providing blocks of code, which once executed then return control back to the
point from which they were called are described in the chapter entitled Procedures
and functions on page 87.
ON... GOTO/GOSUB
The ON … GOTO statement is used to choose one of a number of different lines
depending on the value of a given expression. For example:
10 PRINT "Input a number between 1 and 4"
20 INPUT N%
30 ON N% GOTO 60, 100, 80, 120
60 PRINT "Your number is 1"
70 GOTO 999
80 PRINT "Your number is 3"
90 GOTO 999
100 PRINT "Your number is 2"
110 GOTO 999
120 PRINT "Your number is 4"
999 END
The computer checks the value of N% which is input, then jumps to the N%th line
number in the list. If N% is 3, the computer starts executing at line 80 and so on. If
N% is less than 1 or greater than 4, the error message
ON range at line 30
is displayed.
ELSE can be used to catch all other values. It is followed by a statement which is
executed if the value of the expression after ON has no corresponding line number.
For example, line 30 above could be replaced by:
30 ON N% GOTO 60, 100, 80, 120 ELSE PRINT "Number out of range"
40 GOTO 999
Now, when the program is run, if N% is not between 1 and 4 the message Number
out of range is displayed and the program ends normally.
85
ON... GOTO/GOSUB
86
13 Procedures and functions
87
Parameters and local variables
88
Procedures and functions
A procedure can be defined with more than one parameter. However, it must
always be called with the correct number of parameters. These parameters may be:
● integers
● floating point numbers
● strings
● arrays.
If a string variable is used as a formal parameter, it must have either a string
expression or a string variable passed to it. Floating point and integer parameters
may be passed to one another and interchanged freely, but remember that the
fractional part of a floating point variable is lost if it is assigned to an integer
variable. Array formal and actual parameters must be of exactly the same type. That
is, if the formal parameter is an integer, then only integer arrays may be passed as
actual parameters.
Local variables
The formal parameters of a procedure are local to that procedure. This means that
assigning a value to any variable within the procedure does not affect any variable
elsewhere in the program which has the same name.
In the following program, the procedure PROCsquare has a parameter S% which is
automatically local. It also contains a variable, J%, which is declared as being
LOCAL.
10 FOR I% = 1 TO 10
20 PROCsquare(I%)
30 PROCcube(I%)
40 NEXT
50 END
60
100 DEF PROCsquare(S%)
110 LOCAL J%
120 J% = S% ^ 2
130 PRINT S% " squared equals "J%;
140 ENDPROC
150
200 DEF PROCcube(I%)
210 I% = I% ^ 3
220 PRINT " and cubed equals ";I%
230 ENDPROC
89
Parameters and local variables
In the case of PROCcube, the actual parameter passed and the formal parameter
referred to within it are both called I%. This means that there are two versions of
the variable, one inside the procedure and another outside it.
Adding the line
35 PRINT I%
to the program above prints out the numbers 1 to 10, showing that the assignment
to I% within PROCcube does not affect the value of I% in the main body of the
program.
This example uses a function instead of a procedure. Note that SUM is a built-in
function.
When using local arrays, all LOCAL statements and any DIM … LOCAL memory
reservations in a procedure or function must come before the DIM statements that
dimension the local arrays. After a local array has been dimensioned any further
LOCAL statements in the same procedure or function will generate an error.
90
Procedures and functions
91
ON... PROC
For example, you can make an error handler local to a WHILE loop. However, the
constructs are mentioned here for completeness. More information can be found
in the chapter entitled Error handling and debugging on page 169.
To make the current DATA pointer local, and then restore it, a sequence of the
following form is used:
1000 LOCAL DATA
1010 RESTORE +0
1020 DATA ...
1030 ...
1080 RESTORE DATA
LOCAL DATA stores the current data pointer (i.e. the place where the next READ
will get its data from) away. It can then be changed by a RESTORE to enable some
local data to be read, and finally restored to its original value using RESTORE
DATA. Thus a procedure or function which uses its own local data can read it
without affecting the data pointer being used by the calling program.
As mentioned above, LOCAL DATA and RESTORE DATA can be used anywhere that
localised data is required, not just in functions and procedures. They can also be
nested. However, if LOCAL DATA is used within a function or procedure definition,
it must come after any LOCAL variables. BASIC will perform an automatic
RESTORE DATA on return from a PROC or FN, so that statement isn’t strictly
required at the end of PROCs and FNs.
ON... PROC
ON … PROC is similar to ON … GOTO which is described in the chapter entitled
Control statements on page 73. It evaluates the expression given after the ON
keyword, then calls the designated procedure on the list. For example:
10 REPEAT
20 INPUT "Enter a number ",num
30 PRINT "Type 1 to double it"
40 PRINT "Type 2 to square it"
50 INPUT action
60 ON action PROCdouble(num), PROCsquare(num)
70 UNTIL FALSE
100 DEF PROCdouble(num)
110 PRINT "Your number doubled is ";num*2
120 ENDPROC
200 DEF PROCsquare(num)
210 PRINT "Your number squared is ";num*num
220 ENDPROC
92
Procedures and functions
Note, however, that in most circumstances, the CASE statement provides a more
powerful and structured way of performing these actions.
Recursive procedures
A procedure may contain calls to other procedures and may even contain a call to
itself. A procedure which does call itself from within its own definition is called a
recursive procedure:
10 PRINT "Please input a string :"
20 INPUT A$
30 PROCremove_spaces(A$)
40 END
100 DEF PROCremove_spaces(A$)
110 LOCAL pos_space%
120 PRINT A$
130 pos_space%=INSTR(A$," "):REM =0 if no spaces
140 IF pos_space% THEN
150 A$=LEFT$(A$,pos_space%-1)+RIGHT$(A$,pos_space%+1)
160 PROCremove_spaces(A$)
170 ENDIF
180 ENDPROC
In the example above, PROCremove_spaces is passed a string as a parameter. If
the string contains no spaces, the procedure ends. If a space is found within the
string, the space is removed and the procedure is called again with the new string
as an argument to remove any further spaces. For example, typing the string The
quick brown fox causes the following to be displayed:
The quick brown fox
Thequick brown fox
Thequickbrown fox
Thequickbrownfox
Recursive procedures often provide a very clear solution to a problem. There are
two reasons, however, which suggest that they may not be the best way to solve a
problem:
● Some operations are more naturally expressed as a loop, that is, using FOR …
NEXT, REPEAT … UNTIL, or WHILE … ENDWHILE.
● Recursive procedures often use more of the computer’s memory than the
corresponding loop.
As an example, the following two programs both print Good morning!
backwards. The first one uses a WHILE … ENDWHILE loop. The second uses a
recursive technique to achieve the same result.
93
Functions
First example:
10 PROCreverseprint("Good morning !")
100 DEF PROCreverseprint(A$)
110 FOR i% = LEN A% TO 1 STEP -1
120 PRINT MID$(A$,i%,1)
130 NEXT
140 ENDPROC
Second example:
10 PROCreverseprint("Good morning !")
100 DEF PROCreverseprint(A$)
110 IF LEN(A$) > 0 THEN
120 PRINT RIGHT$(A$);
130 PROCreverseprint(LEFT$(A$))
140 ENDIF
160 ENDPROC
Functions
Functions are similar in many ways to procedures, but differ in that they return a
result. BASIC provides many functions of its own, like the trigonometric functions
SIN, COS, TAN and RND. If you give RND a parameter with an integer value greater
than 1, it returns a random value between 1 and the number given inclusive. For
example,
X = RND(10)
produces random numbers between 1 and 10.
You may define functions of your own using the keyword DEF followed by FN and
the name of your function. The function ends when a statement beginning with an
= sign is encountered. This assigns the expression on the right of the sign to the
function result. This result may be assigned to a variable in the normal way.
Functions obey the same rules as procedures with regard to naming conventions,
the use of parameters and local variables.
We have already seen an example function definition in FNscalar_product
above. Here is another example of how a function may be defined and used:
10 FOR N% = 1 TO 10
20 PRINT "A sphere of radius ";N%;" has a volume "; FNvolume(N%)
30 NEXT N%
40 END
100 DEF FNvolume(radius%)
110 = 4/3*PI*radius%^3
94
Procedures and functions
Notice that although function definitions may be multi-line, the syntax is such that
single line functions as found in older dialects of BASIC may be defined in a
compatible manner. Thus you can say either:
1000 DEF FNdisc(a,b,c)
1010 REM find the discriminant of a, b and c
1020 =b*b-4*a*c
or, using the old-fashioned form:
1000 DEF FND(a,b,c)=b*b-4*a*c
(Another limitation of the non-BBC BASIC syntax was that often only single-letter
function names were allowed.)
95
Function and procedure libraries
INSTALLed libraries. INSTALL must be used before the BASIC program is first run
rather than from within a program – it is a command, and cannot be used as a
program statement.
LIBRARY reserves a sufficient area of memory for the library just above the main
BASIC program and loads the library. Any library loaded in this way remains only
until the variables are cleared. This occurs, for example, when the CLEAR or NEW
commands are given, when the program is edited in some way, or when a program
is run. Thus LIBRARY-type libraries are much more transient than INSTALLed ones
(as temporary as normal variables, in fact), so you would generally use LIBRARY
from within a program.
For example:
10 CLS
20 REM Print out a story
30 REM Load output library
40 LIBRARY "Printout"
50 REM Read and print the heading
60 READ A$
70 PROCcentre(A$)
80 REM Print out each sentence in turn
90 REPEAT
100 READ sentence$
110 REM if sentence$ = "0" then have reached the end
120 IF sentence$ = "0" END
130 REM otherwise print it out
140 PROCprettyprint(sentence$)
150 UNTIL FALSE
200 DATA A story
210 DATA This,program,is,using,two,procedures:
220 DATA 'centre',and,'prettyprint',from,a,library
230 DATA called,'Printout'.
240 DATA The,library,is,loaded,each,time,
245 DATA the,program,is,run.
250 DATA The,procedure,'centre',places,a,string,in,the
260 DATA centre,of,the,screen.
270 DATA The,procedure,'prettyprint',prints,out,
280 DATA a,word,at,the,current,text,cursor,
290 DATA position,unless,it,would,be,split,over,
300 DATA a,line,in,which,case,it,starts,the,word,
305 DATA on,the,next,line,down.
310 DATA 0
96
Procedures and functions
97
Function and procedure libraries
Overlaying
OVERLAY enables you to give a list of filenames which contain libraries. When
BASIC can’t find a PROC or FN within the program or within any of the current
libraries, it will start to look in the OVERLAY files. You give OVERLAY a string array
as a parameter. For example:
10 DIM lib$(5)
20 lib$()="lib1","lib2","lib3","lib4"
30 OVERLAY lib$()
40 ...
When the OVERLAY statement is executed, BASIC reserves enough space for the
largest of the files given in the string array. Then, when it can’t find a PROC or FN
definition anywhere else, it will go through the list, loading the libraries in order
until the definition is found or the end of the array is met.
Once a definition has been found, that library stays in memory (and so the other
definitions in it may be used) until the next time a definition can’t be found
anywhere. The search process starts again, so the current overlay library will be
overwritten with the first one in the list. Once BASIC has found a definition, it will
remember which file it was in (or more precisely, which element of the array held
the filename), so that file will be loaded immediately the next time the definition is
required and it is not in memory.
Because of the way one area of memory is used to hold each of the overlay files
(and only one at any one time), you are not allowed to call a procedure whose
definition is in an overlay library if one of the overlay definitions is currently active.
Another way of putting this is that you can’t nest overlay calls.
If you know that a given overlay file will never be needed again in the program, you
can speed up the search through the overlay list by setting the no-longer-required
elements of the array to the null string. You can also add new names to the end of
the array, as long as none of the new library files is bigger than the largest one
specified in the original OVERLAY statement.
You can execute OVERLAY more than once in a program. Each time it is called, the
memory set aside for the previous set of files will be lost, and a new block based on
the size of the new ones will be allocated.
98
Procedures and functions
99
Function and procedure libraries
100
14 Data and command files
T his chapter describes how you can create data files to read information from
files, and how you can create command files to build up a sequence of
commands to BASIC.
Data files
Programs can create and read information from files, called data files. For example,
if you write a program that creates a list of names and telephone numbers, you
may wish to save the names and telephone numbers as a data file.
101
Writing or reading single bytes
10 A = OPENOUT "books"
20 FOR I = 1 TO 5
30 READ book$
40 PRINT#A, book$
50 NEXTI
60 CLOSE#A
70 END
80 DATA "Black Beauty"
90 DATA "Lord of the Rings"
100 DATA "The Wind in the Willows"
110 DATA "The House at Pooh Corner"
120 DATA "The BBC BASIC Reference Manual"
102
Data and command files
The following writes all the upper-case letters to a file using BPUT# as part of the
program:
10 channel = OPENOUT "characters"
20 FOR N% = ASC("A") TO ASC("Z")
30 BPUT#channel,N%
40 NEXT N%
50 CLOSE#channel
BGET# is used as part of a program that allows each character to be read into a
string as follows:
10 channel = OPENIN "characters"
20 string$ = ""
30 REPEAT
40 string$ += CHR$(BGET#channel)
50 UNTIL EOF#channel
60 CLOSE#channel
103
Command files
Command files
A command file is a file whose contents are a sequence of commands to be
executed as if they had been typed at the keyboard. You can use a variety of
methods to create a command file. Using Edit is probably the easiest, especially if
that application is already loaded and can be activated from the desktop. See the
RISC OS User Guide for details on using Edit.
Another way of creating a command file is to use the *BUILD command. If you type
*BUILD keyfile
everything subsequently typed from the keyboard is sent directly to the file called
keyfile. If there is a file named keyfile already, it is deleted when the *BUILD
command is given.
Press Return at the end of each line. When you finish entering the commands,
press Esc to end keyboard input to keyfile.
104
Data and command files
Note: If you do this, each line in the file is executed as a * command, i.e. it is
passed to the operating system command line interpreter only – not to BASIC. In
this case you do not see the lines that are being executed on the screen, and
*OBEY allows parameter substitution.
See the section Command scripts in appendix The command line in the RISC OS User
Guide for more details on *OBEY.
105
Command files
106
15 Screen modes
107
Numbered screen modes
When you type a MODE command from the command line, the desktop is cleared
automatically.
The following resolutions are typically available on most RISC OS computers:
● 640 × 480
● 800 × 600
● 1024 × 768
For a full list of the attributes that may be specified in a mode string see Appendix E
– Specifying screen modes
A second way to select a mode is to use MODE followed by three integer
parameters. The first two give the horizontal and vertical resolution you want and
the third is the requested number of bits per pixel, which specifies how many
colours are available. For example,
MODE 640,480,8
changes the display to a mode that is 640 pixels wide and 480 pixels high with 256
colours. The bits per pixel parameter can take the following values:
Bits per pixel Number of colours
1 2
2 4
4 16
6 256 (VIDC-1 style palette, see below)
8 256 (full palette)
16 32,768
32 16,777,216
A third method is to use MODE followed by five integer parameters. The first two
are the resolution, as in the previous example, and the next three specify the
ModeFlags, NColour and Log2BPP mode variables. For example,
MODE 640,480,&80,255,3
selects the same mode as the previous example (640 pixels wide and 480 pixels
high with a fully controllable palette of 256 colours). For a detailed explanation see
Appendix E – Specifying screen modes.
108
Screen modes
To change to a numbered mode, use MODE followed by the mode number you want.
For example,
MODE 12
changes the display to mode 12. This provides 640 × 256 pixel resolution graphics
in 16 colours (if your monitor supports this resolution).
Banked modes
By adding 128 to the mode number you can select a mode that uses the so-called
‘shadow’ memory. If you imagine that there are two separate areas of memory
which may be used to hold the screen information, then selecting a normal mode
will cause one area to be used, and selecting a shadow mode (in the range 128 to
255) will cause the alternative bank to be used.
You can force all subsequent mode changes to use the shadow bank with the
command:
*SHADOW
After this, you can imagine 128 to be added to any mode number in the range 0 to
127. To disable the automatic use of the shadow memory, issue the command:
*SHADOW 1
Text size
The number of characters displayed on the screen is affected by the number which
are allowed per row (i.e. the width of each character) and the number of rows which
can be displayed on the screen (i.e. the spacing between the rows).
109
Colour modes
Colour modes
The number of colours available on the screen at any given time depends on the
number of bits per pixel in the mode. The value stored in memory for each pixel is
called a colour number and varies between zero and the number of available
colours, minus one.
In modes with more than 256 colours the colour number of each pixel directly
defines the physical colour that is displayed, but in modes with 256 or fewer
colours it is instead a logical colour number which identifies an entry in a table
called the palette that defines the physical colour.
When you first enter a mode that uses a palette, the computer selects the default
colours which it uses for that particular mode. These are assigned to the logical
colour numbers (see Appendix F – Default palettes on page 481).
The computer chooses one colour to display text and graphics and another for the
background. These two colours are chosen so that under default conditions the
text and graphics are in white and the background is black. For example, in
four-colour modes the computer chooses to draw text and graphics in colour 3
(white) on a background which is colour 0 (black).
110
Screen modes
brightness levels are called ‘tints’ and are in the range 0-255. However, because
there are only four different tints, the numbers normally used are 0, 64, 128 and
192.
The VIDC1-style 256-colour modes are described in more detail on page 113.
Changing colours
You may choose to display your text, graphics, or background in a different colour
from the defaults. To do this, use the following commands:
111
Changing the colour palette
Each of r, g and b must be values between 0 and 255. A value of zero specifies that
none of that colour should be used and a value of 255 that the maximum intensity
of that colour should be used. Thus setting all of them to zero gives black and
setting all to 255 gives white. The actual colour selected will be the closest one
available in the current mode.
The following example gives the same result as the previous one:
10 MODE "X640 Y480 C256" : REM 256-colour mode
20 REM yellow foreground, red background
30 COLOUR OF 255,0,0 ON 255,255,0
40 PRINT "Hello There"
If your computer does not support a resolution of 640 × 480, change the first line to
select a valid mode. If you are using RISC OS 3.10 change it to use MODE 15
instead.
112
Screen modes
113
VIDC1-style 256-colour modes
114
Screen modes
or
GCOL 17 TINT 0
115
Using the screen under the Wimp
116
16 Simple graphics
T ext and graphics plotting is performed by the operating system. Many graphics
operations require strings of control characters to be sent to the VDU drivers.
However, BASIC provides keywords to perform some of the more common
operations, such as plotting points, lines and circles and changing colours. This
chapter describes those keywords.
117
The point command
(850,1500)
959
typical
screen
X-axis 0
-32768 +32767
0 1279
(-1300,-900)
Y-axis
-32768
Note: Many of the graphics examples in this and the following chapters start with
the command MODE MODE. This performs a mode change to the mode you are
currently in, resetting the state of the VDU drivers and clearing the screen, but
leaving the resolution and number of colours unchanged.
118
Simple graphics
The program below plots random points within a radius of 200 units from the
centre of the screen:
10 MODE MODE
20 ScreenW%=(VDU 11 + 1) << VDU 4
30 ScreenH%=(VDU 12 + 1) << VDU 5
40 CentreX%=ScreenW%/2
50 CentreY%=ScreenH%/2
60 REPEAT
70 rad%=RND(199)
80 angle=RADRND(360)
90 GCOL RND(255),RND(255),RND(255)
100 POINT CentreX%+rad%*COSangle, CentreY%+rad%*SINangle
110 UNTIL FALSE
POINT may also be used as a function to discover the colour of a pixel. It has the
form:
col = POINT(x%,y%)
In modes with less than 256 colours POINT returns the logical colour number. In
256-colour modes it returns a number between 0 and 63. To find the tint of the
pixel, you use the TINT keyword as a function in a similar way:
tint = TINT(x%,y%)
If you are using a 256-colour mode with a full palette it is possible to convert the
values returned by POINT and TINT into the logical colour number used by the
palette, but the mapping is not straightforward. It can be found as follows:
pal = (col AND 33)<<2 OR (col AND 14)<<3 OR (col AND 16)>>1 OR tint>>6
In modes with more than 256 colours POINT returns the colour number of the
pixel, the format of which depends on the number of bits per pixel (which can be
determined by reading VDU 9, Log2BPP), and the colour format (which can be
determined from bits 12-15 of VDU 0, ModeFlags).
For example, in a 32-bit per pixel mode with a TBGR format (Log2BPP=5,
ModeFlags=0) the lowest 8 bits of the returned number is the amount of red, the
next 8 bits are the amount of green and the next 8 bits are the amount of blue.
119
Rectangle and rectangle fill
You could draw the line the other way and produce the same result:
LINE 840,920, 120,120
The following program uses LINE four times to draw a box on the screen:
10 MODE MODE
20 left% = 100
30 right% = 400
40 bottom% = 200
50 top% = 800
60:
70 LINE left%,bottom%, right%,bottom%
80 LINE left%,top%, right%,top%
90 LINE left%,bottom%, left%,top%
100 LINE right%,bottom%, right%,top%
120
Simple graphics
-AJOR AXIS
-INOR AXIS
121
Graphics colours
For example:
ELLIPSE 640,512, 200,100, PI/4
This produces the outline of an ellipse centred at (640,512). The length of it is 200,
the width is 100 and it is rotated by pi/4 radians (45 degrees) from the horizontal. If
you omit the angle, an axis-aligned ellipse is produced:
ELLIPSE 400,500, 320,80
Try the following program, which plots eight ellipses of two different sizes with the
same centre point to form multi-petalled flowers:
10 MODE MODE
20 ScreenW%=(VDU 11 + 1) << VDU 4
30 ScreenH%=(VDU 12 + 1) << VDU 5
40 CentreX%=ScreenW%/2:CentreY%=ScreenH%/2
50 GCOL 255,0,0
60 FOR angle = 0 TO 3*PI/4 STEP PI/4
70 ELLIPSE FILL CentreX%,CentreY%,200,60,angle
80 NEXT angle
90 GCOL 255,255,0
100 FOR angle = PI/8 TO 3*PI/4+PI/8 STEP PI/4
110 ELLIPSE FILL CentreX%,CentreY%,100,30,angle
120 NEXT angle
Graphics colours
In previous examples, GCOL has taken three parameters selecting the amount of
red, green and blue respectively. This form of GCOL works in any mode and will
select the closest colour available to the requested colour. In modes with fewer
than 256 colours, GCOL can also be used with a single parameter to select the
current logical colour for the graphics foreground or background. For example,
GCOL 3
GCOL 129
selects the graphics foreground colour to be logical colour three and the
background colour to be one.
GCOL may also take two parameters: GCOL m,c. In this case the second (c) selects
the foreground and background graphics colours, and the first (m) selects the
manner in which c is applied to the screen as follows:
122
Simple graphics
m Meaning
0 Store the colour c on the screen
1 OR the colour on the screen with c
2 AND the colour on the screen with c
3 EOR the colour on the screen with c
4 Invert (NOT) the colour on the screen (disregards c)
5 Leave the colour on the screen unchanged (disregards c)
6 AND the colour on the screen with NOT c
7 OR the colour on the screen with NOT c.
Two of the options ignore the second parameter and either leave the colour on the
screen unchanged or invert it. Inverting a colour means that all the bits in the
colour number are altered: zeros are set to ones and vice versa. For example:
10 REM Pick a mode with 16 colours 0(%0000) - 15 (%1111)
20 MODE "X640 Y480 C16" : REM Use MODE 12 on RISC OS 3.10
30 GCOL 128+5
40 CLG
50 GCOL 4,0 : REM plot in NOT (screen colour)
60 LINE 0,0, 100,100
The colour on the screen is colour 5 (%0101). The colour used to draw the line is,
therefore, NOT (%0101) or colour 10 (%1010).
The OR, AND and EOR operators act on the bits of the colour already on the screen
and on the colour given as the second GCOL parameter as described in the chapter
Bases. Thus:
10 REM Pick a mode with 16 colours 0(%0000) - 15 (%1111)
20 MODE "X640 Y480 C16" : REM Use MODE 12 on RISC OS 3.10
30 GCOL 128+5 : REM clear screen to magenta
40 CLG
50 GCOL 0,6 : LINE 0,0, 100,100
60 GCOL 1,6 : LINE 100,100, 200,200
70 GCOL 2,6 : LINE 200,200, 300,300
80 GCOL 3,6 : LINE 300,300, 400,400
90 GCOL 6,6 : LINE 400,400, 500,500
100 GCOL 7,6 : LINE 500,500, 600,600
The colour already on the screen when the lines are drawn is colour 5 (%0101). The
foreground colour is selected as colour 6 (%0110) in all cases. The method of
applying it to the screen, however, alters the actual colour displayed as follows:
● The first line appears in colour 6
● The second line appears in colour 7 (%0101 OR %0110 = %0111)
● The third line appears in colour 4 (%0101 AND %0110 = %0100)
123
The graphics cursor
124
Simple graphics
10 MODE MODE
20 ScreenW%=(VDU 11 + 1) << VDU 4
30 ScreenH%=(VDU 12 + 1) << VDU 5
40 CentreX%=ScreenW%/2:CentreY%=ScreenH%/2
50 MOVE CentreX%,CentreY%
60 REPEAT
70 dx%=8*(RND(3)-2)
80 IF dx%=0 THEN dy%=8*(RND(3)-2) ELSE dy%=0
90 DRAW BY dx%,dy%
100 UNTIL FALSE
125
Printing text at the graphics cursor
126
17 Complex graphics
T he commands such as MOVE, DRAW, CIRCLE, etc are special cases of the
more general PLOT command. This command can give a far wider range of
options over what kind of shape you produce and how you produce it. Of course,
the added functionality it provides makes it more complicated to use.
PLOT takes the following format:
PLOT k,x,y
where k is the mode of plotting, and x and y are the coordinates of a point to be
used to position the shape. PLOT takes one pair of coordinates. To produce shapes
which need more than one pair to define them, such as rectangles, it uses the
previous position or positions of the graphics cursor to provide the missing
information. This means that you must pay careful attention to the position of the
graphics cursor after a shape has been drawn. Otherwise future plots may produce
unexpected results.
Each type of plot has a block of eight numbers associated with it. These are listed
below in both decimal and hexadecimal notation. (See the chapter entitled Binary
and logic on page 33).
0-7 (&00 - &07) Solid line including both end points
8-15 (&08 - &0F) Solid line excluding final points
16-23 (&10 - &17) Dotted line including both end points
24-31 (&18 - &1F) Dotted line excluding final points
32-39 (&20 - &27) Solid line excluding initial point
40-47 (&28 - &2F) Solid line excluding both end points
48-55 (&30 - &37) Dotted line excluding initial point
56-63 (&38 - &3F) Dotted line excluding both end points
64-71 (&40 - &47) Point plot
72-79 (&48 - &4F) Horizontal line fill (left & right) to non-background
80-87 (&50 - &57) Triangle fill
88-95 (&58 - &5F) Horizontal line fill (right only) to background
96-103 (&60 - &67) Rectangle fill
104-111 (&68 - &6F) Horizontal line fill (left & right) to foreground
112-119 (&70 - &77) Parallelogram fill
120-127 (&78 - &7F) Horizontal line fill (right only) to non-foreground
127
128-135 (&80 - &87) Flood to non-background
136-143 (&88 - &8F) Flood to foreground
144-151 (&90 - &97) Circle outline
152-159 (&98 - &9F) Circle fill
160-167 (&A0 - &A7) Circular arc
168-175 (&A8 - &AF) Segment
176-183 (&B0 - &B7) Sector
184-191 (&B8 - &BF) Block copy/move
192-199 (&C0 - &C7) Ellipse outline
200-207 (&C8 - &CF) Ellipse fill
208-215 (&D0 - &D7) Graphics characters
216-223 (&D8 - &DF) Reserved for Acorn expansion
224-231 (&E0 - &E7) Reserved for Acorn expansion
232-239 (&E8 - &EF) Sprite plot
240-247 (&F0 - &F7) Reserved for user programs
248-255 (&F8 - &FF) Reserved for user programs
Within each block of eight, the offset from the base number has the following
meaning:
offset meaning
0 move cursor relative (to last graphics point visited)
1 plot relative using current foreground colour
2 plot relative using logical inverse colour
3 plot relative using current background colour
4 move cursor absolute (i.e. move to actual coordinate given)
5 plot absolute using current foreground colour
6 plot absolute using logical inverse colour
7 plot absolute using current background colour
PLOT is a good example of where using hexadecimal notation helps to make things
clearer. Each block of eight starts at either &x0 or &x8, where x represents any
hexadecimal digit, so a plot absolute in the current foreground colour, for example,
has a plot code of &x5 or &xD. Thus, it is obvious which mode of plotting is being
used. Similarly, it is obvious which shape is being plotted, and so, for example, if
the plot is between &90 and &9F, then it is a circle. This is a far easier range to
recognise than 144 to 159.
Each of the types of plot is described in further detail below.
128
Complex graphics
Dot-dash lines
Straight lines do not have to be drawn as a solid line. Instead you can set up a
pattern of dots and dashes and use that to determine which pixels along the line
will be plotted.
A dot-dash pattern is set up using:
VDU 23,6,n1,n2,n3,n4,n5,n6,n7,n8
where n1 to n8 define a bit pattern. Each bit which is set to one represents a point
plotted and each bit set to zero represents no point. The pattern starts at bit 7 of
n1, then for each pixel plotted moves one bit to the right in n1. After bit 0 of n1
has been used, bit 7 of n2 is used, and so on.
The pattern can be made to repeat (i.e. go back to bit 7 of n1) after a given number
of pixels. The maximum pattern repeat is 64. However, you can set up any repeat
between one and 64 using:
*FX 163,242,n
If you set n to zero, this sets up the default pattern which has a repeat length of
eight bits and is alternately on and off, i.e. n1 is %10101010 (&AA).
129
Plotting simple lines
There are four different methods which may be used to plot the line:
PLOT range Effect
&10-&17 Both end points included, the pattern being restarted when
each new line is drawn.
&18-&1F Final point omitted, the pattern being restarted when each new
line is drawn.
&30-&37 Initial point omitted, the pattern being continued when each
new line is drawn.
&38-&3F Both end points omitted, the pattern being continued when
each new line is drawn.
Triangles
To draw a triangle plot, you need the coordinates given with the triangle PLOT code
and two previous points which mark the other corners. For example:
10 MODE MODE
20 MOVE 200,200
30 MOVE 600,200
40 PLOT &55,400,400
This plots a triangle with corners (200,200), (600,600) and (400,400).
Adding a further line:
50 PLOT &55,800,400
plots a further triangle using corners (600,200), (400,400) and (800,400).
Rectangles
An axes-aligned (filled) rectangle plot can be plotted between the coordinates
given by the PLOT and the previous position of the graphics cursor. For example:
MOVE 200,200
PLOT &61,600,600
This is equivalent to RECTANGLE FILL 200,200, 600,600. You can also specify
absolute coordinates in the PLOT version, for example:
MOVE 200,200
PLOT &65,800,800
130
Complex graphics
Parallelograms
A parallelogram plot is constructed as a rectangle which has been sheered
sideways. For example:
(400,800) (900,800)
(200),(200) (700,200)
These require three points to define them. Thus to plot the parallelogram shown
above the following could be used:
MOVE 200,200
MOVE 700,200
PLOT &75,900,800
Although any three corners of the parallelogram may be used to define it, the order
in which these are given affects which way round the parallelogram appears.
Consider the three points given below:
(700,800)
(200,500) (600,500)
These could produce any of three parallelograms, depending on the order in which
they were used. The rule to determine what the final parallelogram will look like is
as follows: the three points specify adjacent vertices, with the fourth vertex being
calculated from these. From this, it can be seen that the unspecified corner is the
one which appears diagonally opposite the second point given.
131
Plotting simple lines
Suppose, for example, you used the following sequence of statements with the
three points shown above:
MOVE 200,500
MOVE 600,500
PLOT &75,700,800
The final point is calculated by the computer to have the coordinates (300,800),
diagonally opposite the point (600,500).
The other two possible parallelograms that would be obtained using these three
sequences are:
MOVE 600,500 : MOVE 700,800 : PLOT &75,200,500
MOVE 700,800 : MOVE 200,500 : PLOT &75,600,500
When specifying the corners, you can give them in ‘clockwise’ or ‘anti-clockwise’
order; the same shape is drawn regardless.
Circles
To plot a circle, define the centre by moving to it, and then use PLOT with the
relevant plot code and the coordinates of a point on its circumference. For
example, to plot a solid circle centred at (640,512) with a radius of 100, type
MOVE 640,512 :REM centre
PLOT &9D,740,512 :REM Xcentre+radius,Ycentre
Alternatively you could use relative plotting:
MOVE 640,512 :REM centre
PLOT &99,100,0 :REM radius,0
In both these examples the circles are solid and could have been produced using
the CIRCLE FILL command. The equivalent of the CIRCLE command for producing
outlines of circles would be PLOT &95 and PLOT &91.
132
Complex graphics
Ellipses
Ellipses are more complicated to define than circles:
133
Arcs
10 MODE MODE
20 FOR step% = 0 TO 400 STEP 25
30 MOVE 640,512
40 MOVE 215+step%,512
50 PLOT &C5,640,512+step%
60 NEXT step%
Solid ellipses are drawn in the same way using the plot codes &C8 to &CF.
The ELLIPSE keyword provides an easier way of specifying rotated ellipses.
Arcs
We saw above how circle outlines are defined and drawn. In a similar way, just a
portion of the circle outline may be drawn to produce an arc. In this case, three
points are required: the centre of the circle and two points to indicate the starting
and finishing points of the arc. Ideally, these would be given as follows:
&INISHING POINT
In the example above, however, both the starting and finishing points are on the
arc itself. This is a design which requires a large amount of calculation. It is easier
for the starting point to be taken as being on the arc and used to calculate the
radius, the finishing point being used just to indicate the angle the arc subtends.
For example:
0OSSIBLE
FINISHING POINTS
134
Complex graphics
This is the method used by the VDU drivers. To draw an arc, you need to specify the
centre of the circle it is based upon and the starting point of the arc, and then to
plot to a third point to specify the angle.
The example below draws an arc based on a circle whose centre is at (640,512). It
draws the portion of the arc from 0 to 270. Since arcs are drawn anticlockwise this
means that its starting position is the point (440,512) (270) and its finishing
position (640,512+n) (0):
MOVE 640,512
MOVE 440,512
PLOT &A5,640,1000
The resulting arc would look like that drawn below:
(640,512)
(440,512)
Sectors
A sector is a filled shape enclosed by two straight radii and the arc of a circle.
%ND
3TART
#ENTRE
135
Segments
Segments
A segment is an area of a circle between the circumference and a chord as shown
below:
%ND
#ENTRE 3TART
Segments are defined in exactly the same way as arcs and sectors.
Flood-fills
This section is concerned with how to fill the inside of any closed region, however
awkward the shape. The method used is flood-filling; with this you can start off at
any point within the boundaries of the shape. The whole shape is then filled at
once.
Note that flood-filling is not compatible with BASIC programs written under the
window manager environment (described in the section entitled Window managed
programs on page 7).
Flood to non-background
This can be used on shapes which are in the current background colour and
bordered by non-background colours. The shape is filled with the current
foreground colour.
136
Complex graphics
137
Copying and moving
The rectangle move and copy commands may also be expressed in terms of PLOT
codes. The relevant range of codes is &B8 to &BF: first move to two points which
denote the bottom left and top right of the rectangle to be copied or moved; then
plot, using one of the range of codes described above, to the bottom left corner of
the destination rectangle. The meanings of the plot codes are as follows:
&B8 Move relative (no copy/move operation)
&B9 Relative rectangle move
&BA Relative rectangle copy
&BB Relative rectangle copy
&BC Move absolute (no copy/move operation)
&BD Absolute rectangle move
&BE Absolute rectangle copy
&BF Absolute rectangle copy
The rectangle move operations erase the source rectangle, whereas the copy
operations leave it intact. So, the RECTANGLE FILL … TO example above could
also be expressed as:
MOVE 400,600
MOVE BY 60,80
PLOT &BD,700,580
138
18 Graphic patterns
Any of the colours which are available in a given mode may be ‘interwoven’ to
give a tremendous range of colour patterns. When using modes with a limited
number of colours, for example any of the four-colour modes, this feature may be
used to extend the colours available, since combining similar colours produces
further shades which look like pure colours. Alternatively, contrasting colours may
be used to give checks, wavy lines, and so on.
Default patterns
Default patterns are set up for you as follows, depending on the number of bits per
pixel in the current mode:
Bits per pixel Pattern Pattern
1 1 Dark grey
2 Grey
3 Light grey
4 Hatching
2 1 Red-orange
2 Orange
3 Yellow-orange
4 Cream
4 1 Orange
2 Pink
3 Yellow-green
4 Cream
8 1 White-grey stripes
2 Black-grey stripes
3 Green-black stripes
4 Pink-white stripes
To use these patterns you issue a GCOL with a plot action which depends on the
pattern desired. In general, to use pattern n, the GCOL command should be
GCOL n*16+action, col
139
Plotting using pattern fills
where action is the plotting action you want to use with the pattern (for example
0 for store, 1 for OR etc, as described earlier), and col is 0 if you want to set the
foreground colour as a pattern or 128 for a background pattern. The parameter n is
in the range 1 to 4 for the normal patterns, or 5 for a large pattern which is formed
by placing patterns 1 to 4 next to each other.
140
Graphic patterns
141
Native mode patterns
142
Graphic patterns
Two-colour modes
This is the easiest case to understand. Each pixel in the block corresponds to one
bit of the parameter, the least significant bit applying to the pixel on the right, so
pixels on the screen appear in the same order as the bits are written down on
paper. For example, to set a row of the pattern as follows:
black white white white black black black white
%0 %1 %1 %1 %0 %0 %0 %1
the value required is 113 (%01110001).
Defining a pattern in a two-colour mode is similar to setting up a user-defined
character.
Four-colour modes
In four-colour modes each colour is defined using two bits as follows:
yellow (%10) red (%01) white (%11) yellow (%10)
bit 7 6 5 4 3 2 1 0
1 0 10 (yellow)
0 1 01 (red)
1 1 11 (white)
1 0 10 (yellow)
1 0 1 1 0 1 1 0
16-colour modes
In 16-colour modes the situation is different again. There are just two pixels in a
row, four bits of the parameter being used to hold the value of each colour.
However, it is not the case that the left-most four bits correspond to the first colour
and the right-most four bits to the other. Instead, the bits of each are interleaved,
as shown:
143
Giant patterns
Giant patterns
Giant patterns can be set up which take all four of the separate patterns and place
them side by side, giving an overall pixel size as shown below:
Bits per pixel Horizontal pixels Vertical pixels
1 32 8
2 16 8
4 8 8
8 4 8
16 4 4
32 4 2
To produce a giant pattern in this way, the first parameter given to GCOL should be
in the range 80 to 95.
144
Graphic patterns
Simple patterns
Often the most effective way of using the pattern fills is for simple cross-hatch
patterns. If you want to use this sort of colour pattern in a mode with less than 256
colours, a simpler way of defining it is available. In this method, just a small block
of eight pixels is defined which is used to form the normal-sized block.
The eight pixel colours in the following diagram are set up using
VDU 23,12,n1,n2,n3,n4,n5,n6,n7,n8 defines pattern 1
VDU 23,13,n1,n2,n3,n4,n5,n6,n7,n8 defines pattern 2
VDU 23,14,n1,n2,n3,n4,n5,n6,n7,n8 defines pattern 3
VDU 23,15,n1,n2,n3,n4,n5,n6,n7,n8 defines pattern 4
where n1 to n8 correspond to the actual colours to be used as follows:
n1 n2
n3 n4
n5 n6
n7 n8
In 256 colour modes VDU 23,12-15 will define a 1×8 pattern, but the difference from
using VDU 23,2-5 is that the values given to the parameters are interpreted in the
same way as the values specified for COLOUR and TINT commands, so if the
default palette is in use this will work as follows:
Bit Meaning
0 Red bit 2
1 Red bit 3 (high)
2 Green bit 2
3 Green bit 3 (high)
4 Blue bit 2
5 Blue bit 3 (high)
6 Tint bit 0 (red + green + blue bit 0)
7 Tint bit 1 (red + green + blue bit 1)
145
Simple patterns
146
19 Viewports
Text viewports
Normally, text may appear anywhere on the screen. However, you can define a text
viewport, which allows the text to appear only inside the viewport. To set up a text
viewport, use the VDU 28 command as follows:
VDU 28,left,bottom,right,top
where left,bottom is the bottom lefthand and right,top the top righthand
position inside the viewport given in text coordinates:
top
bottom
left Text
Viewport
right
147
Text viewports
Nothing outside the text viewport is affected by text statements, such as CLS to
clear the text screen, or screen scrolling. Note that TAB(X,Y) positions the text
cursor relative to the position of the top left of the current text viewport. The
following program demonstrates how text viewports behave:
10 MODE MODE
20 REM Set up a text viewport 6 characters square
30 VDU 28,5,10,10,5
40 REM Change the background colour to red
50 COLOUR ON 255,0,0
60 REM Clear the text screen to show where it is
70 CLS
80 REM Demonstrate scrolling
90 FOR N% = 1 TO 20
100 PRINT N%
110 NEXT N%
120 REM Show position of character (2,3)
130 PRINT TAB(2,3);"*"
140 END
To revert back to having the whole screen as the text viewport type
VDU 26
The precise actions of the VDU 26 command are as follows:
● Restore text viewport to the whole screen
● Restore graphics viewport to the whole screen
● Home the text cursor
● Restore graphic origin to bottom left of screen
● Home graphics cursor to (0,0).
148
Viewports
Graphics viewports
Just as text may have a text viewport defined, so a graphics viewport may be set up
using
VDU 24,left;bottom;right;top;
where (left,bottom) and (right,top) are the coordinates of the lower lefthand
and upper righthand pixels inside the viewport. Be sure to use semi-colons as
indicated, not commas.
right
Graphics
Viewport
left
top
bottom
149
Graphics viewports
150
20 Sprites
A sprite is just a graphic shape made up of an array of pixels. You can create and
manipulate sprites using Paint. This is a general-purpose painting program
whose output happens to be stored in a sprite. It is fully described in the
RISC OS User Guide.
Having created one or more sprites in a Sprite file (using Paint), you can then:
● load this file;
● manipulate and plot one or more sprites from it.
For a full description of how to load, manipulate and plot sprites see the Sprites
chapter of the RISC OS Programmer’s Reference Manual.
151
Plotting a user sprite
the ARM’s built-in instructions). In BASIC, SWIs are called using the SYS
statement, and the first parameter this SWI takes is a number between 1 and 62
specifying the particular action to be taken. Adding 256 to this number indicates
that it is a user sprite. These actions include:
OS_SpriteOp 9 + 256 initialise a sprite area
OS_SpriteOp 10 + 256 load sprites from a sprite file into a sprite area
OS_SpriteOp 34 + 256 plot a sprite at the coordinates supplied
152
21 Teletext mode
T he teletext mode, mode 7, is unique in the way it displays text and graphics.
Commands such as COLOUR, GCOL, MOVE and DRAW do not work in this
mode (or in the Wimp). Instead colourful displays are produced using teletext
control codes.
Mode 7 is compatible with the teletext pages that were broadcast in many
countries before the introduction of digital television. You can produce your own
teletext displays using the limited but effective graphics which are available.
In mode 7 the screen is 40 characters wide and 25 characters high, but with
RISC OS 5.24 and later it is possible to select a Teletext mode of a different size by
using the T, TX and TY attributes in a mode string. See Appendix E – Specifying screen
modes for further details.
Coloured text
Type in the following program and run it:
10 MODE 7
20 PRINT"THIS";CHR$(129);"demonstrates";CHR$(130);"the";CHR$(131);"use"
30 PRINT CHR$(132);"of";CHR$(133);"control"; CHR$(134); "codes"
The characters 129, etc, which are printed using CHR$(129) are the control codes.
Although the control codes are invisible they still take up a character position, so
the words are separated by a space.
Each control code affects the way in which the remaining characters on that
particular line are displayed. For example, printing CHR$(129) makes the computer
display the text in red. The full list of colours and their associated control codes is:
Code Text colour
129 Red
130 Green
131 Yellow
132 Blue
133 Magenta
134 Cyan
135 White (default)
153
Making text flash
Every line starts off with the text in white. So, if you want several rows of text to
appear in red, for example, you must start each of these rows with CHR$(129).
Double-height text
Double-height text can be produced as follows:
10 MODE 7
20 PRINT CHR$(141)"Double height"
30 PRINT CHR$(141)"Double height"
To obtain double-height text, the same text must be printed on two successive
lines beginning with CHR$(141). If the text is only printed once, only the top half of
the letters is displayed.
To revert to single-height graphics on the same line, the control code is 140. For
example:
10 MODE 7
20 PRINT CHR$(141)"Double Height";CHR$(140); "Single Height"
30 PRINT CHR$(141)"Double Height";CHR$(140); "Single Height"
154
Teletext mode
above. Hence to print text visibly on a coloured background, three control codes
are required, two to change the background colour, and a third to change the
colour of the text.
For example:
10 MODE 7
20 PRINT CHR$(131);CHR$(157);CHR$(132)"Blue on yellow"
Teletext graphics
Certain characters, such as the lower-case letters, may either be printed normally
as text or made to appear as graphics shapes by preceding them with one of the
graphics control codes. These are:
Code Graphics colour
145 Red
146 Green
147 Yellow
148 Blue
149 Magenta
150 Cyan
151 White
156 Set background to black
157 Set background colour to the current foreground colour
Each line of the teletext display starts with the following attributes: white, alpha
(i.e. non-graphics) characters on a black background.
155
Teletext graphics
A B
It is possible to calculate the code for any particular graphics shape, since each of
the six cells contributes a particular value to the code as follows:
1 2
4 8
16 64
The base value for the codes is 160, so that they lie in the ranges 160 to 191 and 224
to 255. For example,
has a code of 160 + 1 + 8 + 16 = 185 and so may be produced on the screen in red.
To do this, type
PRINT CHR$(145);CHR$(185)
156
Teletext mode
Code 152 conceals the display of all graphics characters until a colour change
occurs. Hence the solid red graphics block is not displayed.
Code 158 holds the graphics. This means that it remembers the previous
graphics character, in this case the solid block, and displays all future
graphics shapes and control codes as the remembered character.
Code 146 first colour change. As a result, it reverses the concealing effect of
code 152 so that future characters are displayed, and also selects
green graphics.
Code 147 control code displayed as a solid graphics block in the current colour
which is green. It selects yellow graphics.
Code 159 control code displayed as a solid graphic block in the current colour
which is yellow. It releases the graphics, i.e. it reverses the effect of
any previous 158 codes.
157
Teletext graphics
158
22 Sound
159
Setting the stereo position
A full list of the resident voices can be obtained, along with their channel
allocations, using the *VOICES command. With “Percussion-Snare” allocated to
channel 1, the list appears as follows:
Voice Name
1 WaveSynth-Beep
2 StringLib-Soft
3 StringLib-Pluck
4 StringLib-Steel
5 StringLib-Hard
6 Percussion-Soft
7 Percussion-Medium
1 8 Percussion-Snare
9 Percussion-Noise
^^^^^^^^ Channel Allocation Map
Note that *VOICES indicates only the mapping of voices to channels – it does not
specify how many channels have been selected with BASIC’s VOICES command.
160
Sound
Creating a note
BASIC provides a SOUND statement to create a note on any of the channels. This
requires four parameters which can be summarised as follows:
SOUND channel, amplitude, pitch, duration [, after]
Channel
There are eight different channels, numbered 1 to 8. Each of these is identical,
except for the voice assigned to it.
Pitch
The pitch can be controlled in steps of a quarter of a semitone by giving a value
between 0 and 255. The lowest note (0) is the A# one octave and two semitones
below middle C. The highest note is the D four octaves and a tone above middle C.
A value of 53 produces middle C itself. The following table is a quick reference
guide to help you find the pitch you require:
Note Octave number
1 2 3 4 5 6
161
Synchronising the channels
Alternatively, a finer control is available by giving a value between 256 (&0100) and
32767 (&7FFF). Each number consists of 15 bits. The left-most three bits control
the octave number. The bottom 12 bits control the fractional part of the octave.
This means that each octave is split up into 4096 different pitch levels. Middle C
has the value 16384 (&4000).
Using hexadecimal notation is a particularly useful way of seeing what pitch a
given value defines. Each value in hexadecimal notation comprises four digits. The
left-most one gives the octave number and the right-most the fractional part of the
octave. The following table illustrates this:
Note Octave number
1 2 3 4 5 6 7 8 9
Duration of sound
The fourth SOUND parameter determines the duration of a sound. A value of 0 to
254 specifies the duration in twentieths of a second. For example, a value of 20
causes the note to sound for one second. A value of 255 causes the note to sound
continuously, stopping only when you press Esc. Values between 256 and 32767
also give the duration in 20ths of a second.
162
Sound
You can set the value that this counter will count up to by typing
BEATS n
The counter then counts from 0 to n–1 and when it reaches n it resets itself to zero.
To find the current beat counter limit, type
PRINT BEATS
Increasing the number of beats increases the time taken before two notes are
repeated. It has no effect on the time interval between the two notes themselves.
163
Executing a sound on a beat
Synchronising sounds
If you give –1 as the after parameter, the sound, instead of being scheduled for a
given number of beats, is synchronised with the last sound that was scheduled. For
example,
SOUND 1,-10,200,20,100
SOUND 2,-10,232,20,-1
will cause two sounds, an octave apart, to be made 100 beats from the present
moment, assuming that at least two channels are active and have voices assigned.
Note: If you alter the sound system, you should restore it before returning to the
desktop, or running any other programs.
164
23 Accessing memory locations
165
The ‘?’ indirection operator
166
Accessing memory locations
The least significant byte of the integer is stored in the first memory location, and
the most significant byte in the fourth location. This can be seen in the following
example:
10 DIM pointer% 100
20 !pointer% = &12345678
30 PRINT ~pointer%?0
40 PRINT ~pointer%?1
50 PRINT ~pointer%?2
60 PRINT ~pointer%?3
This prints:
78
56
34
12
167
The ‘$’ indirection operator
10 DIM space% 10
20 REM set all bytes to zero
30 FOR N% = 0 TO 10
40 space%?N% = 0
50 NEXT N%
60 REM Store the string
70 $space% = "STRING"
80 REM Print out the bytes
90 FOR N% = 0 TO 10
100 PRINT space%?N% " ";CHR$(space%?N%)
110 NEXT N%
As with |, there is no dyadic form of $. For example, although you may use
$(string+1), the form string$1 is not allowed.
168
24 Error handling and debugging
B y default, when the BASIC interpreter finds an error it halts execution of the
program and prints an error message on the screen. Most errors are generated
by incorrect programming, such as using a variable which has not had a value
assigned to it. You have to correct this kind of error to make the program work.
However, even if the syntax of the program is correct, errors can occur whilst it is
being executed, because it cannot cope with the data it is given.
For example:
10 REPEAT
20 INPUT "Number",N
30 L = LOG(N)
40 PRINT "LOG of ";N" is ";L
50 UNTIL FALSE
This program takes a number from the keyboard and prints the logarithm of that
number. If you type in a negative number, however, the program gives the message:
Logarithm range at line 30
The same thing happens if you type 0, or a character such as W, or a word such as
TWELVE.
Trapping an error
You may decide that you would like to trap such an error and print a message to
tell the user what he or she has done wrong instead of having the program end
abruptly. You can do this using the ON ERROR statement.
169
Trapping an error
For example:
5 ON ERROR PROCerror
10 REPEAT
20 INPUT "Number",N
30 L = LOG(N)
40 PRINT "LOG of ";N" is ";L
50 UNTIL FALSE
60 END
100 DEFPROCerror
110 IF ERR=22 THEN
120 PRINT "The number must be greater than 0"
130 ELSE REPORT
140 PRINT " at line ";ERL
150 END
160 ENDIF
170 ENDPROC
The ON ERROR statement can be followed by a series of statements given on the
same line. In many cases, it is more convenient to follow it with a call to an error
handling procedure, as in the example above, which can then be as complex as you
like.
When an error occurs, BASIC passes control to the first statement on the ON
ERROR line, as if it jumped there using a GOTO. It will ‘forget’ about any loops or
procedures that were active when the error occurred, as if the program had been
re-started. Of course, the values of all the variables and so on will still be intact.
Each error has an error number associated with it. When a particular error occurs,
its number is placed in a variable called ERR (these numbers are guaranteed to
remain the same). A full list of error numbers is given in Appendix C – Error messages.
In the example above, the error handling procedure tests for error 22 which is the
Logarithm range error. If it was this error which occurred, it is dealt with
appropriately. If a different error occurred, the program executes the REPORT
instruction which prints out the error message and then prints the number of the
line where the error occurred which is given in the function ERL. Then it executes
the END to end the execution of the program. Trapping all errors is not necessarily
a good idea since you then would not be able to press Esc, which is treated as an
error, to stop the program.
If a program contains more than one ON ERROR statement, the most recently
executed one is used when an error occurs.
170
Error handling and debugging
Errors in libraries
If an error occurs in a library, the error message displayed by REPORT is suffixed
with the name of the library, for example Mistake in "MyLib". The name that
will be printed is everything that follows REM or REM> on the first line of the
library.
Generating errors
In addition to the error messages that the interpreter itself generates when it
discovers a mistake in the program, you can cause your own errors. This can be
useful when, for example, you find a mistake in the user’s input data and want to
notify the user through your standard error handler. To generate an error, use the
statement:
ERROR errnum, errstring
The errnum expression is a number which will be passed to the error handler via
the ERR function, as usual. The errstring is accessible to the error handler
through the REPORT statement and REPORT$ function. ERL will be set to the line
number at which the ERROR statement was executed.
If you use 0 as the error number, the error will be a ‘fatal’ one. As with built-in errors
with that number, it cannot be trapped by using ON ERROR.
An example of the use of ERROR is:
1000 ch=OPENIN(f$)
1010 IF ch=0 THEN ERROR 214,"File '"+f$+"' not found"
External errors
If an error occurs in a program, you may wish to leave BASIC altogether and pass
the error back to the program that called BASIC in the first place. You can do this
using the ERROR EXT statement. Its syntax is very similar to ERROR, described
above. If you say:
ERROR EXT 0,"Can't find template file"
then BASIC will quit and the error message and number will be passed back to the
error handler of the program that called BASIC (e.g. the RISC OS Supervisor
prompt or error box).
171
Local error handling
BASIC’s default error handler uses this form of the ERROR statement if the
program being executed was called from a command of the form
*BASIC -quit filename
(A BASIC program filename typed as a * command will behave like this.)
When BASIC is called like this, it loads and executes the program stored in
filename, and then QUITs automatically when the program terminates. In
addition, the function QUIT will return TRUE instead of FALSE, as it usually does.
This is used in BASIC’s default error handler, which reads as follows:
TRACE OFF
IF QUIT THEN
ERROR EXT ERR,REPORT$
ELSE
RESTORE
IF ERL THEN
REM Equivalent to PRINT REPORT$+" at line "+STR$(ERL)
CALL !ERRXLATE:PRINT $STRACC
ELSE
REPORT:PRINT
ENDIF
END
ENDIF
The CALL !ERRXLATE statement calls a function that stores a translated version
of REPORT$+" at line "+STR$(ERL) at $STRACC.
172
Error handling and debugging
10 PROCcalculate(100)
20 END
100 DEFPROCcalculate(A)
110 LOCAL I
120 LOCAL ERROR
130 FOR I = -15 TO 15
140 ON ERROR LOCAL PRINT"Infinite Result":NEXT I:ENDPROC
150 PRINT A / I
160 NEXT I
180 ENDPROC
Local error handlers can be used in any loops, not just inside procedures and
functions.
173
Debugging
For example:
100 LOCAL ERROR
110 WHILE ...
120 ON ERROR LOCAL ...
130 ...
140 ENDWHILE
150 RESTORE ERROR
160 ...
Debugging
A program may contain errors which cause it to behave differently from the way you
intended. In these circumstances, you may wish to watch more closely how the
program is being executed.
174
Error handling and debugging
TRACE STEP ON
to stop after every line traced, or
TRACE STEP n
to trace all lines below n and stop after each one, or
TRACE STEP PROC
to stop after every procedure call.
Instead of having TRACE output displayed on the screen, you can send it to a file.
To do this, type
TRACE TO filename
This means that you have a permanent record of the path taken through your
program.
Any TRACE option affects all programs which are subsequently run until tracing is
turned off by
TRACE OFF
or until an error occurs.
Because TRACE is a statement, you can also use it from within a program. Thus if
you know that a program is going wrong within a particular procedure, you could
insert a TRACE ON statement at the start of the procedure, and a TRACE OFF just
before the ENDPROC. That way, trace information will only be produced while the
procedure is executing.
175
Debugging
on page 234. If a service call handler wishes to call any of the internal BASIC
routines then it must first switch to user mode and transfer the state information
to the correct registers.
176
25 VDU control
T he Visual Display Unit (VDU) driver is a part of the operating system which
provides a set of routines used to display all text and graphical output. Any
bytes sent to the VDU driver are treated either as characters to be displayed or as
VDU commands: instructions which tell the driver to perform a specific function.
Their interpretation depends on their ASCII values as follows:
ASCII value Interpretation
0-31 VDU commands
32-126 Characters to be displayed
127 Delete
128-159 Characters to be displayed / teletext control codes
160-255 International characters to be displayed
The nearest equivalent to the statement VDU X is PRINT CHR$(X); with the
exception that VDU ignores the value of WIDTH and does not affect COUNT.
In addition, the VDU commands can be given from the keyboard by holding down
Ctrl and one further key as shown in the table below. For example, to give the
command VDU 0, you would press Ctrl-@. Some VDU commands require extra data
to be sent. The number of bytes extra is also given in the table.
VDU Code Ctrl plus Extra bytes Meaning
0 2 or @ 0 Do nothing
1 A 1 Send next character to printer only
2 B 0 Enable printer
3 C 0 Disable printer
4 D 0 Write text at text cursor
5 E 0 Write text at graphics cursor
6 F 0 Enable VDU driver
7 G 0 Generate bell sound
8 H 0 Move cursor back one character
9 I 0 Move cursor on one space
10 J 0 Move cursor down one line
11 K 0 Move cursor up one line
12 L 0 Clear text viewport
13 M 0 Move cursor to start of current line
14 N 0 Turn on page mode
15 O 0 Turn off page mode
177
16 P 0 Clear graphics viewport
17 Q 1 Define text colour
18 R 2 Define graphics colour
19 S 5 Define logical colour
20 T 0 Restore default logical colours
21 U 0 Disable VDU drivers
22 V 1 Select screen mode
23 W 9 Multi-purpose command
24 X 8 Define graphics viewport
25 Y 5 PLOT
26 Z 0 Restore default viewports
27 [ 0 Does nothing
28 \ 4 Define text viewport
29 ] 4 Define graphics origin
30 6 or ^ 0 Home text cursor
31 - or _ 2 Move text cursor
In the VDU commands described below, note the following three points:
● Expressions followed by a semi-colon are sent as two bytes (low byte first) to
the operating system VDU drivers.
● Expressions followed by a comma (or nothing) are sent to the VDU drivers as
one byte, taken from the least significant byte of the expression.
● The vertical bar | means ,0,0,0,0,0,0,0,0,0, and so sends the
expression before it as a byte followed by nine zero bytes. Since the maximum
number of parameters required by any of the VDU statements is nine, the
vertical bar ensures that sufficient parameters have been sent for any
particular call. Any surplus ones are irrelevant, since VDU 0 does nothing.
VDU 0
VDU 0 does nothing.
VDU 1
VDU 1 sends the next character to the printer only, if the printer has been enabled
(with VDU 2 for example).
VDU 2
VDU 2 causes all subsequent printable characters, and certain control characters,
to be sent to the printer as well as to the screen (subject to FX3 mask etc).
178
VDU control
VDU 3
VDU 3 cancels the effects of VDU 2 so that all subsequent printable characters are
sent to the screen only.
VDU 4
VDU 4 causes all subsequent printable characters to be printed at the current text
cursor position using the current text foreground colour. Cursor control characters
(e.g. carriage return and line feed) affect the text cursor and not the graphics cursor.
VDU 5
VDU 5 links the text and graphics cursors and causes all subsequent printable
characters to be printed at the current graphics cursor position using the current
graphics foreground colour and action. Cursor control characters (e.g. carriage
return and line feed) affect the graphics cursor and not the text cursor.
VDU 6
VDU 6 restores the functions of the VDU driver after it has been disabled (using
VDU 21). Hence, this command causes all subsequent printable characters to be
sent to the screen.
VDU 7
VDU 7 generates the bell sound.
VDU 8
VDU 8 causes either the text cursor (by default or after a VDU 4 command) or the
graphics cursor (after a VDU 5 command) to be moved back one character position.
It does not cause the last character to be deleted. Note that during command
input, Ctrl-H acts as the Backspace key, so the last character will be deleted.
VDU 9
VDU 9 causes either the text cursor (by default or after a VDU 4 command) or the
graphics cursor (after a VDU 5 command) to be moved on one character position.
VDU 10
VDU 10 causes either the text cursor (by default or after a VDU 4 command) or the
graphics cursor (after a VDU 5 command) to be moved on one line.
179
VDU 11
VDU 11 causes either the text cursor (by default or after a VDU 4 command) or the
graphics cursor (after a VDU 5 command) to be moved back one line.
VDU 12
VDU 12 clears either the current text viewport (by default or after a VDU 4
command) or the current graphics viewport (after a VDU 5 command) to the current
text or graphics background colour respectively. In addition the text or graphics
cursor is moved to its home position (see VDU 30).
VDU 13
VDU 13 causes the text cursor (by default or after a VDU 4 command) or the
graphics cursor (after a VDU 5 command) to be moved to the start of the current
line.
VDU 14
VDU 14 enters paged mode, and so makes the screen display wait for Shift or
Scroll Lock (twice) to be pressed before displaying the next page.
VDU 15
VDU 15 cancels the effect of VDU 14 so that scrolling is unrestricted.
VDU 16
VDU 16 clears the current graphics viewport to the current graphics background
colour using the graphics and action. It does not affect the position of the graphics
cursor.
VDU 17,n
VDU 17 sets either the text foreground (n<128) or background (n>=128) colours to
the value n. It is equivalent to COLOUR n.
VDU 18,k,c
VDU 18 is used to define either the graphics foreground or background colour and
the way in which it is to be applied to the screen. The BASIC equivalent is
GCOL k,c.
180
VDU control
VDU 19,l,p,r,g,b
VDU 19 is used to define the physical colours associated with the logical colour l.
If p <= 15 & p >= 0, r, g and b are ignored, and one of the standard colour settings is
used. This is equivalent to COLOUR l,p.
If p = 16, the palette is set up to contain the levels of red, green and blue dictated
by r, g and b. This is equivalent to COLOUR l,r,g,b.
If p = 24, the border is given colour components according to r, g and b.
If p = 25, the mouse logical colour l is given colour components according to r, g
and b. This is equivalent to MOUSE COLOUR l,r,g,b.
VDU 20
VDU 20 restores the default palette for the current mode and so cancels the effect
of all VDU 19 commands or their BASIC keyword counterparts. It also sets the
default text and graphics foreground and background colours.
VDU 21
VDU 21 stops all further text and graphics output to the screen until a VDU 6
command is received.
VDU 22
VDU 22 is used to change mode. It is equivalent to MODE n.
See Appendix D: Old-type Screen Modes in the RISC OS 5 User Guide for full details of the
modes available.
VDU 23,p1,p2,p3,p4,p5,p6,p7,p8,p9
VDU 23 is a multi-purpose command taking nine parameters, of which the first
identifies a particular function. Each of the available functions is described below.
Eight additional parameters are required in each case.
VDU 23,0,n,m|
If n = 8, this sets the interlace as follows:
Value Effect
m=0 Toggles the screen interlace state
m=1 Sets the screen interlace state to the current *TV setting
m = &80 Turns the screen interlace off
m = &81 Turns the screen interlace on
181
If n = 10, then m defines the start line for the cursor and its appearance. Thus:
Bits Effect
0-4 define the start line
5-6 define its appearance:
Bit 6 Bit 5 Meaning
0 0 Steady
0 1 Off
1 0 Fast flash
1 1 Slow flash
If n = 11, then m defines the end line for the cursor.
VDU 23,1,n|
This controls the appearance of the cursor on the screen depending on the value of
n. Thus:
Value Effect
n=0 Stops the cursor appearing (OFF)
n=1 Makes the cursor reappear (ON)
n=2 Makes the cursor steady
n=3 Makes the cursor flash
VDU 23,6,n1,n2,n3,n4,n5,n6,n7,n8
This sets the dot-dash line style used by dotted line PLOT commands. Each of the
parameters n1 to n8 defines eight elements of the line style, n1 controlling the start
and n8 the end. The bits in each are read from the most significant to the least
significant, zero representing a space and one representing a dot. See the chapter
entitled Complex graphics on page 127 for more details.
VDU 23,7,m,d,z|
This scrolls the current text screen. The values of m, d and z determine the area to
be scrolled, the direction of scrolling and the amount of scrolling respectively.
Thus:
182
VDU control
Value Effect
m=0 Scroll the current text viewport
m=1 Scroll the entire screen
d=0 Scroll right
d=1 Scroll left
d=2 Scroll down
d=3 Scroll up
d=4 Scroll in the positive X direction
d=5 Scroll in the negative X direction
d=6 Scroll in the positive Y direction
d=7 Scroll in the negative Y direction
z=0 Scroll by one character cell
z=1 Scroll by one character cell vertically or one byte horizontally
VDU 23,8,t1,t2,x1,y1,x2,y2;0;
This clears a block of the current text viewport to the text background colour. The
parameters t1 and t2 indicate the base positions relating to the start and end of the
block to be cleared respectively. The positions to which the values of t refer are
shown below:
Value Position
t=0 top left of viewport
t=1 top of cursor column
t=2 off top right of viewport
t=4 left end of cursor line
t=5 cursor position
t=6 off right of cursor line
t=8 bottom left of viewport
t=9 bottom of cursor column
t = 10 off bottom right of viewport
The parameters x1, y1 and x2, y2 are the x and y displacements from the positions
specified by t1 and t2 respectively. They determine the start and end of the block.
183
VDU 23,9,n|
VDU 23,10,n|
These set the durations for the first and second flashing colours respectively. The
duration is set to n frame periods (1/50th of a second in the standard modes). For
example, VDU 23,9,10| sets the duration of the first flash colour to 10/50 or 1/5
of a second. An alternative to the VDU command is *FX9 or *FX10 described in the
appendix *FX commands.
VDU 23,11|
This sets the four-colour patterns to their default values. See the chapter entitled
Graphic patterns for more details.
VDU 23,16,n|
This alters the direction of printing on the screen.
Normally when a character has been printed, the cursor moves to the right by one
place, and then to the start of the row below when a character is entered in the
righthand column. This movement, however, can be altered so that, for example,
the cursor moves down one row after each character, and moves to the top of the
next column to the right when the bottom of the screen has been reached. This
effect can by produced by typing
VDU 23,16,8|
The effect on cursor movement depends on the value n as shown below:
Value Effect
0 Positive X direction is right, positive Y direction is down
2 Positive X direction is left, positive Y direction is down
4 Positive X direction is right, positive Y direction is up
6 Positive X direction is left, positive Y direction is up
8 Positive X direction is down, positive Y direction is right
10 Positive X direction is down, positive Y direction is left
12 Positive X direction is up, positive Y direction is right
14 Positive X direction is up, positive Y direction is left
184
VDU control
Altering the direction of cursor movement also affects the way in which the screen
scrolls; so in the example above, when a character has been entered at the bottom
righthand corner, the screen scrolls to the left by one column rather than scrolling
up by one row as it usually does.
The following is the complete list of VDU commands for moving the cursor:
Command Movement
VDU 8 Moves the cursor one place in the negative X direction
VDU 9 Moves the cursor one place in the positive X direction
VDU 10 Moves the cursor one place in the negative Y direction
VDU 11 Moves the cursor one place in the positive Y direction
VDU 13 Moves the cursor to negative X edge
VDU 30 Moves the cursor to the negative X and Y edges (home)
VDU 31,x,y Moves the cursor to TAB(x,y)
VDU 127 Moves the cursor one place in the negative X direction,
destructively
VDU 23,17,n,m|
If n = 0 to 3, this command sets the tint to the value m for the text foreground, text
background, graphics foreground and graphics background colours respectively. It
is equivalent to TINT n,m. See the chapter entitled Screen modes on page 107 for
more details.
If n = 4, this command chooses which set of default colour patterns is used. m = 0
gives the Master 128-compatible set; m = 1 gives the native set. See the chapter
entitled Graphic patterns for more details.
If n = 5, this command swaps the text foreground and background colours.
If n = 6, then the command has the format:
VDU 23,17,6,x;y;0;0
This is used to set the origin of colour patterns. By default, patterns are aligned so
that the top left corner of the pattern coincides with the top left corner of the
screen. Using this call, you can make the top left of the pattern coincide with any
pixel on the screen, given by the coordinates (x,y).
If n = 7, then the command has the format:
VDU 23,17,7,flags,dx;dy;0;0
The bits in the flag byte have the following meanings:
185
Bit Meaning if set
0 Set VDU 4 character size from dx,dy
1 Set VDU 5 character size from dx,dy
2 Set VDU 5 character spacing from dx,dy
The bit 0 option is not implemented at present.
If bit 1 is set, then dx and dy give the size in pixels of characters plotted in VDU 5
mode. The standard size of 8 by 8, and double height, 8 by 16, are optimised. Other
sizes use the scaled character option of the SpriteExtend module and are therefore
somewhat slower.
Bit 2 set causes dx and dy to be used to set the amount by which the VDU driver
moves after each VDU 5-mode character has been printed (dx) and the amount to
move down for a line feed (dy). Usually these would be set to the same values as
the character size (so you would set bit 1 and 2), but they can be set independently
to allow, for example, narrower than usual spacing.
VDU 23,18,0,n|
Set Teletext transparency mode. This only has an effect in a system that has a video
frame buffer with a graphics frame buffer overlay, and controls whether the video is
visible through the Teletext display.
Value Effect
0 “Text” mode: the whole display is set opaque (default)
1 “Mix” mode: foreground colours, and both the foreground and
background of boxed text are opaque; non-boxed background
colours are all transparent
2 “Box” mode: boxed regions are opaque, others are transparent
3 “TV” mode: the whole display is set transparent
VDU 23,18,1,n|
In a Teletext mode this allows updating of the screen to be suspended or resumed.
If n is 1 the screen will not be updated when characters are output. If n is 0 any
suspended output is displayed in a single pass, and subsequent output causes the
screen to be updated each time.
Suspending the display can allow for a significant speed increase in the rendering
time for a large amount of text, for example when redrawing a complete teletext
page, because each time you plot a single character, it can cause the whole of the
rest of the line to be redrawn.
Note that the appearance of the display is undefined if you cause a hardware scroll
while in suspend mode.
186
VDU control
VDU 23,18,2,n|
This sets the Teletext reveal state. If n is 0, characters between the Conceal control
code (152) and the next colour control code are replaced by spaces. If n is 1 all
characters are displayed. The default is 0.
VDU 23,18,3,n|
This determines whether Teletext black foreground colour control codes have an
effect. If n is 0 (the default state) control codes 128 and 144 do nothing. If n is 1
control code 128 selects black text and control code 144 selects black graphics.
Enabling black colour control will only have a visible effect when Teletext is
overlaid over video and the transparency mode is not opaque (see VDU 23,18,0).
VDU23,19 to 24,n1,n2,n3,n4,n5,n6,n7,n8
These are reserved for future expansion.
VDU 23,27,m,n|
If m = 0, this command selects the sprite whose name is STR$n. It is equivalent to
*SChoose n.
If m = 1, this command defines sprite n to contain the contents of the previously
marked rectangle. It is equivalent to *SGET n.
VDU 24,x1;y1;x2;y2
VDU 24 defines a graphics viewport. The four parameters define the left, bottom,
right and top boundaries respectively, relative to the current graphics origin.
187
The parameters may be sent as shown, with semicolons after them. This indicates
that the values are each two bytes long. Alternatively, they can be sent as eight
one-byte values separated as usual by commas. The first of each pair contains the
low byte for the boundary; the second contains the high byte.
For example,
VDU 24,160;300;360;800;
is equivalent to
VDU 24,160,0,44,1,104,1,32,3.
See the chapter entitled Viewports on page 147 for more details.
VDU 25,k,x;y;
VDU 25 is a multi-purpose graphics plotting command. It is equivalent to PLOT
k,x,y. See the chapter entitled Complex graphics on page 127 for more details.
VDU 26
VDU 26 returns the text and graphics viewports to their default states: full screen
size. In addition, it resets the graphics origin to (0,0), moves the graphics cursor to
(0,0), and moves the text cursor to its home position.
VDU 27
VDU 27 has no effect.
VDU 28,lx,by,rx,ty
VDU 28 defines a text viewport. The parameters specify the boundary of the
viewport; the left-most column, the bottom row, the right-most column and the top
row respectively. See the chapter entitled Viewports for more details.
VDU 29,x;y;
VDU 29 moves the graphics origin. x and y specify the coordinates of the new
position. Normally the origin is at the bottom left of the screen at (0,0): whenever a
position is given as an absolute value, for example MOVE 20,80, the coordinates
are taken as being relative to the graphics origin. This command, therefore, affects
all movements of the graphics cursor and all subsequent graphics viewport
commands. The position on the screen of any existing graphics viewport is not
affected. This command is equivalent to ORIGIN x,y.
188
VDU control
VDU 30
VDU 30 moves the text cursor to its home position.
VDU 31,x,y
VDU 31 moves the text cursor to a specified position on the screen. It is equivalent
to PRINT TAB(x,y);.
189
190
26 Editing BASIC files
191
Editing BASIC files with Edit
● Strip line numbers produces a text file with no line numbers. If a reference to
a line is found, an error box will appear asking whether you want to leave the
number in. This option is on by default.
● Line number increment sets the number increment between successive lines
in the program.
192
Editing BASIC files
193
Editing BASIC files with the BASIC screen editor
The cursor is at the beginning of the top line on the screen, just to the right of the
line number. Note that the editor automatically puts a line number on the
beginning of each line: there is no need for you to type them in.
194
Editing BASIC files
Changing a line
To change a line, use the cursor keys to position the cursor on the correct line. You
can then delete part or all of the line and type new text in place of the old.
Now, assume that the program looks like this:
10 FOR X = 2 TO 30
20 PRINT X+X
30 NEXT X
and that it needs to be changed to look like this:
10 FOR X = 2 TO 20
11 PRINT X*X
20 PRINT X+X
30 NEXT X
To achieve this you must change line 10 and add a new line: line 11.
Position the cursor on the 0 of 30 on line 10, press Backspace and type 2. The 30 is
replaced by 20.
Adding a line
To create a new line in the middle of the program move the cursor to the line above
the place where you want the new line and press Return.
In the example above, move the cursor to line 10 and press Return.
Line 11 is now created.
To complete the above program type
PRINT X*X
The program should now be complete. You may like to experiment with the Return
and cursor keys to create a larger program.
195
Editing BASIC files with the BASIC screen editor
Inserting lines
There are two function keys which, no matter where you are in the program, create
a new line at the top or end of the program and move you there directly. These keys
are Ctrl-F9 (INSERT AT START) and Ctrl-F10 (INSERT AT END).
Deleting text
There are two ways to delete single characters. The Backspace or Delete key
removes the character to the left of the cursor and moves the characters to the
right of the cursor back one space.
To delete the character on which the cursor is placed, hold the Shift key down and
press the Backspace or Delete key. Backspace/Delete and Shift-Backspace/Delete
both move the following text back a space, but Shift-Backspace/Delete leaves the
cursor in the same position.
To delete all the characters from the cursor position to the end of the line, press
the F11 key.
Long lines
If a statement is too long to fit on one line of the screen, it wraps around to the
next line. To see this, try typing more text after one of the lines in the program. As
in a BASIC program, the length of a line is limited by the BASIC Editor to 251
characters.
Loading a program
You may now wish to load in one of your own programs to experiment with before
moving on to the next section. To do this press F2 (LOAD).
A window appears ready to accept the filename.
Type in the name of the program and press Return or F12 (EXECUTE).
196
Editing BASIC files
If the current program has been modified but not saved a warning message is
given.
Appending a program
You can also join one program onto the end of the current one.
To do this press Shift-F2 (APPEND) and then proceed in the same manner as for
loading.
Moving vertically
If you move the cursor to the top screen line and keep pressing the ↑ key, previous
statements are brought onto the screen one at a time until you reach the beginning
of the program. Similarly, pressing ↓ from the bottom screen line brings the
following statements onto the screen one at a time until you reach the end of the
program.
To move directly to the top of your program, press Ctrl ↑ which moves the cursor to
the first line of the program. Pressing Ctrl ↓ moves to the last line.
If you press Shift ↓, the next screenful of your program is displayed. In this way, you
can move quickly around your program from beginning to end. Similarly, if you
press Shift ↑, you can see the previous screenful. These functions are duplicated by
the Page Up and Page Down keys.
If you press Ctrl-Shift ↑ or Ctrl-Shift ↓ you can move to the first or last statement
on the current screen. In addition, if the cursor starts n characters along a
statement, it remains n characters along. It does not go to the beginning of the
statement.
Moving horizontally
Pressing the Shift → and Shift ← enables you to move sideways across the screen
at twice the normal speed.
Pressing Ctrl ← takes you to the beginning of the current statement and Ctrl →
takes you to the end of the current line. Pressing Ctrl-Shift → takes you to the
beginning of the next statement. Pressing Ctrl-Shift ← takes you to the beginning
of the previous statement.
197
Editing BASIC files with the BASIC screen editor
198
Editing BASIC files
There may also be occasions when you want to join two statements together. To do
this, move the cursor to the first of the two statements and press Ctrl-F1 (JOIN).
The editor automatically puts a colon between the two statements. If the combined
length of the two statements would exceed the maximum space available, the join
is not carried out and an error message is displayed.
Repeating a line
To create an exact copy of any statement immediately after it, move to the
statement you wish to copy and press Shift-F8 (REPEAT). As in the case of SPLIT,
this may cause renumbering to be carried out.
Marking a line
Placing the marker line
As you move about your program, there may be a statement which you wish to
come back to later on. The editor provides a way of marking a statement so that
you can go back to it with a single key-stroke. To mark a statement, first move to it
and press F6 (TOGGLE MARK). Pressing the same key again removes the marker. A
full stop appears on the screen between the line number and the start of the text,
indicating that this statement has been marked. Up to four marks may be set at any
time.
Finding a marker
Wherever you are in the program, pressing Shift-F6 (GOTO MARK) brings the
marked statement to the top of the screen and positions the cursor there. If there
is no marked line, pressing GOTO MARK displays an error; pressing Esc then
allows you to continue.
Line command
These are commands which allow you to delete, move and copy either a single line
or a block of lines. They can be inserted into the lefthand margin and are not
executed until F12 (EXECUTE) is pressed.
For example, to delete a single line, move the cursor onto that statement, hold
down the Ctrl-key and press D. The line number is removed and replaced by the
letter D. To delete the line from your program, press F12 (EXECUTE). The line is
removed from the screen and the cursor positioned on the previous line.
199
Editing BASIC files with the BASIC screen editor
Deleting lines
If there is a block of lines which you want to delete, move to the first line in the
block and press Ctrl-D twice. The line number disappears and is replaced by the
letters DD. Now move to the last line in the block and press Ctrl-D twice more.
Finally, press F12 (EXECUTE) to remove this block of lines from your program.
You may wish to delete from the current line to the end of the program. In this
case, press Ctrl-D twice on the current line and then press Ctrl-E. The line number
is replaced by DDE and the block from there to the end of the program can be
removed by pressing F12 (EXECUTE).
In a similar way, you can delete from the current line to the top of the program by
using Ctrl-T instead of Ctrl-E and then pressing F12 (EXECUTE).
Ctrl-E and Ctrl-T are examples of destinations and we shall encounter more of
these later.
Moving a block
To move a single statement from its current position to the end of the program,
move to it and press Ctrl-M followed by Ctrl-E. The line number is replaced by ME
and pressing F12 (EXECUTE) moves that line to the end of the program.
Ctrl-T can be used likewise to move a statement to the top of a program.
Instead of using Ctrl-T or Ctrl-E to specify the destination as the top or the end of
the program you can specify that the destination is before or after a certain line.
To move text to a position after a particular line, move to the destination and press
Ctrl-A.
Alternatively you can use Ctrl-B to move text to a position before a particular line.
Blocks of lines can be moved as easily as a single line by putting MM around the
block to be moved, choosing your destination, and pressing F12 (EXECUTE).
Copying lines
Whereas moving text removes it from its original position, copying text leaves the
original unchanged and duplicates it elsewhere. The command to copy text is
Ctrl-C instead of Ctrl-M, but otherwise the move and copy commands are the
same.
Naturally, for both the move and copy commands the destination must not be
within the block being moved or copied.
200
Editing BASIC files
Denoting limits
You can limit the effect of certain operations either to one line or to a block of
lines. These operations are:
● SAVE: Part of a program can be saved.
● SEARCH, SEARCH & EDIT: The search is limited to the line or block.
● SELECTIVE REPLACE, GLOBAL REPLACE: The replacement is limited to the
line or block.
To limit the operation to a single line, move the cursor to that line and press Ctrl-L.
To limit the operation to a block of lines, press Ctrl-L twice each on the first and
last line of the block.
To limit the operation from a particular line to the top (or end) of the program,
move the cursor to that line and press Ctrl-L Ctrl-L T (or Ctrl-L Ctrl-L E).
When a limit is set up, the functions which take account of it display the limit in
their window.
Justifying text
The editor can indent all or part of a program automatically. To reformat a part of
the program, move to the first line of the block you want to justify and press Ctrl-J
twice. Then move to the last line of the block and press Ctrl-J twice. Pressing F12
(EXECUTE) justifies the block so that the indentation of each line is identical to
that of the first line.
201
Editing BASIC files with the BASIC screen editor
Search
As an alternative to SEARCH & EDIT you can find all occurrences of a given string
and have them displayed. To do this press F7 (SEARCH) and enter the string which
is to be located. Then press F12 (EXECUTE) to perform the search. Any line on
which a match is found is displayed. You may then move up and down the list,
choose one to look at and press Home. This line is then placed at the top of the full
edit screen and you can edit it.
Global replace
To change one string for another throughout your entire program press F5
(GLOBAL REPLACE) and enter the text to be changed. You must then enter the
new text, and when you are happy with it press F12 (EXECUTE) to carry out the
change.
Selective replace
It is possible to perform a replace operation selectively. To do so press Shift F5
(SELECTIVE REPLACE). You must then enter both the text to be changed and the
new text. Press F12 (EXECUTE) to start the search. Each match is displayed and
you are prompted for either Y or N to indicate whether the replacement is to be
performed or not.
Keyboard options
Pressing Shift-F3 brings up a window which allows you to select various options.
This is called the Options Window. The options are displayed in three groups
described below. Pressing Return allows you to cycle through the groups.
202
Editing BASIC files
Auto indentation
The editor can automatically line up text in a program so that each line starts
beneath the first position of the line above which is not blank. This is known as
auto-indentation. It can be turned on or off using the Options Window:
Auto-indent (on/off)
Wildcard options
There are four wildcards, each of which may be customised using the options
available.
● Single character (default is .).
● Multiple characters (default is |).
● Start case insensitivity: This will match both PRINT and print (default is { ).
● End case insensitivity: this will match exactly what is entered. This is the
normal method of searching (default is }).
Wildcards can be changed to any punctuation character, or can be disabled by
using the Space Bar. Different wildcards must not use the same character.
203
Editing BASIC files with the BASIC screen editor
User-defined keys
The editor makes extensive use of the normal function keys, but you can still
program your own in the usual way via the *KEY command. To access them you
must press Ctrl Shift together with the function key, and not just the function key
on its own.
204
Editing BASIC files
Input windows
Valid keys and their actions are:
Keys Effect
Tab / Return / ↓ Moves cursor to next field
Shift-Tab / ↑ Moves cursor to previous field
Esc Cancels window, returns to editing
F12 (EXECUTE) Validates input & executes command
Insert Toggles insert/overtype for this window only
Backspace/Delete Deletes character to left of cursor
Shift-Backspace/Delete Deletes character at cursor
F11 Deletes characters from cursor to end of field
Shift-F11 Deletes all characters before cursor
Ctrl-F11 Deletes all text in this field
← / Shift ← Moves cursor left 1 or 2 positions
→ / Shift → Moves cursor right 1 or 2 positions
Ctrl ← Moves cursor to beginning of field
Ctrl → Moves cursor to end of field
Information windows
Esc Removes window and returns to editing.
Entering data
Data can be entered in one of three ways:
● Typing in text (eg program name)
● Selecting a prompted action (eg Y/N)
● Pressing the Space Bar to cycle through a list of valid choices (eg foreground
colour)
Pressing another function key whilst a window is present usually executes its
function. The exceptions are those functions which manipulate the program text
(eg SPLIT and JOIN).
205
Editing BASIC files with the BASIC screen editor
Keyboard summary
The following actions are performed directly via key presses:
Editing keys
← Moves right
→ Moves left
↑ Moves up
↓ Moves down
Shift → Moves right two characters
Shift ← Moves left two characters
Shift ↑ Moves cursor up a screenful
Shift ↓ Moves cursor down a screenful
Ctrl → Moves to the end of the statement
Ctrl ← Moves to the beginning of the statement
Ctrl ↑ Moves to the beginning of the program
Ctrl ↓ Moves to the end of the program
Ctrl-Shift → Moves to beginning of next statement
Ctrl-Shift ← Moves to beginning of previous statement
Ctrl-Shift ↑ Moves to top of current screen
Ctrl-Shift ↓ Moves to bottom of current screen
Page Up Moves cursor up a screenful
Page Down Moves cursor down a screenful
Tab Moves right to next tab position
Shift-Tab Moves left to previous tab position
Home Brings statement to top of screen
End (Copy) Enters copy mode
Enter Ends copy mode
Insert Toggles insert/overtype mode
Backspace/Delete Deletes character to left of cursor
Shift-Backspace/Delete Deletes character at cursor position
Enter Creates a new statement after the current one
Function keys
F1 (* COMMAND) Perform OS command
F2 (LOAD) Load a program
F3 (SAVE) Save a program
F4 (SEARCH & EDIT) Find string and edit from it
F5 (GLOBAL REPLACE) Global search and replace
206
Editing BASIC files
207
Editing BASIC files with the BASIC screen editor
Error messages
The editor displays the following messages. In each case, an explanation is given
below the message.
Limit is xxxx to xxxx/Limit is xxxx only
A range has been set using the L or LL line commands, and this function will only
operate within the range.
Line xxxx is too long to be edited
The program already contains a line which is too long.
Not enough room in RMA for The BASIC Editor
RMA initialisation failed to acquire workspace.
Replace? (Y/N)
Displayed on the status line when prompting during the SELECTIVE REPLACE
operation.
Tab must be between 0 and 63
Displayed by OPTIONS.
The combined length of these statements would be too
big
The two statements cannot be joined.
The destination must be outside the block being moved
or copied
Raised by EXECUTE.
The first statement in the block to be justified must
not be blank
Raised by EXECUTE.
The maximum line is 65279
Raised by GOTO LINE.
The name has been truncated
On saving, the program name following REM > in the first line of the program is
longer than can be displayed in the window.
The named program is invalid
The user appended a program which was invalid. The editor restored the original.
The named program is too big
208
Editing BASIC files
The user tried to load or append a program for which there was not enough room
in memory.
The renumber has failed.Unmatched line numbers have
been replaced by @@@@
When trying to renumber the program one or more line number references could
not be resolved.
The search string has no text
The search string must not be blank, and must not contain only wildcards.
The string could not be found
The search string could not be found.
There is not enough memory to update the program
All available memory has been used up.
This is not a valid mode
An invalid screen mode was specified in OPTIONS.
This is not a valid program
OLD was pressed with no valid BASIC program in memory, or the user tried to load
an invalid program.
This program could not be found
The named program on a load or append was not in the directory.
This program has not been saved
The user is warned on a load if the program has been modified and not saved.
This program has not been saved
Press NEW again to confirm.
Press ESCAPE to cancel
The user pressed NEW but the program had been modified and not saved.
This statement is too long
The statement is too long, and needs to be shortened.
This statement is too long to be changed
Replacing or justifying would make the statement too long.
This statement is too long to be split
Even after splitting, both parts of the statement would still be too long.
Wildcards must not be the same
Raised by OPTIONS.
209
Editing BASIC files with the BASIC screen editor
210
Editing BASIC files
211
Editing BASIC files with the BASIC screen editor
212
Part 3 – Reference
213
214
27 Keywords
T his chapter describes the BBC BASIC keywords. First, there is a short list
grouping the keywords by function. Use this list if you are not sure what
keywords are available for a particular task.
● Assembly language
CALL, SYS, USR
● Character/string handling
ASC, CHR$, INSTR(, LEFT$(, LEN, MID$(, RIGHT$(, STR$, STRING$(
● Error handling
ERL, ERR, ERROR, LOCAL ERROR, ON ERROR, REPORT, REPORT$, RESTORE
ERROR
● File commands
BGET#, BPUT#, CLOSE#, EOF#, EXT#, GET$#, INPUT#, OPENIN, OPENOUT,
OPENUP, PRINT#, PTR#
● Graphics
BY, CIRCLE, CLG, CLS, COLOUR (COLOR), DRAW, ELLIPSE, FILL, GCOL, LINE,
MODE, MOVE, OFF, ON, ORIGIN, PLOT, POINT, POINT(, RECTANGLE, TINT,
VDU, WAIT
● Input/Output
GET, GET$, INKEY, INKEY$, INPUT, INPUT LINE, LINE INPUT, MOUSE, PRINT,
SPC, TAB, WIDTH
● Logical
AND, EOR, FALSE, NOT, OR, TRUE
● Numerical
ABS, DIV, EVAL, INT, MOD, RND, SGN, SQR, SUM, SUMLEN, SWAP, VAL
● Program construction
APPEND, AUTO, CRUNCH, DELETE, EDIT, HELP, INSTALL, LIST, LISTO, LOAD,
LVAR, NEW, OLD, RENUMBER, SAVE, TEXTLOAD, TEXTSAVE
215
● Program statements
CHAIN, CLEAR, DATA, DEF, DIM, END, ENDPROC, FN, GOSUB, GOTO, LET,
LIBRARY, LOCAL, ON, OSCLI, PROC, QUIT, READ, REM, RESTORE, RETURN,
RUN, STOP, TRACE
● Sound
BEAT, BEATS, ENVELOPE, SOUND, STEREO, TEMPO, VOICE, VOICES
● Structures
CASE, ELSE, ENDCASE, ENDIF, ENDWHILE, FOR, IF, NEXT, OF, OTHERWISE,
REPEAT, THEN, UNTIL, WHEN, WHILE
● Trigonometric
ACS, ASN, ATN, COS, DEG, EXP, LN, LOG, PI, RAD, SIN, TAN
● Variables
ADVAL, COUNT, HIMEM, LOMEM, PAGE, POS, TIME, TIME$, TOP, VPOS
The remainder of this chapter lists the keywords alphabetically for ease of
reference. It gives complete definitions of syntax, with examples.
Each keyword is listed in the index.
Syntax descriptions
In the descriptions of the syntax of each keyword, words in upper case are the
keywords themselves. Most punctuation such as ‘,’ and ‘=’ also stands for itself,
except for square brackets ‘[]’ which enclose items that are optional, and ellipsis
‘...’ which indicate that the item preceding them may be repeated an arbitrary
number of times (including zero).
For keywords that take arguments the class of each argument is shown in italics and
these stand for items that you need to supply. The classes used are as follows:
expression or expr
This is any valid numeric or string expression. The type of the expression may be
qualified, e.g. numeric-expression or string-expression, and details of possible types and
ranges is always given in the explanation of the keyword.
Where more than one expression is required expression1, expression2 or expr1, expr2 is
often used to make the identification of each expression easier.
In general, wherever an integer is required, BASIC will accept a real, as long as it
can be converted into an integer.
216
Keywords
factor
This means an expression which is a single unit, i.e. a variable reference, a
constant, a function call (user-defined or built-in), or a general expression
enclosed in round brackets. For functions that only take a single argument the
argument is always a factor, so examples of keywords using factors are:
SINRAD45
LENA$
STR$1234
EXP-A%
TAN(ang%+45)
RND(10)
It can be seen that brackets are only needed around arguments if they contain
more than one element or, as in the case of RND, if the argument is optional.
relational
This is an expression that contains operators of higher precedence than the logical
operator under discussion. Thus in the syntax:
relational AND relational
the relational expression may contain any operator except AND, OR and EOR, as
these have the same or lower precedence. To use one of these operators (e.g. OR)
in an argument, you will need brackets, for example:
(a>b OR c<d) AND f<>1
For a full description of operator precedence see Arithmetic operators on page 31
variable or var
This is a reference to any variable. Examples are a, a%, a$, a(23), a%(32),
a$(i+1), $a, ?a, !a, a?1, a!1 etc. Sometimes it is qualified, e.g. numeric variable.
statements
This means zero or more statements, separated by colons, e.g.
PRINT "Hello":GOTO 100
Null statements are permitted in BBC BASIC, so lines such as:
IF GET
are valid. In this example, the optional THEN is omitted and there is a null THEN
part. This can be useful if you want to use a function call but discard the return
value.
217
The keywords REPEAT, THEN, ELSE, OTHERWISE and the assembly language
introducer ‘[’ do not require colons to separate them from the next statement.
Also, there is no need for a colon after the PROC or FN part of a DEF statement.
pathname
This is a string expression that contains a valid RISC OS pathname, identifying a
file on a filing system. This may be simply the name of a file, for example MyFile,
in which case it will be located in the currently selected directory of the current
filing system, or it may be a full pathname identifying the filing system and the full
path to the file, for example ADFS::HardDisc4.$.Examples.MyFile.
Technical details
Some keyword descriptions contain a technical details section which gives further
information on how the keyword is implemented that may be of use to advanced
programmers.
History
For keywords that have been altered or extended after interpreter version 1.04 (the
first version of BASIC V) a history section summarises the changes. More detailed
information can be found in Appendix I – BBC BASIC’s history.
218
Keywords
ABS
Function returning the magnitude (absolute value) of its numeric argument, i.e.
changes negative numbers into positive numbers.
Syntax
ABS factor
Argument
Any numeric.
Result
Same as the argument if this is positive, or –(the argument) if it is negative.
Notes
The largest negative integer does not have a legal positive value, so that if
a%=-2147483648, ABS(a%) yields the same value: -2147483648. However, this
does not arise with floating point numbers.
Example
diff=ABS(length1-length2)
219
ACS
ACS
Function returning the arc-cosine of its numeric argument.
Syntax
ACS factor
Argument
Real or integer between –1 and 1 inclusive.
Result
Real in the range 0 to π radians, being the inverse cosine of the argument.
Examples
ang=ACS(normvec1(1)*normvec2(1)+normvec1(2)*normvec2(2))
angle=DEG(ACS(cos1))
PRINT ACS(0.5)
220
Keywords
ADVAL
Function returning buffer data or reading data from an analogue or joystick port if
fitted.
Syntax
(1) ADVAL negative-factor
(2) ADVAL 0
(3) ADVAL positive-factor
Argument (1)
Negative integer –n, where n is a buffer number between 1 and 10.
Result (1)
The number of spaces or entries in the buffer is given in the table below:
arg Buffer name Result
–1 Keyboard (input) Number of characters used
–2 Serial (input) Number of characters used
–3 Serial (output) Number of characters free
–4 Printer (output) Number of characters free
–10 Mouse (input) Number of bytes used
Argument (2)
Zero.
Result (2)
An integer giving the state of joystick switches. Bit 0 is the state of the first switch,
bit 1 gives the state of the second switch and so on.
This behaviour is usually implemented by the Joystick module and will only work if
this module is loaded and suitable hardware is present. If this is absent, the
function will result in a Command not recognised error.
Argument (3)
Positive integer n, where n is an analogue–digital converter channel number.
221
ADVAL
Result (3)
An integer giving the current voltage level of the analogue–digital converter
channel in the range 0 to 65535.
This behaviour is usually implemented by the Joystick module and will only work if
this module is loaded and suitable hardware is present. If this is absent, the
function will result in a Command not recognised error.
Technical details
The ADVAL keyword uses OS_Byte 128.
Example
IF ADVAL(-1)=0 THEN PROCinput
222
Keywords
AND
Operator performing logical AND or bitwise AND.
Syntax
relational AND relational
Arguments
Relational expressions, or bit values to be ANDed.
Result
The bitwise AND of the arguments. Corresponding bits in the integer arguments
are ANDed to produce the result. Hence a bit in the result is one if both of the
corresponding bits of the arguments are one. Otherwise it is zero.
If used to combine relational values, AND’s arguments should be either TRUE (-1)
or FALSE (0). Otherwise, unexpected results may occur. For example, 2 and 4 are
both true (non-zero), but 2 AND 4 yields FALSE (zero).
Examples
a = x AND y : REM a is set to binary AND of x and y
PRINT var AND 3 : REM print lowest 2 bits of var
IF day=4 AND month$="April" THEN PRINT "Happy birthday"
IF temp>10 AND NOT windy THEN PROCgo_out ELSE PROCstay_in
REPEAT
a=a+1
b=b-1
UNTIL a>10 AND b<0
isadog = feet=4 AND tails=1 AND hairy
223
APPEND
APPEND
Command to append a file to a BASIC program.
Syntax
APPEND pathname
Argument
pathname is a string expression which should evaluate to the pathname of a valid
file.
Purpose
The file specified is added to the end of the BASIC program currently in memory. If
the file contains a BASIC program, the line numbers and any references to them in
the added section are renumbered so that they start after the last line of the
current program.
Examples
APPEND ":0.lib"
APPEND second_half$
224
Keywords
ASC
Function returning the ASCII code of the first character in a string.
Syntax
ASC factor
Argument
String of length 0 to 255 characters.
Result
ASCII code of the first character of the argument in the range 0 to 255, or –1 if the
argument is a null string.
Examples
x2=ASC(name$)
IF code >= ASC("a") AND code <= ASC("z") THEN PRINT "Lower
case"
225
ASN
ASN
Function returning the arc-sine of its numeric argument.
Syntax
ASN factor
Argument
Numeric between –1 and 1 inclusive.
Result
Real in the range –π/2 to +π/2 radians, being the inverse sine of the argument.
Examples
PRINT ASN(opposite/hypotenuse)
angle=DEG(ASN(0.2213))
226
Keywords
ATN
Function returning the arc-tangent of its numeric argument.
Syntax
ATN factor
Argument
Any numeric.
Result
Real in the range –π/2 to +π/2 radians, being the inverse tangent of the argument.
Examples
ang = DEG(ATN(sin/cos))
PRINT "The slope is ";ATN(opposite/adjacent)
227
AUTO
AUTO
Command initiating automatic line numbering.
Syntax
AUTO [start][,step]
Arguments
start is an integer constant in the range 0 to 65279 and is the first line to be
generated automatically. It defaults to 10.
step is an integer constant in the range 1 to 65279 and is the amount by which the
line numbers increase when Return is pressed. If omitted, 10 is assumed.
Purpose
AUTO is used when entering program lines to produce a line number
automatically, so that you do not have to type them yourself. To end automatic line
numbering use Esc. AUTO will stop if the line number becomes greater than 65279.
Examples
AUTO
AUTO 1000
AUTO 12,2
228
Keywords
BEAT
Function returning the current beat value.
Syntax
BEAT
Result
An integer giving the current beat value. This is the value yielded by the beat
counter as it counts from zero to the number set by BEATS at a rate determined by
TEMPO. When it reaches its limit it resets to zero. Synchronisation between sound
channels is performed with respect to the last reset of the beat counter.
Example
PRINT BEAT
229
BEATS
BEATS
Function returning or statement altering the beat counter.
Syntax
as a statement:
(1) BEATS expression
as a function:
(2) BEATS
Arguments (1)
expression gives the value 1 higher than that which the beat counter
increments to, i.e. it counts from 0 to expression-1. This counter is used in
conjunction with the SOUND and TEMPO statements to synchronise sound
outputs from different sound channels.
Result (2)
An integer giving the current value of the beat limit, as set by a BEATS statement,
or 0 if no counting is currently being performed.
Examples
BEATS 2000
PRINT BEATS
230
Keywords
BGET#
Function returning the next byte from a file.
Syntax
BGET# factor
Argument
A channel number returned by an OPENxx function.
Result
The ASCII code of the character read (at position PTR#) from the file, in the range 0
to 255.
Notes
PTR# is updated to point to the next character in the file. If the last character in the
file has been read, EOF# for the channel will be TRUE. The next BGET# will return
an undefined value and the one after that will produce an End of file on
file handle nn error.
Examples
char%=BGET# channel
char$=CHR$(BGET#fileno)
WHILE NOT EOF# channel
char% = BGET# channel
PROCprocess(char%)
ENDWHILE
231
BPUT#
BPUT#
Statement to write a byte or a string to a file.
Syntax
(1) BPUT#factor,numeric-expression
(2) BPUT#factor,string-expression[;]
Arguments (1)
factor is a channel number as returned by an OPENxx function.
numeric-expression is truncated to an integer 0 to 255, and is the ASCII code
of the character to be sent to the file.
Arguments (2)
factor is a channel number as returned by an OPENxx function.
string-expression is a string containing 0 to 255 characters. The ASCII codes
of all the characters in the string are sent to the file. This is followed by a newline
(ASCII value 10), unless the statement is terminated by a ; (semi-colon).
Notes
PTR# is updated to point to the next character to be written. If the end of the file is
reached, the length (EXT#) increases too. It is only possible to use BPUT# with
OPENUP and OPENOUT files, not OPENIN ones.
Examples
BPUT#outputfile,byte%
BPUT#channel,ASC(MID$(name$,pos,1))
BPUT#file,"Hello"
BPUT#chan,A$+B$;
232
Keywords
BY
Optional part of MOVE, DRAW, POINT and FILL statements.
Syntax
See the above-mentioned keywords.
Purpose
The BY keyword changes the effect of certain graphics statements. In particular it
indicates that the coordinates given in the statement are relative rather than
absolute. For example, POINT BY 100,100 means plot a point at coordinates
displaced by (100,100) from the current graphics cursor position, rather than a
point which is at (100,100).
In terms of its effect at the VDU driver level, BY makes BASIC use the relative forms
of the appropriate OS_Plot calls, instead of the absolute ones.
Examples
MOVE BY 4*x%,4*y%
POINT BY 100,0
DRAW BY x%*16, y%=4
FILL BY x%, y%
233
CALL
CALL
Statement to execute a machine code or assembly language subroutine.
Syntax
CALL expression[,variable...]
Arguments
expression is the address of the routine to be called. The parameter variables, if
present, may be of any type. They are accessed through a parameter block which
BASIC sets up. The format of this parameter block and of the variables accessed
through it is described below.
Purpose
CALL can be used to enter a machine code program from BASIC. Before the routine
is called, the ARM’s registers are set up as follows:
R0 A%
R1 B%
R2 C%
R3 D%
R4 E%
R5 F%
R6 G%
R7 H%
R8 Pointer to BASIC’s workspace (ARGP)
R9 Pointer to list of l-values and types of the parameters
R10 Number of parameters
R11 Pointer to BASIC’s string accumulator (STRACC)
R12 BASIC’s LINE pointer (points to the character after the CALL statement)
R13 Pointer to BASIC’s full, descending stack
R14 Link back to BASIC and environment information pointer.
The called routine does not need to preserve any of these registers except R13.
234
Keywords
The second word is the type of variable. This list is in reverse order, so the l-value
pointed to by R9 is that of the last parameter in the list. The pointer to the list is
always valid, even when if the list is null (i.e. R10 contains 0). The possible types
are as follows:
Type BASIC l-value points to
&00 ?factor byte-aligned byte
&04 !factor byte-aligned word
&04 name% word-aligned word
&04 name%(n) word-aligned word
&05 |factor byte-aligned FP value (5 bytes)
&05 name byte-aligned FP value (5 bytes)
&05 name(n) byte-aligned FP value (5 bytes)
&08 |factor word-aligned FP value (8 bytes)
&08 name word-aligned FP value (8 bytes)
&08 name(n) word-aligned FP value (8 bytes)
&80 name$ byte-aligned SIB (5 bytes)
&80 name$(n) byte-aligned SIB (5 bytes)
&81 $factor byte-aligned byte-string (CR-terminated)
&100+&04 name%() word-aligned array pointer
&100+&05 name() word-aligned array pointer
&100+&08 name() word-aligned array pointer
&100+&80 name$() word-aligned array pointer
For types &00, &04, &05 and &08, the address points to the actual byte, the four–
byte integer, the five–byte floating point value or the eight–byte floating point
value.
For type &80, the address points to a five-byte ‘string information block’. The first
four bytes are a byte-aligned word pointing to the first character of the string itself,
which is on a word boundary, followed by a byte containing the length of the string.
For types &100+n the value points to a word-aligned word. If the array has not been
allocated, or has been made LOCAL but not DIMed, this word contains a value less
than 16. Otherwise, the word points to a word-aligned list of integer subscript sizes
(the values in the DIM statement plus 1) terminated by a zero word, followed by a
word which contains the total number of entries in the array, followed by the zeroth
element of the array. For example, consider the following program:
235
CALL
10 DIM a(10,20)
20 a = 1.23
30 a$ = "char"
40 ...
100 CALL code, a, a(), a$
5 bytes
a(0,0)
word
a type (&05) # elements (231)
5 bytes word
a I-value terminator
1.23
word
a () type (&105) sub 2 size (21)
word word
a () I-value array pointer sub 1 size (11)
R10=3 byte r
a$ type (&80) length(4) a
h
R9 word
a$ I-value c
string pointer Increasing
addresses
The diagram above shows the resulting parameter block and other data items
when code is called. The access method into the arrays is given by the following
algorithm:
position = 0
number = 0
REPEAT
IF subscript(number) > array(number) THEN fault
number = number+1
IF number<>total THEN position = (position+subscript) *
array(number)
UNTIL no_more_subscripts
position = position*size(array)
This means that the last subscript references adjacent elements. For a simple two
dimensional array DIM A(LIMI–1,LIMJ–1) the address of A(I,J) is
(I*LIMI+J)*size+base_address
MOV PC,R14 returns to the BASIC calling program. If V is set on return an error
will be signalled, with R0 being treated as a pointer to a standard RISC OS error
block. However, R14 also points to an array of useful values:
236
Keywords
237
CALL
The word at address [R14] is a branch instruction which returns you to the BASIC
interpreter. The word before it, [R14,#–4] identifies that the code is running from
BASIC. The current BASIC interpreter provides &BA51C005, and the bottom three
nybbles (&005) denote that the calling standard follows the one shown here (to
allow for possible future changes). The words which follow it contain useful
addresses which are not absolute, but are offsets from the contents of the ARGP
register, R8.
The first offset word, at [R14,#4], gives the location of the string accumulator,
STRACC, where string results are kept. Thus if you execute
LDR R0,[R14,#4] ;Get STRACC offset from R8
ADD R0,R8,R0 ;Add offset to ARGP
R0 will give the base address of the string accumulator. (Actually, the address of
STRACC is also in R11 on entry, so this isn’t a particularly good example.) Similarly,
to load the pointer to the end of free space into R0, you would use:
LDR R0,[R14,#&1C] ;Get FSA offset from R8
LDR R0,[R8, R0] ;De-reference it
Although the word referenced through the TRACEF offset is the TRACEFILE handle,
the four that follow it are also used. They contain respectively:
[TRACEF+4] LOCALARLIST a pointer to the list of local arrays
[TRACEF+8] INSTALLLIST a pointer to the list of installed libraries
[TRACEF+12] LIBRARYLIST a pointer to the list of transient libraries
[TRACEF+16] OVERPTR a pointer to the overlay structure
The first of these is probably not very useful, but the other three allow routines to
access the libraries that have been loaded. For example, a ‘find’ routine would be
able to find a procedure no matter where it was defined (which LIST IF can’t do).
Libraries are stored as a word, which is a pointer to the next library (0 denoting the
end of the list). The word is followed immediately by the BASIC program which
forms the library.
Before an OVERLAY statement has been executed, OVERPTR contains 0. After a
statement such as OVERLAY a$(), it contains a pointer to the following structure:
OVERPTR+&00 Pointer to base of OVERLAY array, i.e. a$(0)
OVERPTR+&04 Index of current OVERLAY file (or –1 if none loaded)
OVERPTR+&08 Total allowed size of OVERLAY area
OVERPTR+&0C Start of current OVERLAY file in memory.
...
After the word offsets come the branches useful to BASIC routines. For example, to
call STOREA, whose branch is at offset &34 from R14, you might use:
238
Keywords
VARIND
Entry with R0:
R0 = Address of l-value, i.e. where to load the variable from
R9 = Type of l-value, as in CALL parameter block
R12 = LINE
Returns with R0..R3 as the value, R9 the type of the value as follows:
R9 Type Location of value
0 String STRACC, R2 points to end ([R2]–STRACC is length)
&40000000 Integer R0
&80000000 Float R0..R3 (or F0 if using BASIC64, D0 if using BASICVFP)
239
CALL
Uses no other registers (including stack). Unless used for the output value, R0-R3
are corrupted. Possible error if asked to take value of an array fred(): will need R12
valid for this error to be reported correctly.
When floating point values are returned/required in R0..R3, the format is as
follows:
R0 = 32-bit mantissa, normalised (so bit 31 = 1)
R1 = Exponent in excess-128 form
R2 = Undefined
R3 = Sign. 0 positive, &80000000 negative
This is provided for information only. We reserve the right to change this format;
you should treat R0..R3 as a single item, without regard to the constituent parts.
STOREA
Entry with value in R0..R3, as appropriate to the type of value in R9. Strings must
be located within STRACC – use STSTORE for strings which are not. For BASIC64,
floating point values will be in F0. For BASICVFP, floating point values will be in D0.
R4 = Address of l-value (where to store the value)
R5 = Type of l-value (as in CALL parameter block)
R8 = ARGP
R9 = Type of value
R12 = LINE (for errors)
R13 = Stack pointer (for free space check)
Converts between integer and floating point numbers, or produces an error if
conversion is impossible.
Returns with R0-R7 and R9 destroyed. BASIC64 may also destroy F0-F2, F7.
BASICVFP may also destroy F0-F2, F7, D0-D15.
STSTORE
This stores a string into a string variable. Entry with:
R2 = Length (i.e. address of byte beyond the last one)
R3 = Address of start of string
R4 = Address of l-value
R8 = ARGP
R12 = LINE (for error reporting)
R13 = Stack pointer (for free space check)
The string must start on a word boundary and the length must be 255 or less.
Uses R0, R1, R5, R6, R7. Preserves input registers. Stack not used.
240
Keywords
LVBLNK
This routine looks up a variable from the name pointed to by R8.
On entry:
R8 = ARGP
R11 = Pointer to start of name
R12 = LINE (many errors possible, such as subscript error in array)
R13 = Stack (may call EXPR to evaluate subscripts)
The string is processed to read one variable name and provide an address and type
which can be given to VARIND.
If a valid variable name (or more precisely l-value) was found:
Z flag = 0
R0 = Address of l-value
R9 = Type of l-value
R11 = Points to next character after the end of the accepted name
If a valid variable was not found:
Z flag = 1
C flag = 1 if there is no way the string was a variable name (e.g. %Q)
C flag = 0 Could be a variable but hasn’t been created (e.g. A)
Other registers set up for a subsequent call to CREATE.
If the name contains BASIC keywords, for example array%(SIN PI), then it
must be tokenised using MATCH first.
Uses all registers except R8 and R12. For BASIC64, F0-F2 and F7 may also be used.
For BASICVFP, F0-F2, F7 and D0-D15 may also be used.
CREATE
This creates a variable. Input is the failure of LVBLNK to find something. Thus we
have:
R3 = Second character of name or 0
R4 = Points to start of the rest of the name
R8 = ARGP
R9 = Contains the number of zero bytes on the end
R10 = First character of name
R11 = Points to the end of the name
R12 = LINE
R13 = Stack pointer
It is recommended that CREATE is only called immediately after a failed LVBLNK.
241
CALL
CREATE uses all registers. Returns result as LVBLNK. The LVBLNK and CREATE
routines can be combined together to provide a routine which checks for a variable
to assign to, and creates it if necessary:
STMFD R13!,{R14} ;Save return address
MOV R6,R14 ;Set R6 to info pointer
MOV R14,PC ;Set return address
ADD PC,R6,#&3C ;Look-up name (LVBLNK)
LDMNEFD R13!,{PC} ;Return if found
LDMCSFD R13!,{PC} ;Or illegal name
MOV R14,PC ;Set return address
ADD PC,R6,#&40 ;Create a new var (CREATE)
LDMFD R13!,{PC} ;Return
EXPR
This evaluates an expression pointed to by R11. On entry:
R8 = ARGP
R11 = Pointer to start of string
R12 = LINE
R13 = Stack pointer
EXPR stops after reading one expression (like those in the PRINT statement).
The value is returned in the same manner as VARIND. On exit:
Z flag = 1 the expression was a string
Z flag = 0 the expression was a number
N flag = 1 expression was a floating point number
N flag = 0 expression was an integer
R9 = Type
R11 = Pointer to next character after the expression, which will be to the next
expression (if any) if it is, for example, a comma-separated list
Uses all registers except R8 and R12. For BASIC64, F0-F2 and F7 may also be used.
For BASICVFP, F0-F2, F7 and D0-D15 may also be used.
The status found in the Z and N flags on exit can be recreated by executing the
instruction TEQ R9,#0.
One useful thing about EXPR is that it enables the machine code to call a BASIC
routine. You do this by evaluating a string which has a call to a user-defined
function in it. For example, the string you evaluate might be "FNinput". The
function could perform some task which is tedious to do in machine code, such as
input a floating point number.
242
Keywords
One slight complication is that the string to be evaluated must have been
tokenised already, so you must either call MATCH described below, or store the
string with the tokenised form of FN (the byte &A4).
MATCH
This routine takes a text string and tokenises it to another string. Strings passed to
EXPR and LVBLNK must be tokenised first if they contain any BASIC keywords. On
entry:
R1 = Points to the source string (terminated by ASCII 10 or 13)
R2 = Points to the destination string
R3 = MODE
R4 = CONSTA
R13 = Stack pointer
Note that MATCH does not need ARGP or LINE.
The MODE value is 0 for left-mode (before an = sign, or at the start of a statement)
and 1 for right-mode (in an expression). The difference is in the way that BASIC
tokenises the pseudo-variables. Each of these has two tokens, one for when it is
used as a statement (e.g. TIME=…) and one when it is used as a function (PRINT
TIME). As you will generally use MATCH to tokenise an expression string, you will
use MODE = 1.
The CONSTA value is 0 if you do not want BASIC to convert integers which could be
line numbers (in the range 0 to 65279) into internal format, and 1 if you do. Internal
format consists of the token &8D followed by three bytes which contain the
encoded line number. A property of these bytes is that they lie in the range 64 to
127, and therefore do not contain control codes or tokens.
Encoded constants are used for line numbers after GOTO, GOSUB, RESTORE,
THEN and ELSE keywords. Because they are of fixed length, the program can be
renumbered without having to move program lines about. Because they don’t
contain special characters, certain BASIC search operations (e.g. for the ELSE in a
single-line IF) are speeded up.
Both MODE and CONSTA will be updated during the use of the routine. For
example, GOTO will set CONSTA to &8D to read the line number, PRINT will
change MODE to 1 to read an expression. The table below summarises the setting
of MODE and CONSTA:
MODE CONSTA Meaning
0 0 Tokenise a statement
0 &8D Used to read line number at the start of a line
1 0 Tokenise an expression
1 &8D Tokenise an expression after GOTO etc.
243
CALL
TOKENADDR
This routine converts a token value into a pointer to the text string representing it.
On entry:
R0 = The token value
R12 = Pointer to next byte of token string
The value of R12 is only used when two-byte tokens are required. No other
registers are used or required.
Returns R1 as a pointer to the first character of the string, terminated by a byte
whose value is &7F or greater. R0 is set to the address of the start of the token table
itself. R12 will have been incremented by one if a two-byte token has been used.
FSTA
Store a four-word FP value into a five-byte variable. On entry:
R0..R3 = Source floating pointer value
R9 = Pointer to destination value
On exit:
R2 = Altered (but this doesn’t affect the FP value)
No errors. Stack not used.
FLDA
Load a five-byte variable into a four-word FP value. On entry:
R9 = Pointer to source value
244
Keywords
On exit:
R0..R3 = Loaded FP value
No errors. Stack not used.
FADD/FMUL
Add/multiply the four-word FP value in R0..R3 by the variable at [R9]. On entry:
R0..R3 = Source FP value
R9 = Pointer to five-byte variable.
On exit:
R0..R3 = Added/multiplied by [R9]
R4..R7 = Corrupted
Overflow errors possible. Stack not used.
FSUB/FDIV
Subtract R0..R3 from [R9] or divide [R9] by R0..R3, with the result in R0..R3. On
entry:
R0..R3 = FP value
R9 = Pointer to five-byte variable.
On exit:
R0..R3 = [R9] minus old value or [R9] / old value
R4..R7 = Corrupted
Overflow errors possible. Divide by zero possible for FDIV. Stack not used.
FLOAT
Convert integer to four-word floating point value. On entry:
R0 = Integer
On exit:
R0..R3 = Floated version
R9 = &80000000 (floating type code)
No overflow possible. Stack not used.
FIX
Convert four-word floating point value to an integer. On entry:
245
CALL
FSQRT
Take the square root of the floating point number in R0..R3. On entry:
R0..R3 = Floating point value
On exit:
R0..R3 = SQR(old value)
R0..R7 = Corrupt
Negative root error possible. Stack not used.
246
Keywords
This facility is provided for backwards compatibility only. You should not use it in
new programs. Also, you must be careful that any machine code you assemble in a
program does not lie in the address range &FFCE to &FFF7; otherwise when you
call it, it might be mistaken for a call to an old MOS routine.
Examples
CALL invertMatrix,a()
CALL sampleWaveform,start%,end%,values%()
247
CASE
CASE
Statement marking the start of a CASE … OF … WHEN … OTHERWISE …
ENDCASE construct. It must be the first statement on the line.
Syntax
CASE expression OF
WHEN expression [,expression...] [:statements...]
[statements]
[WHEN ...]
OTHERWISE [statements...]
[statements...]
ENDCASE
Arguments
expression can be any numeric or string expression. The value of expression
is compared with the values of each of the expressions in the list following the first
WHEN statement. If a match is found, then the block of statements following the
WHEN down to either the next WHEN or OTHERWISE or ENDCASE is executed.
Then control moves on to the statement following the ENDCASE. If there is no
match, then the next WHEN is used, if it exists. OTHERWISE is equivalent to a
WHEN but matches any value.
Examples
CASE A% OF
CASE Y*2 + X*3 OF
CASE GET$ OF
248
Keywords
CHAIN
Statement to load and run a BASIC program.
Syntax
CHAIN pathname
Argument
pathname should evaluate to the pathname of a valid BASIC file.
Notes
A filing system error may be produced if, for example, the file specified cannot be
found.
When the program is loaded, all existing variables are lost (except the system
integer variables and installed libraries).
Examples
CHAIN "partB"
CHAIN a$+"2"
249
CHR$
CHR$
Function returning the character corresponding to an ASCII code.
Syntax
CHR$ factor
Argument
An integer in the range 0 to 255.
Result
A single-character string whose ASCII code is the argument.
Examples
PRINT CHR$(code)
lower$=CHR$(ASC(upper$) OR &20)
250
Keywords
CIRCLE
Statement to draw a circle.
Syntax
CIRCLE [FILL] expression1,expression2,expression3
Arguments
The expressions are integers in the range –32768 to +32767. The first two values
give the x and y coordinates of the centre of the circle. The third gives the radius.
CIRCLE produces a circle outline, whereas CIRCLE FILL plots a solid circle. The
current graphics foreground colour and action are used.
Notes
In both cases, the position of the graphics cursor is updated to lie at a position on
the circumference which has an x coordinate of expression1 + expression3
and a y coordinate of expression2. The ‘previous graphics cursor’ position (as
used by, for example, triangle plotting) will be updated to lie at the centre of the
circle plotted.
Examples
CIRCLE 640,512,50
CIRCLE FILL RND(1278),RND(1022),RND(200)+50
251
CLEAR
CLEAR
Statement to remove all program variables.
Syntax
CLEAR
Purpose
When this statement is executed, all variables are removed and so become
undefined. In addition, any currently active procedures, subroutines, loops, and so
on are forgotten, and LIBRARY and OVERLAY libraries are lost. The exceptions to
this are the system integer variables and INSTALLed libraries which still remain.
252
Keywords
CLG
Statement to clear the graphics viewport to the graphics background colour, using
the graphics background action.
Syntax
CLG
Examples
CLG
MODE 1
GCOL 130
VDU 24,200;200;1080;824;
CLG
253
CLOSE#
CLOSE#
Statement to close an open file.
Syntax
CLOSE#factor
Argument
A channel number as returned by the OPENxx function. If zero is used all open files
on the current filing system are closed. Otherwise, only the file with the channel
number specified is closed.
Notes
You should not use the CLOSE#0 form within programs, as other programs may be
relying on files remaining open. You should only use it as an immediate command,
and possibly in a program during its development stage.
Purpose
Closing a file ensures that its contents are updated on whatever medium is being
used. This is necessary as a certain amount of buffering is used to make the
transfer of data between computer and mass-storage device more efficient. Closing
a file, therefore, releases a buffer for use by another file.
Examples
CLOSE#indexFile
CLOSE#0
254
Keywords
CLS
Statement to clear the text viewport to the text background colour.
Syntax
CLS
Notes
CLS also resets COUNT to zero and moves the text cursor to its home position,
which is normally the top left of the text window.
Examples
CLS
MODE “X640 Y480 C4”
COLOUR 129
VDU 28,4,28,35,4
CLS
255
COLOUR (COLOR)
COLOUR (COLOR)
Statement to set the text colours or alter the palette settings.
Syntax
(1) COLOUR expression [TINT expression]
(2) COLOUR expression,expression
(3) COLOUR expression,expression,expression
(4) COLOUR [OF expr,expr,expr] [ON expr,expr,expr]
(5) COLOUR [OF expr] [ON expr]
(6) COLOUR expr,expr,expr,expr[,expr]
Arguments (1)
expression is an integer in the range 0 to 255. The range 0 to 127 sets the text
foreground colour. Adding 128 to this (i.e. 128 to 255) sets the text background
colour. The colour is treated MOD the number of colours in the current mode. The
argument is the logical colour. For a list of the default logical colours, see the
chapter entitled Screen modes on page 107.
The optional TINT is only effective in VIDC1-style 256-colour modes. It selects the
amount of white to be added to the colour. The value can lie in the range 0 to 255,
with only the values 0, 64, 128 and 192 currently being used to obtain different
whiteness levels. Colours in VIDC1-style 256-colour modes are in the range 0 to 63.
Arguments (2)
The first expression is an integer in the range 0 to 15 giving the logical colour
number. The second expression is an integer in the range 0 to 15 giving the actual
colour to be displayed when the logical colour is used. The actual colour numbers
correspond to the default colours available in 16-colour modes: eight steady
colours and eight flashing colours. The colour list is given in the chapter entitled
Screen modes on page 107.
This form of the command sets the palette, so any changes are visible immediately.
Arguments (3)
The text foreground colour is set using the three expressions which are integers in
the range 0 to 255 giving the amount of red, green and blue. The actual colour
selected will be the closest colour available in the current mode and palette.
256
Keywords
Arguments (4)
The text foreground colour is set using the three expressions following OF, and the
text background colour is set using the three expressions following ON. In each
case the expressions are integers in the range 0 to 255 giving the amount of red,
green and blue, and either the ON or OFF part may be omitted. The actual colour
selected will be the closest colour available in the current mode and palette.
Arguments (5)
This form allows the foreground and/or background colour to be set using colour
numbers. The expression following OF is an integer giving the foreground colour
number, and the expression following ON is an integer giving the background
colour number.
Arguments (6)
This form of the command sets the palette. The first expression is an integer in the
range 0 to 255 giving the logical colour number. The next three expressions are
integers in the range 0 to 255 giving the amount of red, green and blue which are to
be assigned to that logical colour. The optional fifth expression is an integer in the
range 0 to 255 giving the supremacy value for this palette entry – this is used for
alpha blending, and is only supported on certain types of graphics hardware.
Notes
The keyword is listed as COLOUR in programs, even if it was typed in using the
alternative spelling.
In all modes the default state, before any changes to the palette, dictates that
colour 0 is black and colour 63 is white.
Only colours 0 and 1 are unique in two-colour modes. After that the cycle repeats.
Similarly, only colours 0, 1, 2 and 3 are distinct in the four-colour modes.
In Wimp-based programs, you should use the call Wimp_SetPalette to control
the palette.
Technical Details
(1) sets the colour and tint using VDU 17, for (3) and (4) the colour is set using
ColourTrans_SetTextColour, and for (5) OS_SetColour is used. (6) sets
the palette by using VDU 19 if it has four parameters and by using PaletteV with
reason code 2 if it has five.
257
COLOUR (COLOR)
History
(3) was added in version 1.06. (4) and (5) were added in version 1.34. The optional
fifth parameter for (6) was added in version 1.39.
Examples
COLOUR 128+1 : REM text background colour = 1
COLOUR 1,5 : REM logical colour 1 = colour 5 (magenta)
COLOUR 1,255,255,255 : REM logical colour 1 = white
258
Keywords
COS
Function returning the cosine of its numeric argument.
Syntax
COS factor
Argument
factor is an angle in radians.
Result
Real between –1 and +1 inclusive.
Notes
For BASIC V if the argument is outside the range –8388608 to +8388608 radians, it
is impossible to determine how many πs to subtract. The error Accuracy lost
in sine/cosine/tangent is generated. For BASIC VI the range is larger, from
approximately –6E9 to +6E9 radians, and outside this range the error Floating
point exception: invalid operation is generated.
Examples
PRINT COS(RAD(45))
adjacent = hypotenuse*COS(angle)
259
COUNT
COUNT
Function returning the number of characters printed since the last newline.
Syntax
COUNT
Result
Positive integer, giving the number of characters output since the last newline was
generated by BASIC.
Notes
COUNT is reset to zero every time a carriage return is printed (which may happen
automatically if a non-zero WIDTH is being used). It is incremented every time a
character is output by PRINT, INPUT or REPORT, but not when output by VDU or
any of the graphics commands. COUNT is also reset to zero by CLS and MODE.
Examples
REPEAT PRINT " ";
UNTIL COUNT=20
chars = COUNT
260
Keywords
CRUNCH
Command to strip various spaces from a program.
Syntax
CRUNCH expression
Argument
expression is an integer in which the lowest 5-bits are significant:
Bit Meaning
0 strips out all spaces before statements.
1 strips out all spaces within statements.
2 strips out all REM statements, except those on the first line.
3 strips out all empty statements.
4 strips out all empty lines.
Notes
The interpreter has been optimised for fully CRUNCHed programs.
CRUNCH %10 may make a program uneditable.
If the system variable BASIC$Crunch exists with any value, programs run with
-quit set will be automatically CRUNCHed with CRUNCH %1111, as will LIBRARY
subprograms. OVERLAY libraries will not be CRUNCHed.
Examples
CRUNCH %1101
CRUNCH %10011
261
DATA
DATA
Passive statement marking the position of data in the program.
Syntax
DATA [expression][,expression], etc
Arguments
The expressions may be of any type and range, and are only evaluated when a
READ statement requires them.
Notes
The way in which DATA is interpreted depends on the type of variable in the READ
statement. A numeric READ evaluates the data as an expression, whereas a string
READ treats the data as a literal string. Leading spaces in the data item are
ignored, but trailing spaces (except for the last data item on the line) are counted.
If it is necessary to have leading spaces, or a comma or quote in the data item, it
must be put between quotation marks. For example:
100 DATA " HI","A,B,", """ABCD"
If an attempt is made to execute a DATA statement, BASIC treats it as a REM. In
order to be recognised by BASIC, the DATA statement, like other passive
statements, should be the first item on a line.
Items in a DATA statement are not tokenised so, for example, PI/2 will generate an
error if used with a numeric READ. Read the item as a string and use EVAL to get
the numeric value.
Examples
DATA Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
DATA 3.26,4,4.3,0
262
Keywords
DEF
Passive statement defining a function or procedure.
Syntax
(1) DEF FNproc-part
(2) DEF PROCproc-part
where proc-part has the form identifier[(parameter-list)].
The optional parameters, which must be enclosed between round brackets and
separated by commas, may be of any type. For example: parm, parm%, parm$. Any
parameter may be preceded by RETURN to use value-result passing instead of
simple value passing. In addition, whole arrays may be passed as parameters, e.g.
a(), a$().
Purpose
The DEF statement marks the first line of a user-defined function or procedure, and
also indicates which parameters are required and their types. The parameters are
local to the function or procedure (except for arrays), and are used within it to
stand for the values of the actual parameters used when it was called.
Notes
Function and procedure definitions should be placed at the end of the program, so
that they cannot be executed except when called by the appropriate PROC
statement or FN function. The DEF statement should be the first item on the line.
If not, it will not be found.
Examples
DEF FNmean(a,b)
DEF PROCinit
DEF PROCthrow_dice(d%,tries,RETURN mesg$)
DEF PROCarray_determinant(A())
263
DEG
DEG
Function returning the number of degrees of its radian argument.
Syntax
DEG factor
Argument
Any numeric value.
Result
A real equal to 180*n/π where n is the argument’s value.
Examples
angle=DEG(ATN(a))
PRINT DEG(PI/4)
264
Keywords
DELETE
Command to delete a section of the program.
Syntax
DELETE integer, integer
Arguments
Integer constants in the range zero to 65279. They give the first and last line to be
deleted respectively. If the first line number is greater than the second, no lines are
deleted. To delete just a single line the DELETE command is not necessary. Instead
type the line number and press Return.
Examples
DELETE 5,22
DELETE 110,150
265
DIM
DIM
Statement declaring arrays or reserving storage.
Function returning information about an array.
Syntax
DIM dim-part [,dim-part] etc
where dim-part is:
(1) identifier[% or $](expression[,expression] etc)
or
(2) numeric-variable expression
(3) numeric-variable LOCAL expression
or as a function:
(4) DIM(array)
(5) DIM(array,expression)
Argument (1)
The identifier can be any real, integer or string variable name. The expressions
are integers which should be greater than or equal to zero. They declare the upper
bound of the subscripts; the lower bound is always zero.
This is the way to declare arrays in BASIC. They may be multi-dimensional: the
bounds are limited by the amount of memory available to BASIC, with an absolute
maximum total elements in all dimensions of 16,777,215 (&FFFFFE). Numeric
arrays are initialised to zeros and string arrays to null strings.
Arguments (2)
The numeric-variable is any integer or real name. It is always global, even if it
is declared locally. The expression gives the number of bytes of storage required
minus one, and should be –1 or greater. It is limited only by the amount of free
memory.
The use of this form of DIM is to reserve a given number of bytes of memory, in
which to put for example, machine code. The address of the first byte reserved,
which will be a multiple of four, is placed in the numeric-variable. The byte
array is uninitialised.
266
Keywords
Argument (3)
The numeric-variable is any integer or real name, and should be a local
variable. The expression gives the number of bytes of storage required minus
one, and should be –1 or greater. It is limited only by the amount of free memory.
This form of DIM reserves a given number of bytes of memory on BASIC’s stack so
that it can be used temporarily within a procedure or function. The memory is
uninitialised, and is released when the procedure or function exits, so be careful
not to store the returned address in a global variable and attempt to use it after the
procedure or function exits.
If the expression is –1 no memory is allocated and the numeric-variable is
set to be the value of the BASIC stack pointer at the time of the request. Together
with the value returned by END or DIM –1 (see above), this can be useful for
computing the free space between the top of the BASIC heap and the bottom of the
BASIC stack.
Note: The stack cannot be moved while there are DIM LOCALs defined. This
means that END= will return an error and any Service_Memory calls will be
claimed.
Argument (4)
The array is the name of any previously DIMed array, or an array used as a formal
parameter in a procedure or function.
Result (4)
The result of the function is the number of dimensions which that array has.
Argument (5)
The array is the name of any previously DIMed array or an array used as a formal
parameter in a procedure or function. The expression is a number between one and
the number of dimensions of the array.
Result (5)
The result of the function is the subscript of the highest element in that dimension,
i.e. the value used for that subscript in the DIM statement that declared the array in
the first place.
267
DIM
Notes
It is possible to have local arrays, whose contents are discarded when the
procedure or function in which they are created returns. See LOCAL on page 326.
History
(3) was added in version 1.34.
Examples
DIM name$(num_names%)
DIM sin(90)
DIM matrix%(4,4)
DIM A(64), B%(12,4), C$(2,8,3)
DIM bytes% size*10+overhead
LOCAL ptr%:DIM ptr% LOCAL size%
PRINT DIM(name$())
size%=DIM(name$(),1)
268
Keywords
DIV
Operator performing integer division.
Syntax
factor DIV factor
Arguments
Integer-range numerics. Reals are converted to integers before the divide
operation is carried out. The righthand side must not evaluate to zero.
Result
The (integer) quotient of the arguments is always rounded towards zero. If the
signs of the arguments are the same, the quotient is positive, otherwise it is
negative. The remainder can be found using MOD.
Examples
PRINT (first-last) DIV 10
a%=space% DIV &100
269
DRAW
DRAW
Statement to draw a line to specified coordinates.
Syntax
DRAW [BY] expression,expression
Arguments
The two expressions give the coordinates of one of the end points of a straight line.
The other end point is given by the current graphics cursor position. After the line
has been drawn (using the graphics foreground colour and action), the graphics
cursor is updated to the coordinates given in the DRAW statement.
If the keyword BY is omitted, the coordinates are absolute. That is, they give the
position of the end of the line with respect to the graphics origin. If BY is included,
the coordinates are relative. That means they give the position of the end of the
line with respect to the current graphics cursor position.
Examples
DRAW 640,512 : REM Draw a line to middle of the screen
DRAW BY dx%, dy%
270
Keywords
EDIT
Command to enter the BASIC screen editor.
Syntax
EDIT
Purpose
EDIT enters the BASIC screen editor to allow you to create a new program or
amend the current one. Full details of the editor are given in the chapter entitled
Editing BASIC files on page 191.
271
ELLIPSE
ELLIPSE
Statement to draw an ellipse.
Syntax
ELLIPSE [FILL] expr1,expr2,expr3,expr4[,expr5]
Arguments
expr1 to expr5 are integer expressions. The first two give the coordinates of the
centre of the ellipse. The third expression gives the length of the semi-major axis.
This is the axis parallel with the x axis if the ellipse is not rotated. The fourth
expression gives the length of the semi-minor axis. This is the axis parallel with the
y axis if the ellipse is not rotated.
The optional fifth expression gives the rotation of the ellipse, in radians,
anti-clockwise.
ELLIPSE draws the outline of an ellipse. ELLIPSE FILL plots a solid ellipse.
Notes
The ELLIPSE statement has some (minor) restrictions about the size of its
arguments: if both of the semi-axes are of length zero, then you are not allowed to
specify a rotation value. If the semi-minor axis length is zero, then the rotation, if
specified, must not be zero. The result of trying to draw any of these ‘illegal’
ellipses is a Division by zero error.
Examples
ELLIPSE 640,512,200,100
ELLIPSE FILL x%,y%,major%,minor%,ang
272
Keywords
ELSE
Part of the ON … GOTO/GOSUB/PROC … ELSE or IF … THEN … ELSE or IF …
THEN … ELSE … ENDIF constructs.
Syntax
See IF and ON entries, as appropriate.
Notes
ELSE may occur anywhere in the program, but is only meaningful after an IF
(multi- or single-line) or ON … GOSUB/GOTO/PROC statement. When used as part
of a multi-line IF statement, it must be the first non-space object on the line.
Examples
IF a=b THEN PRINT "hello" ELSE PRINT "good-bye"
IF ok ELSE PRINT "Error"
ON choice GOSUB 100,200,300,400 ELSE PRINT"Bad choice"
IF num>=0 THEN
PRINT SQR(num)
ELSE
PRINT "Negative number"
PRINT SQR(-num)
ENDIF
273
END
END
Statement terminating the execution of a program.
Statement setting the highest address used by BASIC.
Function returning the address of the end of the BASIC heap.
Syntax
as a statement:
(1) END
(2) END = expression
as a function:
(3) END
Purpose (1)
The END statement terminates the execution of a program.
Note: This statement is not always necessary in programs; execution stops
when the line at the end of the program is executed. However, END (or STOP)
must be included if execution is to end at a point other than at the last
program line. This prevents control falling through into a procedure, function
or subroutine. END is also useful in error handlers.
Purpose (2)
When used in a assignment, END sets the highest address used by BASIC when
running under the Wimp. This can be used by programs running under the Wimp to
claim more memory from the free pool, or alternatively to give up unrequired
memory.
The expression should be an integer giving the new value for HIMEM. After the
call, memory above the given address will be de-allocated and HIMEM will be set
to that location. In addition, local arrays and installed libraries are cleared.
274
Keywords
Purpose (3)
The END function returns the address of the end of the BASIC heap and the start of
free user memory. The expression END–TOP gives the number of bytes used by the
BASIC heap.
Examples
PRINT END
END = &10000 : REM only need 32K to RUN
275
ENDCASE
ENDCASE
Statement marking the end of a CASE … OF … WHEN … OTHERWISE …
ENDCASE construct.
Syntax
ENDCASE
Notes
ENDCASE must be the first non-space object on the line. When the statements
corresponding to a WHEN or OTHERWISE statement have been executed, control
then jumps to the statement following the ENDCASE. If ENDCASE itself is
executed, it signals the end of the CASE statement, no matches having been made.
Control then continues as normal.
276
Keywords
ENDIF
Statement terminating an IF … THEN … ELSE … ENDIF construct.
Syntax
ENDIF
Notes
ENDIF marks the end of a block-structured IF statement. It must be the first
non-space object on a line. When the statements corresponding to the THEN or
ELSE statement have been executed, control jumps to the statement following the
ENDIF. If ENDIF itself is executed, it signals the end of the IF statement, nothing
having been executed as a result of it. Control then continues as normal.
277
ENDPROC
ENDPROC
Statement marking the end of a user-defined procedure.
Syntax
ENDPROC
Purpose
When executed, an ENDPROC statement causes BASIC to terminate the execution
of the current procedure and to restore local variables and actual parameters. Any
LOCAL DATA and LOCAL ERROR statements that have not been closed with
RESTORE DATA or RESTORE ERROR will be restored. Local arrays and blocks of
memory allocated with DIM ... LOCAL will be deleted. Any unclosed FOR ... NEXT,
REPEAT ...UNTIL or WHILE ... ENDWHILE loops will be closed. Control is passed
to the statement after the PROC which called the procedure.
ENDPROC should only be used in a procedure. Otherwise, when it is encountered,
a Not in a procedure error message is generated.
Examples
ENDPROC
IF a<=0 THEN ENDPROC ELSE PROCrecurse(a-1)
278
Keywords
ENDWHILE
Statement to terminate a WHILE … ENDWHILE loop.
Syntax
ENDWHILE
Notes
When an ENDWHILE is executed, control loops back to the corresponding WHILE
statement. The statements forming the WHILE … ENDWHILE loop are executed
until the condition following the matching WHILE evaluates to FALSE, whereupon
control jumps to the statement following the ENDWHILE.
Example
MODE “X640 Y480 C256”
INPUT X
WHILE X > 0
GCOL X
CIRCLE FILL 640,480,X
X -= 4
ENDWHILE
279
ENVELOPE
ENVELOPE
Statement used with the SOUND statement to control the volume and pitch of a
sound while it is playing.
Note: Standard RISC OS does not support the ENVELOPE command so it will
have no effect unless a module that provides support for it is loaded.
Syntax
ENVELOPE expr1,expr2,expr3,expr4,expr5,expr6,expr7,expr8,
expr9,expr10,expr11,expr12,expr13,expr14
Arguments
expr1 is the envelope number
expr2 is the length of each step and repeat flag
expr3 is the change of pitch per step in section 1
expr4 is the change of pitch per step in section 2
expr5 is the change of pitch per step in section 3
expr6 is the number of steps in section 1
expr7 is the number of steps in section 2
expr8 is the number of steps in section 3
expr9 is the attack rate (change of amplitude per step in the attack phase)
expr10 is the decay rate (change of amplitude per step in the decay phase)
expr11 is the sustain rate (change of amplitude per step in the sustain phase)
expr12 is the release rate (change of amplitude per step in the release phase)
expr13 is the attack phase target level
expr14 is the decay phase target level
Envelope number
An integer in the range 1 to 16 which specifies the envelope number that is to be
defined.
Length of each step and repeat flag
This is an integer in the range 1 to 127 that determines the length in centi-seconds
of each step of the pitch and amplitude envelopes. The pitch envelope normally
auto-repeats but this can be suppressed by adding 128 to the value of this
argument (setting bit 7).
Change of pitch per step
Number of steps
These parameters determine the pitch envelope. The pitch envelope has three
sections and each section is specified with two parameters; the increment which is
280
Keywords
an integer in the range -128 to 127, and the number of times the increment is
applied during that section, that is the number of steps, which is an integer in the
range 0 to 255.
Change of amplitude per step
Target levels
These parameters determine the amplitude envelope. The shape of the amplitude
envelope is defined in terms of rates (increments) between levels, and is an
extended form of the standard ADSR (attack, decay, sustain, release) system of
envelope control. The envelope starts at zero and then climbs at the attack rate (an
integer between -127 and 127) until it reaches the attack phase target level (an integer
in the range 0 to 126). It then climbs or falls at the decay rate (an integer between
-127 and 127) until it reaches the decay phase target level (an integer in the range 0 to
126). However, if the decay rate is zero the amplitude will stay at the attack phase target
level for the duration of the sound.
The envelope then enters the sustain phase which lasts for the remaining duration
of the sound. The duration is set by the SOUND statement. During the sustain
phase the amplitude will remain the same or fall at the sustain rate (an integer
between -127 and 0).
At the end of the sustain phase the note will be terminated if there is another note
waiting to be played on the selected channel. If no note is waiting then the
amplitude will decay at the release rate (an integer between -127 and 0) until the
amplitude reaches zero. If the release rate is zero then the note will continue
indefinitely, with the pitch envelope auto-repeating if bit 7 of the second parameter
is zero.
Technical details
The ENVELOPE command calls OS_Word 8. For the ENVELOPE command to have
any effect a module that implements OS_Word 8 must be loaded.
Example
ENVELOPE 1,1,4,-4,4,10,20,10,127,0,0,-5,126,126
SOUND 1,1,100,200
281
EOF#
EOF#
Function returning whether the end of a file has been reached.
Syntax
EOF#factor
Argument
A channel number returned by an OPENxx function.
Result
TRUE if the last character in the specified file has been read, FALSE otherwise. EOF
for a file may be reset by positioning its pointer using the PTR# statement.
Examples
REPEAT
VDU BGET#file
UNTIL EOF#file
282
Keywords
EOR
Operator performing bitwise exclusive-OR (EOR).
Syntax
relational EOR relational
Arguments
Relational expressions, or bit values to be EORed.
Result
The logical bitwise EOR of the arguments. Corresponding bits in the arguments are
EORed to produce the result. Each bit in the result is zero if the corresponding bits
in the arguments are equal, and otherwise one.
Examples
PRINT height>10 EOR weight<20
bits = mask EOR value1
283
ERL
ERL
Function returning the last error line.
Syntax
ERL
Result
Integer between 0 and 65279. This is the line number of the last error to occur. An
error line of 0 implies that the error happened in immediate mode or that there has
not been an error. If an error occurs inside a procedure or function in a library, ERL
is set to the line number in the library where the error occurred.
Examples
REPORT : IF ERL<>0 THEN PRINT " at line "; ERL
IF ERL=3245 PRINT "Bad function, try again"
284
Keywords
ERR
Function returning the last error number.
Syntax
ERR
Result
A signed integer. Errors produced by BASIC are in the range 0 to 127.
Notes
The error number 0 is classed as a fatal error and cannot be trapped by the
ON ERROR statement. An example of a fatal error is that produced when a BASIC
STOP statement is executed.
Examples
IF ERR=18 THEN PRINT "Can't use zero; try again!!"
IF ERR=17 THEN PRINT"Sure?":A$=GET$:IF INSTR("Yy",A$) THEN
STOP
285
ERROR
ERROR
Statement generating an error, or part of the ON ERROR statement.
Syntax
(1) ON ERROR ...
(2) ERROR [EXT] numeric-expression, string-expression
Purpose (1):
See ON ERROR on page 348 for details of the error handling statements.
Arguments (2)
numeric-expression evaluates to a four-byte signed integer corresponding to
an error number. string-expression evaluates to a string associated with this
error number. The error described is generated, in the same way as internal BASIC
errors, so ERL will be set to the current line, ERR set to numeric-expression
and REPORT$ set to string-expression. The current error handler will then
be called, unless the error number is zero, in which case a fatal (untrappable) error
will be generated.
If the keyword EXT is present, then BASIC terminates and the error number and
string are passed to the error handler of the program that invoked BASIC. The
default BASIC error handler uses this if the -quit option was given on the
command line.
Examples
ERROR 6, "Type mismatch: number needed"
ERROR EXT ERR,REPORT$ : REM pass on the error
286
Keywords
EVAL
Function which evaluates a string statement as an expression.
Syntax
EVAL factor
Argument
A string which EVAL evaluates as a BASIC expression.
Result
EVAL can return anything that could appear on the righthand side of an
assignment statement, including strings. It can also produce the same errors that
occur during assignment. For example:
Type mismatch: number needed
and
No such function/procedure.
Examples
INPUT hex$
PRINT EVAL("&"+hex$)
f$="LEFT$("
e$=EVAL(f$+"""ABCDE""",2)")
287
EXP
EXP
Function returning the exponential of its argument.
Syntax
EXP factor
Argument
Numeric, which for BASIC V can range from the largest negative real (about 1.7E38)
to approximately +88, and for BASIC VI can range from the largest negative real
(about 1.7E308) to approximately +709.7.
Result
Positive real in the range zero to the largest positive real (about 1.7E38 for BASIC V
or 1.7E308 for BASIC VI). The result is e raised to the power of the argument, where
e is the constant 2.718281828, the base of natural logarithms.
Notes
EXP is the inverse of LN.
Example
DEF FNcosh(x)=(EXP(x) + EXP(-x))/2
288
Keywords
EXT#
Pseudo-variable returning or setting the length (extent) of an open file.
Syntax
(1) EXT#factor
(2) EXT#factor=expression
Argument (1)
factor is a channel number, as allocated by one of the OPENxx functions.
Result
Integer giving the current length of the file from 0 to, in theory 2147483648,
although in practice the extent is limited by the file medium in use.
Argument (2)
factor is a channel number as allocated by one of the OPENxx functions.
expression is the desired extent of the file, whose upper limit depends on the
filing system. The lower limit is 0. The main use of the statement is to shorten a file.
For example: EXT#file=EXT#file-&1000. A file may be lengthened by
explicitly using PTR#, or implicitly by BPUTing to its end.
Notes
As with all the pseudo-variables, the LET keyword and the operators += and –=
cannot be used with EXT#.
EXT is also used a part of the ERROR EXT ... statement; see the ERROR keyword
for details.
Examples
IF EXT#file>90000 THEN PRINT "File full":CLOSE#file
EXT#op=EXT#op+&2000
289
FALSE
FALSE
Function returning the logical value FALSE.
Syntax
FALSE
Result
The constant zero. The function is used mnemonically in logical or conditional
expressions.
Examples
flag=FALSE
REPEAT
CIRCLE RND(1279),RND(1024),RND(200)
UNTIL FALSE
290
Keywords
FILL
Statement flood-filling an area in the current foreground colour.
Syntax
FILL [BY] expression,expression
Arguments
The two expressions give the coordinates of the point from which the flood-fill is to
commence (the ‘seed’ point). The filled pixels are plotted using the current
foreground colour and action over an area bounded by non-background colour
pixels and the graphics viewport. If the seed point is in a non-background colour,
then no filling takes place at all.
The graphics cursor is updated to the coordinates given,
If the keyword BY is omitted, the coordinates are absolute. That is, they give the
position of the seed point with respect to the graphics origin. If BY is included, the
coordinates are relative. That means they give the position of the seed point with
respect to the current graphics cursor position.
Examples
FILL x%,y%
FILL BY dx%,dy%
291
FN
FN
Statement introducing or calling a user-defined function.
Syntax
(1) DEF FNproc-part
(2) FNproc-part
Argument (1)
For the format of proc-part, see DEF above. It gives the names and types of the
parameters of the function, if any. For example:
1000 DEF FNmin(a%,b%) IF a%<b% THEN =a% ELSE =b%
a% and b% are the formal parameters. They stand for the expressions passed to the
function (the actual parameters) when FNmin is called. The result of a user-defined
function is given by a statement starting with =. As the example above shows, there
may be more than one = in a function. The first one which is encountered during
execution terminates the function.
Argument (2)
proc-part is an identifier followed by a list of expressions (or array or RETURN
variables) corresponding to the formal parameters in the DEF statement for the
function. The result depends on the assignment that terminated the function, and
so can be of any type and range. An example function call is:
PRINT FNmin(2*bananas%, 3*apples%+1)
Notes
User-defined functions may span several program lines, and contain all the normal
BASIC statements. They may also declare local variables using the LOCAL
keyword. When a function terminates any LOCAL DATA and LOCAL ERROR
statements that have not been closed with RESTORE DATA or RESTORE ERROR
will be restored, local arrays and blocks of memory allocated with DIM ... LOCAL
will be deleted and any unclosed FOR, REPEAT or WHILE loops will be closed.
Examples
DEF FNfact(n%) IF n%<1 THEN =1 ELSE =n%*FNfact(n%-1)
DEF FNhex4(n%)=RIGHT$("000"+STR$~(n%),4)
REPEAT PRINT FNhex4(GET): UNTIL FALSE
292
Keywords
FOR
Part of the FOR … NEXT statement.
Syntax
FOR variable=expression TO expression [STEP expression]
Arguments
The variable can be any numeric variable reference. The expressions can be any
numeric expressions, though they must lie in the integer range if the variable is an
integer one. It is recommended that integer looping variables are used for the
following reasons:
● the loops go faster
● rounding errors are avoided.
If the STEP part is omitted, the step is taken to be +1. The action of the FOR loop is
as follows. The looping variable is set to the first expression. The limit expression
and step, if present, are remembered for later. The statements up to the matching
NEXT are executed. At this stage, the step is added to the looping variable. The
termination condition is that, for positive steps, the looping variable has become
greater than the limit, and for negative steps it has become less than the limit. If
this condition is met, control continues at the statement after the NEXT.
Otherwise, control jumps back to the statement after the FOR statement.
Notes
The statements between a FOR and its corresponding NEXT are executed at least
once as the test for loop termination is performed at the NEXT rather than the
FOR. Thus a loop started with FOR I=1 TO 0 executes once, with I set to 1 in the
body of the loop. The value of the looping variable when the loop has finished
should be treated as undefined, and should not be used before being reset by an
assignment.
Examples
FOR addr%=200 TO 8000 STEP 4
FOR I=1 TO LEN(a$)
293
GCOL
GCOL
Statement to set the graphics colours and actions.
Syntax
(1) GCOL [expression1,]expression2 [TINT expression3]
(2) GCOL [OF [expr1,]expr2] [ON [expr3,]expr4]
(3) GCOL [expr,]expr,expr,expr
(4) GCOL [OF [expr,]expr,expr,expr] [ON [expr,]expr,expr,
expr]
Arguments (1)
GCOL sets the colour and plot mode that will be used in subsequent graphics
operations.
expression1, if present, is an integer between 0 and 255 which determines the
plot ‘action’, i.e. how the graphics colour, expression2, will be combined with
what’s on the screen when plotting points, lines, etc. Its basic range is 0 to 7, as
shown below:
Action Meaning
0 Store the colour expression2 on the screen
1 OR the colour on the screen with expression2
2 AND the colour on the screen with expression2
3 EOR the colour on the screen with expression2
4 Invert the current colour, disregarding expression2
5 Do not affect the screen at all
6 AND the colour on the screen with the NOT expression2
7 OR the colour on the screen with the NOT expression2
Although action 5 does not actually alter the screen, each pixel is accessed as
though the operation was taking place, so it is no quicker than the other actions.
If you add n*16 to the action number, then colour patterns are used instead of
solid colours. n is in the range 1 to 4 for the four basic patterns, or 5 for a large
pattern made from the other four placed side by side. VDU 23,2 to VDU 23,5 are
used to set the colour fill patterns. If the currently selected pattern is re-defined, it
becomes active immediately.
If you further add 8 to the action, then where the colour pattern contains the
current graphics background colour, nothing is plotted, i.e. that colour becomes
transparent. For example, suppose the display is a four-colour one, and the current
background colour is 129 (red).
294
Keywords
Now, if pattern 1 was selected as the foreground colour (GCOL 16,0), a solid
rectangle would be red-yellow, as pattern 1 consists of alternating red and yellow
pixels. However, if the foreground colour was set using GCOL 24,0 (adding 8 to
the plot action number), then a solid rectangle would appear yellow, with
transparent ‘holes’ where the red pixels would have been plotted.
Adding 8 to the action also causes sprite plotting to use the transparency mask, if
present. See the chapter entitled Sprites on page 151 for more details.
If expression1 is omitted, 0 is used, which means that the colour given is stored
onto the screen.
The colour number, expression2, is in the range 0 to 255. Values below 128 are
used to set the graphics foreground colour. Other values set the background
colour. For example, colour 129 sets the background colour to 129-128, or 1. The
number is treated MOD the number of colours in the current mode, i.e. 2, 4, 16 or
64. Thus in 256-colour modes, the colour range is 0 to 63 (or 128 to 191 for
background).
The TINT value, if present, is used to add one of four whiteness levels to the 64
colours available in VIDC1-compatible 256-colour modes, giving the total 256
possible hues. expression3 is in the range 0 to 255, where currently the only
significant levels are 0, 64, 128 and 192.
Note: Wimp-based programs should use Wimp_SetColour or
ColourTrans_ReturnGCOL, not GCOL.
Arguments (2)
The parameters following OF are used to set the graphics foreground colour and
those following ON are used to set the graphics background colour. expr1 and
expr3, if specified are the plot ‘action’ as described above and expr2 and expr4
are colour numbers
Arguments (3)
The graphics foreground colour is set using the three expressions which are
integers in the range 0 to 255 giving the amount of red, green and blue. The actual
colour selected will be the closest colour available in the current mode and
palette.
Arguments (4)
The graphics foreground colour is set using the three expressions following OF, and
the graphics background colour is set using the three expressions following ON. In
each case the expressions are integers in the range 0 to 255 giving the amount of
295
GCOL
red, green and blue, and either the ON or OF part may be omitted. The actual
colour selected will be the closest colour available in the current mode and
palette.
Technical Details
(1) uses VDU 18, (2) uses OS_SetColour, (3) and (4) use
ColourTrans_SetGCOL.
History
(3) was added in version 1.06. (2) and (4) were added in version 1.34.
Examples
GCOL 2
DRAW 100,100 : REM Draw a line in colour 2
GCOL 4,128
CLG : REM Invert the graphics window
GCOL 1,2 : REM OR the screen with colour 2
GCOL 18 TINT 128
296
Keywords
GET
Function returning a character code from the input stream (e.g. keyboard, serial
port, etc).
Syntax
GET
Result
An integer between 0 and 255. This is the ASCII code of the next character in the
buffer of the currently selected input stream (keyboard or serial port). The function
will not return until a character is available, and so it can be used to halt the
program temporarily.
Notes
The character entered is not echoed onto the screen. To make it appear you must
explicitly PRINT it.
Examples
PRINT "Press space to continue" :REPEAT UNTIL GET=32
ON GET-127 PROCa, PROCb, PROCc ELSE PRINT "Illegal entry"
297
GET$#
GET$#
Function returning a string from a file.
Syntax
GET$#factor
Argument
A channel number returned by an OPENxx function.
Result
A string of characters read until a linefeed (ASCII 10), carriage return (ASCII 13) or
the end of the file is encountered, or else the maximum of 255 characters is
reached. The terminating character is not returned as part of the string.
Notes
PTR# is updated to point to the next character in the file. If the last character in the
file has been read, EOF# for the channel will be TRUE.
Examples
string$ = GET$#channel
PRINT GET$#fileno
298
Keywords
GET$
Function returning a character from the input stream (e.g. keyboard).
Syntax
GET$
Result
A one-character string whose value would be CHR$(GET) if GET had been called
instead. This is provided so you can use statements like IF GET$="*"… rather
than IF CHR$(GET)="*".
Examples
PRINT "Do you want another game?":response$ = GET$
IF response$ = "Y" or response$ = "y" CHAIN "program"
PRINT "Input a digit "; : PRINT GET$
299
GOSUB
GOSUB
Statement to call a subroutine.
Syntax
(1) GOSUB expression
(2) ON expression GOSUB expr1 [,expr2...] [ELSE statement]
Argument (1)
expression should evaluate to an integer between 0 and 65279, in other words a
line number. If the expression is not a simple integer (e.g. 1030) it should be
enclosed between round brackets. The line given is jumped to, and control is
returned to the statement after the GOSUB by the next RETURN statement.
Argument (2)
expression should evaluate to an integer. If this integer is n then the nth
subroutine listed after the GOSUB is jumped to. If the integer is less than 1 or
greater than the number of line numbers given, the statement following the ELSE,
if it is present, is executed.
Notes
Procedures should be used in preference to subroutines since they are more
flexible and produce a better structured program.
The line number after GOSUB should be a constant so that RENUMBER works
properly.
Examples
10 GOSUB 2000
20 GOSUB (2300+20*opt): REM not nice
30 ON x% GOSUB 100,200,300 ELSE PRINT "Out of range"
300
Keywords
GOTO
Statement to transfer control to another line.
Syntax
(1) GOTO expression
(2) ON expression GOTO expr1 [,expr2...][ELSE statement]
Argument (1)
expression should evaluate to an integer between 0 and 65279: a line number. If
the expression is not a simple integer, it should be placed between round brackets.
This line number is jumped to and execution carries on from this new line.
Arguments (2)
expression should evaluate to an integer. expr1… should evaluate to integer
line numbers between 0 and 65279. If the first integer is n then the nth line after the
GOTO is jumped to. If the integer is less than 1 or greater than the number of line
numbers given, the statement following the ELSE, if it is present, is executed.
Notes
The line number after GOTO should be a constant so that RENUMBER and
APPEND work properly.
Examples
GOTO 230
IF TIME<1000 THEN GOTO 1000
ON x GOTO 20,50,30,160
301
HELP
HELP
Command giving help information.
Syntax
HELP [keyword]
Purpose
HELP displays a list of useful information about the status of BASIC. If the
keyword is present, help about that particular command, statement or function is
printed. In addition, HELP . prints a list of all keywords, HELP followed by a single
letter prints all the keywords beginning with that letter, and HELP [ prints help for
the BASIC assembler.
Examples
HELP
HELP HIM.
HELP .
HELP [
302
Keywords
HIMEM
Pseudo-variable holding address of the top of the BASIC stack.
Syntax
(1) HIMEM
(2) HIMEM = expression
Result (1)
An integer giving the address of the location above the end of user memory. The
amount of user memory is given by HIMEM - LOMEM and the amount of free
memory by HIMEM - END.
Argument (2)
expression should be an integer between LOMEM and the top of usable
memory. It restricts the amount of memory which the current program can use for
workspace stacks etc, hence giving an area where data, or machine code routines
can be stored.
Notes
If HIMEM is set carelessly, running the program may produce the No room error.
There must always be enough for the stack.
The INSTALL statement lowers HIMEM by the size of the library being installed.
When an attempt is made to set HIMEM, LOMEM, or PAGE to an illegal value, a
warning message is displayed, and no change is made, but the program
nevertheless continues to run. This means that such errors cannot be trapped
using ON ERROR.
Examples
PRINT "Memory available = ";HIMEM - LOMEM
a%=HIMEM-1000 : HIMEM=a%
303
IF
IF
Statement to execute statements conditionally.
Syntax
(1)
IF expr [THEN] [statements...]
[[ELSE][statements...]]
(2)
IF expression THEN
[statements...]
[ELSE [statements...]
statements...]
ENDIF
Arguments (1)
expr is treated as a truth value. If it is non-zero, it is counted as TRUE and any
statements in the THEN part are executed. If the expression evaluates to zero
(FALSE), then the ELSE part statements are executed.
statements is either a list of zero or more statements separated by colons, or a
line number. In the latter case there is an implied GOTO after the THEN (which has
to be present) or ELSE.
Note: The THEN is optional before statements except before * commands. For
example:
IF a THEN *CAT
not
IF a *CAT
The ELSE part matches any IF, so be wary of nesting IFs on a line. Constructs of
the form:
IF a THEN... IF b THEN... ELSE...
should be avoided because the ELSE part might match either the first or
second IF depending on the values of a and b. To avoid the ambiguity, use a
multi-line IF of the form:
304
Keywords
IF a THEN IF a THEN
IF b THEN IF b THEN
... ...
ELSE or ENDIF
... ELSE REM part of IF a
ENDIF ...
ENDIF ENDIF
depending on the effect required.
However, the form:
IF a THEN... ELSE IF b THEN...
is not ambiguous and can be used with no problems.
Arguments (2)
expression is treated as a truth value. If it is non-zero, it is counted as TRUE and
any statements on the line after the THEN down to either an ELSE or an ENDIF are
executed. If the expression evaluates to zero (FALSE), any statements following the
ELSE (if present) until the ENDIF are executed. Note that in this form, THEN must
be the last thing on the line.
Examples
IF temp<=10 PROClow_temp
IF a%>b% THEN SWAP a%, b% ELSE PRINT "No swap"
IF B^2 >= 4*A*C THEN
PROCroots(A,B,C)
ENDIF
IF r$ = "Y" OR r$ = "y" THEN
PRINT "YES"
ELSE
PRINT "NO"
STOP
ENDIF
305
INKEY
INKEY
Function returning a character code from the current input stream with time limit.
Function returning the operating system version.
Function interrogating the keyboard.
Syntax
(1) INKEY positive-factor
(2) INKEY -256
(3) INKEY negative-factor (where bit 7 is set)
(4) INKEY negative-factor (where bit 7 is clear)
Argument (1)
An integer in the range 0 to 32767, which is a time limit in centi-seconds.
Result (1)
The ASCII code of the next character in the current input buffer if one appears in
the time limit set by the argument, or –1 if a time-out occurs.
Argument (2)
–256
Result (2)
A number indicating which version of the operating system is in the computer.
Value Version Value Version
&A0 Arthur 1.20 &A6 RISC OS 3.60
&A1 RISC OS 2.00 &A7 RISC OS 3.70/3.71
&A2 RISC OS 2.01 &A8 RISC OS 3.80/4.0x
&A3 RISC OS 3.00 &A9 RISC OS 4 Select
&A4 RISC OS 3.10/3.11 &AA RISC OS 5.xx
&A5 RISC OS 3.50
Argument (3)
A negative integer where bit 7 is set, i.e. (negative-factor AND 128)=128.
This is the negative INKEY code of the key being interrogated (see Appendix D –
INKEY values on page 469 for details).
306
Keywords
Result (3)
TRUE if the key is being pressed at the time of the call, FALSE if it is not.
Argument (4)
A negative integer, other than –256, where bit 7 is clear, i.e. (negative-factor
AND 128)=0. This is the negative INKEY code of a key (see Appendix D – INKEY
values on page 469) with 128 subtracted from it. Keys with negative INKEY codes
less than or equal to negative-factor+128 will be interrogated.
Result (4)
255 if no key from the specified range is being pressed, otherwise the bitwise NOT
of the negative INKEY code of the key being pressed.
Examples
DEF PROCwait(secs%)
IF INKEY(100*secs%): REM throw away result
ENDPROC
IF INKEY(-99) THEN REPEAT UNTIL NOT INKEY(-99)
IF INKEY(-256) = &AA THEN PRINT "Using RISC OS 5"
REM Scan for keys excluding Shift, Ctrl, Alt, etc.
Key% = INKEY(-16-128)
IF Key% = 255 THEN
PRINT "No key pressed"
ELSE
PRINT "Negative INKEY code ";NOT Key%;" key pressed"
ENDIF
307
INKEY$
INKEY$
Function returning a character from the input stream.
Syntax
INKEY$ factor
Argument
As INKEY (1)
Result
Where INKEY would return –1, INKEY$ returns the null string "". In all other
situations, it returns CHR$(INKEYargument).
Example
A$ = INKEY$(500)
308
Keywords
INPUT
Statement obtaining a value or values from the input stream.
Syntax
INPUT is followed by an optional prompt, which, if present, may be followed by a
semi-colon or comma, which causes a ? to be printed out after the prompt. This is
followed by a list of variable names of any type, separated by commas. After the
last variable, the whole sequence may be repeated, separated from the first by a
comma. In addition the position of prompts may be controlled by the SPC, TAB
and ' (single quote) print formatters (see PRINT on page 366).
Notes
Leading spaces of the input string itself are skipped, and commas are taken as
marking the end of input for the current item.
When multiple variables are specified, but the input line contains fewer
comma-separated items than are required, additional ? prompts will be printed
until all the requested input has been provided.
Where an input variable type is integer or floating point, but the input string is not
a valid decimal number, zero is assigned to the variable.
Examples
INPUT a$ : REM Print a simple"?" as a prompt
INPUT "How many",num% : REM prompt is "How many?"
INPUT "Address &"hex$ : REM "Address &" no ? because no ,
INPUT TAB(10)"Name ",n$'TAB(10)"Address ",a$
INPUT a,b,c,d,"More ",yn$
INPUT SPC(5)"Letter",char$
309
INPUT LINE
INPUT LINE
Statement obtaining a value or values from the input stream.
Syntax
This has the same syntax as INPUT.
Result
If the input variable is a string, all the user’s input is read into the variable,
including leading and trailing spaces and commas. If the input variable is numeric,
only a single value will be selected from the beginning of the input line.
Notes
INPUT LINE is equivalent to LINE INPUT.
Example
INPUT LINE ">" basic$
310
Keywords
INPUT#
Statement obtaining a value or values from a file.
Syntax
INPUT#factor [,variable,variable...]
Arguments
factor is the channel number of the file from which the information is to be read,
as obtained by an OPENxx function. The variables, if present, may be of any type.
The separators may be semi-colons instead of commas.
Integer variables are read as &40 followed by the two’s complement representation
of the integer in four bytes, most significant byte first.
5–byte real variables are read as &80 followed by five bytes. The first four bytes are
the mantissa and the fifth is the exponent. The mantissa is read least significant
byte (LSB) first. 31 bits represent the magnitude of the mantissa and one bit (bit 7
of the fourth byte) the sign. The exponent byte is in excess-128 form.
8–byte real variables are read as &88 followed by two 4–byte words, in IEEE Double
Precision (D) format. The exponent is represented by bits 20 to 30 in the first word.
The sign bit is bit 31 in the first word. The mantissa is represented by bits 0 to 19 in
the first word and bits 0 to 31 in the second word.
Both BASIC V and BASIC VI can read 5– and 8–byte real formats.
String variables are read as a zero byte followed by a byte containing the string
length and then the characters in the string in reverse order.
Notes
Files read using INPUT# must adhere to the format described above, which implies
they should have been created using PRINT#. BASIC will perform conversion
between integers and floating point values where possible.
Examples
INPUT#data,name$,addr1$,addr2$,addr3$,age%
INPUT#data,$buffer,len
311
INSTALL
INSTALL
Command to load a function or procedure library into memory.
Syntax
INSTALL pathname
Argument
pathname is a string which should evaluate to the pathname of a valid BASIC file.
Purpose
INSTALL loads the chosen function and procedure library into the top of memory
and lowers the BASIC stack and value of HIMEM by an appropriate amount. The
library remains in memory until you QUIT from BASIC. Any number of libraries may
be installed provided that there is enough memory for them.
When searching for a procedure or function, BASIC looks in the following order:
first, the current program is searched, in line-number order; next, any procedure
libraries loaded using LIBRARY are searched – the most recently loaded file is
searched first; then, any INSTALLed libraries are examined, again in the reverse
order of loading. Finally the OVERLAY library list is searched.
The LVAR command lists (the first lines of) libraries in the order in which they are
examined.
Examples
INSTALL "Printout"
A$ = "Library1"
INSTALL A$
312
Keywords
INSTR(
Function to find the position of a substring in a string.
Syntax
INSTR(expression1,expression2[,expression3])
Arguments
expression1 is any string which is to be searched for a substring.
expression2 is the substring required.
expression3 is a numeric in the range 1 to 255 and determines the position in
the main string at which the search for the substring will start. This defaults to 1.
Result
An integer in the range 0 to 255. If 0 is returned, the substring could not be found
in the main string. A result of 1 means that the substring was found at the first
character of the main string, and so on. The position of the first occurrence only is
returned.
Notes
If the substring is longer than the main string, 0 is always returned. If the substring
is the null string, the result is always equal to expression3, or 1 if this is
omitted.
Examples
REPEAT a$=GET$:UNTIL INSTR("YyNn",a$) <> 0
pos%=INSTR(com$,"*FX",10)
313
INT
INT
Function returning the integer part of a number.
Syntax
INT factor
Argument
Any integer-range numeric.
Result
Nearest integer less than or equal to the argument. Note that this is different from
rounding towards zero: whereas INT(1.5) equals 1, INT(-1.5) is equal to -2,
not -1.
Examples
DEF FNround(n)=INT(n+0.5)
DEF FNTruncateToZero(n)=SGNn*INT(ABS(n))
size=len%*INT((top-bottom)/100)
314
Keywords
LEFT$(
Function returning, or statement altering, the left part of a string.
Syntax
as a function:
(1) LEFT$(expression1 [,expression2])
as a statement:
(2) LEFT$(variable [,expression1]) = expression2
Argument (1)
expression1 is a string of length between 0 and 255 characters.
expression2, if present, gives the number of characters from the left of the
string that are to be returned. If it is omitted, LEN(expression1)-1 is used, i.e.
all but the last character of the string is returned. This is useful for stripping off
unwanted trailing characters.
Result (1)
Characters from the left of expression1, where the length of the result is the
minimum of the length of expression1 and expression2 (or the implied
default for expression2).
Argument (2)
variable is the name of the string variable to be altered. The characters in the
variable are replaced, starting from the lefthand character (position 1), by the
string expression2. If the number expression1 is present, this gives the
maximum number of characters that will be overwritten in the variable. Otherwise,
it is the smaller of LENvariable and LENexpression2 – the length the string
in variable can never be altered by this statement.
Examples
start$ = LEFT$(a$)
left_half$=LEFT$(input$,LEN(input$) DIV 2 )
LEFT$(A$) = "ABCD"
LEFT$(A$,n%) = B$
315
LEN
LEN
Function returning the length of a string.
Syntax
LEN factor
Argument
Any string of 0 to 255 characters.
Result
The number of characters in the argument string, from 0 to 255.
Notes
The function SUMLEN returns the total length of the elements in a string array.
Examples
REPEAT INPUT a$: UNTIL LEN(a$)<=10
IF LEN(in$) > 12 THEN PRINT "Too long"
316
Keywords
LET
Statement assigning a value to a variable.
Syntax
LET variable = expression
Argument
The variable is any addressable object, such as a, a$, a%, !a, a?10, $a, a(1),
a() and so on.
expression is any expression of the range and type allowed by the variable: for
reals, any numeric; for integers, any integer-range numeric; for strings, any string of
length 0 to 255 characters, and for bytes any integer in the range 0 to 255 (though
an integer-range number will be treated AND &FF).
If the variable is a whole array, the righthand side obeys the rules described in the
chapter entitled Arrays on page 47.
Notes
The LET keyword is always optional in a variable assignment, and must not be
used in the assignment to a pseudo-variable. For example, LET TIME=100 is
illegal.
Examples
LET starttime=TIME
LET a$=LEFT$(addr$,10)
LET table?i=127*SIN(RAD(i))
LET a() = 1
LET A%() = B%() + C%()
317
LIBRARY
LIBRARY
Statement to load a function or procedure library into memory.
Syntax
LIBRARY pathname
Argument
pathname is a string which should evaluate to the pathname of a valid BASIC file.
Purpose
LIBRARY reserves an area in the BASIC heap (where variables are stored) and loads
the chosen function and procedure library into this area. It remains there until the
heap is cleared. Whilst the library is in memory, the current program can call any of
the procedures and functions it contains. See INSTALL on page 312 for how BASIC
searches for procedures or functions.
Examples
LIBRARY "Printout"
A$ = "Library1"
LIBRARY A$
318
Keywords
LINE
Statement to draw a line between two points.
Syntax
LINE expression,expression,expression,expression
Arguments
The (integer) expressions are two pairs of coordinates between which the line is
drawn. The line is drawn using the current graphics foreground colour and action,
and the graphics cursor position is updated to the second pair of coordinates. It is
equivalent to a MOVE followed by a DRAW.
Examples
LINE 100,100,600,700
LINE x1,y1,x2,y2
LINE x1,y1,x1+xoffset,y1+yoffset
319
LINE INPUT
LINE INPUT
Statement obtaining a value or values from the input stream.
Syntax
This has the same syntax as INPUT
Result
If the input variable is a string, all the user’s input is read into the variable,
including leading and trailing spaces and commas. If the input variable is numeric,
only a single value will be selected from the input line.
Notes
LINE INPUT is equivalent to INPUT LINE
Example
LINE INPUT "Your message" mess$
320
Keywords
LIST
Command to list the program.
Syntax
LIST [line-range][IFstring]
Arguments
line-range gives the start and end lines to be listed. Both values are optional
and should be separated by a comma. The first value defaults to zero and the last
to 65279.
The IF, when present, is followed by a string of characters (not in quotes). Only
lines which contain this string are listed.
Notes
In the search string following the IF statement, leading spaces are included as part
of the string. So the command
LIST IF PRINT
will list
100 PRINT "Single space between line number and statement."
110 PRINT "Several spaces between line number and statement"
but will ignore
120PRINT "No space between line number and statement."
The command
LIST IFPRINT
will find and list all three lines.
The string given after the IF is tokenised before it is checked against the program.
Hence, LIST IF PRINT and LIST IF P. both list lines containing the PRINT
keyword. However, LIST IF PR does not.
Because the string after IF is tokenised, only one version of the pseudo-variables
(each of which has two tokens) can be found. This is the one acting as a function
(as in PRINT TIME), rather than the statement version (as in TIME=expression).
321
LIST
Examples
LIST list the whole program
LIST 1000, list from line 1000 to the end
LIST ,50 list from the start to line 50
LIST 10,40 list from line 10 to 40 inclusive
LIST IFDEF list all lines containing a DEF
LIST ,100 IFfred%= list all lines up to line 100 containing fred%=
322
Keywords
LISTO
Command to set the LIST indentation options.
Syntax
LISTO expression
Argument
expression should be in the range zero to 31 and is treated as a five–bit number.
The meaning of the bits is as follows:
Bit Meaning
0 A space is printed after the line number
1 Structures are indented
2 Lines are split at the : statement delimiter
3 The line number is not listed. An error is displayed at line number
references
4 Keywords are listed in lower case
Examples
LISTO 0 Default
LISTO 2 All loops and conditionals indented by two characters
LISTO %10011 Tokens in lower case, structures indented, line numbers
followed by a space.
323
LN
LN
Function returning the natural logarithm of its argument.
Syntax
LN factor
Argument
Any strictly positive value: a numeric greater than zero.
Result
Real which is the log to base e (2.718281828) of the argument. For BASIC V this will
be between approximately –89 and +88, and for BASIC VI this will be between
approximately –744 and +709.
Notes
LN is the inverse of EXP.
Examples
DEF FNlog2(n)=LN(n)/LN(2)
PRINT LN(10)
324
Keywords
LOAD
Command to load a BASIC program at PAGE.
Syntax
LOAD pathname
Argument
pathname is a string which should evaluate to the pathname of a valid BASIC file.
Notes
Any program which is currently in memory is overwritten and lost with all its
variables. The static integers (A% - Z% and @%) and INSTALLed libraries are not
affected.
Examples
LOAD adfs::GDisc.disasm
where GDisc is the name of a disc.
LOAD FNnextFile
325
LOCAL
LOCAL
Statement to declare a local variable in a procedure or function.
Statement to make current DATA pointer local.
Statement to make the error control status local.
Used with DIM to reserve a block of memory within a procedure or function.
Syntax
(1) LOCAL [variable] [,variable...]
(2) LOCAL DATA
(3) LOCAL ERROR
(4) DIM numeric-variable LOCAL expression
Arguments (1)
variables following the LOCAL may be of any type, such as a, a%, a$, $buffer,
a(), and so on. The statement causes the current value of the variables cited to be
stored on BASIC’s stack, ready for retrieval at the end of the procedure or function.
This means the value inside the procedure may be altered without fear of
corrupting a variable of the same name outside the procedure. At the end of the
procedure, the old value of the variable is restored.
Note: Local numerics are initialised to zero, and local strings are initialised to
the null string. Arrays can be declared as being local and then dimensioned
using DIM as normal.
After a local array has been dimensioned, no additional local variables can be
declared in that procedure or function, so all local variable declarations
should be made before any DIM statements to dimension local arrays. Any
subsequent attempts to declare additional local variables will generate an
error.
Purpose (2)
LOCAL DATA stores the current data pointer on the stack for the duration of a loop
or function/procedure call. This enables a new data pointer to be set up, using
RESTORE, and for the original one to be restored with RESTORE DATA. RESTORE
DATA is performed automatically on return from a function/ procedure.
326
Keywords
Purpose (3)
LOCAL ERROR remembers the current error handler so a subsequent use of
ON ERROR does not overwrite it. This error handler can later be restored using
RESTORE ERROR.
Note: LOCAL ERROR can be used anywhere in a program
If LOCAL ERROR is used within a procedure or function it must be the last
item to be made local.
Returning from a procedure or function call which contained a LOCAL ERROR
automatically restores any stored error status.
See also ON ERROR LOCAL on page 348.
Arguments (4)
See DIM on page 266.
Examples
LOCAL a$,len%,price
LOCAL a(), B() : DIM a(2), B(4,5)
10 ON ERROR PROCerror
20 res = FNdivide(opp,adj)
30 END
40 DEFFNdivide(x,y)
50 LOCAL ERROR
60 ON ERROR LOCAL PRINT "attempt to divide by zero" :=0
70 =x/y : REM end of function restores previous error
status
327
LOG
LOG
Function returning the logarithm to base ten of its argument.
Syntax
LOG factor
Argument
Any strictly positive value: a numeric greater than zero.
Result
Real which is the log to base ten of the argument. For BASIC V this will be in the
range –38 to +38, and for BASIC VI this will be in the range –323 to +308.
Example
PRINT LOG(2.4323)
328
Keywords
LOMEM
Pseudo-variable holding the address of the start of user memory.
Syntax
(1) LOMEM
(2) LOMEM = expression
Result (1)
The address of the start of user memory.
Argument (2)
expression is the address at which user memory starts. The expression should
be in the range TOP to HIMEM to avoid corruption of the program and/or the
generation of No room errors.
Notes
LOMEM should not be changed after any assignments in a program. If it is,
variables assigned before the change are lost. LOMEM is reset to TOP by CLEAR
(and thus by RUN).
If you attempt to set LOMEM to an illegal value, a warning message is given and
LOMEM is not altered.
Examples
LOMEM=TOP+&400 : REM reserve 1k above TOP
PRINT LOMEM
329
LVAR
LVAR
Command displaying the first line of all current libraries, all defined variables and
all procedures and functions that have been called.
Syntax
LVAR
Purpose
LVAR lists all the values of BASIC variables, sizes of arrays, known procedures and
functions. It also lists the first line of all libraries currently loaded. These are
displayed in the same order as that in which the libraries are searched when a
library procedure or function is called.
Notes
In order for LVAR to be useful, you should ensure that the first line of each library
includes the full name of the library and the name of a procedure which can be
called to provide details of all the routines which the library contains.
330
Keywords
MID$(
Function returning, or statement altering, a substring of a string.
Syntax
as a function:
(1) MID$(expression1,expression2[,expression3])
as a statement:
(2) MID$(variable,expression1[,expression2]) = expression3
Argument (1)
expression1 is a string of length 0 to 255 characters.
expression2 is the position within the string of the first character required.
expression3, if present, gives the number of characters in the substring. The
default value is 255 (or to the end of the source string).
Result (1)
The substring of the source string, of a length given in the third argument, and
starting from the position specified. The result string can never be of greater length
than the source string.
Argument (2)
variable is the name of the string variable which is to be altered.
expression3 evaluates to a string which provides the characters to replace
those in variable.
expression1 is the position within the string of the first character to be
replaced.
expression2, if present, gives the maximum number of characters to be
replaced. The replacement stops when the end of the string variable is reached,
even if there are characters in expression3 which are unused.
331
MID$(
Examples
PRINT MID$("ABCDEFG",2,3); : REM should print "BCD"
right_half$=MID$(any$,LEN(any$) DIV 2)
MID$(A$,4,4) = B$
MID$(A$,2,5) = MID$(B$,3,6)
332
Keywords
MOD
Operator performing integer modulo (remainder of division between two integers).
Function returning the modulus of its array argument.
Syntax
as an operator:
(1) factor MOD factor
as a function:
(2) MOD numeric-array
Arguments (1)
The factors are integer-range numerics. The righthand side must not be zero.
Result (1)
Remainder when the lefthand argument is divided by the righthand one using
integer division. The sign of the result is the same as the sign of the lefthand
argument.
Argument (2)
The numeric-array can be any integer or floating point array.
Result (2)
The square root of the sum of the squares (the modulus) of all the elements of the
array.
Examples
INPUT i%: i% = i% MOD max_num%
count%=count% MOD max% + 1
PRINT result% MOD 100
DEF FNrms(a())=MODa()/SQRDIM(a(),1)
333
MODE
MODE
Statement changing, or function returning, the display mode.
Syntax
as a statement:
(1) MODE numeric-expression
(2) MODE string-expression
(3) MODE expr1,expr2,expr3[,expr4]
(4) MODE expr1,expr2,expr3,expr4,expr5[,expr6]
as a function:
(5) MODE
Arguments (1)
If numeric-expression is an integer in the range 0 to 127, it is used to select
an old-type numbered screen mode. When numeric-expression is between
128 and 255, the mode used is numeric-expression–128. Sufficient memory, however,
for two copies of the screen is reserved if the configured screen size allows. This
allows you to have one copy on display whilst you are updating the other, which
means that smooth animation can be obtained.
Details of the numbered modes available are given in the Appendix on old-type
screen modes in the RISC OS User Guide.
If expression is an integer greater than 255 it is treated as a pointer to a mode selector
block and OS_ScreenMode 0 is called. See the RISC OS Programmer’s Reference
Manual for further information.
Arguments (2)
This changes the screen mode using the mode string given in
string-expression. See Appendix E – Specifying screen modes for full details of the
mode string syntax.
BASIC uses OS_ScreenMode 15, if available, to change mode using the
provided string. On versions of RISC OS where OS_ScreenMode 15 is not
available BASIC will attempt to parse the string itself, producing a mode selector
block which is then passed to OS_ScreenMode 0.
334
Keywords
Arguments (3)
MODE x,y,bpp[,framerate]
This builds a mode selector and calls OS_ScreenMode 0 to change the screen
mode. The first and second expressions are integers specifying the mode width and
height in pixels. The third expression gives the colour depth in bits per pixel, and
may be 1, 2, 4, 6, 8, 16 or 32, where 6 selects a VIDC1-style 256 colour mode and 8
selects a 256 colour mode with a full palette. The optional fourth expression is an
integer giving the frame rate in Hertz.
In the mode selector block built by this command, the value of the first expression
(width) is stored at offset 4, the value of the second expression (height) is stored at
offset 8, the value of the third expression is converted to the pixel depth (0, 1, 2, 3,
4 or 5) and stored at offset 12, and if the frame rate is given it is stored at offset 16,
otherwise –1 is stored there. When the third expression is 8, the mode selector
block is extended with extension words to set ModeFlags (VDU variable 0) to 128
and NColour (VDU variable 3) to 255 in order to select a full palette.
This form of the MODE command does not allow all possible modes to be
selected, for example 4,096 and 65,536 colour modes cannot be specified, and the
pixel layout cannot be set to a non-default value. Use the MODE (2) or MODE (4)
forms of the command for more flexibility.
Arguments (4)
MODE x,y,ModeFlags,NColour,Log2bpp[,framerate]
This builds a mode selector and calls OS_ScreenMode 0 to change the screen
mode. The first and second expressions are integers specifying the mode width and
height in pixels and are stored at offsets 4 and 8 in the mode selector block. The
third expression specifies the value of ModeFlags (VDU variable 0), and the fourth
expression the value of NColour (VDU variable 3), and these are stored as
extension words at offset 20 of the mode selector block. The fifth expression gives
the value of Log2BPP (VDU variable 9) and is stored at offset 12. The optional sixth
expression gives the frame rate and this is stored at offset 16 of the mode selector
if specified, otherwise –1 is stored at this offset.
See Appendix E – Specifying screen modes for a table listing the valid combinations of
ModeFlags, NColour and Log2bpp.
Result (5)
An integer describing the current screen mode.
335
MODE
● If the value is between 0 and 255 inclusive, the current mode is a numbered
mode, and the returned value corresponds directly to the mode number. Note
that if a shadow mode had been requested by adding 128 to the mode number,
this is not reflected in the value returned by the MODE function. For example,
if you typed MODE 129, the MODE function would return 1. It is still
recommended however that you use 255 as the upper range limit, as that will
provide consistency with other interfaces which are capable of using mode
numbers in that range.
● If the value is not between 0 and 255, then it is the address of a mode selector
block which describes the current mode. This is true even if the mode was
selected via a mode string (internally the OS will convert the string to an
equivalent mode selector block). Note that the content of this block is only
valid until the next mode change. If you intend to save and restore the current
mode then you must make a copy of the block.
Be careful when checking the MODE value; mode selectors may be located in the
high end of the memory map (above &7FFFFFFF). In BASIC this will be treated as a
negative number, so a simple check of the form IF MODE < 256 THEN … will not
suffice.
Notes
Changing mode also does the following:
● sets COUNT to zero
● sets the text and graphics viewports to their defaults of the whole screen
● clears the screen to the current text background colour
● homes the text cursor
● moves the graphics cursor to (0,0)
● resets the logical-physical colour map (palette) to the default for the new
mode
● resets the colour-fill patterns to their defaults for the new mode sets the dot
pattern for dotted lines to &AA and the repeat length to 8
● resets VDU 5 magnification.
History
(2) was added in version 1.06, but implemented by calling *WimpMode. Support
for passing a mode selector in (1) was also added in version 1.06. (3) was added in
version 1.34. (4) was added in version 1.75, which also improved (2) so that it does
not affect the Wimp mode.
336
Keywords
Examples
MODE 0
MODE m%+128
MODE “X640 Y480 C256”
MODE 640,480,VDU0,VDU3,VDU9:REM keep current colour format
PRINT MODE
337
MOUSE
MOUSE
Statement interrogating and controlling the mouse position and button status.
Syntax
(1) MOUSE variable1,variable2,variable3[,variable4]
(2) MOUSE ON [expression]
(3) MOUSE OFF
(4) MOUSE COLOUR expr,expr,expr,expr
(5) MOUSE TO expression,expression
(6) MOUSE STEP expression[,expression]
(7) MOUSE RECTANGLE expr,expr,expr,expr
Arguments (1)
The first two variables are assigned the x and y positions of the mouse as values in
the range –32768 to 32767. The third variable is assigned a value giving the status
of the mouse buttons as follows:
Value Status
0 No buttons pressed
1 Right button only pressed
2 Middle button only pressed
3 Middle and right buttons pressed
4 Left button only pressed
5 Left and right buttons pressed
6 Left and middle buttons pressed
7 All three buttons pressed
If present, the last variable is assigned the time of a monotonic (always increasing)
centi-second timer, which can act as a time-stamp for making sure that
button-press events are processed in order, and for detecting double clicks, etc.
Argument (2)
MOUSE ON causes the mouse pointer to be displayed. The optional numeric
expression is the pointer shape to be used in the range 1 to 4. If it is omitted, 1 is
used.
If bit 7 of the pointer shape number is set, i.e. the expression is in the range &81 to
&84, then the mouse pointer will be unlinked from the mouse. That is, movements
of the physical mouse will not affect the screen pointer. Instead, you can use
POINT TO x,y to position the pointer.
338
Keywords
Purpose (3)
MOUSE OFF disables the mouse pointer, removing it from the screen.
Arguments (4)
MOUSE COLOUR sets the colour components of the mouse pointer logical colour
given in the first expression to the red, green and blue values given in the second,
third and fourth expressions. Pointer logical colours are in the range 1 to 3. Colour
0 is always transparent.
Arguments (5)
MOUSE TO moves the mouse (and pointer) to the (x,y) position given by the first
and second numeric arguments.
Arguments (6)
MOUSE STEP controls the speed of movement of the mouse pointer compared to
the speed of the movement of the actual mouse device. If there is one argument, it
is used as a multiplier for both the x and y movements. If there are two, the first is
used for x and the second for y. The arguments can be negative to reverse the usual
directions.
Arguments (7)
MOUSE RECTANGLE sets a bounding rectangle outside which the mouse cannot
move. The arguments are the left, bottom, right and top of the rectangle in
graphics units. If the mouse pointer is outside the box when this command is
given, it will be moved to the nearest point within it.
Examples
MOUSE xpos%,ypos%,button%
MOUSE ON 2
MOUSE OFF
MOUSE COLOUR Col%,red%,green%,blue%
MOUSE TO 100,100
MOUSE STEP 3,2
MOUSE RECTANGLE 640,512,1023,1279
339
MOVE
MOVE
Statement to set the position of the graphics cursor.
Syntax
MOVE [BY] expression,expression
Arguments
The expressions are x and y coordinates of the new position for the graphics cursor.
If the keyword BY is omitted, the coordinates are absolute. That is, they give the
position of the cursor with respect to the graphics origin. If BY is included, the
coordinates are relative. That means they give the new position of the cursor with
respect to the current graphics cursor position.
MOVE is equivalent to PLOT 4; MOVE BY is equivalent to PLOT 0.
Examples
MOVE 0,0 : REM Goto the origin
MOVE BY 4*dx%,4*dy%
340
Keywords
NEW
Command to remove the current program, and to initialise the computer so that it
is ready to receive a new program.
Syntax
NEW
Purpose
The NEW command does not destroy the program, but merely sets a few internal
variables as if there were no program in the memory. The effect of NEW may be
undone using the OLD command, providing no program lines have been typed in,
or variables created, between the two commands. BASIC does an automatic NEW
whenever it is entered.
341
NEXT
NEXT
Part of the FOR … TO … NEXT structure.
Syntax
NEXT [variable][,[variable]...]
Arguments
The variables are of any numeric type, and if present should correspond to the
variable used to open the loop. See the FOR entry for a description of the
mechanism of the FOR … NEXT loop.
Notes
The variables after the NEXT should always be specified as this enables BASIC to
detect improperly nested loops. If the loop variable given after a NEXT does not
correspond to the innermost open loop, BASIC closes the inner loops until a
matching looping variable is found. In order for the indentation produced by LISTO
2 to be useful, you should only close one loop per NEXT statement.
Examples
NEXT a%
NEXT : REM close one loop
NEXT j%,i% : REM close two loops
NEXT ,,, : REM close four loops
342
Keywords
NOT
Function returning the bitwise NOT of its argument.
Syntax
NOT factor
Argument
An integer-range numeric.
Result
An integer in which all the bits of the argument have been inverted: ones have
changed to zeros and zeros have changed to ones. If the argument is a truth value,
NOT can be used in a logical statement to invert the condition. In this case, the
truth value should only be one of the values –1 (TRUE) and 0 (FALSE).
Examples
IF NOT ok THEN PRINT "Error in input"
inv%=NOT mask%
REPEAT UNTIL NOT INKEY(-99)
343
OF
OF
Part of the CASE … OF … WHEN … OTHERWISE … ENDCASE statement.
Syntax
CASE expression OF
Argument
expression may yield any type of value: integer, floating point, or string.
Notes
The OF keyword must be the last item on the line. See the CASE keyword on
page 248 for more details.
Examples
CASE n% OF
CASE LEFT$(answer$) OF
344
Keywords
OFF
Statement to remove the cursor from the screen.
Syntax
OFF
Purpose
The OFF statement switches off the flashing text cursor until it is re-enabled by the
ON statement, or until cursor copying is used.
Examples
OFF
345
OLD
OLD
Command to retrieve a program after NEW has been typed.
Syntax
OLD
Purpose
The OLD command retrieves a program lost by NEW or Break providing no new
program lines have been entered, or variables defined. When you recover the
previous program using OLD, you may notice that the first line number has
changed. In particular, it is now its old value MOD 256. So if the first line used to
be 1000, it will now be 232. You can remedy this slight problem using the
RENUMBER command to reduce the value of the line numbers.
346
Keywords
ON
Statement to restore the text cursor on to the screen.
Statement marking the start of an ON … GOTO/GOSUB/PROC … ELSE construct.
Syntax
(1) ON
(2) ON expression GOSUB expr1 [,expr2...] [ELSE statement]
(3) ON expression GOTO expr1 [,expr2...] [ELSE statement]
(4) ON expr PROCproc1 [,PROCproc2...] [ELSE statement]
Purpose (1)
The ON statement re-enables the text cursor after it has been removed with an OFF
statement.
Purpose (2)
See the entry for GOSUB on page 300.
Purpose (3)
See the entry for GOTO on page 301.
Purpose (4)
See the entry for PROC on page 371.
Example
ON
ON x% GOSUB 100,200,300 ELSE PRINT "Out of range"
ON choice% GOTO 50,100,200
ON state% PROCred,PROCamber,PROCgreen ELSE PROCinvalid
347
ON ERROR
ON ERROR
Statement defining or cancelling an error handler.
Syntax
(1) ON ERROR [LOCAL] statements
(2) ON ERROR OFF
Purpose (1)
The ON ERROR statement introduces an error handler. When an error occurs after
an ON ERROR has been executed, control passes to the first statement of the ON
ERROR line. The program continues from there. Note that all of the error handler
code has to be on the ON ERROR line, so complex error handlers should use a
procedure, for example:
10 ON ERROR PROCerr_handler
Usually, before the error handler is called, BASIC will forget about all active
procedures, functions and loops, in effect reverting to the ‘top-level’ of the
program. However, if the LOCAL keyword is used on the ON ERROR line, then the
nesting level current when the ON ERROR is executed will be re-entered when the
error occurs. Thus error handlers which are useful within loops and other
constructs may be written.
See also LOCAL ERROR on page 326 and RESTORE ERROR on page 383.
Purpose (2)
ON ERROR OFF cancels any active error handler, so that this default action is used
when an error occurs:
TRACE OFF
IF QUIT THEN
ERROR EXT ERR,REPORT$
ELSE
RESTORE
IF ERL THEN
REM Equivalent to PRINT REPORT$+" at line "+STR$(ERL)
CALL !ERRXLATE:PRINT $STRACC
ELSE
REPORT:PRINT
ENDIF
END
ENDIF
348
Keywords
Examples
ON ERROR IF ERR=17 STOP : REM trap just Escape
ON ERROR LOCAL PRINT"Bad arguments" : ENDPROC
349
OPENIN
OPENIN
Function opening an existing file for input only.
Syntax
OPENIN pathname
Argument
A string which evaluates to a valid pathname.
Result
An integer acting as a channel number for the file. All subsequent operations on
file (e.g. BGET#, PTR#, EOF# etc.) use the channel number, sometimes called a
handle, as an argument.
OPENIN opens a file for input only. The file must exist prior to the call. If it doesn’t,
a channel number of 0 is returned. Only read-type operations are allowed on the
file. For example, you can get characters from it, but not put them. You can move
PTR# freely within the file, but not outside of it. A file may be opened for reading
several times. However, you can’t OPENIN and OPENOUT (or OPENUP) the same
file.
Examples
in_file%=OPENIN "Invoices"
data%=OPENIN(":0"+data$)
350
Keywords
OPENOUT
Function for opening a new file for input and output.
Syntax
OPENOUT pathname
Argument
A string which evaluates to a valid pathname.
Result
An integer acting as a channel number for the file. All subsequent operations on
file (e.g. BGET#, PTR#, EOF# etc.) use the channel number, sometimes called a
handle, as an argument.
OPENOUT creates and opens a file for input and output. Read- and write-type
operations are allowed on the file. You can both get characters from, and write
characters to, the file. You can move PTR# freely within the file, and extend the file
by moving PTR# outside of the file (beyond EXT#). You can also shorten the file by
assigning to EXT#. Once you OPENOUT a file, it can’t be opened again unless it is
closed first. Trying to OPENOUT an open file gives an error.
Examples
out_file%=OPENOUT "Customers"
data%=OPENOUT(":datadisc."+data$)
351
OPENUP
OPENUP
Function for opening an existing file for input and output (update).
Syntax
OPENUP pathname
Argument
A string which evaluates to a valid pathname.
Result
An integer acting as a channel number for the file. All subsequent operations on
file (e.g. BGET#, PTR#, EOF# etc.) use the channel number, sometimes called a
handle, as an argument.
OPENUP opens a file, which must exist already, for input and output. Read- and
write-type operations are allowed on the file. You can both get characters from,
and write characters to, the file. You can move PTR# freely within the file, and
extend the file by moving PTR# outside of the file (beyond EXT#). You can also
shorten the file by assigning to EXT#. Once you OPENUP a file, it can’t be opened
again unless it is closed first. Similarly, trying to OPENUP an open file gives an
error.
Examples
random_file%=OPENUP("records")
352
Keywords
OR
Operator performing bitwise OR of its arguments.
Syntax
relational OR relational
Arguments
Any integer-range numerics.
Result
An integer obtained by ORing together the corresponding bits in the arguments.
The arguments may be interpreted as bit-patterns, in which case a bit in the result
is set to one if either or both of the corresponding bits in the arguments are one.
Alternatively, they may be interpreted as logical values, in which case the result is
TRUE if either or both of the arguments are TRUE.
Examples
PRINT a% OR &AA55
IF a<1 OR a>10 THEN PRINT "Bad range"
353
ORIGIN
ORIGIN
Statement to move the graphics origin.
Syntax
ORIGIN expression,expression
Arguments
The expressions are integer numerics in the range –32768 to +32767. They are the
absolute coordinates of the new graphics origin: the position of the point (0,0).
These coordinates are always given with respect to the bottom left corner of the
screen.
The graphics origin is used by all commands which plot graphics, such as MOVE,
LINE, PLOT, CIRCLE, and so on, and also by VDU 24 which sets a graphics
viewport.
Example
ORIGIN 640,512 : REM Set origin to the centre of screen
354
Keywords
OSCLI
Statement to pass a string to the operating system.
Syntax
OSCLI expression
Argument
expression should be a string of between 0 and 255 characters. It is passed to
the operating system OS_CLI routine to be executed.
Notes
The difference between passing a string to the operating system via a * command
and via OSCLI is that the former makes no attempt to process the text following it,
whereas the latter evaluates the text as a BASIC string expression. Thus you can
say:
OSCLI "LOAD file "+STR$~buffer%
but not (usefully)
*"LOAD file "+STR$~buffer%
Many extensions to BBC BASIC on 6502-based BBC Microcomputer operating
systems used ‘internal’ BASIC routines called from OSCLI commands. BBC BASIC
provides extra information when using * or OSCLI to allow such software to be
ported to the BASIC built into RISC OS. (Note that this does not happen for
SYS "OS_CLI","fred").
Information is passed in registers R0 to R5, because the high user-mode registers
are not conveniently readable from other modes:
R0 contains CLI string pointer
R1 contains &BA51Cxxx
R2 pointer to BASIC’s workspace (ARGP)
R3 BASIC’s LINE pointer (points to the current statement)
R4 pointer to BASIC’s full, descending stack
R5 environment information pointer
Note that by the time a module’s * command handler is invoked these registers
will have been overwritten, which means that any module wishing to use them will
need to claim CLIV and take a copy.
355
OSCLI
The value in R1 should be inspected by any routine in order to validate that the call
is, indeed, from BASIC (it is also a good idea to check R2 to R5 for valid addresses);
this value is also at address [R5,#–4]. The current BASIC interpreter provides
&BA51C005, and the bottom three nybbles (&005) denote that the calling
standard follows the one shown here (to allow for possible future changes to which
registers are passed).
Registers R2 to R5 contain information about BASIC’s environment corresponding
to the information passed in registers R8, R12, R13 and R14 by the CALL
statement. Further information can be found in the section describing CALL on
page 234. The value in LINE (R3) should not be relied on, except that it is sufficient
for BASIC to produce the correct line number in case of an error.
If a handler wishes to call any of the internal BASIC routines then it must ensure it
is executing in user mode and transfer the state information to the correct
registers. When BASIC is eventually returned to at the end of the SWI OS_CLI call,
its (user-mode) registers must not have been altered.
Examples
OSCLI "CAT"
OSCLI "LOAD "+file$+" "+STR$buff%:REM get file in buffer
356
Keywords
OTHERWISE
Part of the CASE … OF … WHEN … OTHERWISE … ENDCASE statement.
Syntax
See CASE on page 248.
Notes
The OTHERWISE statement is executed only when the previous WHEN statements
have failed to match the value of the CASE expression. OTHERWISE matches any
values. If it is present, all statements following it will be executed until the
matching ENDCASE is encountered. It must be the first statement on a line.
Examples
OTHERWISE PRINT "Bad input"
OTHERWISE PROCdraw(x,y) : PROCwait
357
OVERLAY
OVERLAY
Statement setting up a list of overlay libraries.
Syntax
OVERLAY string-array
Argument
string-array is a one-dimensional array which should contain the pathnames
of the libraries to be overlaid. Elements containing a null string will be ignored.
Purpose
When the OVERLAY statement is executed, BASIC reserves enough space in the
BASIC heap (where variables are stored) for the largest of the files given in the
array. Then, when it can’t find a PROC or FN definition anywhere else, it will go
through the list, loading the libraries in order until the definition is found or the
end of the array is met.
Once a definition has been found, that library stays in memory (and so the other
definitions in it may be used) until the next time a definition can’t be found
anywhere. The search process then starts again, so the current overlay library will
be overwritten with the first one in the list. Once BASIC has found a definition, it
will remember which file it was in (or more precisely, which element of the array
held the pathname), so that file will be loaded immediately the next time the
definition is required and it is not in memory.
Because of the way one area of memory is used to hold each of the overlay files
(and only one at any one time), you are not allowed to call a procedure whose
definition is in an overlay library if one of the overlay definitions is currently active.
Another way of putting this is that you can’t nest overlay calls.
If you know that a given overlay file will never be needed again in the program, you
can speed up the search through the overlay list by setting the no-longer-required
elements of the array to the null string. You can also add new names to the end of
the array, as long as none of the new library files is bigger than the largest one
specified in the original OVERLAY statement.
You can execute OVERLAY more than once in a program. Each time it is called, the
memory set aside for the previous set of files will be lost, and a new block based on
the size of the new ones will be allocated.
358
Keywords
Example
DIM lib$(2)
lib$() = "Import","Printout","Export"
OVERLAY lib$()
359
PAGE
PAGE
Pseudo-variable holding the address of the program.
Syntax
(1) PAGE
(2) PAGE = expression
Result (1)
An address which is an unsigned number. PAGE is the location at which the current
BASIC program starts.
Argument (2)
expression is an integer in the range n to HIMEM, where n is the limit of BASIC’s
own workspace, which is &8F00 for BASIC V and &9700 (2 kbytes higher) for
BASIC VI (this could change in later versions of BASIC). PAGE should be on a word
boundary. By changing PAGE, you can have several BASIC programs residing in the
machine at once.
Notes
If you attempt to set PAGE to an invalid address, a warning message is given and
PAGE is not altered.
Example
PAGE = HIMEM - &4000
360
Keywords
PI
Function returning the value of π.
Syntax
PI
Result
The constant 3.141592653589793.
Examples
DEF FNcircum(r)=2*PI*r
361
PLOT
PLOT
Statement performing an operating system PLOT function.
Syntax
PLOT expression1,expression2,expression3
Arguments
expression1 is the plot number in the range from 0 to 255. For example, 85 is
the plot number for an absolute triangle plot in the foreground colour.
The second and third expressions are the x and y coordinates respectively, in the
range –32768 to +32767.
See Appendix G – Plot codes on page 483 for a full list of PLOT codes.
Examples
PLOT 85,100,100 : REM Draw a triangle
PLOT 69,x,y : REM Plot a single point
362
Keywords
POINT
Statement to plot a single point or move the on-screen pointer.
Syntax
(1) POINT [BY] expression,expression
(2) POINT TO expression,expression
Arguments (1)
The expressions are integers giving the coordinates at which the point will be
plotted. The point is plotted using the current graphics foreground colour and
action, and the graphics cursor is updated to these coordinates.
If the keyword BY is omitted, the coordinates are absolute. That is, they give the
position of the point with respect to the graphics origin. If BY is included, the
coordinates are relative. That means they give the position of the point with
respect to the current graphics cursor position.
Arguments (2)
The expressions are integers giving the coordinates at which the on-screen pointer
will be placed if it is not linked to the mouse position. If the pointer is linked to the
mouse this command is ignored. See MOUSE for more details about unlinking the
pointer from the mouse.
Examples
POINT 320,600
POINT X%+4, Y%+4
POINT BY 100,0
POINT TO 640,512
363
POINT(
POINT(
Function retuning the logical colour of a graphics pixel.
Syntax
POINT(expression,expression)
Arguments
The expressions are the coordinates of the pixel whose colour is required.
Result
This is an integer identifying the colour of the pixel or –1 if the point specified lies
outside the current graphics viewport.
Note that the value returned is in the range 0 to 63 for the 256-colour modes. The
function TINT(x,y) will read the tint of the given coordinate, returning a value in the
range 0 to 255.
In modes with less than 256 colours POINT returns the logical colour number in
the range 0 to n, where n is one less than the number of logical colours in the
current mode. For example, n is 15 in a 16-colour mode.
In 256-colour modes the value returned will be between 0 and 63 and the TINT
function will be required to find the tint of the pixel.
In modes with more than 256 colours POINT returns the colour number of the
pixel, the format of which depends on the number of bits per pixel (which can be
determined by reading VDU 9, Log2BPP), and the colour format (which can be
determined from bits 12-15 of VDU 0, ModeFlags). For example, in a 32-bit per
pixel mode with a TBGR format (Log2BPP=5, ModeFlags=0) the lowest 8 bits of the
returned number is the amount of red, the next 8 bits are the amount of green and
the next 8 bits are the amount of blue.
Example
REPEAT Y%+=4:UNTIL POINT(640,Y%)<>0
364
Keywords
POS
Function returning the x-coordinate of the text cursor.
Syntax
POS
Result
An integer between 0 and n, where n is the width of the current text viewport minus
one. This is the position of the text cursor which is normally given relative to the
lefthand edge of the text viewport. If the cursor direction has been altered using
VDU 23,16,… then it is given relative to the negative x edge of the screen which
may be top, bottom, left or right.
Notes
Even in VDU 5 mode, POS returns the position of the text cursor. You should
therefore keep track of the horizontal position explicitly in programs which must
operate in VDU 5 mode (e.g. Wimp-based programs). COUNT still works as
expected in VDU 5 mode.
Examples
old_x%=POS
IF POS<>0 THEN PRINT
365
PRINT
PRINT
Statement printing information on the output stream(s) (e.g. screen, printer, etc).
Syntax
The items following PRINT may be string expressions, numeric expressions, and
print formatters. By default, numerics are printed in decimal, right justified in the
print field given by @% (see below). Strings are printed left justified in the print
field. The print formatters have the following effects when printing numbers:
; Do not right justify (print leading spaces before) numbers in the
print field. Set numeric printing to decimal. Semi-colon stays in
effect until a comma is encountered. Do not print a new line at
the end if this is the last character of the PRINT statement.
, (comma) Right justify numbers in the print field. Set numeric printing to
decimal. This is the default print mode. Comma stays in effect
until a semi-colon is encountered. If the cursor is not at the
start of the print field, print spaces to reach the next one.
~ (tilde) Print numbers as hexadecimal integers, using the current
left/right-justify mode. Tilde stays in effect until a comma or
semi-colon is encountered.
' (single quote) Print a new line. Retain current left/right-justify and
hexadecimal/decimal modes.
TAB( If there is one argument, for example, TAB(n), print
(n_COUNT) spaces. If the cursor is initially past position n (i.e.
COUNT>n), print a new line first. If there are two arguments, for
example, TAB(10,20), move directly to that tab position.
Left/right-justify and hexadecimal/decimal modes are retained.
SPCfactor Print the given number of spaces. For example SPC5 outputs
five spaces. Right-justify and hexadecimal/decimal modes are
retained.
space Print the next item, retaining left/right-justify and
hexadecimal/decimal modes.
When strings are printed the descriptions above apply, except that hexadecimal
mode does not affect the string. Also no trailing spaces are printed after a string
unless it is followed by a comma. This prints enough spaces to move to the start of
the next print field.
The print formatters TAB, SPC and ' may also be used in INPUT statements.
366
Keywords
Formatting numbers
The format in which numbers are printed, and the width of print fields are
determined by the value of the special system integer variable, @%. This can be set
as an integer or in a special way using a string expression.
Examples of @%
@%="G10.9" is the default setting. It is a General format, with a field width of 10
and a precision of 9 digits; for example 12.3456789. STR$ uses its default.
@%="+E10.3" is an Exponent format, with a field width of 10, and 3 digits after
the decimal point; for example 1.24E1. STR$ uses this format instead of its
default.
@%="F7.4" is a Fixed format, with a field width of 7, and 4 digits after the decimal
point; for example 12.3457. STR$ uses its default.
367
PRINT
Setting @% as an integer
You can set the variable @% to an integer value to produce the same results (this is
the only method possible in BASIC 1.04 and earlier). The value of @% is specified
using a hexadecimal word four bytes long, as follows:
@%=&wwxxyyzz
● Byte 4 (ww), which can be 1 or 0, corresponds to the + STR$ switch. If this byte
is 1, STR$ uses the format specified by the rest of @%. If it is 0, STR$ uses its
default value of &00000A00.
● Byte 3 (xx) can be 0, 1 or 2 to select the G, E or F format with a dot as decimal
point, or &80, &81 or &82 to select G, E or F format with a comma as decimal
point
● Byte 2 (yy), which can take values from 1 to 10, determines the number of
digits printed. In General format, this is the number of digits which may be
printed before reverting to Exponent format (1 to 10); in Exponent format it
gives the number of significant figures to be printed after the decimal point (1
to 10). In fixed format it gives the number of digits (exactly) that follow the
decimal point.
● Byte 1 (zz), which is in the range 0 to 255, gives the print field width for
tabulating using commas.
When the value of @% is read, it returns an integer in the above format.
Examples of @%
@%=&0000090A uses General format with up to nine significant digits in a field
width of ten characters. Note that General format reverts to Exponent format when
the number is less than 0.1. This is the default setting of @%.
@%=&0101030A uses Exponent format. Three significant digits are printed, in a
field of ten characters. These numbers look like 1.23E0 or 1.10E-3, etc. In
addition, STR$ uses this format instead of its default (which is &00000A00).
368
Keywords
@%=&00020407 uses Fixed format with four decimal places in a tab field width of
seven. Numbers are printed out in the form 1.23, 923.10, etc.
@%=&00820407 is the same as the previous example but using a comma for the
decimal point. Numbers will look like 4,56 or 821,20, etc.
Notes
Setting byte two to 10, e.g. &0A0A, shows the inaccuracies which arise when trying
to store certain numbers in binary. For example:
PRINT 7.7
prints 7.699999999 when @%=&0A0A.
Examples
PRINT "Hello there";
PRINT a,SIN(RAD(a)),x,y''p,q;
PRINT TAB(10,3)"Profits"SPC(10);profits;
369
PRINT#
PRINT#
Statement printing information to an open file.
Syntax
PRINT#factor [,expression,expression...]
Arguments
factor is the channel number of a file opened for output or update. The
expressions, if present, are any BASIC integer, real or string expressions. They are
evaluated and sent to the file specified with the corresponding type information.
Integers are written as &40 followed by the two’s complement representation of the
integer in four bytes, most significant byte first.
5–byte real variables are written as &80 followed by five bytes. The first four bytes
are the mantissa and the fifth is the exponent. The mantissa is written least
significant byte (LSB) first. 31 bits represent the magnitude of the mantissa and
one bit (bit 7 of the fourth byte) the sign. The exponent byte is in excess-128 form.
BASIC V only prints real numbers in 5–byte real format.
8–byte real variables are written as &88 followed by two 4–byte words, in IEEE
Double Precision (D) format. The exponent is represented by bits 20 to 30 in the
first word. The sign bit is bit 31 in the first word. The mantissa is represented by
bits 0 to 19 in the first word and bits 0 to 31 in the second word. BASIC VI only
prints real numbers in 8–byte real format. You need 1.05 series (rather than 1.04) to
read this information back.
Strings are written as &00 followed by a one byte count of the length of the string,
followed by the characters in the string in reverse order.
Example
PRINT#file,name$+":",INT(100*price+.5),qnty%
370
Keywords
PROC
Statement introducing or calling a user-defined procedure.
Syntax
(1) DEF PROCproc-part
(2) PROCproc-part
(3) ON expr PROCproc1 [,PROCproc2...] [ELSE statement]
Argument (1)
proc-part has the form identifier[(parameter-list)]. It gives the name
of the procedure (the identifier) and the names and types of the optional
parameters, which must be enclosed in brackets and separated by commas.
Argument (2)
The second form is used when the procedure is actually invoked, and this time the
parameter list comprises expressions of types corresponding to the parameters
declared in the DEF PROC statement. The expressions are evaluated and assigned
(locally) to the parameter variables. Control returns to the calling program when an
ENDPROC is executed.
Argument (3)
expr should evaluate to an integer. If this integer is n then the nth procedure listed
is called. If the integer is less than 1 or greater than the number of line numbers
given, the statement following the ELSE, if it is present, is executed.
Examples
DEF PROCdelay(n)
LOCAL t%
t%=TIME:REPEAT UNTIL TIME-t%>=n*100:ENDPROC
IF ?flag=0 THEN REPEAT PROCdelay(0.1): UNTIL ?flag
371
PTR#
PTR#
Pseudo-variable accessing the pointer of a file.
Syntax
(1) PTR#factor
(2) PTR#factor = expression
Argument (1)
factor is a channel number, as returned from an OPENxx function.
Result (1)
An integer giving the position of the next byte to be read or written relative to the
start of the file. The minimum value is 0 and the maximum value depends on the
filing system in use.
Arguments (2)
factor is as (1). The expression is an integer giving the desired position of the
sequential pointer in the file. Files opened for input may only have their PTR#
value set to between 0 and the EXT# of the file.
Examples
PRINT PTR#file;"bytes processed"
PTR#chan%=rec_len%
372
Keywords
QUIT
Statement to leave BASIC.
Function returning -quit status.
Syntax
as a statement:
(1) QUIT [expression]
as a function:
(2) QUIT
Argument (1)
QUIT as a statement leaves the BASIC interpreter. If the optional expression is
specified the system variable Sys$ReturnCode is set to the value of expression, which
should be an integer.
Result (2)
QUIT as a function returns TRUE or FALSE. If the interpreter was invoked using the
-quit flag, then it will return TRUE. If -quit was not specified on the command
line, then the function returns FALSE.
History
The optional expression for (1) was added in BASIC version 1.34.
373
RAD
RAD
Function returning the radian value of its argument.
Syntax
RAD factor
Argument
A number representing an angle in degrees.
Result
A real giving the corresponding value in radians: factor*π/180.
Examples
(sin%+i%*5)=SIN(RAD(i%))
PRINT RAD(theta)-PI/2
374
Keywords
READ
Statement reading information from a DATA statement.
Syntax
READ [variable] [,variable...]
Argument
Any variables should correspond in type to the items in the DATA statement being
read. In fact, a string READ item is able to read any type of DATA and interpret it as
a string constant after stripping leading spaces. A numeric READ item tries to
evaluate its DATA; so in the latter case, the DATA expression should yield a suitable
number. Note that items in a DATA statement are not tokenised so, for example,
PI/2 will generate an error if used with a numeric READ. For cases like this the item
can be read as a string and EVAL used to get the numeric value.
Examples
READ n%
READ a$, fred%, float
375
RECTANGLE
RECTANGLE
Statement to draw a rectangle or copy/move a rectangular area of the screen or set
the mouse bounding box.
Syntax
(1) RECTANGLE [FILL] exp1,exp2,exp3[,exp4]
(2) RECTANGLE [FILL] exp1,exp2,exp3[,exp4] TO exp5,exp6
(3) MOUSE RECTANGLE exp1,exp2,exp3,exp4
Arguments (1)
exp1 and exp2 are integer expressions in the range –32768 to +32767. They are
the coordinates of one of the corners of the rectangle.
exp3 is the width of the rectangle. It is also the height (giving a square) unless
exp4 is given, in which case this is the height.
Purpose (1)
RECTANGLE draws the outline of a rectangle which is aligned with the x and y
axes. RECTANGLE FILL plots a solid axes-aligned rectangle. The rectangles are
drawn using the current graphics foreground colour and action.
RECTANGLE leaves the graphics cursor at the starting position. However, with
RECTANGLE FILL, the graphics cursor is updated to the position of the opposite
corner to the one specified.
Arguments (2)
The first four arguments define a rectangular area of the screen, as for the first
usage described above.
exp5 and exp6 give the position to which the lower left corner of the source
rectangle is copied or moved.
Purpose (2)
RECTANGLE … TO copies the original rectangular area defined to the new
position, hence making a second copy of a rectangular screen area. Pixels in the
source that are outside of the current graphics viewport are drawn in the current
graphics background colour.
376
Keywords
RECTANGLE FILL … TO moves the original rectangular area defined to the new
position, replacing the old area with the current graphics background colour. In
both cases the new position is allowed to overlap with the rectangular area.
Purpose (3)
To set a bounding box for the mouse pointer. See MOUSE for details.
Examples
RECTANGLE 500,500,-200,-100
RECTANGLE FILL bl%(1),bl%(2),width%,height%
RECTANGLE 400,400,60,60 TO 460,400
RECTANGLE FILL x,y,size,size TO xnew,ynew
377
REM
REM
Statement indicating a remark.
Syntax
REM rest-of-line
Argument
rest-of-line can be absolutely anything; it is ignored by BASIC. The purpose
of a REM is to provide comments to make the program clear to any reader.
Example
REM find the next prime
378
Keywords
RENUMBER
Command to renumber the program lines.
Syntax
RENUMBER [start][,step]
Arguments
start is an integer constant in the range 0 to 65279 and is the first line number. It
defaults to 10.
step is an integer constant in the range 1 to 65279 and is the amount by which the
line numbers increase. If omitted, 10 is assumed.
Purpose
RENUMBER resequences the lines in the program so that the first line is start
and the line numbers increase in steps of step. It also changes line numbers
within the program, such as after RESTOREs, so that they match the new line
numbers. If the line used in a RESTORE cannot be found, the message
Failed with nnnn on line llll
is given, where nnnn is the line number which was referenced but which does not
appear in the program, and llll is the line on which the reference was made.
RENUMBER needs some workspace, and if there is not enough room to change the
line numbers successfully, a RENUMBER space error is generated.
Examples
RENUMBER
RENUMBER 1000,20
379
REPEAT
REPEAT
Statement marking start of a REPEAT … UNTIL loop.
Syntax
REPEAT
Purpose
The statements following REPEAT are repeatedly executed until the condition
following the matching UNTIL evaluates to TRUE. The statements may occur over
several program lines, or may all be on the same line separated by colons. The
second approach is useful in immediate statements. The statements are executed
at least once.
Examples
REPEAT UNTIL INKEY-99 : REM wait for SPACE
REPEAT
a%+=1:c%=c% >> 1
UNTIL c%=0
380
Keywords
REPORT
Statement printing the message of the last error encountered.
Syntax
REPORT
Notes
If no error has occurred the BASIC version string (e.g. “ARM BBC BASIC V (C)
Acorn 1989”) will be printed instead.
If an error occurs in a library, the error message is suffixed with the name of the
library, for example Mistake in "MyLib". The name that will be printed is
everything that follows REM or REM> on the first line of the library.
Examples
REPORT:PRINT " at line ";ERL:END
REPORT:PRINT " error!!"'':END
381
REPORT$
REPORT$
Function returning the message of the last error encountered as a string.
Syntax
REPORT$
Notes
See the Notes for REPORT on page 381.
Examples
PRINT REPORT$
ERROR ERR,REPORT$
382
Keywords
RESTORE
Statement setting the DATA pointer.
Statement restoring DATA pointer from the stack.
Statement to restore saved error status.
Syntax
(1) RESTORE [[+] expression]
(2) RESTORE DATA
(3) RESTORE ERROR
Argument (1)
expression is a line number. If it is absent, the DATA pointer is reset to the first
DATA statement in the program, and the next item READ comes from there. If the
line number is present, the DATA pointer is set to the first item of data on or after
the line specified, so that subsequent READs access that particular data item (and
those which follow).
If expression is preceded by a + sign, then it is interpreted as an offset from the
line containing the RESTORE statement and should be a positive number. +1
means the line after the one containing the RESTORE, +2 means the line after
that, and so on. The main use of this is in libraries, where references to actual line
numbers are not allowed (and RESTORE on its own restores to the start of the
main program, not the library).
Purpose (2)
The second form of RESTORE loads a DATA pointer from the stack that was
previously saved using LOCAL DATA. By using these two statements as a pair, you
can prevent any RESTOREs in a procedure or function from changing the DATA
pointer used by the main program.
Purpose (3)
RESTORE ERROR restores the error status previously saved using LOCAL ERROR.
If an error status has not been saved then a fatal error arises.
The error status is restored automatically on return from a procedure or function,
and when one of the loop-terminating constructs is encountered (UNTIL,
ENDWHILE and NEXT).
383
RESTORE
Examples
RESTORE
RESTORE 1000
RESTORE +10
RESTORE DATA
10 LOCAL ERROR
20 REPEAT
30 ON ERROR LOCAL PRINT"Negative value"
40 INPUT x
50 PRINT "Square root of x = ";SQR(x)
60 UNTIL x=0
70 RESTORE ERROR
384
Keywords
RETURN
Statement returning control from a subroutine.
Modifier in formal parameter list.
Syntax
(1) RETURN
(2) RETURN parameter
Purpose (1)
RETURN returns control to the statement following the most recent GOSUB. If
there are no GOSUBs currently active, a Not in a subroutine error occurs.
Purpose (2)
When used in DEF PROC or DEF FN, RETURN indicates value-and-result parameter
passing (as distinct from value passing, the default) when applied to a parameter.
Note that there must be a space between RETURN and the parameter name.
Examples
DEF PROCSwapIfDisordered(RETURN A, RETURN B)
IF A>B SWAP A,B
ENDPROC
385
RIGHT$(
RIGHT$(
Function returning, or statement altering, the right-most character(s) of a string.
Syntax
as a function:
(1) RIGHT$(expression1[,expression2])
as a statement:
(2) RIGHT$(variable[,expression1]) = expression2
Argument (1)
expression1 should be a string of length 0 to 255 characters.
If expression2 is present, it should be a numeric giving the number of
characters from the right of the string to be returned, also in the range 0 to 255. If it
is omitted, a default of 1 is used.
Result (1)
A string consisting of the n right-most character(s) from the source string, where n
is expression2 or 1. If n is greater than the length of the source string, the whole
source string is returned.
Argument (2)
variable is the name of the string variable to be altered. The righthand
characters in variable are replaced by the string expression2.
If present, expression1 gives the maximum number of characters which will be
replaced: the number of characters altered is the lesser of expression1 and
LENexpression2. expression1 defaults to 255.
Examples
PRINT RIGHT$(any$,4)
year$=RIGHT$(date$,2)
RIGHT$(birthday$) = "May"
RIGHT$(name$,4) = "Mary"
386
Keywords
RND
Function returning a random number.
Syntax
(1) RND
(2) RND(expression)
Result (1)
A four-byte signed random integer between -2147483648 and +2147483647
Result (2)
expression < 0
expression should be an integer. This reseeds the random number generator,
and the function returns the integer part of the argument as a result. Reseeding the
generator with a given seed value always produces the same sequence of random
numbers.
expression = 0
This uses the same seed as the last RND(1) call and returns the same random
number rounded between 0 and 1.
expression = 1
This returns a random real number between 0 and 1.
expression > 1
The expression, n, should be an integer. The result is an integer between 1 and n
inclusive.
Note that there should be no space before the opening bracket.
Examples
dummy=RND(-TIME) : REM reseed the generator 'randomly'
x%=RND(1280) : y%=RND AND &3ff
prob=RND(1)
lastProb=RND(0)
r%=RND
387
RUN
RUN
Command to execute the current program.
Syntax
RUN
Purpose
RUN executes the program in memory, if one is present, after clearing all variables
and resetting LOMEM.
388
Keywords
SAVE
Command to save a program as a file.
Syntax
SAVE [pathname]
Argument
If present, pathname should evaluate to a string which is a valid pathname. The
current BASIC program is stored (without variables, etc) on the medium under this
name.
SAVE can be used without an expression, in which case the name is taken from the
first line of the program which should have the format:
10 REM > filename
For example:
10 REM > Game1
Examples
SAVE "Version1"
SAVE "$.BASIC.Games.Adventure"
SAVE FNprogName
SAVE
389
SGN
SGN
Function returning the sign of its argument.
Syntax
SGN factor
Argument
Any numeric.
Result
-1 for negative arguments
0 for zero-valued arguments
+1 for positive arguments
Examples
DEF FNsquare(th)=SGN(SIN(th))
IF SGN(a)<>SGN(b) THEN ...
390
Keywords
SIN
Function returning the sine of its argument.
Syntax
SIN factor
Argument
A numeric representing an angle in radians.
Result
A real in the range –1 to 1, being the sine of the argument.
Notes
For BASIC V if the argument is outside the range –8388608 to +8388608 radians, it
is impossible to determine how many πs to subtract. The error Accuracy lost
in sine/cosine/tangent is generated. For BASIC VI the range is larger, from
approximately –6E9 to +6E9 radians, and outside this range the error Floating
point exception: invalid operation is generated.
Examples
PRINT SIN(RAD(135))
opp=hyp*SIN(theta)
391
SOUND
SOUND
Statement generating a sound or suppressing/allowing subsequent sound
generation.
Syntax
(1) SOUND ON
(2) SOUND OFF
(3) SOUND expr1,expr2,expr3,expr4[,expr5]
Arguments (3)
expr1 is the channel number
expr2 is the amplitude
expr3 is the pitch
expr4 is the duration
expr5, if present, is the delay.
Channel
A two-byte integer giving the channel number to be used. It has the range 1 to 8.
Amplitude
This is an integer in one of two different ranges. The range –15 to 0 is a simple
volume (amplitude), –15 being the loudest and zero being the quietest (no sound).
The range 256 (&100) to 511 (&1FF) is a logarithmic volume range, a difference of
16 providing a doubling or halving of the volume.
Pitch
This is treated as an integer. In the range 0 to 255, the note middle C has a pitch
value of 53; a difference in the parameter of 48 corresponds to a difference in pitch
of one octave. In other words, there are four pitch values per semi-tone. In the
range 256 (&100) to 32767 (&7FFF), the note middle C has a pitch value of &4000,
and a difference in the value of &1000 corresponds to a difference in pitch of one
octave.
392
Keywords
Duration
The last compulsory SOUND parameter is also treated as a two-byte integer. It
gives the duration of the note in twentieths of a second. A value of 255 gives a note
with an infinite duration: one that does not stop unless the sound queue is flushed
in some way. A value greater than 255 is treated as a duration in 20ths of a second.
Delay
This is the number of beat counts from the last beat counter reset before the sound
is produced. See BEATS on page 230 and TEMPO on page 408 for more details. If
this parameter is omitted, the sound is produced immediately. A value of –1
synchronises the new note with the last scheduled sound.
Examples
SOUND OFF
SOUND 1,-15,255,10
SOUND &102,&140,&2400,200
SOUND 3,300,300,100,200
393
SPC
SPC
Print formatter to generate spaces in PRINT and INPUT statements.
Syntax
SPC factor
Argument
A one-byte integer between 0 and 255. It gives the number of spaces to be printed.
Examples
PRINT SPC 10;
INPUT SPC(7)"How many",a$
394
Keywords
SQR
Function returning the square-root of its argument.
Syntax
SQR factor
Argument
Any non-negative numeric.
Result
A real which is the argument’s square-root.
Examples
DEF FNlen(x1,y1,x2,y2)=SQR((x2-x1)^2+(y2-y1)^2)
disc=SQR(b*b-4*a*c)
395
STEP
STEP
Part of the FOR and MOUSE statements.
Syntax
(1) FOR variable=expr TO expr [STEP expr]
(2) MOUSE STEP expression[,expression]
Purpose (1)
See FOR on page 293.
Purpose (2)
See MOUSE on page 338.
396
Keywords
STEREO
Statement setting the stereo position of a sound channel.
Syntax
STEREO expression1,expression2
Arguments
expression1 is the channel number which should be between 1 and the number
of active channels (the maximum being 8).
expression2 is a value giving the stereo position. It can take any value between
–127 (meaning that the sound is fully to the left) and +127 (meaning that the
sound is fully to the right). The default value of each channel is 0, giving central
(mono) production.
If the number of physical channels is eight, only the channel specified is
programmed. Otherwise, the following occurs, where chan is expression1:
No of channels Channels programmed
1 chan to eight
2 chan and every alternate channel up to eight
4 chan and chan+4 if chan+4 is less than or equal to eight
Examples
STEREO 4,-60
STEREO n%, stereo%
397
STOP
STOP
Statement producing the fatal error Stopped to terminate the program.
Syntax
STOP
Purpose
The STOP statement gives the fatal (untrappable) error message Stopped. It
differs from END, as the latter produces no message. It may be used as a
debugging aid to halt the program at a given point so that the current values of the
program’s variables can be determined.
Example
IF NOT ok THEN PRINT"Bad data":STOP
398
Keywords
STR$
Function returning the string representation of its argument.
Syntax
STR$[~] factor
Argument
Any numeric for decimal conversion, any integer for hexadecimal conversion.
Decimal conversion is used when the tilde (~) is absent, hex conversion when it is
present.
Result
Decimal or hex string representation of the argument, depending upon the
absence or presence of the tilde.
Notes
The string returned by STR$ is usually formatted in the same way as the argument
would be printed with @% set to &A00. However, if the most significant byte of @%
is non-zero, STR$ returns the result in exactly the same format as it would be
printed, taking the current value of @% into account. See also PRINT.
Examples
DEF FNhex4(a%)=RIGHT$("000"+STR$~(a%),4)
DEF FNdigits(a)=LEN(STR$(a))
dp=INSTR(STR$(any_val),".")
399
STRING$(
STRING$(
Function returning multiple copies of a string.
Syntax
STRING$(expression1,expression2)
Arguments
expression1 is an integer, n, in the range 0 to 255.
expression2 should be a string of length 0 to (255 DIV n) characters.
Result
A string comprising n concatenated copies of the source string, of a length
n*LEN(expression2).
Examples
PRINT STRING$(40,"_"); :REM underline across the screen
pattern$=STRING$(20,"<-->")
400
Keywords
SUM
Function returning the arithmetic sum or string concatenation of an array.
Syntax
SUM array
Argument
array is the name of an array.
Result
If the argument is an integer or floating point array, it is an integer or floating point
value of the sum of all the elements in the array.
If the argument is a string array, it is the string which contains each of the elements
of the array concatenated. This must be less than 256 characters in all.
Examples
A() = 1 : PRINT "There are ";SUM(A())" elements."
DEF FNmean(a())=SUMa()/DIM(a(),1)
401
SUMLEN
SUMLEN
Function returning the length of the string concatenation of an array.
Syntax
SUMLEN string-array
Argument
string-array is the name of a string array.
Result
The sum of the lengths of all the elements in the array. Thus
SUMLENa$()=LENSUMa$()
except that the former is not limited to a maximum of 255 characters.
Examples
DEF FNmeanlen(a$())=SUMLENa$()/DIM(a(),1)
402
Keywords
SWAP
Statement exchanging the value of two variables or arrays.
Syntax
SWAP variable1,variable2
Arguments
The arguments are variables or array names. Simple variables must be of
assignment-compatible types, i.e. both string or numeric. Arrays must be of
identical type elements (both integer, floating point or string), but can be of
differing sizes.
Purpose
The SWAP statement exchanges the contents of the two variables or arrays. In the
case where arrays are swapped, the number of subscripts and their upper limits are
also swapped. For example, if you have
DIM A(10),B(20,20)
SWAP A(),B()
then after the SWAP, it would be as if the arrays had been DIMed:
DIM A(20,20),B(10)
All of the elements of the arrays are also swapped, though no actual movement of
data is involved so this is a very quick operation.
Examples
SWAP A%, B%
SWAP forename$, surname$
SWAP arr(i%), arr(i%+gap%)
SWAP array1$(), array2$()
SWAP a, B%
SWAP A$, $A%
SWAP matrix(), vector()
403
SYS
SYS
Statement for calling operating system routines.
Syntax
SYS expr1 [,[exprn]... ] [TO [var1][,[var2]...] [;flags]]
Arguments
expr1 defines which operating system routine is to be called. It may evaluate to a
number giving the routine’s SWI number, or to a string which is the name of a
routine. BASIC uses the SWI OS_SWINumberFromString to convert from a string to
number, so the case of the letters in the string must match exactly that of the SWI
name.
The optional list of expressions following this, up to a maximum of ten, is passed
to the routine via registers R0 to R9. If the expression evaluates to a numeric, it is
converted to an integer and placed directly in a register. If the expression evaluates
to a string, the string is placed on BASIC’s stack, beginning at a word boundary and
terminated with a null character. A pointer to it is put in the register. Any
expressions not given (indicated by adjacent commas ,,) default to zero.
The optional TO is followed by a variable list. Each variable is assigned any value
returned by the routine in the registers R0 to R9 respectively. If the variable to
assign to is numeric, the integer in the register is converted to an appropriate
format and stored in it. If the variable to assign to is a string, the register is treated
as a pointer to a string terminated by ASCII 0, 10 or 13 and this string is assigned to
the variable. The strings given on input can be overwritten, but should not be
extended. As with the input expressions, output variables may be omitted using
adjacent commas in the list.
flags is an optional variable, to which the processor flag bits are returned. The
value stored in the flags value is a binary number of the form %NZCV, where the
letters stand for the result flags of the ARM status register.
Purpose
SYS provides access to the routines supplied by the operating system for entering
and outputting characters, error handling, sprite manipulation, and so on. Details
of these operating system routines is beyond the scope of this book, but can be
found in the RISC OS Programmer’s Reference Manual.
404
Keywords
History
Prior to BASIC 1.05, only R0 to R7 could be used with SYS, and calling a SWI which
alters R8 would result in a crash.
In BASIC version 1.54 and later, returned registers containing zero will be converted
to an empty string if the variable to assign to is a string, whereas in earlier versions
of the interpreter this will potentially cause the program to fail.
Examples
SYS "OS_ReadMonotonicTime" TO time
SYS "OS_SpriteOp",28,,"MYSPRITE",,3
SYS "Font_FindFont",,"Homerton.Medium",12*16,12*16 TO f%
10 SYS 0,0,42 : REM output a *
20 OS_Write% = 0
30 SYS OS_Write%, 42
40 END
405
TAB(
TAB(
Print formatter to position text cursor in PRINT and INPUT statements.
Syntax
(1) TAB(expression)
(2) TAB(expression1,expression2)
Argument (1)
A numeric in the range 0 to 255. It expresses the desired x-coordinate of the cursor.
This position is obtained by printing spaces. A new line is generated first if the
current position is at or to the right of the required one. COUNT is updated
appropriately. This form is useful for tabulating on both the screen (even in VDU 5
mode) or printed output.
Arguments (2)
expression1 is the desired x coordinate;
expression2 is the desired y coordinate.
The position is reached using the VDU 31 command. Both coordinates must lie
within the current text viewport, otherwise, no cursor movement will take place.
COUNT is no longer correct. This form is only useful when positioning the cursor
on the screen as it uses control codes which will not be sent to a printer.
Examples
PRINT TAB(10) "Product";TAB(20) "Price"
INPUT TAB(0,10)"How many eggs",eggs%
406
Keywords
TAN
Function returning the tangent of its argument.
Syntax
TAN factor
Argument
A real number interpreted as an angle in radians.
Result
A real giving the tangent of the angle.
Notes
For BASIC V if the argument is outside the range –8388608 to +8388608 radians, it
is impossible to determine how many πs to subtract. The error Accuracy lost
in sine/cosine/tangent is generated. For BASIC VI the range is larger, from
approximately –3E9 to +3E9 radians, and outside this range the error Floating
point exception: invalid operation is generated.
Examples
opp=adj*TAN(RAD(theta))
407
TEMPO
TEMPO
Function returning or statement altering the beat counter rate.
Syntax
as a statement:
(1) TEMPO expression
as a function:
(2) TEMPO
Argument (1)
expression is a scaled fractional number, in which the 12 least-significant bits
are the fractional part. Thus a value of &1000 corresponds to a tempo of one tempo
beat per centi-second; doubling the value (&2000) causes the tempo to double
(two tempo beats per centi-second), halving the value (&800) halves the tempo
(one beat every two centi-seconds).
The tempo determines the rate at which the beat counter increases.
Result (2)
A number giving the current tempo.
Examples
TEMPO &2000
PRINT TEMPO
DEF FNtempo=TEMPO/&1000
DEF PROCtempo(t) TEMPO t*&1000:ENDPROC
408
Keywords
TEXTLOAD
Command to load a BASIC file at PAGE.
Syntax
TEXTLOAD pathname
Argument
pathname is a string that should evaluate to a valid pathname. The file can be a
BASIC program, or a BASIC program that was saved as a text file (see TEXTSAVE).
If a text file is loaded which has lines without line numbers, TEXTLOAD
automatically renumbers it.
Notes
Any program which is currently in memory is overwritten and lost with all its
variables. The static integers (A% - Z% and @%) and INSTALLed libraries are not
affected.
Files loaded with this command must end in a linefeed, otherwise the last line will
be ignored and you will get a “Line too long” error.
Examples
TEXTLOAD "adfs::GDisc.disasm"
where GDisc is the name of a disc.
TEXTLOAD FNnextFile
409
TEXTSAVE
TEXTSAVE
Command to save a BASIC program to a text file.
Syntax
(1) TEXTSAVE pathname
(2) TEXTSAVEO expression, pathname
Argument (1)
pathname is a string that should evaluate to a valid pathname. The current BASIC
program is stored as a text file under this name.
Arguments (2)
expression should be in the range zero to 31, and is treated as a 5–bit binary
number. TEXTSAVEO is similar to TEXTSAVE, but when it converts the program to
text, it uses the LISTO–type option specified by expression to format the output
to the file given by pathname. See LISTO on page 323 for details of the possible
options.
Examples
TEXTSAVE "Version1"
TEXTSAVEO 8, "Version2" : REM strips out line numbers
410
Keywords
THEN
Optional part of a single line IF … THEN … ELSE statement and compulsory part
of multi-line IF … THEN … ELSE … ENDIF statement.
Syntax
See IF on page 304.
Examples
IF a>3 THEN PRINT "Too large" : REM THEN optional
IF mem THEN HIMEM = HIMEM - &2000
IF A$="Y" THEN 1200 ELSE GOTO 1400
MODE “X640 Y480 C4”
IF colour$ = "red" THEN
COLOUR 1
CLS
ELSE
COLOUR 0 : CLS
ENDIF
411
TIME
TIME
Pseudo-variable reading or altering the value of the centi-second clock.
Syntax
(1) TIME
(2) TIME = expression
Result (1)
An integer giving the number of centi-seconds that have elapsed since the last
time the clock was set to zero.
Argument (2)
expression is an integer value used to set the clock. TIME is initially set to the
lowest four bytes of the five–byte clock value maintained by the operating system.
Assigning to the TIME pseudo-variable alters the system centi-second timer (the
one which is read and written by OS_Words 1 and 2 respectively). There is,
however, an additional system clock which is monotonic: it always increases in
value with time, and cannot be reset by software. TIME does not affect this timer.
Notes
Setting the clock is not recommend in Wimp programs since it could cause
unexpected behaviour in other programs that use the clock.
Examples
DEF PROCdelay(n) T%=TIME+n*100:REPEAT UNTIL TIME>=T%
412
Keywords
TIME$
Pseudo-variable accessing the real-time clock.
Syntax
(1) TIME$
(2) TIME$ = expression
Result (1)
TIME$ returns a string of the format:
Fri,24 May 1984.17:40:59
The date and time part are separated by a full stop ‘.’, and the language used for
the day and month names will depend on the current territory.
Argument (2)
The expression should be a string specifying the date, the time, or both.
Punctuation and spacing are crucial and should be as shown in the examples
below. Note that the conversion of month names will be done in the language of
the current territory.
Examples
PRINT TIME$
TIME$="Tue,01 Jan 1972"
TIME$="21:12:06"
TIME$="Tue,01 Jan 1972.21:12:06"
Note that the day of the week is automatically calculated from the date, so that any
three characters may be entered at the start of the date, for example
TIME$="xxx,19 Aug 1987"
413
TINT
TINT
Part of the COLOUR or GCOL statements for use in 256-colour modes, or a
statement on its own, or a function.
Syntax
(1) COLOUR expr [TINT expression]
(2) GCOL [expr,] expr [TINT expression]
(3) TINT expression, expression
(4) TINT(expression,expression)
Arguments (3)
The TINT statement takes two expressions. The first is a number in the range 0 to 3
which indicates which type of colour’s tint value is being set:
Number Colour affected
0 Text foreground
1 Text background
2 Graphics foreground
3 Graphics background
The second expression is a number in the range 0 to 255. This gives the amount of
white to add to the basic colour. Currently, only the top two bits of this number are
significant, so 0, 64, 128 and 192 give distinct tint values.
The two lines below are equivalent:
GCOL 34 TINT 128
GCOL 34 : TINT 2,128
Result (4)
The two expressions within the brackets give the coordinates of the point whose
tint is required. The result is the tint for that pixel, currently one of the values 0, 64,
128 or 192. If the pixel is outside the graphics window, 0 is returned, so POINT()
should be used to check that the point is valid first.
414
Keywords
Notes
If you are using a 256-colour mode with a full palette it is possible to convert the
values returned by POINT and TINT into the logical colour number used by the
palette, but the mapping is not straightforward. It can be found as follows:
p% = POINT(x,y)
t% = TINT(x,y)
lc% = (p% AND 33)<<2 OR (p% AND 14)<<3 OR (p% AND 16)>>1 OR t%>>6
Examples
COLOUR 1+J% TINT N%
GCOL 128+63 TINT 255 : REM solid white
GCOL 3 TINT TINT(x,y) : REM NB two uses at once!
t=TINT(0,0)
415
TO
TO
Part of the FOR … NEXT statement.
Syntax
See FOR on page 293.
416
Keywords
TOP
Function returning the address of the end of the program.
Syntax
TOP
Result
TOP gives the address of the first byte after the BASIC program. The length of the
program is equal to TOP–PAGE. LOMEM is usually set to TOP (or the first word
above if TOP isn’t on a word boundary), so this is where the variables start.
Example
PRINT TOP
417
TRACE
TRACE
Statement to initiate or terminate line/procedure tracing.
Function returning the handle of a trace file.
Syntax
as a statement:
(1) TRACE [STEP] expression
(2) TRACE [STEP] ON
(3) TRACE [STEP] PROC
TRACE [STEP] FN
(4) TRACE OFF
(5) TRACE TO pathname
(6) TRACE CLOSE
(7) TRACE ENDPROC
as a function:
(8) TRACE
Argument (1)
expression is a line number. All line numbers below this line number are
printed out when they are encountered during the execution of the program.
Argument (5)
pathname is the name of the file to which TRACE output is directed.
Result (8)
If TRACE TO has been used to direct trace output to a file then the handle of this
file is returned, otherwise zero is returned.
Purpose
TRACE causes line numbers or procedure and function names to be printed as they
are encountered. In cases (1), (2) and (3), if STEP is present, BASIC will wait for a
key to be pressed before continuing after each traced item.
(1) TRACE expression traces only those lines with a line number below the
value of expression.
418
Keywords
(2) TRACE ON is the same as TRACE 65279, i.e. all line numbers are printed as
they are met.
(3) TRACE PROC traces procedures and functions only. TRACE FN can also be
used and has the same effect.
(4) TRACE OFF disables tracing, as does the default error handler.
(5) TRACE TO sends the output from TRACE to a specified file.
(6) TRACE CLOSE stops output to a named file (the interpreter closes the file
before exit). Note that errors found when writing to this file will cause it to
be closed.
(7) TRACE ENDPROC traces the exit of procedures and functions.
(8) The function TRACE returns either zero, or a file handle. It allows output
other than line numbers to be sent to the trace file, as in the last example
below.
History
(5), (6) and (8) were added in version 1.05, (7) was added in version 1.34.
Examples
IF debug THEN TRACE 9000
TRACE STEP PROC
IF debug THEN TRACE OFF
IF TRACE THEN BPUT#TRACE,"X is "+STR$X
419
TRUE
TRUE
Function returning the constant –1.
Syntax
TRUE
Result
TRUE always returns –1, which is the number yielded by the relational operators
when the condition is true. For example, 1+1<3 gives TRUE as its result.
Examples
debug=TRUE
IF debug PRINT"debug in operation"
420
Keywords
TWIN
Obsolete command previously used to enter the Twin text editor.
Syntax
TWIN
TWINO expression
Purpose
The TWIN keyword is no longer supported by BASIC, although it is still recognised.
Its purpose was to convert the current program to text and call the Twin editor (a
programmer’s editor sold by Acorn Computers as a separate product). TWINO was
similar, except that it converted the program to text using the LISTO-type option
that follows the command.
Since the Twin editor is no longer supported, using this command will result in a
Mistake error.
421
UNTIL
UNTIL
Statement to terminate a REPEAT loop.
Syntax
UNTIL expression
Argument
expression can be any numeric expression which can be evaluated to give a
truth value. If it is zero (FALSE), control passes back to the statement immediately
after the corresponding REPEAT. If the expression is non-zero (TRUE), control
continues to the statement after the UNTIL.
Examples
DEF PROCirritate
REPEAT VDU 7:UNTIL FALSE
ENDPROC
REPEAT PROCmove:UNTIL gameOver
422
Keywords
USR
Function returning the value of R0 after executing a machine code routine.
Syntax
USR factor
Argument
The address of the machine code to be called. Calls to the 6502-based BBC
Microcomputer operating systems are handled by USR for compatibility.
Result
An integer, being the contents of R0 on return to BASIC.
Notes
USR is similar to CALL except that it returns a result and cannot be passed any
parameters. On entry to the routine, R0..R14 are as for CALL. See page 234 for
details.
As with CALL, in BASIC V (but not BASIC VI) if the USR statement is used with an
address which corresponds to a MOS entry point on the BBC Micro/Acorn
Electron/Master series machines, then BASIC treats the call as if it had been made
from one of those machines. See BBC/Master compatible calls on page 246 for further
information.
Example
DEF FNmachinecode =USR(start_of_code)
423
VAL
VAL
Function returning the numeric value of a decimal string.
Syntax
VAL factor
Argument
A string of length zero to 255 characters.
Result
The number that would have been read if the string had been typed in response to
a numeric INPUT statement. The string is interpreted up to the first character that
is not a legal numeric one (0 to 9, E, -, +, and .).
Example
date=VAL(date$)
424
Keywords
VDU
Statement sending bytes to the VDU drivers or function reading VDU variables.
Syntax
as a statement:
(1) VDU [expr [, or ; or | or expr]...[; or |]
as a function:
(2) VDU expression
Arguments (1)
Any expressions may be followed by a comma, a semi-colon, a vertical bar, or
nothing.
Expressions followed by a semi-colon are sent as two bytes (low byte first) to the
operating system VDU drivers.
Expressions followed by a comma (or nothing) are sent to the VDU drivers as one
byte, taken from the least significant byte of the expression.
The vertical bar means ,0,0,0,0,0,0,0,0,0, and so sends the expression
before it as a byte followed by nine zero bytes. Since the maximum number of
parameters required by any of the VDU statements is nine, the vertical bar ensures
that sufficient parameters have been sent for any particular call. Any surplus ones
are irrelevant, since VDU 0 does nothing.
Note: For the meanings of the VDU codes, see the chapter entitled VDU control
on page 177.
Argument (2)
expression is an integer giving the number of a VDU variable. See Appendix H – VDU
variables for the list of valid VDU variables.
Result (2)
The value of the specified VDU variable.
History
(2) was added in version 1.34
425
VDU
Examples
VDU 24,400;300;1000;740; : REM set up a graphics window
VDU 7 : REM Emit a beep
VDU 23,9,200|23,10,200| : REM Slow down the flash rate
TextColour = VDU 155 : REM Get the text foreground colour
426
Keywords
VOICE
Statement assigning a named sound algorithm to a sound channel.
Syntax
VOICE numeric-expression, string-expression
Arguments
numeric-expression is a number between 1 and 8 identifying a sound channel
and string-expression gives the name of the sound algorithm (voice) that
should be assigned to that channel. A list of installed voices can be found by using
the *VOICES command.
Notes
This statement is equivalent to the *CHANNELVOICE command.
Examples
VOICE 1,"StringLib-Steel"
427
VOICES
VOICES
Statement specifying the number of sound channels to be used.
Syntax
VOICES expression
Argument
expression is the number of channels to be used. The maximum number
allowed is eight. Any number between 1 and 8 can be specified, but the number
which the computer is to handle must be a power of two and so the computer
rounds up the number you give to either one, two, four or eight.
Notes
Due to the way the sound system works, increasing the number of active channels
will result in a decrease in volume for each channel. Additionally, older computers
may experience a significant decrease in performance when many channels are
active. It is therefore considered good practice to minimise the number of active
channels.
Examples
VOICES 4
VOICES n%*2
428
Keywords
VPOS
Function returning the y-coordinate of the text cursor.
Syntax
VPOS
Result
An integer between 0 and n, where n is the height of the current text viewport
minus one. This is the position of the text cursor which is normally given relative to
the top edge of the text viewport. If the cursor direction has been altered using
VDU 23,16,… then it is given relative to the negative y edge of the screen which
may be top, bottom, left or right.
Notes
Even in VDU 5 mode, VPOS returns the position of the text cursor. You should
therefore keep track of the vertical position explicitly in programs which must
operate in VDU 5 mode (e.g. Wimp-based programs).
Examples
DEF FNmyTab(x%)
PRINT TAB(x%,VPOS);: =""
IF VPOS>10 THEN PRINT TAB(0,10);
429
WAIT
WAIT
Statement to wait for the end of the current display frame.
Syntax
WAIT
Purpose
To enable a program to synchronise animation effects with the scanning of the
display hardware. Waiting until the end of the frame maximises the amount of time
available in which to draw objects before the display of the next frame begins.
Examples
MODE "X640 Y480 C2"
a=0
REPEAT
POINT 1279,500+200*SINa
a+=RAD5
WAIT:RECTANGLE FILL 0,300,1279,400 TO -4,300
UNTIL FALSE
430
Keywords
WHEN
Part of the CASE … OF … WHEN … OTHERWISE … ENDCASE statement.
Syntax
WHEN expression [,expression...] [:statements]
[statements]
Arguments
WHEN is followed by a list of expressions separated by commas. These expressions
should evaluate to the same type as that of the expression following the
corresponding CASE statement. If the value of the expression following the CASE
statement matches that of any of the list following the WHEN, statements are
executed and control is then passed to the statement following the ENDCASE.
Notes
WHEN must be the first non-space object on a line. A CASE statement can contain
any number of WHEN statements, but only the statements of the first one which
contains a matching value will be executed. To match any value, an OTHERWISE
should be used.
Examples
WHEN 1 : PROCload
WHEN 2,4,6,8 : PRINT "Even" : remainder= 0
WHEN "Y","y","YES","Yes","yes" : PROCgame
431
WHILE
WHILE
Statement marking the start of a WHILE … ENDWHILE loop.
Syntax
WHILE expression
Arguments
expression can be any numeric which can be evaluated to give a truth value. If it
is zero (FALSE), control passes forward to the statement immediately after the
corresponding ENDWHILE. If it is non-zero, control continues until the
ENDWHILE statement is reached, then loops back to the WHILE statement, and
expression is re-evaluated.
Notes
The statements making up the body of the WHILE … ENDWHILE loop are never
executed if the initial value of expression is FALSE.
Examples
WHILE TIME < 1000
PROCdraw
ENDWHILE
WHILE flag : PROCmainloop : ENDWHILE
432
Keywords
WIDTH
Statement setting the line width for BASIC output, and function returning same.
Syntax
(1) WIDTH
(2) WIDTH expression
Result (1)
WIDTH returns the current print width, i.e. the last value used in a WIDTH
statement described below (or 0 by default).
Argument (2)
expression should be a positive integer. Expressions in the range 1 to
2147483627 cause BASIC to print a new line and reset COUNT to zero every time
COUNT exceeds that number. If the expression is 0, BASIC stops generating
auto-newlines, which is the default.
Examples
WIDTH 0: REM 'infinite width'
WIDTH 40: REM newline every 40 characters horizontally
PRINT WIDTH
433
WIDTH
434
28 * Commands
T his chapter describes the full syntax of the four * commands that can be used
to start BBC BASIC.
All four commands take the same options, and the only difference between them is
that they each start BASIC with a different way of handling floating point numbers.
435
*BASIC
*BASIC
The command to enter the BASIC V interpreter.
Syntax
*BASIC [options]
Purpose
To activate the BASIC interpreter.
The options control how the interpreter will behave when it starts, and when any
program that it executes terminates. If no option is given, BASIC simply starts with
a message of the form:
ARM BBC BASIC V (C) Acorn 1989
Starting with 651516 bytes free
The number of bytes free in the above message will depend on the amount of free
RAM available to BASIC, determined by the size of the Next slot set by the
*WimpSlot command. The first line is also used for the default REPORT message,
before any errors occur.
One of three options may follow the *BASIC command to cause a program to be
loaded, and, optionally, executed automatically. Alternatively, you can use a
program that is already loaded into memory by passing its address to the
interpreter. Each of these possibilities is described in turn below.
In all cases where a program is specified, this may be a tokenised BASIC program,
as created by a SAVE command, or a textual program, which will be tokenised (and
possibly renumbered) automatically.
*BASIC -help
This command causes BASIC to print some help information describing the
options documented here. Then BASIC starts as usual.
*BASIC [-chain] filename
If you give a filename after the *BASIC command, optionally preceded by the
keyword -chain, then the named file is loaded and executed. When the program
stops, BASIC enters immediate mode, as usual.
436
* Commands
Examples
*BASIC
*BASIC -quit shellProg
*BASIC @000ADF0C,000AE345
*BASIC -chain fred
437
*BASIC64
*BASIC64
The command to enter the BASIC VI interpreter.
Syntax
*BASIC64 [options]
Purpose
This has exactly the same purpose as the *BASIC command, and takes the same
options, the only difference being that it enters the BASIC VI interpreter instead of
the BASIC V interpreter.
If no option is given, BASIC VI simply starts with a message of the form:
ARM BBC BASIC VI (FPA) (C) Acorn 1989
Examples
*BASIC64
*BASIC64 -quit shellProg
*BASIC64 @000ADF0C,000AE345
*BASIC64 -chain fred
438
* Commands
*BASICFPA
The command to enter the FPA variant of the BASIC VI interpreter.
Syntax
*BASICFPA [options]
Purpose
This has exactly the same purpose as the *BASIC64 command, and takes the
same options, the only difference being that it specifically enters the FPA variant of
the BASIC VI interpreter.
If no option is given, BASIC VI simply starts with a message of the form:
ARM BBC BASIC VI (FPA) (C) Acorn 1989
Examples
*BASICFPA
*BASICFPA -quit shellProg
*BASICFPA @000ADF0C,000AE345
*BASICFPA -chain fred
439
*BASICVFP
*BASICVFP
The command to enter the VFP variant of the BASIC VI interpreter.
Syntax
*BASICVFP [options]
Purpose
This has exactly the same purpose as the *BASIC64 command, and takes the
same options, the only difference being that it specifically enters the VFP variant of
the BASIC VI interpreter.
If no option is given, BASIC simply starts with a message of the form:
ARM BBC BASIC VI (VFP) (C) Acorn 1989
Examples
*BASICVFP
*BASICVFP -quit shellProg
*BASICVFP @000ADF0C,000AE345
*BASICVFP -chain fred
440
29 ARM assembler
441
Using the BASIC assembler
Memory pointers
You need to tell the assembler the start address of the area of memory you have
reserved. The simplest way to do this is to assign P% to point to the start of this
area. For example:
DIM code% required_size
...
P% = code%
P% is then used as the program counter. The assembler places the first assembler
instruction at the address P% and automatically increments the value of P% by four
so that it points to the next free location. When the assembler has finished
assembling the code, P% points to the byte following the final location used.
Therefore, the number of bytes of machine code generated is given by:
P% - code%
442
ARM assembler
It is important to ensure that the number of bytes generated does not exceed the
size of the space that was reserved, otherwise the generated code will overwrite
other data in the BASIC heap and cause the program to fail.The assembler will
check this for you if you set L% to the address of the end of the reserved memory
(i.e. code% + required_size) and set bit 3 of the directive OPT, which is
described in more detail below.
Offset assembly
The method described so far assumes that you wish subsequently to execute the
code at the location at which it was assembled, or that your code is position
independent.
The position in memory at which you load a machine code program may be
significant. For example, it might refer directly to data embedded within itself, or
expect to find routines at fixed addresses. Such a program only works if it is loaded
in the correct place in memory. However, it is often inconvenient to assemble the
program directly into the place where it will eventually be executed. This memory
may well be used for something else whilst you are assembling the program. The
solution to this problem is to use a technique called ‘offset assembly’ where code
is assembled as if it is to run at a certain address but is actually placed at another.
To do this, set O% to point to the place where the first machine code instruction is
to be placed and P% to point to the address where the code is to be run.
To notify the assembler that this method of generating code is to be used, the
directive OPT, which is described in more detail below, must have bit 2 set.
It is however usually easy, and always preferable, to write ARM code that is
position independent, in which case offset assembly is not required, or can be
used with P% set to 0.
Implementing passes
Normally, when the processor is executing a machine code program, it executes
one instruction and then moves on to the one following it in memory. You can,
however, make the processor move to a different location and start processing
from there instead by using one of the ‘branch’ instructions. For example:
.result_was_0
...
BEQ result_was_0
The fullstop in front of the name result_was_0 identifies this string as the name
of a ‘label’. This is a directive to the assembler which tells it to assign the current
value of the program counter (P%) to the variable whose name follows the fullstop.
443
Using the BASIC assembler
BEQ means ‘branch if the result of the last calculation that updated the PSR was
zero’. The location to be branched to is given by the value previously assigned to
the label result_was_0.
The label can, however, occur after the branch instruction. This causes a slight
problem for the assembler since when it reaches the branch instruction, it hasn’t
yet assigned a value to the variable, so it doesn’t know which value to replace it
with. The same issue will apply to instructions such as LDR and STR which refer to
labels that come after the instruction.
You can get around this problem by assembling the source code twice. This is
known as two-pass assembly. During the first pass the assembler assigns values to
all the label variables. In the second pass it is able to replace references to these
variables by their values.
It is only when the text contains no forward references of labels that just a single
pass is sufficient.
These two passes may be performed by a FOR…NEXT loop as follows:
DIM code% required_size
L%=code% + required_size
FOR pass% = 0 TO 10 STEP 10
P% = code%
[
OPT pass%
... further assembly language statements and assembler directives
]
NEXT pass%
Note that the pointer(s), in this case just P%, must be set at the start of both
passes.
444
ARM assembler
From memory
From memory, the resulting machine code can be executed in a variety of ways:
CALL address
USR address
These may be used from inside BASIC to run the machine code at a given address.
445
Format of assembly language statements
From file
The commands below will load and run the named file, using either its filetype
(such as &FF8 for absolute code) and the associated Alias$@LoadType_XXX
and Alias$@RunType_XXX system variables, or the load and execution
addresses defined when it was saved.
*name
*RUN name
*/name
We strongly advise you to use file types rather than load and execution addresses.
446
ARM assembler
● The first four operations initialise the reserved memory to the values specified
by the operand. In the case of DCS the operand field must be a string
expression. In all other cases it must be a numeric expression. EQUB (and =),
EQUW, EQUD, EQUS, EQUFS, EQUFD and EQUFE are synonyms for these
directives.
● The ALIGN directive ensures that the next P% (and O%) that is used lies on a
word boundary. It is used after, for example, a DCS to ensure that the next
instruction is word-aligned. Any unused bytes are set to zero.
● ADR assembles a single instruction – typically but not necessarily an ADD or
SUB – with reg as the destination register. It obtains addr in that register. It
does so in a PC-relative (i.e. position independent) manner where possible.
Recommended Books
One or more of these books will be useful if you are writing a lot of ARM assembler.
● ARM Architecture Reference Manual, Second Edition, edited by David Seal :
Addison-Wesley, 2000, 816 pages, ISBN 0-201-73719-1.
This book is also known as the ‘ARM ARM’ and is an essential reference for
anyone working at a low level with the ARM processor, but its style makes it
unsuitable as introductory reference.
The paper version has not been re-issued since architecture 5TE, but the
electronic version receives updates a few times per year. It is available in PDF
format free of charge from ARM’s website, although you do need to register
first. The manual had a major reworking after architecture 6, when the ‘UAL’
assembler syntax was introduced, and it is now distributed in separate
editions for profile ‘M’ CPUs and other CPUs. The final pre-UAL version of the
manual is also still available. See:
ARMv8-A Architecture Reference Manual
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0487b.a/index.html
ARMv7-AR Architecture Reference Manual
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0406c/index.html
ARMv5 Architecture Reference Manual (includes pre-UAL architecture 6)
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0100i/index.html
Note that the above URLs were correct at the time of publication but are
subject to change.
● ARM 7500FE Data Sheet, document number ARM DDI 0077B, ARM Ltd, 1996,
365 pages, and CL-PS7500FE Advance Data Book, document number
447500-001, Cirrus Logic, 1997, 251 pages. These include the official
documentation of the final hardware implementation of the FPA, so represent
the best and most easily-obtained reference for that part of the instruction set.
Note that these instructions are not included in the ARM ARM.
447
Recommended Books
● Intel XScale Core Developer’s Manual, Intel Corporation, 2004, 220 pages. The
definitive reference for the XScale coprocessor 0.
● ARM Assembly Language: Fundamentals and Techniques, William Hohl, CRC
Press, 2009, 371 pages, ISBN 978-1439806104.
Despite the publication date, this reportedly only describes architectures up to
4T.
● ARM Assembly Language – an Introduction, J.R. Gibson : Lulu Enterprises,
2007, 244 pages, ISBN 978-1847536969.
● ARM System-on-Chip Architecture, 2nd Edition, Prof. Steve Furber :
Addison-Wesley, 2000, 432 pages, ISBN 978-0201675191.
By one of the original designers of the ARM, this is now showing its age, and
only covers up to architecture 5TE.
● The ARM RISC Chip – A Programmer’s Guide, A. van Someren and C. Atack –
Wokingham, UK: Addison-Wesley, 1993, 400 pages, ISBN 0201624109.
This is a good introduction to the ARM although the book is now rather dated
and only covers up to architecture 3.
● Archimedes Assembly Language: A Dabhand Guide, second edition, M. Ginns
– Manchester, UK: Dabs Press, 1988, 368 pages, ISBN 1870336208.
Out of print and difficult to obtain, but useful as it specifically refers to using
RISC OS and the built-in BBC BASIC assembler.
● ARM Assembly Language Programming, P.J. Cockerell – Computer
Concepts/MTC, 1987, ISBN 0951257900.
Out of print and difficult to obtain. Only covers architecture 2a, of historic
interest.
448
Part 4 – Appendices
449
450
Appendix A – Numeric implementation
B efore you can perform any arithmetic operations, you need to know how the
computer handles numbers, and what limitations there are on their use.
This appendix describes the different types of numbers you can use with BBC
BASIC, tells you how they are stored and manipulated, and explains what
limitations this places on your programs.
Numeric types
You can use the following numeric types with BBC BASIC:
Integers
These are whole numbers, which can be represented exactly by the computer, for
example:
1
2
1024
451
Numeric types
The most important factor governing numeric types is the amount of memory used
to store them. For the purposes of this description, we will only consider integers
and floating point numbers.
BASIC VI uses the following storage sizes for numeric types:
Numeric type Storage size
Integers 4 bytes (32 bits)
Floating point numbers 8 bytes (64 bits)
Remember that BASIC V only supports integers and 5–byte reals (we shall use the
term n–byte reals to mean n–byte floating point numbers). The following figures
show how the storage for each numeric type is organised.
Integer
bit bit
31 0
bit bit
31 30..............................20 19............................................. 0
452
Appendix A – Numeric implementation
bit bit
31 30..............................20 19............................................. 0
453
Effects of storage size
Range
The greater the storage size of a given numeric type, the greater the range of
numbers of that type that the computer can represent. For instance, integers are
stored in 4 bytes or 32 bits. The maximum positive integer that the computer can
represent is given by
2 ^ (32 – 1) – 1
which means 2 raised to the power of 31, minus 1, and is equal to 2147483647
The maximum positive real number that the computer can represent depends on
which type of real number you specify. For instance, the maximum positive 5-byte
real that the computer can represent is
1.7 × 1038
Accuracy
The accuracy of a number is determined by how many significant figures of the
number that the computer can show. The computer can show all the significant
figures in an integer (as long as it is within the representable range). However, it
must lose some of the significant figures of a floating point number.
For instance, the value of PI shown to three significant figures is 3.14. Shown to six
significant figures, it is 3.14159. BASIC VI can show up to 17 significant figures of a
floating point number, but this does not mean it is completely accurate. PI has an
infinite number of digits after the decimal point, and so the computer can only
print an approximation to it, by chopping off the trailing digits.
The table below summarises the numerical representation of BBC BASIC.
Range Accuracy Stored in
Integers –2147483648 to 2147483647 absolute 4 bytes
5–byte reals ±1.7×1038 to ±1.5×10–39 11 sig figs 5 bytes
8–byte reals ±1.7×10308 to ±1.5×10–323 17 sig figs 8 bytes
The rest of this appendix explains the two methods used by BASIC VI for
implementing 8-byte floating point arithmetic to IEEE standard 754. BASIC V uses
a software floating point implementation for its 5-byte reals, and is not IEEE 754
compliant.
454
Appendix A – Numeric implementation
Implementation
The three different BASIC modules (BASIC, BASIC64, BASICVFP) each implement
floating point arithmetic in different ways.
BASIC
The BASIC module, which contains the BBC BASIC V interpreter, uses the 5-byte
floating point format for real numbers. Because this is a non-standard format
which is not directly supported by any ARM hardware, all arithmetic operations are
implemented in software.
BASIC64
The BASIC64 module contains a version of the BBC BASIC VI interpreter which uses
the 8-byte IEEE 754 double-precision format for real numbers. The design and
implementation of the interpreter allows it to take advantage of the FPA floating
point co-processor; thus all real arithmetic is implemented in terms of the FPA
instruction set as opposed to using software routines like in the BASIC V
interpreter. On machines with FPA hardware this results in better performance than
that available with BASIC V.
Unfortunately the FPA instruction set was not very popular with manufacturers; the
newest CPU which provides a hardware implementation of FPA is the ARM7500FE
from 1996. On the vast majority of RISC OS machines, BASIC64 is dependent on
the floating point emulator module (FPEmulator), which hooks onto the Undefined
Instruction processor vector and provides a software implementation of the FPA
instruction set. On a machine without FPA hardware, real arithmetic performed in
BASIC64 will be many times slower than the equivalent code executed in the BASIC
V interpreter.
455
Implementation
BASICVFP
Like BASIC64, the BASICVFP module contains a version of the BBC BASIC VI
interpreter which uses IEEE 754 double-precision floating point. However instead
of using the obsolete FPA instruction set, it is tailored for the newer VFP
instruction set. Introduced by ARM in 2001, the VFP instruction set quickly gained
traction with manufacturers, to the extent that almost all general-purpose ARM
cores released after 2005 include hardware support for it.
Unfortunately the many differences between FPA and VFP, combined with the fact
that FPA usage has been deep-set in the design of some of BASIC64's public
interfaces, means that it would be prohibitively difficult to produce a version of
BASIC64 which uses VFP and provides good performance while still retaining full
compatibility with existing BASIC64 programs. Therefore the BASICVFP module
was developed as an alternative, allowing key areas to be re-designed so that the
best performance could be attained on modern CPUs.
Key differences between BASIC64 and BASICVFP are as follows:
● The memory representation of floating-point values is subtly different. FPA
stores double-precision floats with the sign and exponent in the first word,
while VFP stores them with the sign and exponent in the second word. This
may cause compatibility issues with software which uses the '|' indirection
operator, but for compatibility with BASIC data files, INPUT# and PRINT# still
read and write floating-point values using the FPA word ordering.
● The routines exposed by the CALL environment information pointer (e.g.
VARIND) all use VFP double-precision registers to accept and return floating
point values instead of FPA registers. This may cause compatibility issues with
assembler routines.
● If you wish to write VFP assembler routines in BASIC or BASIC64, you will have
to manually register with the VFPSupport module in order to be granted a VFP
context (without a VFP context, the VFP instructions are disabled). If you are
using BASICVFP however, you can just use the context that BASICVFP
provides, there is no need for your code to create a context of its own.
If you do want to create your own VFP context in BASICVFP, you must be careful not
to leave it active while the BASIC interpreter is running, its usage must be
restricted to just your assembler routines.
When using BASICVFP's VFP context, be careful when changing the control bits in
the FPSCR. For example, enabling Short Vector mode in an assembler routine and
then returning to BASIC without disabling it again is likely to result in memory
corruption or a crash.
456
Appendix A – Numeric implementation
457
Implementation
458
Appendix B – Minimum abbreviations
459
Keyword Abbr. Version Token byte(s)
460
Appendix B – Minimum abbreviations
461
Keyword Abbr. Version Token byte(s)
462
Appendix B – Minimum abbreviations
TAN T. I &B7
TEMPO TE. V &C8 &9F
TEXTLOAD TEXTL. V &C7 &9B
TEXTSAVE TEXTS. V &C7 &9C
THEN TH. I,V &8C
TIME TI. I,IV &D1 / &91
TIME$ TI.$ IV &D1 &24 / &91 &24
TINT TINT V &C8 &9C
TO TO I,V &B8
TOP TOP I &B8 &50
TRACE TR. I,V &FC
TRUE TRUE I &B9
TWIN TWIN V &C7 &9D
TWINO TW. V &C7 &9E
UNTIL U. I &FD
USR USR I &BA
VAL VAL I &BB
VDU V. I &EF
VOICE VOICE V &C8 &A1
VOICES VO. V &C8 &A0
VPOS VP. I &BC
WAIT WA. V &C8 &96
WHEN WHEN V &C9
WHILE W. V &C8 &95
WIDTH WI. I &FE
Where more than one version number is given, the second one indicates that the
keyword was employed in a new way in that version.
The two token values for the pseudo-variables LOMEM, HIMEM, PAGE, PTR and
TIME are the statement and function tokens respectively.
The two values for ELSE are the token used in a single-line IF statement and the
token used in multi-line IF statement respectively.
463
464
Appendix C – Error messages
465
Error Error
number message
3 Bad register
Duplicate register in multiply
Too many registers in list
VFP scalar must not change in register list
VFP scalar offset out of range
4 Missing =
Missing = in FOR statement
Mistake
5 Missing ,
6 Array type mismatch as parameter
Can't assign to array of this size
Can't SWAP arrays of different types
Type mismatch between arrays
Type mismatch: array needed
Type mismatch: number needed
Type mismatch: numeric array needed
Type mismatch: numeric variable needed
Type mismatch: string array needed
Type mismatch: string needed
Type mismatch: string variable needed
7 Not in a function
8 Too low a value for $<number>
9 Missing "
10 Arrays cannot be redimensioned
Bad DIM statement
Can't DIM negative amount
DIM() function needs an array
Impossible dimension
No end of dimension list )
No room to do matrix multiply with source(s)
the same as destination
11 Attempt to allocate insufficient memory
No room for program
No room for this DIM
No room for this dimension
466
Appendix C – Error messages
Error Error
number message
Unreferenced local array in END=
12 Items can only be made local in a function or
procedure
13 Not in a procedure
14 Reference array incorrect
Undimensioned array
Unknown array in DIM() function
Unknown array
15 Incorrect number of subscripts
Subscript out of range
16 Syntax error
17 Escape
18 Division by zero
19 String too long
20 Number too big for arc Sine or arc Cosine
Number too big
21 Negative root
22 Logarithm range
23 Accuracy lost in Sine/Cosine/Tangent
24 Exponent range
25 Bad MODE
26 Can't use array reference here
Unknown or missing variable
27 Missing (
Missing )
Missing [
Missing ]
Missing {
Missing }
28 Bad Binary
Bad Hex
Hex number too large
29 No such function/procedure
30 Bad call of function/procedure
467
Error Error
number message
31 Arguments of function/procedure incorrect
Invalid array actual parameter
Invalid RETURN actual parameter
32 Not in a FOR loop
33 Can't match FOR
34 Bad FOR control variable
35 The step cannot be zero
36 Missing TO
37 No room for function/procedure call
38 Not in a subroutine
39 ON syntax
40 ON range
41 No such line
42 DATA pointer not found on stack for RESTORE
DATA
Out of data
43 Not in a REPEAT loop
44 Too many nested structures
45 Missing #
46 Not in a WHILE loop
47 Missing ENDCASE
48 CASE..OF statement must be the last thing on a
line
OF missing from CASE statement
49 Missing ENDIF
50 Bad MOUSE variable
51 Too many input expressions for SYS
Too many output variables for SYS
52 Bad program used as function/procedure library
Can't install library
No room for library
53 Bad screen depth
54 END= not allowed within DIM LOCAL
55 Invalid arithmetic operation
468
Appendix D – INKEY values
In the following tables the key names shown in the Key column correspond to the
those printed on a standard UK-layout keyboard. Where the Acorn Archimedes
keyboard had different labels these are shown in square brackets.
469
INKEY values by functional group
Punctuation keys
Space Bar -99
# [\] -121
' -80
, -103
- -24
. -104
/ -105
; -88
= -94
[ -57
\ -95
] -89
‘ -46
Action keys
Esc -113
Tab -97
Return -74
Caps Lock -65
Backspace -48
Print Screen [Print] -33
Scroll Lock -32
Pause [Break] -45
Insert -62
Delete -90
Home -63
End [Copy] -106
Page Up -64
Page Down -79
470
Appendix D – INKEY values
Modifier keys
Shift (either/both) -1
Ctrl (either/both) -2
Alt (either/both) -3
Shift (left/right-hand) -4/-7
Ctrl (left/right-hand) -5/-8
Alt (left/right-hand) -6/-9
Function keys
F1 -114
F2 -115
F3 -116
F4 -21
F5 -117
F6 -118
F7 -23
F8 -119
F9 -120
F10 -31
F11 -29
F12 -30
471
INKEY values by functional group
Mouse buttons
Select (Left) -10
Menu (Middle) -11
Adjust (Right) -12
472
Appendix D – INKEY values
473
INKEY values by number
474
Appendix D – INKEY values
475
INKEY values by number
476
Appendix E – Specifying screen modes
T he MODE keyword provides several different ways for specifying the screen
mode to be selected. This appendix provides more detail on two of these
methods, specification by mode string and by mode variables.
Mode Strings
MODE string-expression
Mode strings consist of a list of space or comma separated attributes. For example,
"X640 Y480 C256" to describe a 256 colour 640 × 480 pixel mode.
In addition to the standard attributes described below, the string may start with a
mode number. If this is the case then the additional attributes will act as modifiers
on the base attributes of that mode. For example, "28 C16M" for a 16 million colour
version of mode 28.
Attributes
The following attributes are currently defined:
Attribute Details
X Mode X resolution in pixels, e.g. X1024
Y Mode Y resolution in pixels, e.g. Y768
C Number of colours:
C2 = 2 colours (1bpp)
C4 = 4 colours (2bpp)
C16 = 16 colours (4bpp)
C64 = 64 colours (VIDC1 style 256 colour mode) (8bpp)
C256 = 256 colours (8bpp)
C4K/C4T = 4096 colours (16bpp 4:4:4:4)
C32K/C32T = 32768 colours (16bpp 1:5:5:5)
C64K/C64T = 65536 colours (16bpp 5:6:5)
C16M = 16 million colours (32bpp 8:8:8:8)
G Number of greys/colours:
G2 = 2 greys (1bpp)
G4 = 4 greys (2bpp)
477
Mode Strings
Notes
Specifying the same attribute more than once, or specifying conflicting attributes
(e.g. both C and G attributes) is an invalid string and will result in an error.
Likewise, it is illegal to omit a required attribute. E.g. for a standard mode the X, Y
and C, G or T attributes must be provided unless a mode number has been
provided, in which case these attributes are optional as the default values will be
taken from the definition of that mode.
For colour depths which have no space for a transparency/alpha channel (e.g.
C64K, G16M) it is an error to specify a pixel layout which contains alpha. If the pixel
layout is to be specified then only the LTBGR or LTRGB layouts can be used.
For Teletext modes the number of colours given by the T attribute selects the pixel
depth of the underlying frame buffer and must be at least 16, but you can still only
actually use 16 colours in Teletext.
In Teletext modes the X and Y attributes select the size of the underlying frame
buffer and the TX and TY attributes select the number of Teletext characters that
are displayed within it. Depending on the OS version and platform you are using a
character is either 8 × 10 or 16 × 20 pixels in size, and the Teletext screen will either
be centred within the frame buffer or scaled to fill it.
Not all versions of RISC OS support all attributes:
● RISC OS 3.5 only understands the X, Y, C, G, F, EX and EY attributes. 4096 &
64K colour, and 24bpp packed are not supported, and neither is specifying a
base mode number
● RISC OS Select adds support for 64K colour modes, the T, TX and TY attributes,
and specifying a base mode number
478
Appendix E – Specifying screen modes
● RISC OS 5.22 supports all features except 24bpp packed modes and all
attributes except T, TX and TY
● T, TX and TY support is introduced in RISC OS 5.24.
Mode Variables
MODE x,y,ModeFlags,NColour,Log2bpp[,framerate]
The following table lists all the combinations of ModeFlags, NColour and Log2bpp
that can be used to select a valid screen mode, and gives the equivalent mode
string in each case.
ModeFlags NColour Log2BPP Result String Support
&0000 1 0 1bpp paletted C2 RISC OS 3.50
&0100 1 0 1bpp grey paletted G2 RISC OS 3.50
&0000 3 1 2bpp paletted C4 RISC OS 3.50
&0100 3 1 2bpp grey paletted G4 RISC OS 3.50
&0000 15 2 4bpp paletted C16 RISC OS 3.50
&0100 15 2 4bpp grey paletted G16 RISC OS 3.50
&0000 63 3 8bpp semi-paletted C64 RISC OS 3.50
&0080 255 3 8bpp paletted C256 RISC OS 3.50
&0180 255 3 8bpp grey paletted G256 RISC OS 3.50
&0000 4095 4 16bpp 4:4:4:4 TBGR C4K RISC OS 5.22
&4000 4095 4 16bpp 4:4:4:4 TRGB C4K LTRGB RISC OS 5.22
&8000 4095 4 16bpp 4:4:4:4 ABGR C4K LABGR RISC OS 5.22
&C000 4095 4 16bpp 4:4:4:4 ARGB C4K LARGB RISC OS 5.22
&0000 65535 4 16bpp 1:5:5:5 TBGR C32K RISC OS 3.50
&4000 65535 4 16bpp 1:5:5:5 TRGB C32K LTRGB RISC OS 5.22
&8000 65535 4 16bpp 1:5:5:5 ABGR C32K LABGR RISC OS 5.22
&C000 65535 4 16bpp 1:5:5:5 ARGB C32K LARGB RISC OS 5.22
&0080 65535 4 16bpp 5:6:5 BGR C64K RISC OS 5.22
&4080 65535 4 16bpp 5:6:5 RGB C64K LTRGB RISC OS 5.22
&0000 16777215 6 24bpp 8:8:8 BGR G16M Not yet
&4000 16777215 6 24bpp 8:8:8 RGB G16M LTRGB Not yet
&0000 –1 5 32bpp 8:8:8:8 TBGR C16M RISC OS 3.50
&4000 –1 5 32bpp 8:8:8:8 TRGB C16M LTRGB RISC OS 5.22
&8000 –1 5 32bpp 8:8:8:8 ABGR C16M LABGR RISC OS 5.22
&C000 –1 5 32bpp 8:8:8:8 ARGB C16M LARGB RISC OS 5.22
&0007 15 2 4bpp Teletext T16 RISC OS 5.24
Notes
● The 24bpp 8:8:8 modes are shown for completeness, but at the time of writing
RISC OS does not support such modes.
479
Mode Variables
● There are other possible values of ModeFlags that allow modes with different
colour formats, such as YCbCr or CMYK, to be specified, but at the time of
writing there is no support in RISC OS for graphics to be drawn in such modes.
● The eigen factors cannot be specified by this method.
480
Appendix F – Default palettes
Two-colour mode
0 = black
1 = white
Four-colour modes
0 = black
1 = red
2 = yellow
3 = white
16-colour modes
0 = black
1 = red
2 = green
3 = yellow
4 = blue
5 = magenta
6 = cyan
7 = white
8 = flashing black-white
9 = flashing red-cyan
10 = flashing green-magenta
11 = flashing yellow-blue
12 = flashing blue-yellow
13 = flashing magenta-green
14 = flashing cyan-red
15 = flashing white-black
256-colour modes
In 256-colour modes the default palette is set to match the colours available in
VIDC1-style 256-colour modes. This means that the bits of each colour number
map to the physical palette as follows:
481
Bit Meaning
0 Tint bit 0 (red+green+blue bit 0 and 4)
1 Tint bit 1 (red+green+blue bit 1 and 5)
2 Red bit 2 and 6
3 Blue bit 2 and 6
4 Red bit 3 and 7
5 Green bit 2 and 6
6 Green bit 3 and 7
7 Blue bit 3 and 7
For example, colour number 149 is composed as follows: 149 = %10010101, so the
tint bits are %01, the red bits are %11001100, the green bits are %00000000 and the
blue bits are %10001000. This means that the default palette entry uses a physical
colour with a red value of %11011101, a green value of %00010001 and a blue value
of %10011001 and the colour appears as a purple shade.
482
Appendix G – Plot codes
483
Within each block of eight the offset from the base number has the following
meaning:
0 Move cursor relative (to last graphics point visited)
1 Draw relative using current foreground colour
2 Draw relative using logical inverse colour
3 Draw relative using current background colour
4 Move cursor absolute (ie move to actual co-ordinate given)
5 Draw absolute using current foreground colour
6 Draw absolute using logical inverse colour
7 Draw absolute using current background colour
The above applies except for COPY and MOVE where the codes are as follows:
484
Appendix H – VDU variables
The VDU function (see page 425) can be used to read the following VDU variables:
Name No. Meaning
ModeFlags 0 The bits of the result have the following meanings if set:
Bit 0 Non-graphics mode
Bit 1 Teletext mode
Bit 2 Gap mode
Bit 3 ‘BBC’ gap mode (modes 3 and 6)
Bit 4 Hi-resolution mono mode
Bit 5 VDU characters are double height
Bit 6 Hardware scroll disabled
Bit 7 Full 256-entry palette
(only valid if Log2BPP is 3)
65536 colour RGB 5:6:5 mode
(if Log2BPP is 4 and NColour is 65535)
Bit 8 Interlaced mode using two framebuffers
Bit 9 Greyscale palette
(only valid in modes with a palette)
Chroma sub-sampling mode
(only valid if NColour is 420 or 422)
Bits 10-11 Reserved
Bits 12-15 Data format and colour space
Bits 12-13 Family Bits 14-15 Meaning
0 RGB 0 TBGR
1 TRGB
2 ABGR
3 ARGB
1 Misc 0 KYMC
1-3 Reserved
2 YCbCr 0 BT.601, full
1 BT.601, video
2 BT.709, full
3 BT.709, video
3 Reserved 0-3 Reserved
ScrRCol 1 Maximum column number for printing text ie number of
columns–1.
485
ScrBRow 2 Maximum row number for printing text ie number of
rows–1.
NColour 3 Maximum logical colour (for possible values see Mode
Variables on page 479).
XEigFactor 4 This indicates the number of bits by which an
X coordinate must be shifted right to convert to screen
pixels. Thus if this value is n, then one screen pixel
corresponds to 2n external coordinates in the X direction.
YEigFactor 5 This indicates the number of bits by which a Y coordinate
must be shifted right to convert to screen pixels. Thus if
this value is n, then one screen pixel corresponds to 2n
external coordinates in the Y direction.
LineLength 6 Offset in bytes from a point on a pixel row to the same
point on the pixel row below.
ScreenSize 7 Number of bytes one screen buffer occupies. This must
be a multiple of 256 bytes.
YShftFactor 8 Scaling factor for start address of a screen row. This
variable is kept for compatibility reasons and should not
be used.
Log2BPP 9 LOG base 2 of the number of bits per pixel (for possible
values see Mode Variables on page 479).
Log2BPC 10 LOG base 2 of the number of bytes per character. It is in
fact the LOG base 2 of the number of bytes per character
divided by eight. It would be exactly the same as
Log2BPP, except for the ‘double pixel’ modes.
XWindLimit 11 Number of x pixels on screen–1.
YWindLimit 12 Number of y pixels on screen–1.
GWLCol 128 Left-hand column of the graphics window (ic)
GWBRow 129 Bottom row of the graphics window (ic)
GWRCol 130 Right-hand column of the graphics window (ic)
GWTRow 131 Top row of the graphics window (ic)
TWLCol 132 Left-hand column of the text window
TWBRow 133 Bottom row of the text window
TWRCol 134 Right-hand column of the text window
TWTRow 135 Top row of the text window
OrgX 136 x coordinate of the graphics origin (ec)
OrgY 137 Y coordinate of the graphics origin (ec)
GCsX 138 x coordinate of the graphics cursor (ec)
GCsY 139 Y coordinate of the graphics cursor (ec)
OlderCsX 140 x coordinate of oldest graphics cursor (ic)
OlderCsY 141 Y coordinate of oldest graphics cursor (ic)
OldCsX 142 x coordinate of previous graphics cursor (ic)
OldCsY 143 Y coordinate of previous graphics cursor (ic)
486
Appendix H – VDU variables
487
● ec means external coordinates, where (0,0) means the graphics origin, and the
size of one unit depends on the resolution. The number of external units on a
screen is dependent upon the video mode used and the eigen factors
XEigFactor & YEigFactor. The graphics origin is stored in external coordinate
units, but is relative to the bottom left of the screen.
● HLineAddr points to a fast horizontal line draw routine. It is called as follows:
R0 = left x coordinate of end of line
R1 = y coordinate of line
R2 = right x coordinate of end of line
R3 = 0 plot with no action (ie do nothing)
1 plot using foreground colour and action
2 invert current screen colour
3 plot using background colour and action
≥4 pointer to colour block (on 64-byte boundary):
Offset Value
0 OR mask for top ECF line
4 exclusive OR mask for top ECF line
8 OR mask for next ECF line
12 exclusive OR mask for next ECF line
…
56 OR mask for bottom ECF line
60 exclusive OR mask for bottom ECF line
R14 = return address
Must be entered in SVC mode
All registers are preserved on exit
All coordinates are in terms of pixels from the bottom left of the screen. The
line is clipped to the graphics window, and is plotted using the colour action
specified by R3. The caller must have previously called OS_RemoveCursors
and call OS_RestoreCursors afterwards.
● GcolOraEorAddr points to colour blocks for current GCOLs. If the value returned
is n, then:
n+&00–n+&3F is a colour block for the foreground colour + action
n+&40–n+&7F is a colour block for the background colour + action
n+&80–n+&BF is a colour block for the background colour with store
action
Each colour block is as described above. These are updated whenever a GCOL
or TINT is issued or the ECF origin is changed. They are intended for programs
which want to access screen memory directly and have access to the current
colour/action settings.
488
Appendix I – BBC BASIC’s history
T his appendix is designed to pinpoint the variations found among the dialects
of BBC BASIC. You can use it to determine whether a given feature of the
language is present in a particular version. You should also refer to Appendix B –
T
Minimum abbreviations on page 459. This gives the version number of the first
appearance of each keyword. For example, OSCLI has II in the version column, as
the OSCLI statement was first introduced in BASIC II.
There have been six major releases of BBC BASIC, the latest being BASIC VI, and a
number of subsequent improvements. This appendix lists the differences between
each version of BASIC that has been included in a stable RISC OS release.
BASIC I
The original version supplied with early BBC Microcomputers, models A and B.
BBC BASIC is in turn descended from Atom BASIC, a fast integer-only BASIC
supplied with the Acorn Atom.
BASIC II
This was an update to BASIC I. It also ran on the BBC models A and B. It
incorporated various bug fixes to BASIC I, and added the OPENUP and OSCLI
keywords, and offset assembly. Version II is the principal BBC Microcomputer
version of BBC BASIC.
BASIC III
This was supplied on the BBC Microcomputer model B+. It was substantially
unchanged from version II. There were one or two bug fixes, and a new keyword: the
American spelling of the COLOR statement.
BASIC IV
Also known as CMOS BASIC, this version was a major development from BASIC III.
It was designed for use on the BBC Master series and 65C12 Second Processors.
Both these used a slightly more powerful version of the 6502 processor than the
one used in the original BBC. This allowed several major enhancements to be
squeezed into the ROM, such as LIST IF, EXT# as a statement, EDIT, TIME$, ON …
PROC, | in VDU statements and faster floating point. Some bugs were also
corrected.
489
BASIC V, version 1.04
Developed for Acorn RISC computers. BASIC V built on the foundations provided
by BASIC IV. However, because of the lack of restrictions such as 16 kBytes total
code size, the enhancements made were far greater than those that appeared
previously. The interpreter was by now about 61 kBytes long, including
comprehensive built-in help text, and was probably the most powerful BASIC
found on any computer. It was certainly the fastest interpreted BASIC in the world.
490
Appendix I – BBC BASIC’s history
491
BASIC V & VI, version 1.75
This version, included in RISC OS 5.24, adds the VFP version of BASIC VI, improves
the conversion of floating point numbers to strings, and enhances the MODE
keyword. It also adds support for ARMv6, ARMv7 and ARMv8 instructions to the
assembler, as well as fixing an error in the assembler introduced in version 1.59.
This is the version described in this manual.
BASIC II improvements
492
Appendix I – BBC BASIC’s history
Bit 2 of the assembler OPT expression is used to control offset assembly. If this bit
is set, P% holds the run-time location counter, and O% holds the assembly-time
counter where bytes are actually assembled to. If bit 2 is clear, P% holds both the
run-time and assembly-time counters.
Four new assembler directives are introduced: EQUB, EQUW, EQUD, EQUS. These
allow one-, two-, four- and multiple-byte (string) quantities to be embedded into
the code.
Bug fixes
ELSE in an ON … GOTO/GOSUB no longer leaves a byte on the 6502 stack. This
prevented ELSE from being used in ON statements in BASIC I.
INSTR no longer leaves the main string on the software stack when it is shorter
than the substring. This caused ENDPROC and =expression to crash when INSTR was
used inside a PROC or FN under the above-mentioned condition.
The argument of EVAL is now tokenised correctly so that EVAL"TIME" (or any other
pseudo-variable) works. Previously the statement versions of pseudo-variables
were used, resulting in a No such variable error when BASIC tried to evaluate
the expression.
The ABS function can now cope with non-negative integers without returning a
string type. Previously, ABS1 appeared to yield a string so a statement like PRINT
-ABS1 would give a type-mismatch error.
The LN and LOG functions have been re-written. This makes them more accurate
and avoids a problem when BASIC tried to evaluate LN(2E–39). Other changes to
the arithmetic package are a fix to a bug which caused INT1E39 to fail and the
re-coding of the SIN/COS routine to make it more accurate.
A bug associated with ON ERROR GOTO 9999 (and other line numbers) has been
fixed.
DIM var n where n is an expression less than –1 now gives a Bad DIM error instead
of lowering the value of the free space pointer. This former action could result in
the corruption of variables or the program.
493
A string expression in a SAVE command works correctly now, so you can say, for
example, SAVE A$+B$ without error.
The indirection operators ? and ! may be used as formal parameters without
problems. For example, you could have a procedure DEF PROCa(!&70), where
the contents of locations &70..&73 act as a local integer variable.
BASIC IV improvements
The ON … GOTO/GOSUB statement has been extended to include PROCs. The
syntax is ON expression PROCa, PROCb, PROCc… [ELSE statement]. The nth PROC
in the list is called, where n is the value of expression.
The EDIT command converts the program to text and then calls the editor with a
*EDIT command. The program can be edited then re-tokenised by returning to
BASIC. A No room error will be given if there is not enough room to store both the
tokenised and textual version of the program during conversion to text.
The TIME$ pseudo-variable can be used to display and alter the time held in the
CMOS battery-backed clock.
The delimiter | may be used in VDU statements to send nine 0 bytes after the last
expression. This can be used to ensure that, for example, VDU 23 commands which
require many trailing zeros are correctly terminated.
LISTO bits 1 and 2 (which cause loops to be indented) now work correctly,
inasmuch as the NEXT lines up with its FOR and UNTIL with its REPEAT. If LISTO is
non-zero, leading spaces are stripped from input lines (i.e. between the
line-number and first statement). Trailing spaces are always stripped.
LIST has been extended by adding the IF part to it. LIST IFtext will only list lines
which contain text.
The function EXT# returning the length of the file may now also be used as a
statement to set the length of a file (EXT#chan=expr). It relies for its operation on an
OSARGS call supported by ADFS and ANFS.
AUTO no longer prints a space after the line number, as this wasn’t part of the
input line anyway.
The assembler supports the full 65C12 instruction set, and now accepts lower case
in all circumstances (e.g. the x in lda &70,x which previously had to be in upper
case).
RENUMBER and LIST no longer get confused by the presence of an &8D Teletext
control character in REM statements. (&8D is used in internal-format line numbers
by BASIC).
494
Appendix I – BBC BASIC’s history
In previous versions, a FOR loop which used an FN in the start, end or step
expressions, where the FN itself contained a FOR loop would not work properly.
This has been fixed.
The random number generator gives different results from previous versions for
RND(1) and RND(n). This is to avoid certain statistical problems.
A bug whereby it was possible to RESTORE to a line which had no DATA statement
but a comma present has been fixed.
495
Attempts to set PAGE, LOMEM or HIMEM to incorrect values will result in an error
message being printed, but execution will continue.
Many new statements have been introduced. The relevant keywords are: BEATS,
BPUT#, CIRCLE, COLOUR, ELLIPSE, END, ERROR, EXT, FILL, GCOL, LINE, INPUT,
LEFT$, MID$, RIGHT$, MOUSE, ON, OFF, ORIGIN, POINT, QUIT, RECTANGLE,
SOUND, STEREO, SWAP, SYS, TEMPO, VOICE, VOICES, WAIT.
Several new functions have also been introduced. The keywords are: BEAT, BEATS,
DIM, END, GET$#, LEFT$, MODE, REPORT$, RIGHT$, SUM, SUMLEN, TEMPO.
Some new commands have been introduced. They are: APPEND, HELP, LISTO
(enhanced), LVAR, SAVE (enhanced), TWIN, TWINO. Additionally, the *BASIC
command itself now supports several command-line options and arguments.
All error messages have been made more useful, and many new error messages
have been introduced.
The assembler accepts the full ARM instruction set. Full details of the assembler
are given in the chapter entitled ARM assembler on page 441.
CALL and USR may be used to call ARM assembler routines, or to emulate
6502-based MOS routine when supplied with the appropriate addresses. Access to
many internal BASIC routines is (legally) available to writers of CALL, USR and
OSCLI routines. SYS can be used to access operating system SWI routines.
The default error handler sets @% to a value which ensures that the line number
will be printed as an integer. It restores @% at the end.
COUNT and WIDTH are now stored as 32-bit wide quantities. This means that
tabulation using commas is more reliable. (Strange effects used to occur after 255
characters had been printed.)
The pseudo-variables may now be used as statements after an IF even when the
THEN is omitted. That is, IF relocate% PAGE=PAGE+&10000 will work, even
though it didn’t previously.
Integer FOR statements that would overflow will be ignored. (Basically this means
that if limit+step–1 / &7FFFFFFF, the loop will terminate at the NEXT.)
496
Appendix I – BBC BASIC’s history
END= can now be used almost anywhere, with the following exceptions: nested
within EVAL or LOCAL ERROR; nested within assignments to local arrays; within
nested local arrays.
The @% print formatter now uses ANSI G, E or F formats. If you use the 1.04
interpreter, you can achieve the same results using the method given in the
description of the PRINT command.
The new TEXTLOAD command can load a file that is either a BASIC program, or a
BASIC program that was saved as a text file. In the latter case, TEXTLOAD
automatically renumbers the program. TEXTSAVE stores a BASIC program as a text
file, and strips out the line numbers.
The TRACE command is now more versatile. Output from a TRACE command can
now be sent to a file, using TRACE TO filename. TRACE can also be used as a
function, to enable output other than line numbers to be sent to the trace file.
The speed of the following array statements has been increased:
foo()=<expression>
foo%()=<expression>
foo()=fie()
DIM foo(, foo(, foo%
The interpreter now tags error messages with the name of the library which caused
the error message (found from the REM statement on the first line of the library).
The interpreter can now handle such things as TAN1E–5.
PRINT –1^–10 will now print the value 1, instead of causing a crash.
There is now no difference between IF THEN ELSE and IF THENELSE.
497
INPUT# can now read variables in both 5–byte real format and 8–byte real format.
PRINT# only prints numbers in 8–byte real format.
498
Appendix I – BBC BASIC’s history
COLOUR and GCOL have been enhanced to allow colour numbers rather than
old-style colours and to allow background colours can be set with R,G,B forms:
COLOUR [OF f] [ON b]
COLOUR [[OF] r,g,b] [ON r,g,b]
GCOL [OF [action],f] [ON [action],b]
GCOL [[OF] [action,]r,g,b] [ON [action,]r,g,b]
For COLOUR r,g,b, the OF is unnecessary, but provided for uniformity. For GCOL
r,g,b, OF tightens up the usage of action – without it action is passed in to both R3
and R4 of ColourTrans_SetGCOL for backwards compatibility (some programs may
have used GCOL 128,r,g,b to set the background colour, although this ends up
setting reserved flags in the ColourTrans_SetGCOL call).
Used as a function VDU n now returns the value of the specified VDU variable.
BASIC will now surrender application space if possible at certain moments: during
SYS calls (as long as no string parameters are passed in), MODE changes, OSCLI
and * commands. Also, it will not refuse requests to grow application space
(although it will not expand into the extra space). Application space is only
surrendered if no library is INSTALLed, HIMEM is set to the top of BASIC's
memory, and BASIC's memory extends to the top of the application slot. This
permits easy MODE changes etc outside the desktop. Note the effect that now
outside the desktop, with screen memory at <300K and no free pool, MODE 28 will
work, while VDU 22,28 will not.
The new DIM var LOCAL expr syntax allows blocks to be claimed local to a
procedure or function that are automatically released on exit or error. In addition
DIM var LOCAL –1 can be used to obtain the value of SP at the time of request.
Performance on StrongARM and later processors has been slightly improved.
Expression evaluation for the WHEN statement has been improved so that syntax
errors such as WHEN (R%>>25) AND 1)=1 are not incorrectly evaluated.
Problems that would occur when using memory addresses above 64M have been
resolved.
An issue that meant untokenised programs could not be loaded via the *BASIC
command on XScale and later processors has been fixed.
Performance has been improved when BASIC copies data from unaligned
addresses.
499
Keywords that take tokenised line numbers no longer cause number tokenisation if
they appear on the right. This fixes BPUT#TRACE,32 but unfortunately breaks
statements such as IF F% THEN 30.
In the assembler STRT/LDRT now enforce post-indexing. LDRT R0,[R1]
generates correct code, and LDRT R0,[R1,#0] will be faulted.
500
Appendix I – BBC BASIC’s history
BASIC will now correctly report ERL after an external abort. Previously when
external code was called using CALL, USR, SYS, or a *command (either directly or
using OSCLI), and that code failed with a Data Transfer, Undefined Instruction or
Instruction Fetch abort, ERL was often set to the last line of the program, rather
than the line containing the CALL, USR, SYS or *command.
501
A new version of BASIC VI has been added which uses the VFP instruction set
found on modern ARM processors. The *BASIC64 command will now automatically
start either the VFP or FPA version of BASIC VI as appropriate for the current CPU,
and the new *BASICVFP and *BASICFPA commands allow each variant to be
started explicitly.
MODE string now uses OS_ScreenMode 15 rather than *WimpMode, to avoid
programs which use it altering the Wimp mode or having to worry about preserving
it. If OS_ScreenMode 15 isn't supported internal mode string parsing code that
provides a similar level of functionality to the host system's *WimpMode is used.
All MODE variants which use OS_ScreenMode now detect any “SWI not known”
error and replace it with “Bad MODE” (under the assumption the user is running a
version of RISC OS older than 3.50).
MODE x,y,ModeFlags,NColour,Log2bpp[,framerate] has been added to allow
specification of the three parameters necessary for selecting the new screen modes
introduced by RISC OS 5.
The HELP keyword no longer returns help for the obsolete TWIN and TWINO
keywords.
The assembler no longer globally flushes the cache after assembly.
502
Index
Symbols Numerics
^ 32 256-colour modes 110, 113
! 32, 166
? 32, 166
. (matrix multiplication) 51
" 39 A
( 32 ABS 219
) 32 absolute coordinates 124
@% 57, 367 ACS 220
* 32 actual parameter 88
* Commands 435 ADVAL 221
/ 32 ALIGN directive 446
& 33 amplitude, sound 161
% 33 AND 32, 36, 75, 223
+ 32 APPEND 25, 224
+ (string concatenation) 40 arc plot 134
+= 31 arithmetic operator 31
+= (string lengthen) 40 array 47
+= (with arrays) 49 array operations 49
< 32, 74 ASC 43, 225
<< 32, 34 ASCII 43
<= 32, 74 ASN 226
<> 32, 74 assembler
– 32 format of language statements 446-447
–= 31 implementing passes 443-444
= 30, 32, 74 memory pointers 442-443
= (assembler directive) 446 OPT directive 444-445
–= (with arrays) 49 reserving memory for machine code 442
=expression 87 using BASIC variables 442
> 24, 32, 74 assembly language, calling subroutines 234
>= 32, 74 assignment 29, 30
>> 32, 35 ATN 227
>>> 32, 35 AUTO 21, 228
| 32, 167 automatic line numbering 21
~ 45, 56
$ 32, 167
503
byte DIM 165
B byte indirection 166
background colour 111, 122
teletext 154
bases 33
base 16 33 C
base 2 33 CALL 234
*BASIC 436 CASE 82, 248
BASIC assembler see assembler CHAIN 249
BASIC interpreter 5 changing colour 111
BASIC screen editor 191, 193-211 changing text size 110
altering text 195 channel number 101
block copy 200 channel, sound 161
block move 200 *CHANNELVOICE 427
cursor movement 195 character input 65
deleting lines 200 CHR$ 43, 250
deleting text 196 CIRCLE 121, 251
EDIT 193 circle
errors 208 outline 121, 132
insert/overtype 203 solid 121, 132
inserting text 195 CIRCLE FILL 14, 121
keys 205 CLEAR 252
line commands 199 CLG 253
loading programs 196 CLOSE# 102, 254
marking lines 199 CLS 14, 255
mode 204 COLOR 256
renumbering 198 COLOUR 111, 256
saving programs 196 colour
searching 202 changing 111
status line 194 modes 110, 481
wildcards 203 palette 112
windows 205 pattern 139
*BASIC64 438 teletext 153
*BASICFPA 439 command mode 12
*BASICVFP 440 comments 22
BEAT 163, 229 comparison operators 74
beat counter 162 concatenation, string 40
BEATS 163, 230 conditional structures 73
BGET# 102, 231 control variable 77
binary 33 conversions 43
block structured IF 75 Copy key 17
BPUT# 102, 103, 232 copying rectangles 137
BY 124, 233 COS 259
504
COUNT 260
CRUNCH 261 E
cursor EDIT 271
appearance 182 Edit 191
editing 17 editing BASIC programs 191
keys 68 Options submenu
moving 185 Line number increment 192
start line 182 Strip line numbers 192
cursor movement, in editor 195 printing a BASIC program 192
tokenised files 192
editing a program 16
ELLIPSE 121, 272
D ELLIPSE FILL 121
DATA 66, 262 ellipse plot 133
data files 101 ELSE 73, 76, 273
DCB/W/D/S/FS/FD/FE assembler directives 446 (in ON) 85
debugging 174 END 274
DEF 88, 263 End key 17
default ENDCASE 82, 276
colours 112 ENDIF 76, 277
error handler 171 ENDPROC 88, 278
patterns 139 ENDWHILE 81, 279
viewports 149 entering a program 15
defining entering BASIC 11
colour patterns 140 ENVELOPE 280
functions 94 EOF# 102, 282
procedures 87 EOR 32, 36, 75, 283
DEG 264 EQUB/W/D/S/FS/FD/FE assembler directives 446
DELETE 18, 265 ERL 170, 284
deleting programs 19 ERR 170, 285
DIM 47, 266 ERROR 171, 286
as a function 49 ERROR EXT 171, 286
reserving memory 165 errors 169
dimension 47 external 171
disabling error trapping 171 handling 169
displaying text 55 trapping 169
DIV 32, 269 EVAL 44, 287
division, in BASIC 13 *EXEC 104
dot-dash pattern 129 executing a command file 104
double-height characters 110 EXP 288
in teletext 154 expression 216
DRAW 124, 270 EXT# 289
duration, sound 162
505
graphics 117
F cursor 124
factor 217 horizontal line draw routine 488
FALSE 37, 290 resolution 107
files 101 screen 117
creating 101 teletext 155
executing 104 units 117
input 102 viewport 147, 149
output 101
FILL 137, 291
fixed point numbers 451
flashing colours 184 H
flashing, teletext 154 HELP 302
floating point coprocessor 455 hexadecimal 33
floating point emulator (FPE) 455 HIMEM 303
floating point instruction set 455
floating point numbers 451
floating point variable 27, 29
indirection 167 I
flood-fill 136 IF 304
FN 32, 87, 94, 292 multi-line 75
FOR 77, 293 single line 73
foreground colour 111, 122 THEN, ELSE 75
formal parameter 88 immediate mode 12
function keys 71 indirection
programming 71 byte 166
special characters 72 floating point 167
function library 95 string 167
functions 87 word 166
*FX 15 68 INKEY 65, 306
*FX 219 68 values 469
*FX 4 68 INKEY$ 65, 308
INPUT 15, 63, 309
INPUT LINE 64, 310
INPUT# 102, 311
G INSTALL 95, 312
GCOL 111, 122, 294 INSTR 42, 313
GET 65, 297 INT 314
GET$ 65, 299 integer 27, 451
GET$# 103, 298 variable 29
giant patterns 144 interactive mode 12
GOSUB 84, 300 interlace 181
GOTO 84, 301 ISO-8859 43
506
MID$ 40, 331
K MOD 32, 54, 333
*KEY 71 MODE 107, 109, 334
keyboard mode 12, 107
buffer 67 MOUSE 338
input 63 mouse 69
programming 67 MOVE 124, 340
keywords 215 moving rectangles 137
multiplication, in BASIC 13
L
left shift 34 N
LEFT$ 40, 315 negative INKEY 69
LEN 42, 316 values 469
LET 13, 30, 317 NEW 341
libraries NEXT 77, 342
function 95 NOT 32, 75, 343
loading 95 note synchronisation 162, 164
procedure 95 null string 39
LIBRARY 96, 261, 318 numeric types 451
LINE 119, 319
LINE INPUT 64, 320
line number 15
LIST 16, 21, 321 O
LISTO 73, 323 *OBEY 104
LN 324 octave 161
LOAD 24, 325 OF 83, 344
LOCAL 89, 326 OFF 345
LOCAL DATA 92, 326 offset assembly 443
LOCAL ERROR 173 OLD 346
local error handling 172 ON 347
LOG 328 ON ... GOSUB 86, 300
logical operator 31, 37 ON ... GOTO 85, 301
LOMEM 329 ON ... PROC 92, 371
loop structures 73 ON ERROR 169, 348
LVAR 28, 99, 174, 330 ON ERROR LOCAL 172
ON ERROR OFF 171
OPENIN 102, 350
OPENOUT 101, 351
M OPENUP 352
machine code, calling subroutines 234 operators 74
matrix multiplication 53 arithmetic 31
507
logical 31, 74 listing 21
precedence 32 loading 24
relational 74 multiple statements 23
OPT directive 444-445 numbering lines in 20
OR 32, 36, 75, 353 running 15
ORIGIN 354 saving 24
OSCLI 355 window managed 7
OTHERWISE 357 prompt 64
OVERLAY 98, 261, 358 PTR# 372
P Q
PAGE 360 QUIT 12, 172, 373
paged mode 180
palette 112
parallelogram plot 131
parameter 89 R
pathname 218 RAD 374
pattern fill 140 READ 65, 375
PI 361 reading from a file 102
pitch, sound 161 reading text 63
pixel 118 RECTANGLE 120, 376
PLOT 127, 362 RECTANGLE ... TO 137
codes 483 RECTANGLE FILL 120
POINT 118 RECTANGLE FILL ... TO 137
function 364 rectangle plot 130
statement 363 recursion 93
pointer 70 relational 217
POS 365 relative coordinates 124
precedence, of operators 32 REM 22, 378
PRINT 12, 55, 366 RENUMBER 20, 379
PRINT# 101, 370 REPEAT 80, 380
printer 178 REPORT 170, 381
PROC 87 REPORT$ 382
procedure library 95 resequencing programs 20
procedures 87 resident integer variable 31
program 15 resolution 107, 117
data 65 RESTORE 66, 383
deleting 19 RESTORE DATA 92, 383
editing 16 RESTORE ERROR 173, 383
entering 15 RESTORE+ 99
inserting comments 22 RETURN 84, 385
508
parameter 91 STEP 77, 396
right shift STEREO 160, 397
arithmetic 35 STOP 174, 398
logical 35 STR$ 44, 399
RIGHT$ 40, 386 STR$~ 45
RND 387 string array 49
RUN 15, 388 string file I/O 103
running a program 15 string indirection 167
string variable 27, 39
converting to numbers 43
joining strings together 40
S splitting strings 40
SAVE 24, 389 STRING$ 42, 400
scaled characters 185 subroutines
screen display 107 assembly language 234
screen editor see BASIC screen editor machine code 234
scrolling 182 subscript 47
sector plot 135 substring 40
segment plot 136 SUM 54, 401
*SETTYPE 104 SUMLEN 54, 402
SGN 390 SWAP 403
shadow mode 109 synchronisation, sound 162, 164
shift operator 34 syntax descriptions 216
simple patterns 145 SYS 404
SIN 391
single-byte file i/o 102
single-character input 65
SOUND 159, 392 T
sound 159 TAB 59, 406
after parameter 164 Tab key 68
amplitude 161 TAN 407
channel 161 teletext mode 153
duration 162 TEMPO 163, 408
pitch 161 text
scheduling 164 cursor 58
synchronisation 164 defining characters 60
volume 161 direction 184
SPC 394 input 63
sprites 151-??, 187 output 55
loading 151 reading 63
plotting 152 size 110
SQR 395 viewports 147
statements 217 TEXTLOAD 409
509
TEXTSAVE 410
THEN 73, 76, 411 W
TIME 31, 412 WAIT 430
TIME$ 413 WHEN 82, 431
timed input 65 WHILE 81, 432
TINT 114, 119, 414 WIDTH 433
tints 111 window managed programs 7
TO 77 word indirection 166
TOP 417 writing to a file 101
TRACE 174, 418
trapping errors 169
triangle plot 130
TRUE 37, 420
TWIN 421
TWINO 421
U
UNTIL 80, 422
user-defined
characters 60
function 94
procedure 87
USR 423
V
VAL 44, 424
variable 13, 27, 217
VDU 425
commands 60, 177
variables 485
VDU 5 mode 110, 125, 186, 365, 429
VFP 456
viewport 147
VOICE 159, 427
*VOICES 160, 427
VOICES 159, 428
volume, sound 161
VPOS 429
510
Reader’s Comment Form
BBC Basic Reference Manual, Issue 3
We would greatly appreciate your comments about this Manual, which will be taken into account for the
next issue:
General comments:
If there is not enough room for your comments, please continue overleaf
This information will only be used to get in touch with you in case we wish to explore your
comments further
✃