CONVERTING OTHER BASICS TO QL SUPERBASIC
Copyright (C) 2016 David Denham
This document is released as FREEWARE. It may be freely
copied on a no-profit basis.
This document lists some suggestions for how to approach
converting some of the keywords and structures in
Microsoft-style BASICs which differ from QL SuperBASIC.
Sometimes, the differences are major. Sometimes, only a
slight change in syntax is required.
This list is not definitive - BASIC even on 1970s and 1980s
computers differed greatly from machine to machine. However,
this article should help you with the most common things.
In many cases, no simple conversion method is possible, so
the document lists how the original command works so that you
can devise your own conversion routines appropriate for what
the program concerned tries to do.
The term 'QL BASIC' is collectively used to refer to either
or both of SuperBASIC on QDOS systems and SBASIC on SMSQ/E
systems. SMSQ/E is the successor operating system for QL
compatible and derivative hardware systems and emulators. The
term 'PC BASIC' is collectively used to refer to Microsoft
BASIC (TM) and compatibles and derivatives on PC systems.
' comment
The apostrophe ' can be used as shorthand for REM in many
cases.
Example:
100 'comment
can be converted to
100 REMark comment
The apostrophe comment can also appear after some commands
without a colon to separate statements:
Example 1:
900 END 'comment
Convert it like this (END is equivalent to STOP on the QL):
900 STOP : REMark comment
Example 2:
900 DIM A(10)'setup an array of numbers
page 1
Convert it like this:
900 DIM A(10) : REMark set up an array of numbers
<> <= and >=
While all of these operators have the same meaning as in
SuperBASIC, some older BASICs do not mind if a space is
placed between the two characters - this must be removed for
SuperBASIC.
I have come across one instance (only) of a BASIC which does
not mind which order the symbols are placed in - that BASIC
allowed you to use =< and => in place of <= and >=. QL
SuperBASIC insists on >= and <=.
+ String Concatenation
Microsoft-style BASICs generally use the '+' operator to join
together two or more strings. This must be converted to use a
'&' ampersand symbol for SuperBASIC.
Example:
LET A$=B$+C$
is converted to SuperBASIC as
LET A$=B$&C$
?
The query symbol ? is sometimes used as a shorthand for the
PRINT command in some versions of BASIC.
200 ?"Hello"
can usually be converted as
200 PRINT"Hello"
^ Exponentiation.
A value raised ot the power of another. For example, PRINT
2^3 gives 8. Same as the equivalent QL operator.
\ Integer Division
Integer division is denoted by the backslash symbol in some
versions of BASIC, as opposed to the forward slash symbol to
denote ordinary floating point division. Use the INT function
in QL BASIC, or the DIV operator in SBASIC, to replace an
integer divide statement.
3 \ 2 gives 1, whereas 3/2 gives 1.5.
Abbreviation Of Commands
page 2
Some BASICs allow you to abbreviate command names, e.g. P.
for PRINT or L. for LIST. These must be entered in full on
the QL.
Example:
P."Hello world" convert as PRINT"Hello world"
Labels
Some versions of BASIC permit named labels to be used in
place of line numbers in GOTO and GOSUB statements. These
labels may look similar to variable names and either enclosed
in square brackets or followed by a colon symbol, e.g.
GOTO [label1]
GOSUB label2:
The labels themselves are placed at the start of a line
delimited with the relevant punctuation for the version of
BASIC concerned, or after a line number if used. For example:
100 GOSUB [label2]
110 ...
1000 [label2]
1010 ...
1020 RETURN
or:
100 GOTO label1:
110 ...
1000 label1:
1010 ...
There is no direct equivalent in QL BASIC - you need to use
either line numbers or variables with the values of the line
numbers concerned. It may help to place a REM statement at
the destination line to help clarify what the original
program did, e.g.
100 GOTO 1000 : REMark label1
110 ...
1000 REMark label1
1010 ...
Scope Of Variables
Some versions of BASIC such as QBASIC allow you to define
variables to be local to a given part of a program, or to be
'global'. This varies between versions of BASIC on different
systems.
The area of a program that a variable is accessible from is
called its "scope".
In general, variables are local to procedures and functions
page 3
by default (called "local scope"). However, there are times
when it is useful to be able to share a variable between a
number of procedures or functions. You can make a variable
named in a subroutine identical to a variable of the same
name in the main program by including a SHARED statement in
the subroutine.
This is essentially the opposite to QL BASIC, where variables
are generally global in scope unless explicitly declared to
be local to a given routine by the use of a LOCal statement.
SUB sub1
SHARED total
...
END SUB
In QBASIC, a variable may be made global in scope (i.e.
accessible from all parts of a program including procedures
and functions) by proceding the name in the main program body
with a COMMON SHARED statement, e.g. COMMON SHARED total
As well as the scope of a variable there is also the question
of when it exists. A variable defined in a subroutine is by
default local and only accessible within that subroutine. Not
only is access restricted to the subroutine, it is only
brought into being when the subroutine is started and
vanishes again when the subroutine ends. By using a STATIC
statement you can ensure that a variable exists for the life
of the entire program even when a subroutine isn't being run.
A STATIC variable is still local in the sense that it doesn't
have anything to do with a variable of the same name
elsewhere in the program but it now also has a life of its
own independent of the subroutine.
The keyword STATIC may also be appended to the end of a
subroutine definition in QBASIC to make all of its local
variables static.
Here is a summary of the scope keywords in QBASIC.
Type Accessible From Existence
local subroutine that it is while subroutine is
declared in running
shared main program and any sub- always
routine with SHARED name
global main program and every always
subroutine
dynamic one subroutine while subroutine is
running
static one subroutine always
ABS
ABS(X) returns the absolute value of the expression X. Works
the same as the QL BASIC function of the same name.
page 4
AND
AND is a logical operator which performs tests on multiple
relations. Used in a statement such as IF x=1 AND y=2 THEN...
its use is exactly the same in QL BASIC. If the tests are
positive, it returns a "true" (non-zero) result, otherwsie a
"false" value of 0.
Some BASICs allow its use as a bitwise operator where the
outcome depends on a comparison of individual bits in two
values. AND comparisons return a set bit value where the
corresponding bit values are set in both values compared. For
example, x = 255 AND 1 returns a value of 1, because that is
the only bit set in both values when compared as binary
values. Use a double ampersand in QL BASIC for this operator:
LET x = y AND z
would become LET x = y && z in QL BASIC.
Arrays
Arrays are generally dimensioned with the DIM command as in
SuperBASIC. Mostly, arrays are dimensioned to have the zero
subscript as the first entry in an array, but beware of
versions of BASIC where the first element in an array is 1.
Not all BASICs zero an array when redimensioning a second or
subsequent time in the same run. Some BASICs will clear out
arrays when programs stop or start, others may need explicit
CLEAR statements to remove values from past runs - do not
assume an array will always start zeroed and cleared if it
has been run once already.
String arrays may require an extra dimension in SuperBASIC,
as the maximum length of string array elements may not be
specified in some BASICs. For example, DIM A$(10) would set
up an array of 10 or 11 (depending on whether element 0 is
allowed) strings, but without specifying the maximum length,
so you would have to try to work out what the maximum length
of text this array might be expected to hold and add it as an
extra dimensions in SuperBASIC, e.g. DIM A$(10,50) if the
strings needed to hold up to 50 characters of text.
Beware of versions of BASIC which have case sensitive
variable and array names. In this case, DIM A(10),a(10) might
create two separate and distinct arrays called A() and a() -
in other words, A(1) and a(1) are not the same things! There
is no easy way around this in SuperBASIC, where names are
case insensitive, other than to use different variable and
array names, or doing something like keeping the upper case
names as they are and adding a '_' to the lower case
equivalents, e.g. DIM A(10),_a(10)
ASC
Returns a numerical value that is the ASCII code for the
first character of the string given. Corresponds to the
page 5
function CODE in QL BASIC. For example: 10 PRINT ASC("A")
corresponds to 10 PRINT CODE("A"). Within the range of
character codes up to 127, most characters have the same code
value on the QL, although a few symbols vary - see ASCII
Codes below.
ASCII Codes
Not all computershave the same character sets. The same
symbol may have a different character code on different
computers. That said, letters and numbers and most symbols
are the same, but you should be wary of some characters:
# QL code 35
[ \ ] ^ _ QL codes 91 to 95 inclusive
£ QL code 96, often a 'back-tick' character found on
the key above TAB on a U.K. keyboard. To get a Pound symbol
when printing, some printers may require you to send
character code 163 for a Pound symbol, e.g. PRINT CHR$(163)
Arrow symbols may be another source of confusion. On TRS-80
Level 2 BASIC they are at the following code locations:
TRS-80 QL
Left 93 188
Right 94 189
Up 91 190
Down 92 191
Some computers may not have a lower case character set as
such, both cases look the same - printing the CHR$ codes for
A and a may both result in a capital A. But if sent to a
printer they may actually print as separate upper and lower
case characters even though they look the same on screen.
If you get stuck with character sets, especially in programs
where symbols are printed with something like PRINT CHR$(n)
you will need to compare the character sets of the original
machine and the QL to see which codes correspond. If the
manual has no information, or you don't have access to the
manualof the original computer, try looking up character sets
online, such as Code Page 437 or CP437, PC-8 or MS-DOS Latin
US, espcially if the program uses an American character set.
ASCII codes below 32 and above 127 may have differences
between computers. Those below 32 are often called 'control
codes' and may have certain screen functions, e.g. CHR$(9)
may be a tab function, a Carriage Return for CHR$(13), a
Linefeed for CHR$(10), or a Form Feed for CHR$(12), a CHR$(7)
may sound a beep... Additionally, codes below 32 may be used
as various symbols, sometimes called 'dingbats'. All these
control codes may vary - it can be hard to work out what does
what!
Similarly, the high ASCII codes above 128 may vary from
computer to computer. You will need to look up the relevant
information for the computer and version of BASIC in
page 6
question.
AT
This may be used on its own, like the QL AT command or used
in a PRINT command as a PRINT position modifier. Used by
itself, AT X,Y can simply be converted to AT Y,X on a QL.
Note that the QL takes y coordinate first, followed by x
coordinate. Most BASICs have the Y coordinate first, followed
by the X, but a few have the X coordinate first.
In cases where there is no ambiguity caused, no punctuation
is usually required after the parameter(s) of AT, for example
PRINT AT Y,X"Hello" may be perfectly acceptable even if less
readable.
If used in a PRINT modifier context, AT may take one of three
forms:
PRINT AT P;A$ position from start of screen - usually
(y*screen_width)+x. The AT statement must
be made a separate command and P resolved
down to Y and X coordinates, such as AT P
DIV screen_width, P MOD screen_width :
PRINT A$
PRINT AT Y,X;A$ Change to AT Y,X : PRINT A$
PRINT AT X,Y;A$ Change to AT Y,X : PRINT A$
PRINT AT Y,X"OK" Change to AT Y,X : PRINT"OK"
The stand-alone version of AT may appear as a command called
LOCATE in some dialects of BASIC.
The version of AT used in a PRINT statement to position the
cursor may take additional forms in the various versions of
BASIC. Some dialects use the '@' symbol in place of the AT
keyword, e.g. PRINT @Y,X; or both commands may be combined
into a single parameter which represents the number of text
characters from the top left of the screen, e.g. PRINT
@position; where "position" is
(Y*line_width_in_characters)+X.
Some dialects of BASIC replace the PRINT AT Y,X; version with
a TAB command with two parameters: PRINT TAB(Y,X); or PRINT
TAB(X,Y); - you will have to check which way around the
particular version of BASIC expects the parameters.
ATN
ATN(X) retuns the arctangent of X in radians. The result will
be in the range -PI/2 to PI/2. The ATN function corresponds
to the ATAN function on the QL.
AUTO
Used for automatic line numbering and entry of lines of
BASIC. Generally works in the same way as AUTO on the QL.
Allows both initial line number and step vaue to be
page 7
specified. Unlike the QL version, on some machines it
displays a '*' if the line already exists, so that you are
aware you may be about to overwrite an existing line and so
give you a chance to break out of the command.
BEEP
BEEP just issues a short medium pitched bleep from the
computer's speaker. Just use any fairly short BEEP in QL
BASIC, e.g. BEEP 2000,20
BLOAD
BLOAD filespec,offset loads binary data (such as a machine
language program) into memory, rather like LBYTES in QL
BASIC. A knoeledge of system data structures, memory layout
and machine language is needed to convert such code.
BSAVE
BSAVE filespec,offset,length saves binary data to disk. Its
use is similar to that of SBYTES in QL BASIC.
CALL
CALL calls a machine language subroutine. The syntax is CALL
numvar [(variable [,variable]...)]
numvar is the name of a numeric variable. The value of the
variable indicates the starting memory address of
the subroutine being called as an offset into the
current segment of memory (as defined by the last
DEFSEG statement)
variable is the name of a variable which is to be passed as
an argument to the machine language subroutine.
Example:
100 DEF SEG=&H8000
110 OZ=0
120 CALL OZ(A,B$,C)
The CALL statement is one way of interfacing machine language
programs with BASIC. The other way is by using the USR
function.
Machine language code varies greatly from processor to
processor, and even from machine to machine with similar
processors.
The CALL statement on the QL differs slightly in terms of
parameters. Its syntax is CALL address [,registers] where
'registers' means the values to be placed into registers
D1-D7 and A0-A5 in that order.
CDBL
page 8
CDBL(X) converts X to a double precision number. This has
nodirect equivalent in QL BASIC, since SuperBASIC and SBASIC
do not support two levels of numeric precision. In most
programs, this can simply be omitted. Be aware of the
possibility of differently formatted numbers when the QL's
exponential number formatting kicks in.
CHAIN
This command may be similar to a QL BASIC LRUN or MRUN
command.
CHAIN "filename" generally works like an LRUN "filename"
command in QL BASIC, while CHAIN MERGE "filename" generally
works like an MRUN "filename" command in QL BASIC. Both
versions allow an optional line number to be specified, at
which execution continues after the merging. This is not
generally possible in QL BASIC. If no start line number is
specified, execution begins at the first line.
CHR$
CHR$(X) Returns a string whose one character is ASCII
character X. Equivalent to the same function in QL BASIC, but
see ASCII Codes above.
CINT
CINT(X) converts X to an integer by rounding the fractional
portion. X must be in the range -32768 to 32767. CINT will
return 2 for CINT(1.6), or -2 for CINT(-1.6), for example. In
QL BASIC, use an equivalent function such as:
1000 DEFine FuNction CINT(X)
1010 IF X>=0 THEN RETurn INT(X+0.5): ELSE RETurn INT(X-0.5)
1020 END DEFine CINT
CIRCLE
This keyword draws a circle or sllipse on the screen with
centre (x,y) and radius r. The full syntax is:
CIRCLE (x,y),r [,colour [,start,end [,aspect] ] ]
(x,y) are the coordinates of the centre of the ellipse.
The coordinates may be given in either absolute or
relative form.
r is the radius (major axis) of the ellipse in
points.
colour is a number which specifies the colour of the
ellipse. The default is the current foreground
(ink) colour.
start,end are angles in radians and may range from -2*PI to
2*PI, where PI=3.141593
page 9
aspect is a numeric expression.
start and end specify where the drawing of the ellipse will
begin and end. The angles are positioned in the standard
mathematical way, with 0 to the right and going
counterclockwise:
PI/2
-
/ \
PI | | 0,2*PI
\ /
-
3*PI/2
If the start or end angle is negative (-0 is not allowed),
the ellipse will be connected to the centre point with a
line, and the angles will be treated as if they were positive
(note that this is not the same thing as adding 2*PI). The
start angle may be greater or less than the end angle. For
example, this short listing will draw a three quarter circle
with the top left cut out and joined to the centre of the
circle by two straight lines from 12 o'clock and 9 o'clock.
10 PI=3.141593
20 SCREEN 1
30 CIRCLE (160,100),60,,-PI,-PI/2
aspect affects the ratio of the x-radius to the y-radius.
This may be used to adjust the circularity of the shape to
suit the screen aspect ratio of the graphics mode in use at
the time.
If aspect is less than one, the r is the x radius. That is,
the radius is measured in points in the horizontal direction.
If aspect is greater than one, then r is the y-radius.
In many cases an aspect of 1 (one) will give nicer looking
circles. This will also cause the circle to be drawn somewhat
faster.
The last point referenced after a circle is drawn is the
cente of the circle. Points that are off screen are not drawn
by CIRCLE.
As graphics commands like this one tend to vary from computer
system to system, it is not possible to give a singular
method of conversion. QL BASIC supports drawing of circles
and ellipses using the CIRCLE and synonymous ELLIPSE
commands.
CIRCLE x,y,major_radius, ratio, rotation
Rotation is not used in the Microsoft BASIC version, so you
will generally require to draw the ellipse horizontally
(rotation=PI/2) or vertically (rotation=0).
page 10
x, y and radius will be broadly the same, although dependent
on units and screen resolution. The QL BASIC version does not
support the 'start, end' options for drawing part of a
circle, so you may need to use the ARC command in QL BASIC to
achieve this. Aspect ratio is defined as the ratio of minor
to major axis in QL BASIC, and x axis to y axis in Microsoft
BASIC.
CLEAR
As in SuperBASIC, CLEAR by itself clears the values of all
variables. Numeric variables are all reset to a value of 0,
strings to nulls or 'empty'.
CLEAR n
When used with an argument n (n can be a constant or an
expression), this statement causes the Computer to set aside
n bytes for string storage. In addition, all variables are
set to zero. When the TRS-80 is turned on, 50 bytes are
automatically set aside for strings.
The amount of string storage CLEARed must equal or exceed the
greatest number of characters stored in string variables
during execution; otherwise an Out of String Space error will
occur.
Example:
100 CLEAR 2000
makes 2000 bytes available for string storage. By setting
string storage to the exact amount needed, the program can
make more efficient use of memory on older systems with
smaller memories. A program which uses no string variables
could include a CLEAR 0 statement, for example. The CLEAR
argument must be non-negative, or an error will result.
CLOAD and CLOAD?
Load a program from cassette tape, broadly equivalent to a
LOAD command on a QL. Some systems will let you specify a
blank filename, which allows the computer to load the first
BASIC programit comes across on the tape. On some systems, if
a part filename or a single letter is specified the computer
will only load a program whose filename starts with the given
letter or letters. There is no direct equivalent to either
version on the QL.
Some computers have a variant which uses a question mark to
ask the computer to verify that a file on cassette matches
that in the computer's memory (in other words, that it is not
faulty). This usually takes the form CLOAD ?"filename". If no
filename is given, the first program found on the cassette
will be compared.
CLOSE
page 11
Closes a file channel which is already open. Works much like
the QL version of the command, except that multiple channels
may be closed by a single CLOSE command with channel numbers
(called file numbers in the MS BASIC manuals) separated by
commas.
CLOSE #channel is similar to the same command in QL BASIC
CLOSE #chan1, #chan2 is equivalent to CLOSE #chan1 : CLOSE
#chan2 on QL.
A third version of the command with no parameters is able to
close all open file numbers. There is no direct equivalent in
SuperBASIC, unless you have Toolkit 2 which extends the CLOSE
command to close all open channel numbers if no parameter is
given to the CLOSE command.
CLS
Where implemented (some versions of BASIC just clear the
screen automatically when the program starts to run), the
implementation is similar to the QL CLS command. This may
just clear the whole screen, not a given window number as in
QL BASIC, if no parameter is given, otherwise CLS 1 clears
the graphics viewport, while CLS 2 clears the text window.
COLOR - Colour Values
This may vary from system to system, of course. Older style
16 colour systems often use the following colour numbers,
with the closest QL colour number (8 colours - the QL does
not have a 16 colour mode).
Number PC Colour QL Number QL Colour
0 Black 0 Black
1 Blue 1 Blue
2 Green 4 Green
3 Cyan 5 Cyan
4 Red 2 Red
5 Magenta 3 Magenta
6 Brown 6 Yellow
7 White 7 White
8 Grey 0 Black
9 Light Blue 1 Blue
10 Light Green 4 Green
11 Light Cyan 5 Cyan
12 Light Red 2 Red
13 Light Magenta 3 Magenta
14 Yellow 6 Yellow
15 Bright White 7 White
Once you have established the relationship between PC and QL
colours, you may find it easier to set up a colour
translation table in an array and indirectly reference the
colours rather than trying to amend all colour commands in a
program. So, set up an array with the list of colour numbers
in the third column, then instead of using INK 0 to convert
the statement COLOR 0, for example, you could use INK
page 12
colour(0). The keyword COLOR (note American spelling) is
often used to set the colour of both ink and paper, so you
have to use INK or PAPER as appropriate.
COM
The COM command enables or disables trapping of
communications activity to the specified communications
adapter. The format of the command is COM(n) ACTION, where:
n number of the communications adapter (1 or 2)
and ACTION is a one word parameter describing the action to
be taken:
ON A COM(n) ON statement must be executed to allow
trapping by the ON COM(n) statement. After COM(n)
ON, if a non-zero line number is specified int he
ON COM(n) statement, BASIC checks to see if any
characters have come in to the communications
adapter every time a new statement is executed.
OFF If COM(n) is OFF, no trapping takes place and any
communication activity is not remembered even if it
does take place.
STOP If a COM(n) STOP statement has been excuted, no
trapping can take place. However, ay communications
activity that does take place is remembered so that
an immediate trap occurs when COM(n) ON is
executed.
There is no equivalent command in QL BASIC.
COMMON
This command passes variables to a chained program. The
command takes a series of parameters which are either simple
variable names, or if brackets are appended to the variable
name, it is regarded as the name of an array.
100 COMMON A,B(),C$
110 CHAIN "A:PROG2"
This example chains to a program called PROG2 on the A: drive
of the PC, and passes to it the variable A, the array B() and
the string variable C$.
There is no equivalent command in QL BASIC, although the use
of MRUN in place of LRUN (i.e. merging a second program
instead) may achieve the same purpose as long as you are
careful about line numbering.
CONST
The CONST command in QBASIC fixes a value so that it cannot
be changed within the program. The full syntax is:
page 13
CONST name [AS type]=expression or value
'name' is a name given to the value (like a variable name)
'type' indicates the type of constantand may be INTEGER or
STRING.
'value' may be an expression, variable, or a number.
Examples:
CONST PI=3.1415926 assigns the value shown to the
variable PI.
CONST WHITE AS INTEGER=15 assigns the value 15 to the
colour name 'white'
INPUT"What is your name? ";N$ Fix the constant NAME$ as the
CONST NAME$=N$ name first entered.
There is no direct equivalent in QL BASIC, although simple
LET statements could be used as long as you bear in mind that
the assignments are not permanently fixed. You could possibly
use environment variables to create such constants if those
are implemented on your system.
CONT
Similar to CONTINUE on a QL, to resume program operation
following a break or error.
Control Codes
Control codes are mostly keypresses corresponding to
character codes 0 to 31. Sometimes they produce symbols known
as 'dingbats', but were originally (as the name implies) used
to control printers and terminals, possibly via modems. They
may also act as control codes to control screen output in
some ways on some machines.
This is a list of control codes, their 2 or 3 letter symbol
and a brief description. Many of these codes may vary in
their use on different computers while some, such as 8(BS),
9(HT), 10(LF), 12 (FF), 13(CR) and 27 (ESC) generally work
similarly on most systems. Many of these codes have no direct
QL equivalent, you may have to be rather inventive!
0 NUL Null char
1 SOH Start of Heading
2 STX Start of Text
3 ETX End of Text
4 EOT End of Transmission
5 ENQ Enquiry
6 ACK Acknowledgment
7 BEL Bell
8 BS Back Space - move back and erase last character.
Generally, this just means move one space back to the
page 14
left.
9 HT Horizontal Tab - move to the right to the next tab
stop (usually every 8 or 10 characters, although it
can vary)
10 LF Line Feed - move the cursor down to the next line. On
older terminal based system, this was equivalent to
moving the paper up one line, without moving the
cursor left or right horizontally at all. One some
systems, a LF is sometimes interpreted as LF (move
down one line) then CR (move to left hand column of
screen or printer), as it would at the end of a line
of text. By and large, the QL uses just an LF to
signify the end of a line.
11 VT Vertical Tab
12 FF Form Feed - move to the start of the next sheet of
paper, or clear the screen like a CLS command.
13 CR Carriage Return - move the print head or text cursor
to the start of the line. Some systems treat this as
being equivalent to a CR+LF.
14 SO Shift Out / X-On. On some systems, when a CHR$(14) is
sent to the screen, it turns on the cursor, like a
CURSEN command on a QL with Toolkit 2.
15 SI Shift In / X-Off. On some systems, when a CHR$(15) is
sent to the screen, it turns off the cursor, like a
CURDIS command on a QL with Toolkit 2.
16 DLE Data Line Escape
17 DC1 Device Control 1 (oft. XON)
18 DC2 Device Control 2
19 DC3 Device Control 3 (oft. XOFF)
20 DC4 Device Control 4
21 NAK Negative Acknowledgement
22 SYN Synchronous Idle
23 ETB End of Transmit Block. On a TRS-80 this code switches
the screen to 32 characters wide mode.
24 CAN Cancel. On some systems this backspaces the cursor
(move one to the left) without erasing the current
character.
25 EM End of Medium. Move the cursor one position to the
right.
26 SUB Substitute. Also, move the cursor down the screen one
line on some systems such as TRS-80.
27 ESC Escape - used for expanded code sequences, where ESC
signifies this is the start and at least one more code
must follow. On a TRS-80, sending ESC to the screen
acts as an upward linefeed (move the cursor up one
line).
28 FS File Separator. Sent to the screen on some computers
this acts as a 'Home' command to force the cursor to
move to the top left origin, to text coordinates 0,0,
like an AT 0,0 statement on the QL. May also be used
to switch a TRS-80 into 64 characters per line screen
mode.
29 GS Group Separator. On some computers, sending a CHR$ 29
to the screen moves the cursor back to the beginning
of the current horizontal line.
30 RS Record Separator. On some computers, sending a CHR$ 30
to the screen erases text to the end of the line,
page 15
rather like CLS 4 on a QL.
31 US Unit Separator. On some systems sending a CHR$ 31 to
the screen is interpreted as a command to clear to the
end of the form, in other words, clear the screen from
the cursor position to the bottom, although it varies
as to whether this includes the current line or not.
Replicate as either CLS 3 : CLS 2 (to clear both the
current line and below) or just CLS 2 (to clear below
the current line).
COS
COS(X) returns the cosine of X in radians, similar to COS(X)
in QL BASIC.
CSAVE
Saves a BASIC program with the given filename to cassette
tape, similar to a SAVE command on a QL. On some computers,
the filename may consist of a single character only. The
filename should be in quotes, or expressed as a string
variable.
CSNG
CSNG(X) converts the value of X to a single precision number.
Since the QL BASIC does not support different precisions of
floating point values, no conversion is required.
CSRLIN
This function returns the vertical coordinate of the cursor.
On most systems, the top line of the screen is line number 1,
although some may start at 0.
There is no direct equivalent in QL BASIC, although the
information required to convert this function is contained
within the channel definition blocks for the window channel
concerned and may be read using the DIY Toolkit function
CHAN_W% for a given channel number. The vertical cursor
position in pixels may be read from offset 36 decimal (hex
24). This starts from 0 and is in pixel units, so to get a
text character position across, divide by the number of
pixels per character in the current character size, e.g. 6
for CSIZE 0,0 text. The character spacing for a given window
channel may be checked with CHAN_W%(#channel,40), so to read
the current text position as characters across the screen,
use something like:
LET pos=CHAN_W%(#channel,36) DIV CHAN_W%(#channel,40)
On computers where the POS function starts from 1 for the
leftmost position, you should add 1 to this result:
LET pos=1+(CHAN_W%(#channel,36) DIV CHAN_W%(#channel,40))
or write it as a function in QL BASIC:
page 16
1000 DEFine FuNction CSRLIN(chan)
1010 RETurn 1+(CHAN_W%(#chan,36) DIV CHAN_W%(#chan,40))
1020 END DEFine CSRLIN
CVI CVS CVD
These three functions convert string representation values to
numeric values, e.g. values that are read in from a random
disk file. CVI converts a two byte string to an integer. CVS
converts a 4-byte string to a single precision number. CVD
converts an 8-byte string to a double precision number.
The exact conversion method depends on how the program
created the file, and is likely to be specific to the BASIC
concerned. It is better to rewrite the routines which create
the file to create QL-specific data files.
DATA
Similar to the QL BASIC DATA command, so usually no change
required as long as string data is quoted. If the version of
BASIC concerned supports unquoted strings in DATA statements,
something like DATA name1, name2, name3 may need to be
converted as DATA "name1","name2", "name3". Unquoted text
data is allowed in some versions of BASIC unless the string
contains commas, colons, or significant leading or trailing
spaces.
DATE$
DATE$ returns a ten character string, which is the system
date, in the form mm-dd-yyyy. In QL BASIC, the information is
contained in the first 11 characters of the string returned
by DATE$ in QL BASIC, although the month is returned as a
three character month name dependent on the system language
configured., e.g. QL BASIC DATE$ returns 2016 Jan 03 whereas
the same date in Microsoft-style BASICs might be 01-03-2016
To translate this to an approximate equivalent in QL BASIC,
you could write a function which looks up the month names and
converts them to a numeric value. Here, the function name is
changed to DATE_$ t avoid a clash with the QL BASIC function
name DATE$.
7000 DEFine FuNction DATE_$
7010 m$ = DATE$ : m$ = m$(1 TO 11)
7020 y$ = m$(1 TO 4)
7030 d$ = m$(10 TO 11)
7040 m$ = m$(6 TO 8)
7050 t = m$ INSTR 'JanFebMarAprMayJunJulAugSepOctNovDec'
7060 m$ = (t+2) DIV 3 : IF LEN(m$) < 2 THEN m$='0'&m$
7070 RETurn m$&'-'&d$&'-'&y$
7080 END DEFine DATE_$
DEF
The DEF keyword may appear in several contexts.
page 17
1. DEF FN
Define a function - similar to the QL BASIC's DEFine
FuNction.
2. DEF USR
Specifies the start address of an assembly language
subroutine. The syntax of this command is:
DEF USR [<digit>]=<integer expression>
where digit may be a number from 0 to 9 (0 assumed if not
specified) and <integer expression> is the starting address
of the USR routine. Broadly equivalent to a CALL command in
QL BASIC, but since any assembler code is likely to be
processor specific, you are unlikely to be able to easily
convert a DEF USR statement.
DEFDBL letter range
Variables beginning with any letter in the specified range
will be stored and treated as double-precision floating
point, unless a type declaration character is added to the
variable name. A variable defined as double-precision allows
17 digits of precision, with 16 being printed in most cases.
Examples:
200 DEFDBL A Variable names starting with A are double
precision, unless ending in ! % or $. So
A becomes a double-precision variable,
but A$ remains a string variable.
300 DEFDBL A,C Variable names starting with A or C are
double-precision, unless ending in ! % or
$.
400 DEFDBL C-E Variable names startin with C, D, or E
are double-precision, unless ending in !
% or $
DEFDBL and the other DEFxxx commands are generally placed
near the beginning of programs for clarity.
DEFINT letter range
Variables beginning with any letter in the specified range
will be stored and treated as integers, unless a type
declaration character is added to the variable name. A
variable defined as integer can only take on values between
-32768 and +32767 inclusive.
Examples:
200 DEFINT A Variable names starting with A are
integers, unless ending in ! # or $. So A
becomes an integer variable, but A$
remains a string variable.
300 DEFINT A,C Variable names starting with A or C are
page 18
integers, unless ending in ! # or $.
400 DEFINT C-E Variable names startin with C, D, or E
are integers, unless ending in ! # or $
DEFINT and the other DEFxxx commands are generally placed
near the beginning of programs for clarity.
DEFSNG letter range
Variables beginning with any letter in the specified range
will be stored and treated as single-precision floating point
variables unless a type declaration character is added to the
variable name. A variable defined as single-precision are
usually stored with 7 digits precision, although printed to 6
digits of precision.
Examples:
200 DEFSNG A Variable names starting with A are
single-precision, unless ending in # % or
$. So A becomes a single-precision
variable, but A$ remains a string
variable.
300 DEFSNG A,C Variable names starting with A or C are
single-precision, unless ending in # % or
$.
400 DEFSNG C-E Variable names startin with C, D, or E
are single-precision, unless ending in #
% or $
DEFSNG and the other DEFxxx commands are generally placed
near the beginning of programs for clarity.
DEFSTR letter range
Variables beginning with any letter in the specified range
will be stored and treated as strings, unless a type
declaration character is added to the variable name. A
variable defined as string can usually store up to 255
characters, although some BASICs allocate only a fixed small
string space which may have to expanded by a command such as
CLEAR n
Examples:
200 DEFSTR A Variable names starting with A are
strings, unless ending in ! # or %. So A
becomes a string variable, but A% remains
an integer variable.
300 DEFSTR A,C Variable names starting with A or C are
strings, unless ending in ! # or %.
400 DEFSTR C-E Variable names startin with C, D, or E
page 19
are strings, unless ending in ! # or %
DEFSTR and the other DEFxxx commands are generally placed
near the beginning of programs for clarity, since they change
the meaning of variable references without type declaration
characters (variable names not ending in ! # % or $).
DELETE "filename"
Deletes a file from disk, just like DELETE on a QL. You may
need to make changes to "filename" if the drive or file name
syntax is different to that of the QL, e.g. '.' separators
which correspond to the use of '_' in a QL filename.
DELETE line_no-line_no
Using a DELETE command with a line number or range of line
numbers , rather like DLINE on the QL, except that '-' is
used for the range rather than ' TO ' as on the QL.
Examples:
DELETE 100 Delete line 100 only: DLINE 100
DELETE 300-400 Delete lines from 300 to 400 inclusive.
Equivalent to DLINE 300 TO 400 on a QL.
DELETE -200 Delete all lines up to and including 200.
Equivalent to DLINE TO 200 on a QL.
Device Names
QL device names are usually one or three letter names such as
MDV, FLP, WIN and N. Computers running Microsoft-style BASICs
generally use PC-style device names, usually a short sequence
of letters, a drive number and a colon delimiter.
KYBD: Keyboard. Input only. Equivalent to CON for input.
SCRN: Screen. Out put only. Equivalent to SCR or CON for
output on the QL
LPT: Parallel port printer. Equivalent to PAR on QL.
LPTn: Parallel port number (n is usually a low number
such as 1 or 2). Equivalent to PAR1 or PAR2 on QL.
COMn: Communications or serial port number. Equivalent to
SERn on QL.
CAS1: Cassette tape port.
A: or B: Floppy disk drive, like FLP1_ or FLP2_
respectively.
C: etc Hard disk drive name. C: usually corresponds to
WIN1_, although some QL emulators and compatibles
allow the WIN drives to be assigned to any drive
letter, so it does not necessarily follow that C:
is WIN1_, D: is WIN2_ and so on.
PRN: Printer device. On the QL, it might be SER1, SER2,
or PAR for example.
DIM
Like on the QL, DIM sets up an array. On most BASICs the
page 20
arrays start with the subscript zero as the first element of
the array, but some BASICs start from 1 - this should make no
difference when converting to SuperBASIC which always starts
with element zero, apart from wasting a little memory an
unused '0' element perhaps.
Where the DIM statement may differ from SuperBASIC is with
strings, which may be defined without an explicit maximum
length specifier as the last part of a DIM statement.
DIM A$(10) generally sets up a 10 or 11 (depending on whether
subscript zero is used by the computer in question) element
string array - 10 or 11 lines of text for example. To convert
this, you'd need to try to work out from the rest of the
program what the length of maximum string to be stored is,
and add this maximum length as an extra dimension at the end
of the definition.
Examples:
DIM A$(10) convert as DIM A$(10,50) assuming you
have established that the strings in the
array need to be able to hold up to 50
characters each.
Beware of case sensitive variable and array names where DIM
A(10) and DIM a(10) may refer to two separate and distinct
arrays - in this case, A() and a() may be completely separate
arrays and you'd have to work around this in SuperBASIC by
creating different array names, or doing something like
adding an underscore '_' to the array name.
Example:
DIM A(10),a(10) could be converted as DIM A(10),_a(10)
DO...LOOP
This is a conditional loop structure similar to the
REPeat/END REPeat loops in QL BASIC, and also similar to the
WHILE/WEND and REPEAT/UNTIL loop structures in other versions
of BASIC.
DO/LOOP may have a pre-test with WHILE or UNTIL clauses at
the DO end of the loop, or a post-test with a WHILE or UNTIL
clause at the LOOP end of the loop structure.
REM press any key loop - Post-Test
DO
a$=INKEY$
LOOP WHILE a$=""
The above example loop keeps going until you press a key. In
QL BASIC, it could be written like this. Note that unless you
are using SBASIC, REPeat loops needs a control variable name,
and you may need to invert the test condition - the easy way
to do this is to use NOT as in this example.
page 21
REPeat loop
a$ = INKEY$
IF NOT(a$="") THEN EXIT loop
END REPeat loop
REM increment with Post-Test
x=0
DO
x=x+1
LOOP UNTIL x=10
in QL BASIC:
x=0
REPeat loop
x = x + 1
IF x=10 THEN EXIT loop
END REPeat loop
The tests can be done at the DO end of the loop to prevent
execution of any of the loop content if the test is already
met by the time the loop starts:
DO WHILE INKEY$=""
LOOP
These can be converted to QL BASIC by placing the test just
inside the REPeat end of the loop.
REPeat loop
IF INKEY$<>"" THEN EXIT loop
END REPeat loop
DRAW
DRAW "string" draws an object as specified by "string". The
text contained in "string" is a simple graphics definition
language, where the action is specified by a single letter
followed possibly by a space and a value.
U n Move up
D n Move down
L n Move left
R n Move right
E n Move diagonally up and right
F n Move diagonally down and right
G n Move diagonally down and left
H n Move diagonally up and left
n in each of the preceding commands indicates the distance to
move. The number of points moved is n times the scaling
factor (set by the S command)
M x,y Move absolute or relative. If x has a plus sign (+)
or a minus sign (-) in front of it, it is relative.
Otherwise, it is absolute.
page 22
The following two prefix commands may precede any of the
above movement commands.
B Move, but don't plot any points
N Move, but return to the original position when
finished.
The following commands are also available:
A n Set angle n. n may range from 0 to 3, where 0 is 0
degrees, 1 is 90, 2 is 180 and 3 is 270.
C n Set colour n
S n Sets scale factor. n may range from 1 to 255. n
divided by 4 is the scale factor. For example, if n=1, then
the scale factor is 1/4. The scale factor multiplied by the
distances given with the U D L R E F G H and relative M
commands gives the actual distance moved. The default value
is 4 so the scale factor is 1.
X var; Execute substring. This allows you to execute a
second string from within a string,
In all of these commands, the n, x, or y argument can be a
constant like 123 or it can be =variable; where variable is
the name of a numeric variable. The semicolon after the
variable name is required when you use a variable this way,
or int he X command. Otherwise a semicolon is optional
between commands. Spaces are ignored int he string. For
example, variables could be used in a move command this way:
M+=X1;,-=X2
Variables can also be specified inthe form VARPTR$(variable),
instead of =variable; . This is useful in programs which were
to be compiled later. For example:
One Method Alternative Method
DRAW "XA$;" DRAW "X"+VARPTR$(A$)
DRAW "S=SCALE;" DRAW "S="+VARPTR$(SCALE)
The X command was commonly used for two pruposes. The first
and most obvious was to allow command string sof longer than
255 characters. The second was to split up complex drawings
into simpler parts, e.g. if drawing a person, the arms, head,
legs and body could be separate strings.
When coordinates which are out of range are given to DRAW,
the coordinate which is out of range is given the closest
valid value. In other words, negative values become zero and
and points to the right or below the screen are changed to
the screen edge values.
There is no direct equivalent to this DRAW command in QL
BASIC, although it might be possible to write a very simple
page 23
parser which breaks up the string and calls suitable LINE and
LINE_R commands or turtle graphics commands such as MOVE,
TURN, TURNTO, PENUP, PENDOWN
EDIT
Equivalent to the same command on a QL - the command just
enters the BASIC line editor at the given line number.
ELSE
Similar to the ELSE command in an IF...THEN clause in QL
BASIC. Note that in a single line definition, the QL version
will require a colon before the ELSE keyword, so something
like
IF X=2 THEN PRINT"Two" ELSE PRINT"Not two"
becomes
IF X=2 THEN PRINT"Two" : ELSE PRINT"Not two"
ELSE within a multiple line IF...THEN...END IF clause works
in the same way as ELSE in that construct in QL BASIC.
Note that if the statement does not contain the same number
of THEN and ELSE clauses, each ELSE is matched with the
closest unmatched THEN. This may cause some worry in
conversion as to whether the QL version will work in the same
way in such cases. Here is an example:
IF A=B THEN IF B=C THEN PRINT"A=C" ELSE PRINT "A<>C"
will not print "A<>C" when A<>B.
ELSEIF
Used as an alternative to starting multiple IF THEN ELSE
statement for complex or cascaded condition checks, ELSEIF
[conditional] THEN provides a means of making more efficient
multiple conditional statements in QBASIC. Here is an
example. Instead of this:
IF C=1 THEN CALL routine1
IF C=2 THEN CALL routine2
IF C=3 THEN CALL routine3
you could write:
IF C=1 THEN
CALL routine1
ELSEIF C=2 THEN
CALL routine2
ELSEIF C=3 THEN
CALL routine3
END IF
Unfortunately, there is no direct equivalent in QL BASIC
other than multiple multi-line IF THEN ELSE statements,
although with a bit of effort a SELect clause can sometimes
page 24
be used where simple values and ranges are used.
Here is an example of how to convert the above with multiple
IF clauses.
IF C=1 THEN
routine1
ELSE
IF C=2 THEN
routine2
ELSE
IF C=3 THEN
routine3
END IF
END IF
END IF
This particular example is also easily converted using a
SELect statement:
SELect ON C
=1:routine1
=2:routine2
=3:routine3
END SELect
END
Terminates program execution, closes all files and returns to
command level. An END statement at the end of a programis
optional. END is broadly equivalent to a STOP command in QL
BASIC, although STOP does not necessarily close any open
files - you would need to add explicit CLOSE statements just
before the STOP command in this case. Usefully, if you have
Toolkit 2 on the QL system, the CLOSE command is extended
such that a CLOSE with no parameter will close allopen BASIC
channels with numbers higher than 2. So, END is broadly
equivalent to CLOSE:STOP in this case.
EOF
Returns the value -1 (true) if the end of a sequential file
has been reached. Broadly equivalent to the QL EOF function,
although the QL version returns a value of 1.
EOF(file_number) is roughly equivalent to EOF(#channel) in QL
BASIC.
EQV
EQV is an equivalence operator, where the result of the
logical expression is true if both values are true or both
values are false, but false if one operand is true and the
other false. Here is the truth table:
X Y X EQV Y
True True True
page 25
True False False
False True False
False False True
You could write an approximate equivalent in QL BASIC like
this. In Microsoft-style BASICs the expression would be
written as LET R=X EQV Y whereas the QL BASIC version would
be LET R=EQV(X,Y)
1000 DEFine FuNction EQV(X,Y)
1010 IF (X<>0 AND Y<>0) OR (X=0 AND Y=0) THEN
1020 RETurn 1
1030 ELSE
1040 RETurn 0
1050 END IF
1060 END DEFine EQV
ERASE
This command erases arrays from a program. The command takes
a list of array names as its parameter. It can be used to
free up memory taken by an array, or to allow an array to be
redimensioned on systems where this would normally lead to a
Duplicate Definition error. The array name parameter does not
require brackets after it as would be needed in some
commands.
There is no direct equivalent in QL BASIC, the closest being
to redimension an array to a smaller size, e.g.
100 DIM array(100,100)
200 REMark use the array
300 DIM array(0)
ERL
Returns the line number at which an error occurred. Normally
used in error trapping routines. Broadly equivalent to the
ERLIN function in QL BASIC, although please note that ERLIN
does not work on pre-JS ROM QLs.
ERR
Returns the error code for an error which occurred while
running a BASIC program. Broadly equivalent to the QL ERNUM
function, although the error codes and messages are
different.
ERROR
ERROR number is used to simulate the occurrence of a BASIC
error, or to allow error codes to be defined by the user. Can
be used to test how a program copes with a specific error
situation. There is no direct QL equivalent, although
sometimes something like REPORT number:STOP may sometimes be
used (note that REPORT may not work on pre-JS ROM QLs).
page 26
EXIT
Allows the immediate exit from a subroutine or loop, without
processing the rest of that subroutine or loop code. The
command EXIT in versions of BASIC such as QBASIC is followed
by a second word which signifies the type of structure to be
exited.
EXIT DEF exits from a DEF FN function
EXIT DO exits from a DO loop, execution continues
with the command directly after the LOOP
command
EXIT FOR exits from a FOR loop, execution
continues with the command directly after
the NEXT command
EXIT FUNCTION exits a FUNCTION procedure, execution
continues with the statement directly
after the function call
EXIT SUB exits a SUB procedure, execution
continues with the statement directly
after the procedure call
In QL BASIC you will need to convert this as either an EXIT
command (if a looping structure such as a FOR or REPEAT loop)
or a RETURN statement in the case of a function or procedure.
EXP
EXP(X) returns e (base of natural logarithms) to the power of
X. Equivalent to the same function in QL BASIC.
FIELD
FIELD allocates space for variables in a random access file
buffer. It is used to define the field widths associated with
given variable names.
FIELD #file_number,field_width AS string_variable_name
This allocates "field_width" bytes to data held in the given
variable name, and the "field_width AS string_variable_name"
part may be repeated as required.
To calculate the total record size, add up the widths of each
field defined in this command, e.g.
FIELD #file_no,10 AS A$,20 AS B$
is 10+20 or 30 bytes wide.
There is no direct equivalent in QL BASIC. You will need to
manually allocate field widths within the appropriate record
size and use a file positioning command to move the file
pointer around as required, then use something like PRINT
#file_number,string_variable_name$; (note the semi-colon at
the end to prevent an extra linefeed being sent to the file
which might overwrite the start of the next field). If you
page 27
have Toolkit 2 on your QL system, you can use the BGET or
BPUT commands with backslashes to set the file pointer to
move around records and fields.
FILES
FILES displays the name of files residing on a diskette. The
FILES command in Microsoft BASIC is similar to the DIR
command in DOS.
FILES [filespec] where filespec is a string expression for
the file specification (drive name etc). If filespec is
omitted, all the files on the DOS default drive will be
listed.
In QL BASIC, use the DIR command.
FIX
FIX(X) returns the truncated integer part of X. FIX(X) is
equivalent to SGN(X)*INT(ABS(X)). The major difference
between FIX and INT in MS BASIC is that FIX does not return
the next lower number for negative X. For example, PRINT
FIX(-58.75) will return -58, whereas on the QL PRINT
INT(-58.75) will return -59. So we need to write a small
function which takes the integer part of the absolute values
then changes the sign if negative:
DEFine FuNction FIX(X)
IF X<0 THEN RETurn -INT(ABS(X)): ELSE RETurn INT(X)
END DEFine FIX
FN
Used when defining functions, FN is pretty much like the
equivalent keyword in QL BASIC. In MS BASIC, the definition
is that of a single line function definition only, whereas in
QL BASIC it extends over multiple lines. Also, when called,
in MS BASIC the function name must be preceded by FN, whereas
only the function name is required in QL BASIC.
100 DEF FNDOUBLE(X)=2*X
200 PRINT FNDOUBLE(8)
On a QL, you would need to rewrite this over multiple lines:
100 DEFine FuNction DOUBLE(X)
110 RETurn 2*X
120 END DEFine DOUBLE
200 PRINT DOUBLE(8)
FOR
Defines a FOR/NEXT loop, broadly equivalent to the QL version
of the command.
100 FOR A=1 TO 11 STEP 2
page 28
110 PRINT A
120 NEXT a
QL BASIC will generally support ending of FOR loops with a
NEXT command, although it is better to use END FOR in place
of NEXT to indicate the end of a loop:
100 FOR A=1 TO 11 STEP 2
110 PRINT A
120 END FOR A
Note that FOR loops may have an integer index variable, so
allows something like:
200 FOR X%=1 TO 4
210 PRINT X%
220 NEXT X%
Minerva and SBASIC may allow integer loop control variables,
some Sinclair QL ROM versions may not, in which case you'll
have to use a floating point control variable (use X instead
of X% in this example). Beware of non-integer calculation
results where programs modify the loop control variable value
within the loop.
If you plan to compile the converted BASIC program, you may
wish to try using an implicit type definition for a variable
name as an indirect method of converting FOR/NEXT loops which
use integer variables. For QLiberator you will need a
DEF_INTEGER statement to declare a variable with a
conventionally floating point name type (e.g. X) as actually
to be compiled as an integer. For Turbo compiler, the
corresponding directive is IMPLICIT%
Inline FOR loops on a QL do not necessarily require a NEXT
clause. The MS BASIC loop
100 FOR Y=0 TO 19 : PRINT Y : NEXT Y
could be converted as just:
100 FOR Y=0 TO 19 : PRINT Y
When loops are nested in MS BASIC, the NEXT clause can
specify more than one variable name, whereas an explicit NEXT
or END FOR is required for each variable name in QL BASIC:
100 FOR X=0 TO 31
110 FOR Y=0 TO 10
120 PRINT" ";
130 NEXT Y,X
Convert that to:
100 FOR X=0 TO 31
110 FOR Y=0 TO 10
120 PRINT" ";
page 29
130 END FOR Y
140 END FOR X
You may encounter NEXT statements with no variables
specified. In this case the most recently executed FOR loop
counter is updated.
100 FOR X=0 TO 31
110 NEXT
The loop control variable must be explicitly stated in QL
SuperBASIC:
100 FOR X=0 TO 31
110 END FOR X
FRC
Returns the fractional part of a supplied value, the part
left after removing the whole number part. In other words,
the complementary function to INT.
QL BASIC has no direct equvalent to FRC, so we need to write
one. Note that as INT generally rounds down negative number,
it is wise to use ABS in this function to ensure that FRC
works correctly for negative numbers.
200 DEFine FuNction FRC(x)
210 RETurn ABS(x)-INT(ABS(x))
220 END DEFine FRC
FRE
There are two forms of this function. FRE returns the amount
of free memory.
PRINT FRE(0) just returns the amount of free memory in bytes
PRINT FRE("") does a garbage collection before returning the
amount of free memory.
Both can be replaced by the Toolkit 2 FREE_MEM function in QL
BASIC. If the FREE_MEM function is not implemented on your
system, you may be able to use the following PEEK as an
approximation, which only works on a standard QL:
PRINT PEEK_L(163856)-PEEK_L(163852)
FUNCTION and END FUNCTION
This command is used in QBASIC to define a multi-line
function, broadly equivalent to DEF FN is QL BASIC.
Such a function is essentially the same as a subroutine which
returns a value. The return value is created by using the
function name as a variable - the return value is then passed
to the calling expression.
page 30
FUNCTION name (parameters)
REM shared variables declarations here
rem ...
name = result
REM ...
END FUNCTION
This corresponds to:
DEFine FuNction name(parameters)
REM ...
RETurn result
REM ...
END DEFine name
QBASIC lso supports an older form of multi-line function
definition, as defined with the DEF FN command.
DEF FNname(parameters)
REM ...
FNname = RESULT
REM ...
END
This would be converted using the same code in QL BASIC.
GET
GET #file_number,record_number reads a record from a random
access file into the random access file buffer. file_number
is similar to a channel number in QL BASIC. record_number is
usually the nth record stored in a file, up to a highest
value of 32767. If record_number is not specified, the next
record is fetched from the file.
The conversion method will depend on the way in which the
program concerned works and how the file is saved in the
first place. Remember that GET (and the opposite, PUT) works
via the buffer.
You may be able to convert the program by PRINTing variables
to file and using INPUT to retrieve them, although it's
possible that fixed width fields may be involved in which
case a large rewrite may be needed for QL BASIC which does
not handle files in quite the same way.
GET (x1,y1)-(x2,y2),arrayname
This version of GET is a graphics command which reads points
from a given area of the screen. It is used together with the
PUT command (q.v.) to eprform an action similar to a cut and
paste.
x1,y1 coordinates of top left corner of the block to be
copied.
x2,y2 coordinates of bottom right corner of the block to
be copied.
page 31
arrayname numeric array to hold colour values of each pixel
in the block grabbed. The array must have the same
dimensions as the block to be grabbed.
GET and PUT can be used for animation, for example, where an
object is grabbed from the screen to be redrawn in a
different position.
An approximate QL BASIC adaptation of GET relies on having a
function to read the colour of a pixel on the screen. Such
functions are available in some toolkits - we shall assume
here you are using such an extension called PIXEL to check
the colour of a pixel.
1000 DEFine PROCedure GET2(x1,y1,x2,y2)
1010 w = x2-x1+1 : REMark width of block in pixels
1020 h = y2-y1+1 : REMark height of block in pixels
1030 DIM array(w-1,h-1)
1040 FOR x = 0 to w-1
1050 FOR y = 0 TO h-1
1060 array(x,y) = PIXEL(x,y)
1070 END FOR y
1080 END FOR x
1090 END DEFine GET2
The procedure is called GET2 to avoid a clash with the file
handling procedure called GET in Toolkit 2. The block is read
into an array imaginatively called array(). This block can
then be restored with the PUT2 procedure listed under PUT
below.
Some versions of this command store the width and height of
the block in the first two entries of the array.
GOSUB
GOSUB is generally used in exactly the same way as the GOSUB
command in QL BASIC. Additionally, some versions of BASIC
allow GOSUB to a label within the program rather than a line
number. Either substitute the actual line number for the
label, or define a variable of same or similar name to the
label name.
GOTO
GOTO is generally used in exactly the same way as the GOTO
command in QL BASIC. Additionally, some versions of BASIC
allow GOTO to a label within the program rather than a line
number. Either substitute the actual line number for the
label, or define a variable of same or similar name to the
label name. In an IF THEN line involving GOTO lines, the
keyword GOTO may sometimes be omitted, but must be included
in QL BASIC:
1000 IF X=20 THEN 2000
Convert as
page 32
1000 IF X=20 THEN GOTO 2000
HEX$
v$ = HEX$(n) returns a string which represents the
hexadecimal value of the decimal argument. n is a numeric
expression in the range -32768 to 65535. If n is negative,
the two's complement form is used. That is, HEX$(-n) is the
same as HEX$(65536-n)
You could convert this function using the HEX$ function in
Toolkit 2, although you'd need to specifiy the 'width' of the
value by giving the number of bits to use to represent the
value. Here is a function written in QL BASIC which more
closely mimics the HEX$ function as described here.
3000 DEFine FuNction HEX$(dec)
3010 LOCal x,c,c$
3020 x = dec : IF x < 0 THEN x = 65536-x
3030 c$ = ""
3040 REPeat loop
3050 c = x - (INT (x/16) * 16)
3060 IF c < 10 THEN
3070 c$ = CHR$(48+c) & c$ : REMark 0-9
3080 ELSE
3090 c$ = CHR$(55+c) & c$ : REMark A-F
3100 END IF
3110 x = INT (x/16)
3120 IF x = 0 THEN EXIT loop
3130 END REPeat loop
3140 RETurn c$
3150 END DEFine
IF
IF clauses in MS BASIC are generally single line clauses, and
are generally the same as the equivalent single line IF
statements in QL BASIC, albeit with minor variations possible
mostly involving the ELSE part.
1000 IF X=2 THEN GOTO 2000 ELSE GOTO 3000
would need to be converted as having a ':' before the ELSE
keyword:
1000 IF X=2 THEN GOTO 2000 : ELSE GOTO 3000
The 'THEN' before the 'GOTO' may sometimes be omitted in MS
BASIC:
1000 IF X=2 GOTO 2000
Convert by adding a THEN:
1000 IF X=2 THEN GOTO 2000
IMP
page 33
The IMP or Implication operator is a logical operator, with
the following truth table for results. Basically, the result
of x IMP y is false only if x is true and y is false.
X Y X IMP Y
True True True
True False False
False True True
False False True
An approximate equivalent in QL BASIC could be written like
this.
2000 DEFine FuNction IMP(X,Y)
2010 IF X<>0 AND Y=0 THEN RETurn 0 : ELSE RETurn 1
2020 END DEFine IMP
Whereas the original expression would be written as LET R=X
IMP Y, the QL BASIC equivalent is a function written as LET
R=IMP(X,Y)
INKEY$
Works like the equivalent INKEY$ function in QL BASIC, but
does not allow channel numbers or timeouts.
INP
INP(I) returns the byte value read from port number I, which
must be in the range 0 to 255. There is no direct equivalent
in QL BASIC. INP is the opposite to the OUT statement (q.v.)
INPUT
Like the INPUT command in QL BASIC, this receives input from
the keyboard during program execution.
INPUT[;]["prompt";] variable[,variable]...
When the program sees an INPUT statement, it pauses and
displays a question mark on the screen to indicate that it is
waiting for data. If a "prompt" is included, the string is
displayed before the question mark. You may then enter the
required data from the keboard.
INPUT can use a comma instead of a semicolon after the prompt
string to suppress the question mark. For example, the
statement INPUT"ENTER BIRTHDATE",B$ prints the prompt without
the question mark.
As there is no equivalent to this in the QL BASIC version of
INPUT, the question mark must be explicitly included in the
prompt string if required.
Different versions of BASIC may or may not print spaces
before a variable, so you may come across something like
INPUT"ENTER";A where you would have to add a space to the
page 34
prompt string in QL BASIC - INPUT"ENTER ";A
The data that is entered is assigned to the variable(s) given
in the variable list. The data items supplied must be
separated by commas, and the number of data items must be the
same as the number of variables in the list.
The type of each data item that you enter must agree with the
type specified by the variable name. Strings entered in
response to an INPUT statement need not be surrounded by
quotation marks unless they contain commas or significant
leading or trailing spaces.
Some versions of BASIC allow you to press ENTER with no
characters inputted in response to INPUT of a numeric
variable - the value of zero (0) is then given to the numeric
variable.
Some versions of BASIC allow a single quote mark to be
included between prompts to indicate a newline between prompt
strings, e.g. INPUT "HELLO"'"THERE";A - this can be replaced
by a backslash (\) character in QL BASIC:
INPUT"HELLO"\"THERE";A
INPUT #
Reads data items from a sequential device or file and assigns
them to program variables.
INPUT #filenum,variable [,variable]...
This is similar to INPUT #channel,variable in QL BASIC,
although for string items, the first character encountered
that is not a space, carriage return or linefeed is assumed
to be the start of the string item. If this first item is a
quotation mark ("), the string item will consist of all
characters read between the first quotation mark and the
second, so a quoted string may not contain a quotation mark
as a character.
INPUT$
INPUT$(X,#Y) is a function which returns a string of X
characters from the terminal (keyboard) if the file number
(#Y) is not from specified, or from file number Y if
specified. Unless you have an equivalent toolkit extension
such as INPUT$ of Turbo Toolkit (parameters in reverse order
- INPUT$(#Y,X) in the Turbo Toolkit version), the easiest way
to replace this is to write a function which uses INKEY$ to
fetch a string of a given number of bytes from a specified
channel:
1000 DEFine FuNction INPUT_STRING$(X,Y)
1010 LOCal counter,string$
1020 string$ = ""
1030 FOR A = 1 TO X
page 35
1040 string$ = string$ & INKEY$(#Y)
1050 END FOR A
1060 RETurn string$
1070 END DEFine INPUT_STRING$
INSTR
INSTR([I,]X$,Y$) is a function which searches for the first
occurrence of Y$ within X$ and returns the position at which
the match was found, starting from 1, or returns 0 if no
match was found. An optional first parameter allows the start
position of the search within X$ to be specified.
The QL BASIC version of INSTR is broadly similar, although
the parameters are given differently. LET P=INSTR(X$,Y$) may
be replaced by LET P=Y$ INSTR X$.
The version with three parameters is a bit more difficult and
fiddly to convert, but may be done using string slicing once
we know how the MS BASIC version works, here's an example:
10 X$="ABCDEB"
20 Y$="B"
30 P=INSTR(4,X$,Y$)
This returns a value of 6 into the variable P. In other
words, start searching from the fourth character, return the
position at which a match was found in the full string - in
this case, the last character position (sixth character of
Y$).
QL BASIC version:
10 X$ = "ABCDEB"
20 Y$ = "B"
30 P = Y$ INSTR X$(4 TO LEN(X$) : IF P > 0 THEN P = P+4-1
INT
Exactly the same as the INT function on the QL.
KEY
Sets or displays soft keys, similar to altkeys or hotkeys in
QL BASIC. This command lets you assign a string to any of the
10 function keys.
KEY n,x$ assigns the string expression x$ to function key
number n. In QL BASIC, the function keys take the following
key codes, bearing in mind that F6-F10 are SHIFT F1-SHIFT F5
respectively on a QL, as it only has 5 function keys.
KEY 1 to 5 are QL key codes 232, 236, 240, 244, and 248.
KEY 6 to 10 are QL key codes 234, 238, 242, 246, and 250.
So, KEY 6,x$ would be translated to QL basic as ALTKEY
CHR$(234),x$ for example.
page 36
Other variations of this command are KEY ON, which displays
the key definitions on the 25th line of the screen. KEY OFF
turns off this display. KEY LIST displays all the key
definitions, rather like a HOT_LIST command in QL BASIC.
KILL
KILL "filename" is the same as DELETE "filename" in QL BASIC.
LEFT$
LET A$=LEFT$(X$,J) returns a string comprising the leftmost J
characters of X$. This is equivalent to LET A$=X$(1 TO J) in
QL BASIC. If J is 0, a null string is returned, while a value
of J greater than the length of X$ means that the full length
of X$ is returned. Both of these cases may cause an error in
QL SuperBASIC. So the safest way is to control the range of
values J can take in this example:
REM convert LEFT$(X$,J)
IF J=0 THEN
A$=""
ELSE
IF J>LEN(X$) THEN J=LEN(X$)
A$ = X$(1 TO J)
END IF
LEN
LEN(A$) is a function which returns the length of the string
given as a parameter. It works the same as the equivalent
function in QL BASIC.
LET
The use of the LET command is broadly the same as in
SuperBASIC. LET is optional in many BASICs, where you can use
either 100 LET A=0 or 100 A=0.
Some BASICs permit multiple assignments to be made with one
LET statement, e.g. LET A=1,B=2,C=3 so you need to break
these apart into multiple statements such as LET A=1 : LET
B=2 : LET C=3
LINE INPUT
LINE INPUT [;] [<"prompt string">;] <string variable>
Its purpose is to input an entire line of up to 254
characters to a string variable, without the use of
delimiters. The prompt string works broadly like that on a QL
BASIC INPUT command. Unlike standard MS BASIC INPUT, a '?' is
not auotmatically printed. The optional ';' between LINE
INPUT and the prompt string suppresses the carriage return
typed by the user to end the input line is not echoed at the
terminal.
page 37
LINE INPUT is broadly similar to string INPUT on the QL,
except that the use of the semi-colon to suppress the
carriage return may be simulated by adding a semi-colon at
the end:
100 INPUT ;"Enter something";S$
becomes
100 INPUT "Enter something";S$;
LINE INPUT#
LINE INPUT# file_number,string_variable$ is used to fetch a
line of up to 254 characters of data from a sequential data
file to a string variable. LINE INPUT# is similar to INPUT#
in QL BASIC, although you may need to be careful about how
the data is organised and what end of line characters are
used if you work directly from the original MS BASIC data
files.
LINE INPUT #file_number,S$ corresponds to INPUT#channel,S$ in
QL BASIC.
LIST
Lists the given line number or range of line numbers to the
screen. Equivalent to LIST on the QL, but uses '-' to specify
range of line numbers instead of ' TO '.
Examples:
LIST List all of the program to screen. Use
the same command on a QL.
LIST n Lists line number n to the screen. Use
the same command on a QL.
LIST m,n,o Lists the given line numbers only to the
screen. Use the same command on a QL.
LIST m-n Lists all line numbers from m to n
inclusive to the screen, like LIST m TO n
on a QL.
LLIST
Like LIST, but sends output to a printer device, or sometimes
to a file. Use the OPEN/LIST#/CLOSE equivalent on a QL, e.g.
to list program to SER1, use:
OPEN #3,"SER1":LIST #3: CLOSE #3
On a QL you could also use SAVE SER1, interestingly!
LOAD
The LOAD command corresponds to the QL BASIC LOAD command,
apart from syntactical differences in the filename itself of
course. The LOAD command may take a ",R" additional
page 38
parameter, which signifies that the program should start
running after it has loaded, so LOAD "filename",R corresponds
to LRUN "filename" in QL BASIC.
LOC
LOC file_number returns the record number just read or
written from a GET or PUT statement with random files. If the
file was opened but no disk I/O has been performed yet, LOC
returns a 0. With sequential files, LOC returnsthe number of
sectors (128-byte blocks) read from or written to the file
since it ws OPENed. Such files do not work in the same way on
the QL so there is no directly equivalent method of
converting this.
LOCATE
LOCATE [row][,[col] [,[cursor] [,[start] [,stop] ]]]
Positions the cursor on the active screen. Optional
parameters turn the blinking cursor on and off and define the
size of the blinking cursor.
row is a numeric expression in the range 1 to 25 (or as
many lines as fit on the screen in this version of
BASIC). It indicates the screen line number where
you want to place the cursor. Note: some versions
of BASIC may use 0 to 24 instead of 1 to 25.
col is a numeric expression in the range 1 to 40 or 1
to 80, depending on which screen width. It
indicates the screen column number where you want
to place the cursor. Note: some versions of BASIC
may use 0 to 39 or 0 to 79 instead of 1 to 40 or 1
to 80.
cursor is a value indicating whether the cursor is visible
or not. A 0 (zero) indicates off, 1 (one) indicates
on.
start is the cursor starting scan line. It must be a
numeric expression in the range 0 to 31.
stop is the cursor stop scan line. It also must be a
numeric expression in the range 0 to 31.
cursor, start and stop do not apply when the computer is in
graphics mode.
A LOCATE command with just two parameters can be converted
using an AT command in QL BASIC. So LOCATE y,x would become
AT y-1,x-1.
The "cursor" parameter could be emulated in QL BASIC by using
a separate command such as CURSEN (cursor enable) or CURDIS
(cursor disable) from Toolkit 2. The "cursor" parameter can
be used with the "row" and "col" parameters, or without -
either of these examples would be valid:
page 39
LOCATE row, col, cursor
LOCATE ,,cursor
There is no way to emulate the "start" and "stop" parameters.
LOF
LOF(file_number) returns the length (number of bytes)
allocated to the file identified by "file_number". With
communications files, LOF returns the amount of free space in
the input buffers. If you have Toolkit 2 on your QL system,
FLEN(#file_number) will perform an approximately equivalent
function.
LOG
LOG(X) returns the natural logarithm of X. X must be greater
than zero. Corresponds to LN(X) in QL BASIC.
LOWER, UPPER and MIXED
These functions alter the case of a given string. LOWER
converts the string entirely to lower case, UPPER converts it
to upper case and MIXED converts the first character too
upper case and the remainder of the string to lower case.
Similar to what is sometimes called 'Sentence case'
LOWER('HELLO') returns "hello" (without the quotes)
UPPER('Hello') returns "HELLO"
MIXED('hELLO') returns "Hello"
Some BASICs may append a '$' symbol to the names (i.e.
LOWER$, UPPER$, MIXED$) to indicate that they are type
string.
QL BASIC has no direct equivalent to these, so we have to
write equivalent functions such as these.
2350 DEFine FuNction LOWER (u$)
2360 LOCal t$,a,c
2370 REMark convert u$ to lower case
2380 t$ = u$ : REMark working copy of u$
2390 FOR a = 1 TO LEN(t$)
2400 c = CODE(t$(a))
2410 IF c > 64 AND c < 91 THEN t$(a) = CHR$(c+32)
2420 END FOR a
2430 RETurn t$
2440 END DEFine LOWER
2450 :
2460 DEFine FuNction UPPER (u$)
2470 LOCal a,c,t$
2480 REMark convert u$ to upper case
2490 t$ = u$ : REMark working copy of u$
2500 FOR a = 1 TO LEN(t$)
2510 c = CODE(t$(a))
2520 IF c > 96 AND c < 123 THEN t$(a) = CHR$(c-32)
2530 END FOR a
page 40
2540 RETurn t$
2550 END DEFine UPPER
2560 :
2570 DEFine FuNction MIXED(u$)
2580 LOCal a,c,t$
2590 REMark convert string to have upper case first letter
only
2600 t$ = u$ : REMark working copy
2610 c = CODE(t$)
2620 IF c > 96 AND c < 123 THEN t$(1) = CHR$(c-32)
2630 FOR a = 2 TO LEN(t$)
2640 c = CODE(t$(a))
2650 IF c > 64 AND c < 91 THEN t$(a) = CHR$(c+32)
2660 END FOR a
2670 RETurn t$
2680 END DEFine MIXED
LPOS
Returns the current position of the print head within the
printer buffer for the parallel port number given as a
parameter in the function vall v=LPOS(n).
There is no equivalent function in QL BASIC.
LPRINT
Similar to the PRINT command, except that it sends output to
a printer instead of the screen. To convert this, a channel
should be open to a printer so that you can use PRINT#channel
to ensure output is sent to the printer. You could also write
a simple procedure called LPRINT to open a temporary channel
to the printer to send output to the printer as a quick and
dirty conversion method if it's only the occasional single
item, instead of a range of items as might be the case with
the full allowed PRINT-style syntax.
DEFine PROCedure LPRINT(text$)
OPEN #3,"SER1": REMark printer port- change as required
PRINT #3,text$
CLOSE #3
END DEFine LPRINT
An extnded version, LPRINT USING "string_expression",item$
allows formatting of printed output in a similar way to the
PRINT USING command.
LSET
LSET <string_variable>=<string_expression>
RSET <string_variable>=<string_expression>
The purpose of this keyword is to move data from a random
file buffer (in preparation for a PUT statement).
If <string_expression> requires fewer bytes than were FIELDed
to <string_variable>, LSET left-justifies the string in the
page 41
field, and RSET right-justifies the string. (Spaces are used
to pad the extra positions). If the string is too long for
the field, characters are dropped from the right. Numeric
values must be converted to strings before they are LSET or
RSET. See MKI$, MKS$ and MKD$
Examples: 1000 LSET A$=MKS$(AMOUNT)
1010 LSET D$=DESC($)
LSET or RSET may also be used with a nonfielded string
variable to left-justify or right-justify a string in a given
field. For example, the program lines
110 A$ = SPACE$(20) : RSET A$=N$
right-justify the string N$ in a 20-character field. This can
be very handy for formatting printed output.
There is no direct equivalent to this in QL BASIC, but it is
fairly easy to approximate its function via QL string
handling functions.
The basic idea is to try to force strings to a given length
so that they will fit in a field of a random access file with
that length. So if the field is designed to hold a 20
character string, you would need to pad out or truncate a
string to exactly 20 characters long by either adding the
required number of spaces, or chopping characters off the
appropriate end of the string if it is already too long.
So we could write procedures like this:
1000 DEFine PROCedure Lset(variable$,length,expression$)
1010 variable$ = expression$
1020 IF LEN(variable$) < length THEN
1030 variable$ = variable$ & fill$(' ',length -
LEN(expression$))
1040 ELSE
1050 IF LEN(variable$) > length THEN
variable$=variable$(1 TO length)
1060 END IF
1070 END DEFine Lset
In order to write an Rset procedure, you would have to work
out if the string is to be right justified by adding spaces
between words in the string, or merely byadding spaces to the
left of the string.
LTRIM$
This function strips any leading spaces from a string whose
name is given in the function's paramater, which may be a
text constant or a string variable or a single array element.
n$ = LTRIM$(" Hello"
returns "Hello" (without the quote marks).
page 42
n$ = LTRIM$(s$) returns a copy of s$ but without any spaces
at the start of the string.
LTRIM$ may be written as a function in QL BASIC like this:
1000 DEFine FuNction LTRIM$(s$)
1010 LOCal t$,a
1020 REMark return copy of s$ minus any leading spaces
1030 t$ = "" : REMark in case s$ is all spaces
1040 FOR a = 1 TO LEN(s$)
1050 IF s$(a) <> " " THEN t$ = s$(a TO LEN(s$)) : EXIT a
1060 END FOR a
1070 RETurn t$
1080 END DEFine LTRIM$
The corresponding function RTRIM$ (q.v.) strips any spaces
from the right hand side of the string.
Stripping spaces from both sides of a string is achieved by
combining the two functions.
PRINT LTRIM$(RTRIM$(s$))
MAX and MIN
These functions return the maximum or minimum respectively of
the two values supplied as parameters. Some forms of these
functions may only handle numeric values, while others may
also handle strings.
100 LET value=MAX(2,4) would return the value 4, the higher
of the two values given. In the case of equality, such as LET
value=MAX(3,3) the value of the first parameter is returned,
in this case 3.
MIN works in a similar way for the minimum value, e.g. value
= MIN(2,4) returns the value 2.
The paramters may be numbers or numeric variables. Some
versions of BASIC allow for expressions too, e.g. LET
value=MIN(VAL("1"),VAL("2")).
QL BASIC has no direct equivalents, although it is easy to
write similar functions.
100 DEFine FuNction MAX(val1,val2)
110 IF val1 > val2 THEN
120 RETurn val1
130 ELSE
140 RETurn val2
150 END IF
160 END DEFine MAX
170 :
180 DEFine FuNction MIN(val1,val2)
190 IF val1 < val2 THEN
200 RETurn val1
210 ELSE
page 43
220 RETurn val2
230 END IF
240 END DEFine MIN
MERGE
Similar to the MERGE command in QL BASIC, except that the
format of the filename parameter may obviously vary in line
with the differences between the operating systems.
MID$
MID$(S$,N,M) is a string slicing function which returns a
section of the string S$ which is M characters long starting
at subscript N. If M is not specified, it defaults to the
last character of S$.
Examples:
A$=MID$("HELLO",2,3) returns the three letters ELL
A$=MID$("HELLO",4) returns LO
The best way to convert this is to write a function like
this:
DEF FN Mid$(S$,N,M)
RETurn S$(N TO N+M-1)
END DEF Mid$
That example doesn't cater for the case where the third
parameter is not specified.
MKD$ MKI$ MKS$
These three functions convert numeric values to string
values. Any numeric value that is placed ina random access
file buffer with LSET or RSET statements must be converted to
a string. MKI$ converts an integer to a 2-byte string. MKS$
converts a single precision number to a 4-byte string. MKD$
converts a double precision number to an 8-byte string.
The syntax is:
LET I$=MKI$(integer_expression)
LET S$=MKS$(single_precision_expression)
LET D$=MKD$(double_precision_expression)
There is no direct equivalent to these functions in QL BASIC,
and QL BASIC doesn't distinguish between single and double
precision numeric values, so you will have to try to figre
out exactly what the program is doing and write appropriate
code to handle the program code concerned.
If it is simply a matter of making strings of fixed length to
write to data files, you may be able to write code based on
the BPUT and PUT keywords from Toolkit 2 to write QL data
values to files in fixe dlength formats (2 bytes for
integers, 6 bytes for floating point values on QL).
page 44
MOD
MOD gives the integer value that is the remainder of an
integer division. Its use is the same as MOD in QL BASIC.
MOTOR
The MOTOR command turns the cassette player motor off (0) or
on (non-zero). Not required on the QL.
NAME
Changes the name of a file on disk.
NAME <old_filename> AS <new_filename>
is broadly equivalent (apart from differences in filename
syntax) to
RENAME old_filename TO new_filename
in QL BASIC. Note that RENAME is a Toolkit 2 extension and
not built into original unexpanded Sinclair QL BASIC.
NEW
Like NEW on a QL, this clears out an existing program and
resets all variables. Usually, the only difference to the QL
version is that the string space allocated by CLEAR N is not
reset.
NEXT
NEXT is used as the closing statement in a FOR/NEXT loop,
corresponding broadly to the use of END FOR in QL BASIC,
although in most cases the QL BASIC NEXT statement may be
used as an equivalent too. In some versions of BASIC, in
nested FOR/NEXT loops the NEXT keyword may take more than one
loop variable name, for example:
FOR x=1 TO 10
FOR y=1 TO 2
REM any code here
NEXT y,x
In QL BASIC, NEXT y,x should be replaced by NEXT y:NEXT x or
(better) END FOR y: END FOR x
In some versions of BASIC, the loop variable name may be
omitted, in which case the most recently executed FOR loop
counter is incremented. QL SuperBASIC has no equivalent for
this - FOR loop names must be specified, although SBASIC does
allow such omission of loop names:
FOR x=1 TO 10
PRINT x
NEXT
is perfectly valid in SBASIC, but not in SuperBASIC.
page 45
NOT
The logocal NOT is broadly the same as the use of NOT in QL
BASIC. A bitwise NOT such as x=NOT y corresponds to the use
of the double tilde in QL BASIC: x= ~~ y
where the two's complement of an integer is the bit
complement plus one, or NOT x=-(x+1)
OCT$
v$=OCT$(n) returns a string which represents the octal value
of the decimal argument. n is a numeric expresion in the
range -32768 to 65535. If n is negative, the two's complement
form is used, i.e. OCT$(-n) is the same as OCT$(65536-n).
Here are a pair of functions written in QL BASIC to convert
decimal numbers into octal (OCT$) and vice versa (DECIMAL).
8000 DEFine FuNction OCT$(dec)
8010 LOCal x,c$
8020 x = dec : IF x < 0 THEN x = 65536-x
8030 c$ = "" : REMark octal character string
8040 REPeat loop
8050 c$ = CHR$(48+x-(INT(x/8)*8)) & c$
8060 x = INT (x/8)
8070 IF x <= 0 THEN EXIT loop
8080 END REPeat loop
8090 RETurn c$
8100 END DEFine OCT$
8110 :
8120 DEFine FuNction DECIMAL(bs$)
8130 LOCal d,l,n,v
8140 d = 0
8150 l = LEN(bs$)
8160 FOR n = 1 TO l
8170 v = CODE(bs$(n))-48
8180 d = d + 8^(l-n) * v
8190 END FOR n
8200 RETurn d
8210 END DEFine DECIMAL
ON
The ON keyword may be used in ON ERROR GOTO <line_number>
clauses, or in ON...GOTO and ON...GOSUB selection clauses.
ON ERROR GOTO has no direct equivalent in QL BASIC, although
it may be possible to use WHEN ERRor to provide an
approximation of the function, but be aware that early QL
ROMs do not include support for the WHEN ERRor structure and
it is also bugged in some early ROM versions. Basically, when
an error occurs (indicated by the value of ERROR becoming
non-zero) program flow jumps to an indicated line number to
provide an action to handle the error condition.
100 ON ERROR GOTO 1000
page 46
may be converted as:
100 WHEN ERRor
101 GOTO 1000
102 END WHEN
1000 PRINT"An error has occurred."
In Microsoft-style BASICs an ON ERROR GOTO clause may be
turned off by executing something like ON ERROR GOTO 0. In QL
BASIC, an empty WHEN ERRor clause is an approximate
equivalent for turning off WHEN ERRor error trapping.
ON x GOTO and ON x GOSUB are equivalent to the same
structures in QL BASIC. The value of x (starting from 1)
decides which line number in the list after GOTO or GOSUB is
jumped to. Microsoft BASICs can handle a list withvalues from
1 to 255 for the line number selection and if the value given
is out of range (less than 0, greater than 255, or higher
than the amount of line numbers given) the program continues
from the next executable statement, whereas a QL BASIC
program will stop with an error message.
OPEN
Command format:
OPEN <mode>,[i]<file number>,<filename>[,<reclen>]
Purpose: To allow I/O to a disk file.
A disk file must be OPENed before any disk operation can be
performed on that file. OPEN allocates a buffer for I/O to
the file and determines the mode of access that will be used
with the buffer.
<mode> is a string expression whose first character is one of
the following:
O Specifies sequential output mode.
I Specifies sequential input mode.
R Specifies random input/output mode.
<file number> is an integer expression whose value is between
1 and 15. The number is then associated with the file for as
long as it is OPEN and is used to refer other disk I/O
statements to the file.
<filename> is a string expression containing a name that
conforms to the operating system's rules for disk filenames.
<reclen> is an integer expression which if included, sets the
record length for random files. The default record length is
128 bytes.
Note
Example: A file can be OPENed for sequential input or random
access on more than one file number at a time. A file may be
OPENed for output, however, on only one file number at a
time.
It is difficult to convert this precisely to QL BASIC,
although the OPEN command and its variants, for example, the
use of OPEN_NEW to open a new file for output, or OPEN_IN to
open a file just for input.
page 47
OPTION BASE
OPTION BASE n declares the minimum value for array
subscripts. n is 0 or 1 and OPTION BASE should be used before
any arrays are declared. There is no equivalent in QL BASIC -
arrays always start from a 0 subscript.
OR
The use of the logical OR is the same as that in QL BASIC,
whereas the bitwise operator OR corresponds to the use of the
double bar operator in QL BASIC. In other words, x = y OR z
corresponds to x = y || z in QL BASIC.
Order Of Arithmetic Operations
This refers to the order of priority in whch the elements of
calculations are carried out. this may vary somewhat between
versions of BASIC and some adjustment by hand may be
required, e.g. adding parentheses (brackets) to force the
order of precedence.
Operations in the innermost level of parentheses are
performed first, then evaluation proceeds to the next level
out, etc. Operations on the same nesting level are generally
performed according to the following hierarchy:
Exponentiation: A ^ B
Negation: -X
*, / (left to right)
+, - (left to right)
<, >, =, <=, >=, <> (left to right)
NOT
AND
OR
OUT
Format: OUT I,J
Where I and J are integer expressions in the range a to 255,
OUT I,J sends an integer value J to the output port I.
There is no direct equivalent in QL BASIC, although where
memory mapped devices are concerned it may be possible to use
POKE I,J.
PAINT
Fills an area of the screen with the selected colour. The
command syntax is:
PAINT (x,y) [,paint [,boundary]]
(x,y) are the coordinates of a point within the area to
be filled in. The coordinates may be given in
absolute or relative form. This point is used as a
starting point.
page 48
paint is the colour to be painted with. The default is
the foreground colour.
boundary is the colour of the edges of the figure to be
filled in.
The figure to be filled in is the figure with edges of
"boundary" colour. The figure is filled in with the colour
"paint"
The starting point of PAINT must be inside the figure to be
painted. If the specified point already has the colour
"boundary" then PAINT will have no effect.
There is no direct equivalent to PAINT in QL BASIC (the
closest being the FILL command which works in a different
way), although a few add-on toolkits may have a PAINT or
equivalent command.
PEEK
PEEK(a) reads a byte value from the address 'a'. The value
read may be from 0 to 255. Although this function is the same
as the PEEK function in QL BASIC, the memory locations read
from are unlikely to be the same - some knowledge of the
system will be needed to work out how best to convertthis,
e.g.where colours or characters are read directly from screen
memory on different computers.
Some versions of BASIC allow the address value to be
specified as a hexadecimal number by the use of &H as a
prefix to the hex value, e.g. PEEK(&H5A00)
PEN
This keyword is used for reading a light pen connected to the
PC. There is no equivalent in QL BASIC.
PLAY
PLAY "string" plays music as specified by "string". The
command implements a concept similar to DRAW by embedding a
"tune definition language" into a character string.
string is a string expression consisting of single
character music commands
The single character commands in PLAY are:
A to G with optional #, +, or -
Plays the indicated note in the current octave. A
number sign (#) or plus sign (+) afterwards
indicates a sharp, a minus sign (-) indicates a
flat. The #, +. or - is not allowed unless it
corresponds to a black key on a piano. For example,
B# is an invalid note.
page 49
O n Octave. Sets the current octave for the following
notes. There are 7 octaves, numbered 0 to 6. Each
octave goes from C to B. Octave 3 starts with
middle C. Octave 4 is the default octave.
N n Plays note n. n may range from 0 to 84. In the 7
possible octaves, there are 84 notes. n=0 means
rest. This is an alternative way of selecting notes
besides specifying the octave (O n) and the note
name (A-G).
L n Sets the length of the following notes. The actual
note length is 1/n. n may range from 1 to 64. The
following table may help explain this:
Length Equivalent
L1 whole not
L2 half note
L3 one of a triplet of three half notes (1/3
of a 4 beat measure)
L4 quarter note
L5 one of a quintuplet (1/5 of a measure)
L6 one of a quarter note triplet
.
.
.
L64 sixty-fourth note
The length may also follow the note when you want
to change the length only for the note. For
example, A16 is equivalent to L16A
P n Pause (rest). n may range from 1 to 64, and figures
the length of the pause in the same way as L
(length).
(dot or period). After a note, causes the note to
be played as a dotted note. That is, its length is
multiplied by 3/2. More than one dot may appear
after the note, and the length is adjusted
accordingly. For example, "A.." will play 9/4 as
long as L specifies, "A..." will play 27/8 as long,
etc. Dots may also appear after a pause (P) to
scale the pause length in the same way.
T n Tempo. Sets the number of quarter notes in a
minute. n may range from 32 to 255. The default is
120.
MF Music foreground. Music (created by SOUND or PLAY)
runs in foreground. That is, each subsequent note
or sound will not start until the previous note or
sound is finished. You can press Ctrl-Break to exit
PLAY. Music foreground is the default state.
MB Music background. Music (created by SOUND or PLAY)
runs in background instead of in foreground. That
page 50
is, each note or soundis placed in a buffer
allowing the BASIC program to continue executing
while music plays in the background. Up to 32 notes
(or rests) may be played in the background at a
time.
MN Music normal. Each note plays 7/8 of the time
specified by L (length). This is the default
setting of MN, ML and MS.
ML Music legato. Each note plays the full period set
by L (length).
MS Music staccato. Each note plays 3/4 of the time
specified by L.
X variable;
Executes specified string.
In all of these commands the n argument can be a constant
like 12 or it can be =variable; where variable is the name of
a variable. The semicolon (;) is required when you use a
variable in this way, and when you use the X command.
Otherwise a semicolon is optional between commands, except a
semicolon is not allowed after MF, MB, MN, ML, or MS. Also,
any blanks in "string" are ignored.
Variables can also be specified in the form
VARPTR$(variable), instead of =variable; which is often
useful where a program is to be compiled. For example:
One Method Alternative Method
PLAY "XA$;" PLAY "X"+VARPTR$(A$)
PLAY "O=I;" PLAY "O="+VARPTR$(I)
X can be used to store a "subtune" in one string and call it
repetitively with different tempos or octaves from another
string.
As the PLAY command can be difficult to grasp and there is no
direct equivalent in QL BASIC without writing a small program
to emulate the actions of PLAY "string", here is an example
to help set you on the way.
10 REM little lamb
20 MARY$="GFE-FGGG"
30 PLAY "MB T100 03 L8;XMARY$;P8 FFF4"
40 PLAY "GB-B-4; XMARY$; GFFGFE-."
POINT
Reads a colour value from the specified co-ordinates on the
screen. For example, c=POINT(x,y) reads the colour value of
the pixel at x across and y down the screen. There is no
direct equivalent in QL BASIC, although some BASIC extensions
have been written to extract a colour value from the screen,
page 51
for example in the DIY Toolkit series.
POKE
POKE a,d writes the byte value d to the address a. The value
written may be from 0 to 255. Although this function is the
same as the POKE command in QL BASIC, the memory locations
written to are unlikely to tbe the same - some knowledge of
the system will be needed to work out how best to convert
this, e.g. where colours or characters are written directly
to screen memory on different computers.
Some versions of BASIC allow the address value to be
specified as a hexadecimal number by the useof &H as a prefix
to the hex value, e.g. POKE &H5A00,d
POS
POS(X) returns the current cursor position. The leftmost
position is 1. X is a dummy argument.
Example: IF POS(X)>60 THEN PRINT CHR$(13)
There is no direct equivalent in QL BASIC, although the
information required to convert this function is contained
within the channel definition blocks for the window channel
concerned and may be read using the DIY Toolkit function
CHAN_W% for a given channel number. The horizontal cursor
position in pixels may be read from offset 34 decimal (hex
22). This starts from 0 and is in pixel units, so to get a
text character position across, divide by the number of
pixels per character in the current character size, e.g. 6
for CSIZE 0,0 text. The character spacing for a given window
channel may be checked with CHAN_W%(#channel,38), so to read
the current text position as characters across the screen,
use something like:
LET pos=CHAN_W%(#channel,34) DIV CHAN_W%(#channel,38)
On computers where the POS function starts from 1 for the
leftmost position, you should add 1 to this result:
LET pos=1+(CHAN_W%(#channel,34) DIV CHAN_W%(#channel,38))
or write it as a function in QL BASIC:
1000 DEFine FuNction POS(chan)
1010 RETurn 1+(CHAN_W%(#chan,34) DIV CHAN_W%(#chan,38))
1020 END DEFine POS
PRINT
In general, works almost exactly the same as the QL PRINT
command, the main exception being that in cases where no
ambiguity would result, punctuation between items to be
printed (; or ,) can be omitted. These need to be included in
QL PRINT statements.
Example:
page 52
PRINT 2"Hello" Must be converted to PRINT 2;"Hello" on a
QL.
There may be differences in syntax when PRINT output is
routed to a channel or device.
PRINT may take position and format identifiers - see AT, TAB
and USING.
When printing numbers, or numeric variables, some BASICs may
add a space before and/or after a number, to clearly separate
numbers from any surrounding text.
Example:
A=3:PRINT "Buy";A;"items."
prints the avriable with spaces both sides in this case
Buy 3 items.
So to convert exactly to the QL, you would need to add the
extra spaces at the appropriate sides of the variable A in
the PRINT statement:
A=3:PRINT "Buy";" ";A;" ";"items"
A bit of an extreme example, but serves to illustrate what
you need to do.
Some versions of BASIC allow you to use a query symbol as a
shorthand way of entering a print command in the BASIC
editors. Often this is expanded to a PRINT keyword, but not
always, so you may come across listings with lines such as
100 ?"Hello" which is obviously the same as 100 PRINT"Hello"
PRINT @
This is a version of PRINT which allows you to locate the
cursor at given text coordinates. The value after the '@'
symbol may in some cases be a pair of coordinates (X,Y or Y,X
- both forms exist). or a single coordinate which specifies
the total number of characters from the top left of the
screen - (Y times line_width)+X.
For example, a Tandy TRS-80 can have a 64 column or 32 column
screen width. So PRINT @64 could refer to the start of the
second line down in 64 column mode (like AT 1,0 on a QL) or
to the start of third line down in 32 column mode (like AT
2,0 on a QL).
Some versions of BASIC may use a comma or semi-colon between
the @value and the string or variable to be printed. Some may
omit the separator completely!
See also LOCATE command.
Example 1:
page 53
The single value version is best converted after reference to
the number of characters across the screen mode of the
computer in question:
PRINT @N,"Hello" convert this as AT (N DIV screen_width),
(N MOD screen_width) : PRINT"Hello"
Example 2:
PRINT @X,Y;"Hello" convert as AT Y,X : PRINT"Hello"
Example 3:
PRINT @Y,X"Hello" (note missing separator after X) convert
as AT Y,X : PRINT "Hello"
PRINT #
PRINT #filenum, [USING v$;] listofexps writes data
sequentially to a file.
filenum is the number used when the file was opened for
output (like a channel number in QL BASIC)
v$ is a string expression comprised of formatting
characters as described under USING below.
listofexps
is a list of numeric and/or string expressions that
will be written to the file.
PRINT # is very similar to PRINT # in QL BASIC, except that
filenum and channel numbers may be different, and the
punctuation between items ot be printed may be more flexible
in QL BASIC - normally, you'd only use semicolons between
items in PRINT # statements in Microsoft BASIC to send
numeric values or variables ot a file - note that like PRINT
a space may be sent between two variables separated by a
semicolon.
PSET PRESET
Draws a point at the specified position on the screen. The
difference between PSET and PRESET is that if no colour
(third parameter) is specified, PSET defaults to the
forgeground (ink) colour, while PRESET defaults to the
background (paper) colour. Both commands take the same two or
three parameters.
PSET (x,y) [,colour]
PRESET (x,y) [,colour]
x and y are the coordinates of the point to be set, and may
be absolute or relative values depending on the system
concerned. Relative coordinates are specified by preceding
the open bracket with a STEP keyword, e.g. PSET STEP(10,-20)
page 54
colour is optional and the colour values depend on the system
concerned.
An approximate conversion is to write a short procedure in QL
BASIC to use BLOCK to colour a pixel, although you will need
some knowledge of the system concerned to know the range of
pixel sizes and colour numbers to use.
8500 DEFine PROCedure PSET(x,y,colour)
8510 BLOCK 1,1,x,y,colour
8520 END DEFine PSET
8530 :
8540 DEFine PROCedure PRESET(x,y,colour)
8550 BLOCK 1,1,x,y,colour
8560 END DEFine PRESET
Depending on which screen window you use to draw the graphics
on a QL, you may wish to add a channel number to the BLOCK
commands - without one, they default to channel #1.
PUT
PUT [*]<file number>[,<record number>]
Write a record from a random buffer to a random disk file.
<file number> is the number under which the file was OPENed.
If <record number> is omitted, the record will assume the
next available record number (after the last PUT). The
largest possible record number is 32,767. The smallest
record number is 1.
As the QL filing system is so different to that used on these
other computer system, it is hard to give a definitive
conversion method. Best to study how the filing system works
and devise an individual conversion based on that.
PUT (x,y) , array [, action]
As a graphics command, PUT writes a block of pixels onto the
screen, with the colour information and block size specified
by 'array', and action may be PSET, PRESET, AND, OR, XOR. The
array is likely to have been grabbed into the array
originally by the GET command (q.v.)
x,y Coordinates of top left corner of image to be
transferred.
array Two dimensional array with colour value for each
pixel.
action PSET - draw pixel (see PSET and PRESET above)
PRESET - draw pixel (see PSET and PRESET above)
AND - used when you want to transfer the image only
if an image already exists under the transferred
image.
OR - is used to superimpose the image onto the
existing image (like OVER 1 in QL BASIC)
page 55
XOR - a special mode which may be used for
animation. XOR causes the points on the screen to
be inverted where a point exists in the array
image, so if the image is PUT against a complex
background twice, the background is restored
unchanged, which allows you to move an image around
without obliterating the background. A bit like
OVER -1 on a QL.
Note that the default is XOR for the fourth
parameter.
Here is a simple QL BASIC equivalent, slightly renamed to
avoid a name clash with the other use of the PUT command. The
bracketing around the parameters has to be different, the
word used for action must be in quotes, and there is no
equivalent to the AND action.
1000 DEFine PROCedure PUT2 (x,y,array,logic$)
1010 w = DIMN(array,1)
1020 h = DIMN(array,2)
1030 IF logic$ == 'OR' THEN OVER 1
1040 IF logic$ == 'XOR' THEN OVER -1
1050 FOR a = 0 to h-1
1060 FOR b = 0 TO w-1
1070 BLOCK 1,1,b,a,array(b,a)
1080 END FOR b
1090 END FOR a
1100 OVER 0
1110 END DEFine PUT2
RANDOMISE
RANDOMISE [ <expression> ] reseeds the random number
generator. If <expression> is omitted, Microsoft BASIC
suspends program execution and asks for a value by printing:
Random Number Seed (-32768 to 32767)?
before executing RANDOMIZE.
If the random number generator is not reseeded, the RND
function returns the same sequence of random numbers each
time the program is RUN. To change the sequence of random
numbers every time the program is RUN, place a RANDOMIZE
statement at the beginning of the program and change the
argument with each RUN.
This command is broadly the same as that in QL BASIC,
although if <expression> is omitted in QL BASIC, the random
number generator is reseeded with a value based on the
current clock value.
Note that the sequence for a given seed value is not likely
to be the same in QL BASIC as the same seed in other BASICs.
READ
READ <list of variables>
page 56
As in QL BASIC, with minor differences this reads values from
DATA statements assigns them to variables. The variable used
for READ must be of the same data type as the data value
contained in the DATA statement, although some BASICs allow
unquoted strings to be used in DATA statements. Such strings
must be quoted in QL BASIC.
1000 DATA HELLO
must be altered like this for QL BASIC:
1000 DATA "Hello"
Some versions of BASIC only allow one data type in a READ
statement, or even only single variables, which is why you
may come across something like:
1000 READ a : READ b : READ c$
It is possible to join these together into a single clause in
QL BASIC:
1000 READ a,b,c$
REM
The comment command REM is the same as the command REMark in
QL BASIC. Some versions of BASIC allow REMark to be
abbreviated to an apostrophe:
1000 LET a=b 'assign b to a
is the same as
1000 LET a=b : REMark assign b to a
REPEAT UNTIL
REPEAT and UNTIL form a kind of repeat loop where a test
expression to determine the termination of the loop is
performed at the REPEAT statement.
1000 X=0
1010 REPEAT
1020 X=X+!
1030 UNTIL X=10
This can be converted to a REPEAT / END REPEAT loop in QL
BASIC, but the test condition will need to be written as an
EXIT statement test just before the END REPEAT, and the loop
given a name (unless you are using SBASIC, which permits
unnamed loops).
1000 X=0
1010 REPEAT loop
1020 X=X+1
1030 IF X=10 THEN EXIT loop
page 57
1040 END REPEAT loop
RESET
The RESET command closes all diskette files and clears the
system buffer. There is no direct equivalent in QL BASIC,
other than a CLOSE statement for all open file channels.
On some systems, a RESET command is a graphics command which
resets the colour of a pixel to the screen background colour
- see the SET command for further details.
RESTORE
RESTORE [ <line number>]
To allow DATA statements to be read from a specified line.
After a RESTORE statement is executed, the next READ
statement accesses the first item in the first DATA statement
in the program. If <line number> is specified, the next READ
statement accesses the first item in the specified DATA
statement.
Equivalent to the RESTORE command in QL BASIC.
RESUME
RESUME continues program execution after an error recovery
procedure has been performed. Up to four formats may be
encountered:
RESUME Execution resumes at the statement which
caused the error.
RESUME 0 Execution resumes at the statement which
caused the error.
RESUME NEXT Execution resumes at the statement
immediately following the one which
caused the error.
RESUME line_number Execution resumes at line_number.
For RESUME or RESUME 0, use a WHEN ERRor statement with a
RETRY command to resume execution at the line which caused
the error:
100 WHEN ERRor
110 PRINT'Oops'
120 RETRY
130 END WHEN
140 INPUT'Enter a number:';num%
150 REMark reset error processing
160 WHEN ERRor
170 END WHEN
For RESUME NEXT, use a similar structure, but use the
page 58
CONTINUE command in place of the RETRY command in line 120.
For RESUME line_number, use a GOTO line_number in place of
the RETRY or CONTINUE commands in line 120.
RETURN
The RETURN statement(s) in a subroutine cause Microsoft BASIC
to branch back to the statement following the most recent
GOSUB statement. A subroutine may contain more than one
RETURN statement, should logic dictate a return at different
points in the subroutine. The use of the RETURN statement in
subroutines in Microsoft-style BASICs is the same as the use
of RETURN in QL BASIC.
REVERSE$ or REVERSE
REVERSE$("string") is a function which reverses the
characters of a string, for example, PRINT REVERSE$("Hello")
prints "olleH". In some versions of BASIC the function is
called REVERSE (i.e. without the '$' symbol).
QL BASIC has no equivalent function, but it is easy to write
a similar function as shown in this example. This version can
reverse the digits of a number as well as strings thanks to
typeless QL parameters (n in this case, which can be a number
or a string).
100 DEFine FuNction REVERSE$(n)
110 LOCal a,t1$,t2$
120 t1$ = n : t2$ = n
130 FOR a = 1 TO LEN(t1$)
140 t2$(a) = t1$(LEN(t1$)-a+1)
150 END FOR a
160 RETurn t2$
170 END DEFine REVERSE$
RIGHT$
RIGHT$(X$,I) is a function which returns the rightmost I
characters of string X$. If I is equal to the number of
characters in X$ (LEN(X$)), returns X$. If I=O, the null
string (length zero) is returned.
To create an equivalent function in QL BASIC, you can write a
function called RIGHT$ like this:
3000 DEFine FuNction RIGHT$(x$,i)
3010 IF i < 1 THEN RETurn ""
3020 IF i > LEN(x$) THEN RETurn x$
3030 RETurn x$(LEN(x$)-i+1 TO LEN(x$))
3040 END DEFine RIGHT$
RND
RND returns a random number between 0 and 1 (the next number
in the pseudo-random sequence of random numbers) when used
page 59
without a parameter, or with a parameter value of greater
than 0, e.g. RND(2). RND(0) repeats the last random number
generated. In some versions of BASIC, RND followed by a
positive whole number returns a random integer in the range
of 1 up to the value given, e.g. RND(9) returns a random
number between 1 and 9 (inclusive). In QL BASIC, replace
RND(10) with either RND(1 TO 10) or RND(10)+1
RND*10 will generate a random decimal number from 0 to 9
inclusive. Convert that with exactly the same code in QL
BASIC. An expression like (RND*10)+1 will generate a random
decimal number from 1 to 10 inclusive (that may also be
converted with identical code in QL BASIC), while an
expression such as INT(RND*10)+1 will generate a random
integer from 1 to 10 inclusive. While the latter example may
be written using the same code in QL BASIC, you may find it
clearer and more brief to use RND(1 TO 10) instead. In QL
BASIC, the statement RND(n) generates a random whole number
from 0 to n inclusive.
In QL BASIC, RND without a parameter gets a floating point
random number in the range 0 to 1. RND(n) gets an integer
between 1 and n inclusive. RND(m TO n) gets an integer
between m and n inclusive.
So, to convert the version of RND with a positive number
parameter, i.e. RND(n) which generates a random number from 1
to n inclusive, use RND(1 TO n) in QL BASIC.
Summary:
PC Basic QL BASIC Notes
RND RND Random number from 0
to 1
RND(0) no equivalent Repeat last random
number
RND*n RND*n Random decimal number
from 0 to n-1
(RND*n)+1 (RND*n)+1 Random decimal number
from 1 to n
INT(RND*n)+1 RND(1 TO n) or Random integer from 1
INT(RND*n)+1 to n
RND(n) RND(1 TO n) Random integer from 1
to n (in some early
BASICs may be 0 to
n-1)
RSET
see LSET.
RTRIM$
page 60
This function returns a copy of a string minus any trailing
spaces at the right hand side of the string. It is related to
the LTRIM$ function (q.v.) which strips spaces from the left
hand side of a string.
An equivalent funtion to RTRIM$ may be written like this in
QL BASIC.
3350 DEFine FuNction RTRIM$(s$)
3360 LOCal t$,a
3370 REMark return a copy of s$ minus any leading spaces
3380 t$ = "" : REMark in case s$ is all spaces
3390 FOR a = LEN(s$) TO 1 STEP -1
3400 IF s$(a) <> " " THEN t$ = s$(1 TO a) : EXIT a
3410 END FOR a
3420 RETurn t$
3430 END DEFine RTRIM$
RUN
Equivalent to the QL RUN command, except that in most BASICs
the RUN command also does the equivalent of a CLEAR command
to reset all variables. So you may have to do something like
CLEAR:RUN on a QL. RUN can take an optional line number.
RUN "filename"
Equivalent to LRUN "filename" on a QL.
SAME
SAME is a function which tests if two supplied numbers or
strings are the same. This sounds very similar to a simple
'=' statement and in some cases it is. The main difference is
that when comparing strings, the case of text characters does
not matter - "hello" is considered to be the same as "HELLO"
The function returns a TRUE value (1 or -1, depending on the
system concerned) if the two parameters match, or 0 if not
matched.
The easiest way to write a similar function in QL BASIC is to
use the PARTYP function of Toolkit 2 to establish if the
parameters are numbers or strings, then use either '=' for
number comparison or '==' for case insensitive string
matching. The QL BASIC functions returns a TRUE value of 1
for a match.
3750 DEFine FuNction SAME(x,y)
3760 IF PARTYP(x) > 1 AND PARTYP(y) > 1 THEN
3770 REMark both numbers
3780 RETurn (x=y)
3790 ELSE
3800 REMark not both numbers, compare as strings
3810 RETurn x == y
3820 END IF
3830 END DEFine SAME
page 61
SAVE
SAVE <filename>[{,A!,P}]
Save a program file on disk.
<filename> is a quoted string that conforms to your operating
system's requirements for filenames. (Your operating system
may append a default filename extension if one was not
supplied in the SAVE command). If <filename> already exists,
the file will be written over.
Use the A option to save the file in ASCII format. Otherwise,
Microsoft BASIC saves the file in a compressed binary format.
ASCII format takes more space on the disk, but some disk
access requires that files be in ASCII format. For instance,
the MERGE command requires an ASCII format file, and some
operating system commands such as LIST may require an ASCII
format file.
Use the P option to protect the file by saving it in an
encoded binary format. When a protected file is later RUN (or
LOADed), any attempt to list or edit it will fail.
The SAVE command does the same function in QL BASIC, although
SAVE always saves in ASCII format, and does not automatically
overwrite existing files. Also, there is no QL BASIC
equivalent for the P option.
SCREEN
This command sets the screen attributes to be used by
subsequent statements. It is system-specific, so often would
not be required in QL BASIC conversions, although some
features may be relevant.
SCREEN [mode] [,burst] [,page] [,vpage]
mode is a numeric expression resulting in a low integer
value which describes the text (0) mode or graphics
mode.
burst is a numeric expression resulting in a true or
false value. It enables colour. In text mode (mode
value = 0) a false (zero) value disables colour
(black and white only) and a true (non-zero) value
enables colour.
apage (active page) is an integer expression in the range
0-7 for width 40, or 0 to 3 for width 80. It
selects the page to be written to by screen output
statements and is valid in text modes only.
vpage (visual page) selects which page is to be displayed
on the screen, in the same way as apage. The visual
page may be different to the active page. vpage is
valid in text mode (mode=0) only. If omitted, vpage
page 62
defaults to apage.
Here are some standard values for "mode", taken from a QBASIC
manual.
Mode Resolution Colours/Palette Adapters
0 Text only 16/16 (64 EGA) All
1 320x200 4/(16 EGA VGA) CGA EGA VGA
2 640x200 2/(16 EGA VGA) CGA EGA VGA
3 720x348 2/2 HGA
4 640X400 2/16 Olivetti
M24/M28
7 320x200 16/16 EGA VGA
8 640x200 16/16 EGA VGA
9 640x350 16/64 EGA VGA
10 640x350 4/9 (monochrome) EGA VGA
11 640x480 2/262144 VGA
12 640x480 16/262144 VGA
13 320x200 256/262144 VGA
SELECT CASE
This is a structure very similar to the QL BASIC SELect ON
clauses, allowing selection of actions on the basis of
individual values or ranges of values. A multi-way
conditional branching structure if you like. Broadly
speaking, the two structures are similar with only minor
variations, although one major difference is that SELECT CASE
can handle strings, whereas QL BASIC SELect ON can only
handle numbers.
SELECT CASE x
CASE 2
...
CASE 3,6
...
CASE ELSE
...
END SELECT
In QL BASIC, this corresponds to
SELect ON x
=2
...
=3,6
...
=REMAINDER
...
END SELect
Note that if the selection variable (x in this example) is an
integer such as x% you may find that some QL ROM versions
such as AH and JM don't allow the use of an integer variable
name in a SELECT ON clause. SBASIC does, many QDOS ROM
versions will allow the use of integer variables in compiled
BASIC programs but not interpreted BASIC programs. For
page 63
compatibility purposes allow you to imply that a variable is
floating point when interpreted (for compatibility) and
treated as integer variables when compiled. The Turbo
compiler allows the use of IMPLICIT% x for this purpose, and
the QLiberator compiler allows the use of DEF_INTEGER x for
this purpose.
The string selection version is a little more complex to
reproduce in QL BASIC. Here is an example of a string SELECT
CASE structure:
SELECT CASE n$
CASE "Fred"
...
CASE "Joe"
...
CASE ELSE
...
END SELect
Probably the easiest way to achieve a similar coding in QL
BASIC is the use of multiple IF...THEN statements:
IF n$ = "Fred" THEN
...
ELSE
IF n$ = "Joe" THEN
...
ELSE
REMark CASE ELSE
...
IF
END IF
If the version of BASIC concerned allows for case independent
string matching, you may prefer to use the '==' equivalence
operator in the QL BASIC version to allow upper case lower
case to be matched.
SET
SET and RESET are commands used in some versions of BASIC
having low resolution graphics. SET x,y sets a pixel x pixels
across the screen and y pixels down the screen. A
corresponding function POINT interrogates the screen to
return the colour value, or on a monochrome screen TRUE or
FALSE values for a set or reset pixel respectively.
In general, a SET command may be converted using a BLOCK
command, but you will need to know the resolution of the
screen to know how to scale the BLOCK size per pixel. As an
example, older computers with low resolution screens may have
graphics based on 2 pixels across and three down per text
character, so if using CSIZE 0,0 on the QL you will need to
use a BLOCK 2,3,x,y,colour_value command to convert a SET
command, and a BLOCK 2,3,x,y,paper_colour for a RESET
command.
page 64
SGN
This is a function which returns the sign of a number. It
returns -1 if the value is less than 0, 1 if greater than 0
and zero if the value is 0. The QL does not have a SGN
function, but it is easy to write a QL BASIC function to
provide this keyword, using a couple of logical tests to
compare the range of values.
1000 DEFine FuNction SGN(value)
1010 RETurn -1*(value<0)+(value>0)
1020 END DEFine SGN
SIN
SIN(angle) returns the sine of the angle specified in
radians, as in QL BASIC. If the version of BASIC works in
units of degrees, use SIN(RAD(angle)) in QL BASIC. To convert
degrees to radians without using the RAD function, multiply
the angle value in degrees by PI/180:
LET sine=SIN(degrees*PI/180)
SLEEP
SLEEP n suspends execution of a program for n seconds. May be
simulated with a PAUSE command in QL BASIC (although an
extension such as SUSPEND_TASK from Turbo Toolkit may be
better). Note that PAUSE works in units of frames, so n
seconds should be converted to 50*n on the QL. That is, SLEEP
n is converted as PAUSE 50*n.
SOUND
This command generates sound through the speaker.
SOUND freq, duration
freq is the desired frequency in Hertz (cycles per
second). It must be a numeric expression in the
range 37 to 32767.
duration is the desired duration in clock ticks. The clock
ticks occur 18.2 times per second. duration must be
a numeric expression in the range 0 to 65535.
QL BEEP duration is measured in units of 72 microseconds
compared to 5495 microseconds for SOUND. QL BEEP pitch values
are not directly related to musical notes or particular
pitch, but here is a table showing approximate relationships
between note and the pitch parameter of BEEP duration,pitch
in QL BASIC. Outside this range the pitch values become less
reliable.
Note Pitch Note Pitch
A 41 A 15
A# 38 A# 14
B 36 B 12
page 65
C 33 (middle C) C 11
C# 31 C# 10
D 28 D 9
D# 26 D# 8
E 24 E 7
F 22 F 6
F# 20 F# 5
G 19 G 4
G# 17 G# 3
When the SOUND statement produces a sound, the program
continues to execute until another SOUND statement is
reached. If duration of the new SOUND statement is zero, the
current SOUND statement that is running is turned off.
Otherwise the program waits until the first sound completes
before it executes the new statement.
If no SOUND statement is running, SOUND x,0 has no effect.
The tuning note, A, has a frequency of 440. The following
table correlates notes with their frequencies for two octaves
on either side of middle C.
Note Frequency Note Frequency
C 130.810 C* 523.250
D 146.830 D 587.330
E 164.810 E 659.260
F 174.610 F 698.460
G 196.000 G 783.990
A 220.000 A 880.000
B 246.940 B 987.770
C 261.630 C 1046.500
D 293.660 D 1174.700
E 329.630 E 1318.500
F 349.230 F 1396.900
G 392.000 G 1568.000
A 440.000 A 1760.000
B 493.880 B 1975.500
* middle C. Higher (or lower) notes may be approximated by
doubling (or halving) the frequency of the corresponding note
in the previous (next) octave.
To create periods of silence, use SOUND 32767,duration.
The duration for one beat can be calculated from beats per
minute by dividing the beats per minute into 1092 (the number
of clock ticks in a minute)
The next table shows typical tempos in terms of clock ticks:
Tempo Beats/Minute Ticks/Beat
very slow Larghissimo
. Largo 40-60 27.3-18.2
. Larghetto 60-66 18.2-16.55
. Grave
. Lento
page 66
. Adagio 66-76 16.55-14.37
slow Adagietto
. Andante 76-108 14.37-10.11
medium Andantino
. Moderato 108-120 10.11-9.1
fast Allegretto
. Vivace
. Veloce
. Presto 168-208 6.5-5.25
very fast Prestissimo
SPC
The function SPC(n) skips n spaces in a PRINT statement. n
must be in the range 0 to 255. If n is greater than the
defined width of the device (e.g. a 60 column screen or 80
column printer), then the value used is n MOD width. SPC may
only be used with PRINT, LPRINT and PRINT # statements. If
the SPC function is at the end of the list of data items,
then BASIC does not add a carriage return, as though the SPC
function had an implied semicolon after it. Also, see the
SPACE$ function below.
Dependent on whether the version of BASIC concerned uses SPC
like a TAB statement or a SPACE$ function, this could be
converted to QL BASIC using a PRINT TO n; statement for the
former, or a FILL$ function for the latter as described under
SPC$ and SPACE$ below.
SPC$ SPACE$
These two functions return a string consisting of n spaces.
Both versions are the same, just different names used in
different versions of BASIC.
In QL BASIC, the FILL$ function can be used to return n
spaces: FILL$(" ",n), or write a function with a similar name
to the source BASIC like this, dependent on whether the
source BASIC uses SPC$ or SPACE$:
1000 DEFine FuNction SPC$(n)
1010 RETurn FILL$(" ",n)
1020 END DEFine
SQR
Returns the square root of a given value. Equivalent to the
SQRT function in QL BASIC. You could write a function called
SQR to provide a function of the same name.
2000 DEFine FuNction SQR(value)
2010 RETurn SQRT(value)
2020 END DEFine SQR
STEP
Part of the FOR / NEXT loops structure, used the same way as
page 67
STEP in QL BASIC.
STICK
Returns the x and y co-ordinates of two joysticks. The syntax
is v=STICK(n) where
n is a numeric expression in the range 0 to 3 which
affects the result as follows
0 - returns the x coordinate of joystick A
1 - returns the y coordinate of joystick A
2 - returns the x coordinate of joystick B
3 - returns the y coordinate of joystick B
Note: STICK(0) retrieves all four values for the
coordinates, and returns the value for STICK(0).
STICK(1), STICK(2) and STICK(3) do not sample the
joystick - they get the values previously retrieved
by STICK(0).
The range of values for x and y depends on your
particular joysticks.
Since the QL has no specific commands to read such joysticks,
a direct conversion is not possible. QL joysticks work by
emulating the keyboard - the arrow keys for joystick 1, and
the function keys for joystick 2, both of which may be read
with INKEY$ to provide joystick control for programs.
STOP
The use of STOP is broadly equivalent to the same command in
QL BASIC. Other BASICs tend to have both a STOP and an END
command, the main difference between them being that STOP
does not close files on return to command level.
STR$
STR$ is a function which returns a string version of a
supplied value, e.g. LET x$=STR$(y).
In some versions of BASIC, the string return may contain a
leading space, reserved for the sign of the number. A
positive value may omit the sign, so that it is returned as a
space, whereas the space becomes a minus sign for negative
numbers.
PRINT STR$(3.5) might return " 3.5" whereas PRINT STR$(-3.5)
might return "-3.5".
In QL BASIC, this function is replaced by string coercion
whereby numeric and string values are converted implicitly.
So the above example would simply be replaced by LET x$=y
although you could write a function in QL BASIC to provide a
function of the same name for simplicity of conversion:
3000 DEFine FuNction STR$(value)
3010 RETurn value
3020 END DEFine STR$
page 68
The function type is denoted by the '$' symbol at the end of
the function name in QL BASIC. If this is not sufficiently
explicit, a simple coercion using a local string variable
could be used prior to the RETurn statement:
3000 DEFine FuNction STR$(value)
3010 LOCal t$
3020 t$ = value
3030 RETurn t$
3040 END DEFine STR$
If you wish to emulate the leading space feature, simply do a
test for positive or neagtive values and add a leading space
if not negative:
3000 DEFine FuNction STR$(value)
3010 LOCal t$
3020 if value < 0 then t$ = value : ELSE t$ = " "&value
3030 RETurn t$
3040 END DEFine STR$
STRIG
STRIG returns the status of the joystick buttons (triggers).
STRIG(n) ON must be executed to enable trapping by the ON
STRIG(n) statement. After STRIG(n) ON every time the program
starts a new statement, BASIC checks to see if the specified
button has been pressed.
IF STRIG(n) OFF is executed, no testing or trapping takes
place. Even if the button is pressed, the event is not
remembered. If a STRIG(n) STOP statement is executed, no
trapping takes place. However, if the button is pressed, it
is remembered so that an immediate trap takes place when
STRIG(n) ON is executed.
The values of n for the statements above may be 0, 2, 4, or 6
and indicates the button to be trapped as follows:
0 button A1
2 button B1
4 button A2
6 button B2
Used as a function v=STRIG(n)
n is a numeric expression in the range 0 to 3. It
affects the value returned by the function as
follows:
0 Returns -1 if button A1 was pressed since
the last STRIG(0) function call, returns
0 if not.
1 Returns -1 if button A1 is currently
pressed, returns 0 if not.
page 69
2 Returns -1 if button B1 was pressed since
the last STRIG(2) function call, returns
0 if not.
3 Returns -1 if button B1 is currently
pressed, returns 0 if not.
Some systems allow four buttons to be read from the joystick,
using the values 4 to 7 for buttons A2 and B2. Same return
values.
STRING$
Returns a string of length n whose characters have the ASCII
code m or the first character of x$. So you may encounter two
versions:
v$ = STRING$(n,m) or
v$ = STRING$(n,x$)
Either version can be replaced by the FILL$ function in QL
BASIC, with parameter type adjusted accordingly. v$ =
STRING$(n,m) would become v$ = FILL$(CHR$(m),n) while v$ =
STRING$(n,x$) would become v$ = FILL$(x$,n)
If a program uses both forms of the command, you may be able
to write a function which tests the type of the second
parameter using the Toolkit 2 function PARTYP to test the
type of the second parameter and adjust the action of the
function accordingly:
4000 DEFine FuNction STRING$(n,m)
4010 IF PARTYP(m) > 1 THEN
4020 REMark numeric
4030 RETurn FILL$(CHR$(m),n)
4040 ELSE
4050 REMark null or string
4060 RETurn FILL$(m,n)
4070 END IF
4080 END DEFine STRING$
SUB and END SUB
The SUB command is used to create a named subroutine, rather
like DEF PROC in QL BASIC. END SUB corresponds to END DEF in
QL BASIC
SUB name
...list of instructions
END SUB
corresponds to:
DEFine PROCedure name
...list of instructions
END DEFine name
page 70
The named subroutine defined by SUB is called either by name
alone or by using the CALL command followed by the subroutine
name (CALL name using the example above). The call command is
optional, but its use makes it clearer that the code is
calling a named subroutine.
SWAP
This command swaps the values of two variables, as you might
need to do when sorting or reordering data. The syntax of the
command is SWAP variable1,variable2.
Any type of variable (integer, string, single precision,
double precision, array element) may be swapped, but both
must be of the same type or a Type Mismatch error is caused.
A simple procedure can be written in QL BASIC to emulate this
command, thanks to typeless procedure parameters this should
cover all data types, although you will need to change tmp to
tmp$ if swapping strings, although if you have Toolkit 2 you
could probably adapt it using PARTYP to check the type of one
of the parameters and an IF...THEN to provide separate
versions for strings and numbers, but remember that coercion
could mean you could just use tmp$ which would happily hold
numeric values, albeit a little slower.
2000 DEFine PROCedure SWAP(variable1,variable2)
2010 LOCal tmp
2020 tmp = variable1
2030 variable1 = variable2
2040 variable2 = tmp
2050 END DEFine SWAP
SYSTEM
Puts the computer into Monitor mode for calling and examining
machine code programs. On some computers this enters an
operating system "shell" mode. No direct equivalent on the QL
without additional software to provide a QDOS or SMSQ shell.
QL emulators may have a command to quit the emulator and
return to the host operating system, e.g. QPC_EXIT on the
QPC2 emulator.
TAB
Used with PRINT, this moves the cursor to the specified
position across the current line. TAB is followed by a number
from 0 to 255 representing the horizontal psotion to move to.
If the value given is greater than the screen width, it is
reduced modulo the screen width.
No punctuation is usually required after TAB, although it may
make PRINT TAB commands which include items to be printed
easier to read. Some BASICs insist that the TAB value is
enclosed in brackets, e.g. TAB(3)
The equivalent modifier on a QL is the TO separator, e.g.
page 71
PRINT TO 10; is the same as PRINT TAB(10);
Examples:
PRINT TAB(10) Move to column 10 across the screen line.
PRINT TAB(10); Same.
PRINT TAB 10; Same.
PRINT TAB(10);"OK" Move to column 10 across the screen line
and print the letters OK there.
TAN
Returns the tangent of x. The angle x is specified in radians
normally, although in QL BASIC you could use the RAD function
to convert an angle specified in degrees, or multiply the
angle in degrees by PI/180. Used in the same way as the
function TAN in QL BASIC.
THEN
Part of the IF...THEN structure in most versions of BASIC. In
most cases the same as the use of THEN in QL BASIC, although
an IF...THEN GOTO ... statement in some versions of BASIC may
omit the keyword THEN:
IF...GOTO...
The keyword THEN is always required in this structure in QL
BASIC, although in some cases it may be replaced by a colon
in single line IF clauses, or omitted in multi-line IF
structures. So, IF x=2 GOTO 1000 would be replaced by IF
x=2:GOTO 1000
TIME$
TIME$ sets or retrieves the current time.
Its format may vary from system to system, the most common
format is a function to return the time as an 8 digit string
of the form hh:mm:ss which can be replaced by a slice of the
last 8 ditis of the DATE$ function in QL BASIC.
5000 DEFine FuNction TIME$
5010 LOCal t$
5020 t$ = DATE$
5030 RETurn t$(13 TO 20)
5040 END DEFine TIME$
When used as a command to set the time, the format is
TIME$=x$, where x$ may be given in one of the following
forms:
hh Set the hour in the range 0 to 23. Minutes and
seconds default to 00.
hh:mm Set the hour and minutes. Minutes must be in the
range 0 to 59. Seconds default to 00.
hh:mm:ss Sets the hour, minutes and seconds. Seconds must be
page 72
in the range 0 to 59.
There is no direct equivalent to this command in QL BASIC, as
you can only set the time and date together using the SDATE
command with all six parameters specifying date and time.
TO
Part of the FOR/NEXT loop structure, used in the same way in
QL BASIC.
TROFF
Turns off the line number Trace system, whereby the currently
executing line number is displayed on the screen to help you
diagnose program flow.
TRON
Turns on the line number Trace system, whereby the currently
executing line number is displayed on the screen to help you
diagnose program flow. There is no direct equivalent command
on the QL unless you use add-on software.
UBOUND
UBOUND is a QBASIC function to find the upper limit of an
array passed to it (the highest subscript of that array). For
example, DIM A(100):PRINT UBOUND(A,1) prints the value 100.
The second parameterspecifies which dimension of the array is
to be checked.
UBOUND corresponds to DIMN in QL BASIC.
USING
PRINT USING statements allows you to specify a format for
printing string and numeric values. It can be used in many
applications such as printing report headings, accounting
reports, cheques ... or wherever a specific print format is
required.
The PRINT USING statement uses the following format:
PRINT USING string; value
String and value may be expressed as variables or constants.
This statement will print the expression contained in the
string, inserting the numeric value shown to the right of the
semicolon as specified by the field specifiers.
The following field specifiers may be used in the string:
# This sign specifies the position of each digit
located in the numeric value. The number of # signs
you use establishes the numeric field. If the
page 73
numeric field is greater than the number of digits
in the numeric value, then the unused field
positions to the left of the number will be
displayed as spaces and those to the right of the
decimal point will be displayed as zeros.
The decimal point can be placed anywhere in the
numeric field established by the # sign.
Rounding-off will take place when digits to the
right of the decimal point are suppressed.
The comma - when placed in any position between the
first digit and the decimal point - will display a
comma to the left of every third digit as required.
The comma establishes an additional position in the
field.
** Two asterisks placed at the beginning of the field
will cause all unused positions to the left of the
decimal to be filled with asterisks. The two
asterisks will establish two more positions in the
field.
$$ Two dollar signs placed at the beginning of the
field will act as a floating dollar sign. That is,
it will occupy the first position preceding the
number.
**$ If these three signs are used at the beginning of
the field, then the vacant positions to the left of
the number will be filled by the * sign and the $
sign will again position itself in the first
position preceding the number.
^^^^ Causes the number to be printed in exponential (E
single-precision or D double-precision) format.
+ When a + sign is placed at the beginning or end of
the field, it will be printed as specified as a +
for positive numbers or as a - for negative
numbers.
- When a - sign is placed at the end of the field, it
will cause a negative sign to appear after all
negative numbers and will appear as a space for
positive numbers.
% spaces % To specify a string field of more than one
character, % spaces % is used. The length of the
string field will be 2 plus the number of spaces
between the percent signs.
! Causes the Computer to use the first string
character of the current value.
Any other character that you include in the USING string will
be displayed as a string literal.
page 74
If you have access to the original BASIC interpreter for
which the program was written, a simple three line program
can be used to test how the various options work:
100 INPUT A$, B
110 PRINT USING A$;B
120 GOTO 100
The USING modifier can have subtle differences and sometimes
additional facilities on different computers, so some degree
of familiarisation with the BASIC in question (or at least
access to manuals) will be required.
The nearest QL equivalent command is the PRINT_USING command
in Toolkit 2. While there is some considerasble overlap of
formatting, there can be differences too and some care will
be required to get a close match in functionality. You are
advised to read the Toolkit 2 manual section 13 for a full
description of the PRINT_USING command to ensure you
understand how it works so that you can use the equivalent
formatting string in cases where the QL version differs
slightly from the other version.
Another way of using the PRINT USING statement is with the
string field specifiers "!" and % spaces %.
Examples:
PRINT USING "!"; S$
PRINT USING "% %"; S$
The "!" sign will allow only the first letter of the string
to be printed. This would be quivalent to PRINT S$(1) or
PRINT_USING "#",S$ in SuperBASIC.
The "% spaces %" allows spaces +2 characters to be printed.
In other words, 1 character for each of the % symbols plus
the number of spaces. Again, the string and specifier can be
expressed as string variables. This would be equivalent to
PRINT S$(1 TO 1+spaces+1) or PRINT_USING
FILL$('#',1+spaces+1),S$
This can get really complicated when multiple values or
strings are to be printed using more complex forms. Here is
one example, where by using more than one ! symbol, the first
letter of each string in the PRINT list will be printed with
spaces corresponding to the spaces inserted between the !
symbols in the USING string. In this example, the first
character of each string is printed with spaces between them:
PRINT USING "! ! !";"ABC","DEF","GHI"
results in
A D G
To cope with this, you may need to split multiple parameters
to single commands:
PRINT_USING "#","ABC"
page 75
PRINT_USING "#","DEF"
PRINT_USING "#","GHI"
or become inventive with the format string, so that it
contains a format pattern or field for each of the following
elements of the command:
PRINT_USING "# # #","ABC","DEF","GHI"
USR
USR [<digit>] (X) is a function which calls the specified
user assembler routine numbered from 0 to 9 (0 assumed if not
specified), passing the value of X to the routine.
LET A=USR(0,B) calls user assembler routine number 0, and
passes the value of B to it.
There is no direct equivalent in QL BASIC - the user
assembler code will be processor specific and the nearest
equivalent is likely to be writing an extension function in
680x0 assembler code to do the same job.
VAL
VAL(X$) returns the numerical value of string X$. The VAL
function also strips leading blanks, tabs and linefeeds from
the argument string. String coercion in QL BASIC means this
command is not needed - LET A$="-3":LET B=VAL(A$) is simply
converted as LET A$="-3":LET B=A$
The opposite function to convert a number to a string is
STR$.
In QL BASIC, this function is replaced by string coercion
whereby numeric and string values are converted implicitly.
So the above example would simply be replaced by LET y=x$
although you could write a function in QL BASIC to provide a
function of the same name for simplicity of conversion:
3000 DEFine FuNction VAL(value$)
3010 RETurn value$
3020 END DEFine STR$
The function type is denoted by the lack of a '$' symbol at
the end of the function name in QL BASIC. If this is not
sufficiently explicit, a simple coercion using a local
variable could be used prior to the RETurn statement:
3000 DEFine FuNction VAL(value$)
3010 LOCal v
3020 v = value$
3030 RETurn v
3040 END DEFine VAL
VARPTR
page 76
This command may take two forms.
1. LET AD=VARPTR(X)
This function returns the address of the first byte of data
associated with the given variable name. There is no direct
equivalent in QL BASIC.
2. LET F=VARPTR(#file_number)
This function returns the starting address of the disk I/O
buffer assigned to the given file number (or channel), or for
random files returns the address of the FIELD buffer assigned
to file_number. No direct equivalent in QL BASIC.
VARPTR$
Returns a character form of the address of a variable in
memory. It is promarily for use with PLAY and DRAW in
programs that were later compiled. The command syntax is LET
v$=VARPTR$(variable). All simple variables should have been
assigned before calling VARPTR$ for an array element, because
addresses of arrays change whenever a new simple variable is
assigned. VARPTR$ returns a 3 byte stringin the form:
Byte 0 Byte 1 Byte 2
type low byte of high byte of
variable address variable address
type indicates the variable type:
2=integer
3=string
4=single precision
5=double precision
The returned value is essentially the same as:
CHR$(type)+MKI$(VARPTR(variable))
There is no direct equivalent in QL BASIC. The above
information shuld help you understand what's going on if you
come across VARPTR and VARPTR$ in a program, so that you can
write suitable conversion code on a case-by-case basis.
Variable Names
In some early BASICs, only the first few characters of a
variable name are significant, for example in TRS80 level 2
BASIC only the first two characters of a name are
significant. This means that the variables SUM, SUB, SUPER,
and SU are treated as though they are one and the same.
This restriction does not apply in QL SuperBASIC obviously,
although poorly written old BASIC programs which use
different lengths of the same variable name (e.g. SUPER in
one part of the program, abbreviated to SU in another part)
can cause havoc when ported to the QL, where the two
page 77
variations of the same variable name will be treated as
different variables. On the QL, LET SU=0 is not the same as
LET SUPER=0. Unfortunately, there is no hard and fast rule on
this, other than reading the manual for the BASIC in question
if you have access to it (many BASIC manuals are available to
download from the internet these days).
Some BASICs may have four distinct types of variable names:
(1) Integer - whole numbers from -32768 to + 32767. Variable
names end with '%' as on the QL
(2) Single Precision floating point - usually to 6
significant figures. Names end with the ! symbol. In most
cases just use ordinary QL floating point variables, but
remove the ! type declaration symbol.
(3) Double Precision floating point - usually up to 16
significant figures. Variable names end with the hash #
symbol, e.g. ZZ# is such a variable. In most cases you
will be able to replace these with ordinary QL floating
point values just be removing the # symbol from the
variable name.
(4) String variables end with a '$' symbol like in QL
SuperBASIC. Strings may be limited to just 255 characters
in length, and in some cases only about 50 characters may
be available by default for a given string.
In some early BASICs, only variable names starting with A or
B may be used to hold strings (e.g. TRS80 BASIC level 1).
Variable names such as A or DE which appear to be floating
point may in fact be overriden with implicit type definition
commands such as DEFINT. See the entries for DEFINT, DEFSTR,
DEFSNG and DEFDBL above.
Beware of versions of BASIC which have case sensitive
variable and array names. In this case, 'A' and 'a' might be
two separate and distinct variables - in other words, A and a
may not the same variables! There is no easy way around this
in SuperBASIC, where names are case insensitive, other than
to use different variable and array names, or doing something
like keeping the upper case names as they are and adding a
'_' to the lower case equivalents, e.g. LET A=0:LET _a=0
WAIT
This command suspends program execution while monitoring the
status of a machine input port. The command syntax is WAIT
port, n [,m]
port is the port number, in the range 0 to 65535
n, m are integer expressions in the range 0 to 255
The WAIT statement auses execution to be suspended until a
page 78
specified machine port develops a specified bit pattern.
The data read at the port is XORed with the integer
expression m and then ANDed with n. If the result is zero,
BASIC loops back and reads the data at the port again. If the
result is nonzero, execution continues with the next
statement. If m is omitted, it is assumed to be zero.
There is no direct equivalent in QL BASIC and the different
hardware configuration of various computers means that a
conversionis unliekly to be meaningful, but if you really
wanted to try with a memory mapped peripheral, you could
probably write a piece of code like this:
1000 DEFine PROCedure WAIT (port,n,m)
1010 LOCal waiting,value
1020 REPeat waiting
1030 value = (PEEK(port) ^^ m) && n
1040 IF value <> 0 THEN EXIT waiting
1050 END REPeat waiting
1060 END DEFine WAIT
WHILE / WEND
loop structure whereby a series of statements in a loop are
executed as long as the given expression is true. The
condition is evaluated at the WHILE statement and if that
condition is not true (i.e. it is FALSE, or 0) program
execution continues at the statement following the WEND
keyword.
6000 x=0
6010 WHILE x < 10
6020 x=x+1
6030 WEND
This is distantly related to REPeat/END REPeat statements in
QL BASIC, although the REPeat and END REPeat commands do not
in themselves perform the expression test - you need to write
the test as a separate line within the loop and use an EXIT
statement to exit the loop if the expression is false.
6000 x=0
6010 REPeat loop
6020 IF NOT(x<10) THEN EXIT loop
6030 x=x+1
6040 END REPeat loop
Note the inversion of the expression test result using the
NOT operator in line 6020.
WIDTH
Sets the output line width in number of characters. Similar
to the WIDTH command in QL BASIC, but QL BASIC needs a
channel number.
page 79
WRITE
This command writes out a list of expressions, much like
PRINT, except that WRITE inserts commas between the items as
they are displayed and delimits strings with quotation marks.
Also, positive numbers are not preceded by blanks. This
example shows how WRITE displays numeric and string values.
10 A=80: B=90: C$="Hello"
20 WRITE A,B,C$
RUN
80,90,"HELLO"
OK
As this is mainly used as a variable value dump to help debug
programs, you may not need to convert it to QL, although
easily done by writing it like this:
PRINT A;",";B;",";'"';C$;'"'
WRITE #
WRITE #filenum,list_of_expressions writes data to a
sequential file.
filenum is the number under which the file was opened for
output, like a channel number in QL BASIC.
list_of_expressions
is a list of string and/or numeric expressions,
separated by commas or semicolons
The difference between WRITE # and PRINT # is that WRITE #
inserts commas between the items as they are written and
delimits strings with quotation marks. Therefore, it is not
necessary for the user to put explicit delimiters in the
list. Also, WRITE # does not put a blank in front of a
positive number. A carriage return/linefeed sequence is
inserted after the last item in the list is written.
Example:
LET A$="CAMERA" : LET B$="93604-1"
WRITE #1,A$,B$
writes the following image to the file.
"CAMERA","93604-1"
A subsequent INPUT # statement, such as:
INPUT #1,A$,B$
would input "CAMERA" to A$ and "93604-1" to B$.
There is no direct equivalent in QL BASIC, so you would
rewrite WRITE #filenum,A$,B$ as
PRINT #filenum,'"';A$;'","';B$;'"'
page 80
XOR
The XOR operator tests for an Exclusive Or condition, whereby
the result is true if either of the conditions tested is true
but not the other. Here is the truth table for this operator.
X Y X XOR Y
True True False
True False True
False True True
False False False
The use of XOR in QL BASIC is the same.
_____________________________________________________________________________
File: D:\_web\tfs\basic\convert_doc
Translated by Quill-View 0.5 Beta (compiled Oct 13 2008)
Copyright 2008 Mikael Strom