Documentation
Documentation
BASIC is the name of the language that BASin uses. It stands for Beginners All-
purpose Symbolic Instruction Code - which means that people who have never
tried to write their own programs before will find it easy to understand and use.
This version of BASin is called "BASin for Beginners" because it has some
changes that are designed to make learning as easy as possible. While there are
other languages that you can use, we would recommend that you start here. The
things that you learn with BASin for Beginners will help you when you feel you
are ready to learn more about programming on your PC.
Before you start, you may want to read the following topics that explain what
BASin does and how the BASIC language started:
What is BASin?
What is a Sinclair Spectrum?
History of Sinclair BASIC.
How BASin differs from a real ZX Spectrum.
To get help on a particular topic
To learn how to do something in BASin, use the Contents and Index areas on
the left of this help window. You can look for the topic you want, or enter a
codeword on the index tab.
What is BASin?
BASin is a what is called a "Development Environment". It was designed to
make programming in BASIC easy.
Way back in the early 1980s, a company called Sinclair Research Ltd made a
computer called the ZX Spectrum. Nothing quite like it had been made before, at
least not as cheap to buy as Sinclair's computer - so a great many children of that
time had one in their houses. For the price, it was very powerful - it had colour
graphics, a full keyboard (trust me, that was a big deal back then!) and connected
to your living room TV.
AND it played games! Lots of them. Throughout the life of the Spectrum, about
10 years, there were thousands of games made and sold. Because this was a new
thing at the time (because games hadn't been around for long) most of them were
made by people like you and me - who made programs as a hobby.
That is the real genius of Sinclair's computers. They not only had the ability to
play games, they also had a secret weapon built-in: A programming language
called BASIC. With BASIC you could give the computer instructions that could
be used to make it do anything you wanted - including make games.
BASin runs what is called an "emulator" - that is, a program for a PC that
pretends to be another computer. This means that BASin will let you program in
the same language as the Spectrum, and that's what makes it easy to do.
Programming for a PC is a very complex thing to do, and not something an
absolute beginner should attempt. Once they have learnt one language though, it
makes it easier to program in another. So starting with Sinclair BASIC on a
Spectrum, although quite simple, will open the doors to a world that is so vast
and full of fun that you will spend the rest of your life exploring it!
BASin's editor looks like that of the Spectrum, with the addition of codeword
help, a "Coding teacher" that checks your program as you write it, and
development tools such as a UDG editor and a variable viewer/editor. BASin
also provides advanced debugging features: conditional breakpoints, watches,
and full program flow control at the line/statement level. Don't worry if you
don't understand what all that means - you soon will!
Program development in BASin is easier and faster than it was on the original
ZX Spectrum. The Spectrum BASIC manual - an excellent introduction not only
to the language, but to programming in general - is included here for beginners,
and has been modified where necessary to take account of BASin's features.
What is a Sinclair Spectrum?
Released in 1982 as a direct rival to Acorn's BBC range of educational
computers, the Sinclair ZX Spectrum was a true home computer at an affordable
price. It loaded games from a standard cassette player and produced a display on
the family television set. Unlike its competitors, the Spectrum was small and
black, with rubber keys and a small buzzer for making simple beeping noises -
and it was amazingly successful.
The hardware
The screen display measured 256 × 192 pixels, a high resolution for its time, and
supported eight colours at two brightness levels, totalling fifteen colours (since
bright and dull black were identical). The display was divided into 24 rows and
32 columns of "character cells", each 8 × 8 pixels and capable of containing any
two of the basic eight colours (or attributes), as long as they were at the same
intensity. This led to some "attribute clash", one of the most endured and loved
features of the hardware: where two coloured objects collided, their attributes
would overlap, giving the impression of coloured squares.
Sound was similarly simple and to the point: a buzzer capable of outputting one
channel of beeping. The BEEP command was used to drive it from BASIC, but
clever machine code routines could produce multi-channel effects and music,
which no other computer of the time could rival without dedicated sound
hardware.
The BASIC
Spectrum BASIC was more or less unique, as was the method of programming.
Keys on the keyboard were imprinted with BASIC keywords, which meant that
a single keypress (such as P) could produce an entire keyword (PRINT). The
use of shift keys made further keywords available. It was a quirky system, but
easy to learn. This style of coding was the standard for all Spectrums prior to the
128K machine.
The Spectrum continued to grow, not only with new incarnations, but with an
increasing selection of peripherals. You could buy printers, mass storage devices,
joysticks, light-pens, and light-guns - all in the same sleek rounded black style. It
was a hobbyist's dream.
In July 1975, Micro-Soft, as it was then called, shipped BASIC (Beginner's All-
purpose Symbolic Instruction Code) version 2.0 for the MITS Altair 8800
hobbyist computer. This was the first commercial version of the BASIC
programming language, originally developed by J G Kemeny and T E Kurtz in
1964 at Dartmouth College in the United States.
By then, Kemeny and Kurtz had addressed the main criticisms of BASIC - that it
lacked structure and encouraged bad programming habits - but the 4K and 8K
versions for the Altair, written by Paul Allen and Bill Gates, were based on the
original Dartmouth BASIC.
Microsoft BASIC became so popular that it made Gates and Allen their first
fortune and was subsequently supplied with the majority of 8-bit computers. So,
not surprisingly, when the ANSI Standard for Minimal BASIC (X3.60-1978)
was launched, it was based mainly on the Microsoft version.
In May 1979, Clive Sinclair's engineers began work on the machine that would
become the ZX80. Sinclair was inspired to create the machine after seeing how
much his son enjoyed using a TRS-80 but guessing that many people would be
put off buying one because of the high price - just under £500.
Unlike the MK14, Sinclair's previous foray into the computer hobbyist market,
this machine would ship with BASIC based on the ANSI standard. But the aim
was to keep costs down, and that precluded paying a licence fee to Microsoft. To
this end, Sinclair had already met with John Grant of Nine Tiles in April to
discuss the software requirements of the ZX80.
Given the tiny R&D; budget, Nine Tiles stood to make hardly any money out of
the deal, but the feeling was that the project was exciting and worthwhile, and
one the company would benefit from being associated with.
To achieve the launch price of £79.95 in kit form, RAM was limited to 1K and
the integer BASIC had to be crammed into a 4K ROM. Grant wrote the bulk of
the ROM between June and July. But the resulting program was 5K in length, so
Grant spent that August trimming the code.
The kit was launched at a computer fair in the first week of February 1980, and
while it was not a massive success by comparison with the ZX Spectrum, it
turned Sinclair's fortunes around, eventually earning him a knighthood, and it
sold well enough to persuade him to make a new computer: the ZX81.
Work on the ZX81 hardware had begun in September 1979, even before the
launch of the ZX80, but it was the development of the uncommitted logic array,
or ULA, which allowed the machine to go into production. The ULA, produced
by Ferranti for Sinclair, reduced the chip count and brought the retail cost of the
machine, in kit form, down to £49.95.
Again, Nine Tiles was called on to provide the new BASIC, but this time there
was 8K to play with. Vickers, who had joined Nine Tiles in January 1980, wrote
the BASIC more or less from scratch, only using some of the ZX80 code,
making numerous improvements while managing to maintain backwards
compatibility with the ZX80 hardware.
"As far as Clive was concerned, it wasn't a question of what the machine ought
to be able to do, but more what could be crammed into the machine given the
component budget he'd set his mind on," said Vickers in an interview on July 23,
1985. "The only firm brief for the '81 was that the '80's math package must be
improved."
The ROM was almost complete by the end of autumn 1980, but support still had
to be added for the ZX Printer. Somewhere between this time and the launch, a
bug crept in which caused the square root of 0.25 to be 1.3591409. Nine Tiles
quickly fixed the bug, but Sinclair was somewhat tardy in making this version
available to people who had already bought the machine.
Despite this problem, the ZX81 was well received and became a massive
success, spawning a series of clones, both illegal and licensed by Timex, which
was manufacturing the UK models for Sinclair at its Dundee plant. Inspired by
the public reaction to the ZX81, and annoyed at not winning the contract to
design a computer for the British Broadcasting Corporation, Sinclair decided the
market needed a budget colour computer.
The ZX80 and ZX81 hardware had been the primarily the work of one man, Jim
Westwood, but he had been moved to the flat-screen television department, so
the hardware design job on the ZX82, which became the ZX Spectrum, was
given to Richard Altwasser - while Vickers at Nine Tiles was again asked to
provide the BASIC.
What started out as an expansion of the ZX81 BASIC soon turned into a large
16K program. Sinclair wanted as few changes to the ZX81 code as possible, but
Nine Tiles felt that software designed for a machine with 1K was inappropriate
for a machine with 16K and that problems would occur later on. They were
right.
"Certainly with the Spectrum we wanted to rewrite the code, but there wasn't the
time and there definitely weren't the resources," said Grant in an interview on
September 8, 1985. "At every point [in the development of the ZX range] Clive
wanted the maximum new facilities for the minimum money."
After the best part of a year's work the BASIC was almost finished. While it was
greatly enhanced, it was also depressingly slow, but more problems were to
follow. The main problem was providing support for the planned peripherals,
because no working prototypes were available to Vickers until near the end of
1981. But then, in February 1982, Nine Tiles began to have financial
disagreements with Sinclair over royalties which it became apparent would not
be forthcoming.
To make matters worse, Vickers and Altwasser both handed in their resignations
in order to form their own company, Cantab, which went on to produce the
Jupiter Ace, essentially a ZX80 with the Forth language taking the place of
BASIC. The result of the delays these problems caused was that when Sinclair
launched the machine, it did so with an incomplete ROM. Nine Tiles continued
working on the ROM for three months after the launch in April 1982, but by
then too many units had been sold and the program was never finished.
The original plan was to issue only a limited number of Spectrums with the
incomplete ROM and provide an upgrade, much in the way the bug in the ZX81
ROM had been handled; except that by the time Sinclair got its act together,
around 75,000 units had been sold and the plan became unworkable. This is the
reason why the microdrive commands don't work in the standard ROM, and led
to the development of the shadow ROM in the Interface 1 in order to handle
peripherals which should have been supported directly by BASIC.
How BASin differs from a real Spectrum
This section is intended for Adults who are familiar with the Sinclair Spectrum
to read
Tokens are handled differently too. You no longer enter entire words using a
single key-press - the editor is based on the 128k Spectrum, which means full
typing support with the available use of every key on a modern keyboard. You
are also free to use the mouse to make selections and get context sensitive help.
For more information, consult the section devoted to Using the Editor.
Screen display
The main display output (the Spectrum "screen") sits to the right of the Editor in
the main window. When a program is running, this window will be where any
program output appears. It behaves exactly the same way as a real Spectrum's
display. Because the editor is now in a separate area to the display, runtime
errors no longer report to the bottom of the display - they can be redirected to an
error dialog which also provides information on that error. This again helps
prevent display corruption, but is a feature that can be turned off.
prompts have been enhanced: they use the same blue-and-white cursor as the
editor, and they support cut and paste operations.
BASin uses text files with the .bas extension to store BASIC code. This code is
in raw text format (windows notepad compatible) with escape codes to represent
tokens that cannot be rendered in plain text. See the chapter on .BAS File Format
for more details. These files can be used just like tape files on the original
hardware - they can store runtime variable contents and auto-start when loaded.
BASin for Beginners can load any of the formats that BASin supports, but can
only save in .szx format. This is to ensure that any program saved by BASin can
be run on a Sinclair Spectrum Vega.
The sound is enhanced over the simple beeper of the 48k, by using an AY-3-
8912 sound chip, which enables the BASIC to produce three channel sound and
white noise, with full envelope control.
The extra memory of the 128k Spectrum is available to BASIC via the silicon
disc which is a "virtual disk" system providing 64kb of storage space which is
almost instant to access. With careful programming and judicious use of the
MERGE command, up to 91kb of BASIC program can be stored at any one
time.
128k Commands
BASin will allow you to use the extra sound and silicon disc systems by
"branching" the emulation out to the 128k +2 rom and AY-3-8912 sound chip as
commands are intepreted. The commands given are...
PLAY
LOAD !
SAVE !
MERGE !
CAT
ERASE
For instruction on how to use these commands, see the following sections of this
help file...
Because of this limitation, BASin will only replace these UDGs with their
command-replacements if your program makes use of the silicon disc or PLAY
command. This is worth bearing in mind if you would like to use them. As an
example, the program "frogger" from the BASin examples, displays correctly
when run in a 48k mode...
...and as you can see, all the graphics are accounted for and display well.
However, placing a PLAY command anywhere in the game produces a quite
drastic and undesireable effect...
...where all the instances of UDGs "T" and "U" have been replaced with
"SPECTRUM" and "PLAY". This kind of thing was common in BASIC games
designed on the 48k spectrum and run on the 128k without modification.
In order to provide a full 128kb of memory in the later Spectrum models, the
designers utilised an ingenious method of "paging" - pages of RAM could be
swapped into and out of the upper memory at will.
Also, to provide the extra commands for the silicon disc and AY chip, two
ROMs were used, which could be swapped in a similar manner to the RAM
pages in upper memory. Of course, when one ROM was paged in it would need
to know that it had to page itself back out to allow the main ROM to resume
control. This was not possible for the 48k ROM that lived behind the newer
128k ROM - it had to be an exact copy of the original 48k ROM for
compatibility reasons, and this ROM had not been designed for paging systems.
This meant that an area of RAM had to be allocated which the 48k ROM, when
it had finished the job it was called for, would jump back to. This area contains
code that swaps the 128k ROM back in. Because the 128k Spectrum used an RS-
232 port to communicate with more advanced printers, it was felt that the printer
buffer utilised by the 48k ROM was no longer needed, and as such this area was
reclaimed for the paging system and some more system variables which
contained information about the silicon disk, amongst other things.
Because BASin allows the user to use the old 48k printer routines, then the use
of the commands for it will try to read (and write) to the buffer region
maintained by the paging system. The repercussions of this are that if any
printing commands (LPRINT, LLIST) are used after a 128k command, at best
you will see garbage on your printout, and at worst it may crash the emulated
spectrum. If you use the printer commands with silicon disk commands, you
may find that the silicon disc becomes corrupted, which may in turn also crash
the emulation.
So if you're going to use 128k commands, then please avoid the use of the ZX
Printer support.
To help remind you which computer your program is compatible with, BASin
provides a small indicator at the bottom of the editor window. This is updated as
you create or edit your program, and appears like this...
As you enter commands into BASin, this indicator will remain in "48k mode"
until you enter a 128k command which utilises the enhanced sound (PLAY) or
the silicon disc (LOAD !, SAVE !, MERGE !, CAT ! and ERASE !).
When BASin detects these, the indicator will change...
...and when this happens you may also notice that any instances of the UDGs "T"
and "U" will change to their small-character hexadecimal equivalents.
Removing 128k commands from your program will revert it back to 48k mode.
This section will give you an overview of what BASin can do, and what all the
options and windows you can open actually do. BASin is quite a complex
application, but is very user-friendly and helpful. You can call up help for any of
the dialogs that BASin presents to you by using the F1 key (except in the Editor
window, where this is used for fast context sensitive BASIC Keyword help).
Starting BASin
System requirements
Getting help
The BASIC editor
The display window
Loading and saving files
Running and debugging programs
Debugging your programs
Configuring BASin
BASin's tools
Sinclair BASIC reference
Starting BASin
BASin has been made easy to use, and starting is no different. Start BASin by
using the icon supplied (BASin.exe) in the Start Menu or in the folder
BASin was installed into. You will firstly be greeted by the Editor window,
which will remain unresponsive until the emulated Spectrum has been
initialised.
This is a process whereby the original 48k ROM is loaded into an emulated
memory model and executed from address zero. The ROM will perform a self-
test, which is to fill all available RAM with the number two, and then read that
back, whilst clearing the RAM back to zeros. Originally, this was a useful test
which could tell the ROM how much memory is available back in the days of
16k and 48k Spectrums. It's not essential to BASin's operation, but is a nice
historical effect. The net result is that the Display Window will display a white
border around an animated black rectangle, with faint red vertical lines, before
clearing to white with the message
at the bottom of the display. This indicates that all is well, and BASin is ready to
start.
The Editor will then gain focus and pop to the front, with a blank white editing
area, and a flashing blue/white cursor similar to the 128k Spectrum's Editor. The
gutter at the left is for line numbers, and is not a bug in the Editor.
System requirements
BASin is designed to perform well regardless of PC hardware specification. The
emulation has been tested using a 50 MHz 486 DX/2, and (with sound disabled)
runs very well on that specification. The editor is more resource-hungry, but the
BASin tab allows certain features to be disabled if necessary.
Sound
DirectX 5 or higher must be installed in order for sounds to play. DirectX is not
required for the display, but performance in this case will vary depending on
your display driver software and computer usage by other programs.
Help file
BASin requires unmodified Spectrum 48K and +2 ROM images, which are
included in the installation package. Amstrad has graciously given permission
for Spectrum ROM images to be freely distributed and included with emulators.
Getting help
BASin has a very detailed help file, to allow you to easily find help on any topic.
You can open the main help page using Ctrl-F1 or by using the Help Menu in the
Editor.
The Help file also includes a complete BASIC programming course, adapted
from the original Sinclair BASIC manual. This also includes specific help on
any of the codewords found in Sinclair BASIC. Just hover your mouse over the
keyword you want help with, and click your right mouse button to get a
Codeword Context Menu for that codeword, which includes, amongst other
options, help for that codeword. You can also use the Editor cursor to move to
the codeword you want help with, and press F1.
To get help on an item in a tool, click the Help button in the window you want
help with, or use the Help menu if available.
As a last resort, you can fnd contact details for the Author in the Contact chapter.
The editor
The editor is the area where you enter and modify your BASIC program.
Like any other Notepad program, you can use the mouse and/or shift keys to
make selections and cut/copy them to the windows clipboard. They will be
stored in .bas format which can be pasted into any text editor. Pasting is a little
different. A single line of text pasted in will be sent directly to the editor, but
more than one line will be sent to the Add Code Window - where you can view
the lines and change them as you wish. Multiple line pastes must each have a
line number, and contain no syntax errors. If an error occurs when pasting the
lines in, the offending line will be ignored and will not appear in your program.
You can see the status of any errors in pasting by viewing the Log Window. This
facility allows you to copy a BASIC program from say, a web page or text
document, and paste it directly into BASin.
The darker area at the left-hand side is the gutter, where line numbers are
displayed. To aid debugging and make things easier to read, program lines that
contain more than one statement are split on the : (colon) character, so that each
statement begins on a new line of the display.
Program lines, as mentioned earlier, are stored in the editor in order, sorted by
their line number. This makes the program easier to follow for the programmer.
The coding teacher is a bar that appears at the bottom of the editor window,
which tracks your code as you type and offers hints as to what the current
codeword actually does, and it's syntax.
If you type an error, it will colour the relevant part of the syntax list red.
The syntax that is currently expected is coloured blue, and any return types
of codewords is in green. Error messages will appear at the bottom of the
helper bar which explains what has gone wrong.
This option is available in the View menu, rather than the Options dialog.
The character ruler helps you to make long strings for display on-screen.
Due to the nature of the PRINT keyword, a string longer than 32 characters
will "wrap" round to the beginning of the next line down. This can be useful
for displaying many lines of text with one PRINT. The character ruler will
show you at a glance how long your string is, and a red marker will appear
at any point where the 32 character boundary is reached. This activity will
be activated whenever the cursor enters a string area in the BASIC text.
BASin will not allow you to enter a line that contains a syntax error, and
when you make one the cursor will move to the error and if you have
sounds enabled, will emit a low pitched beep to alert you.
BASin has a shortcut (the "." key) which will create a line number for you.
Pressing the "." key at the start of a new line will choose a line number
roughly halfway between the previous line number (of the line directly
above the current cursor position - Line 0 is assumed if you're at the start of
the program) and the next line number if it exists. If no next line is present,
then 10 is added to the previous line number. The "." will not be displayed -
instead, your new line number will be typed out. This behaviour can be
enabled or disabled in the Options window.
Auto-Bracket completion
(a+(b/c))*3
Which make use of brackets - BASin has an option which can make
counting many brackets easier - BASin can either insert a closing bracket as
you type, ahead of the cursor, or can complete any open brackets when you
press enter to finish a line.
Syntax Highlighting
The text of your program can optionally colour in the text according to the
type of words displayed.
This is called "syntax highlighting", and can make a program a lot easier to
read and follow. Keywords, user defined functions, comments, numbers,
symbols, strings, variables (BASin will colour variable names that exist in
VARS memory space differently to those that do not, which can quickly
show up typing errors where they may occur) and the
background/foreground colours can all be altered in appearance, also to be
set to bold or italics in style. Be aware that this requires quite a lot more
effort to display by your CPU, so may slow the editor down on older PCs.
Predictive typing
This option will display any keyword or variable name in dark grey to the
right of your cursor as you type.
If you continue to type, the search for the correct word will be narrowed
down - when you see the correct word displayed, hit the right cursor key, or
the "." key to accept it. You can, of course, continue typing over the top. If
you do not accept a word and press return, any predicted text will be
removed.
Source Markers
Mode indicator
The mode indicator is a black strip that appears at the bottom of the editing
area. It shows which type of spectrum your program is compatible with,
based on commands that your program uses. It shows "48 BASIC" by
default, until you use a 128k command, at which point it will show "128
BASIC". The Mode Indicator is visible at all times, and cannot be turned
off.
Editor features
The toolbar.
The character ruler.
The coding teacher.
The status bar.
Variable ToolTips.
Source Markers
Expression Evaluator.
The status bar
The status bar is located at the bottom of the editor, , and shows some
information that can be useful when programming in BASin. It can be enabled or
disabled from the View Menu.
The white-on-black letter at the left-hand side indicates the type of syntax
element that BASin expects you to type next. (This is roughly equivalent to the
old-style edit cursor on a 48K Spectrum.)
Hint area
The hint area usually displays the size of your program and the amount of free
memory in kilobytes. A Spectrum has about 38 kilobytes of memory for BASIC
programs.
When a menu is open, the hint area displays a short description of the selected
menu command.
The editor uses a standard set of keys for editing, as well as some special ones
that are unique to Spectrum BASIC.
Ctrl + Home, End Jumps to the beginning or end of the entire program.
Insert Toggles overtype mode, where newly typed characters replace old ones.
Tab Inserts three spaces. (Actual tab characters are not supported.)
When you attempt to move the cursor away from a modified line, BASin
behaves as though the line had been entered, checking it for mistakes before
storing it in the program.
Graphics characters
Spectrum BASIC programs can contain two kinds of graphics characters: built-
in chequered graphics and user-defined graphics (UDGs). These characters are
described in Chapter 14 of the manual.
In BASin, you can toggle graphics mode using Num Lock or Scroll Lock, or
(under Windows NT and XP) enable it temporarily by holding down Alt Gr. The
key to be used can be configured on the BASin tab.
Control characters
You can insert control characters using either the Token Table window or the
function keys F1 to F8.
Note: Control codes will appear in the program as small hex numbers, two per
character square, when Syntax Highlighting is enabled - when this is disabled,
then BASin will show the text with any colour modifications as it would appear
on a real spectrum, with the exception of the FLASH attribute.
F1 Blue
F2 Red
F7 White Flash on
In graphics mode, a function key sets the ink colour, and a function key with
Shift sets the paper (background) colour.
The toolbar
The toolbar is located at the top of the editor.
It provides quick access to some of the more commonly used menu commands.
Buttons
New - This button will clear the current program and variables from memory, allowing you to
start afresh. You will be prompted to save any changes you may have made to the current
program.
LOAD "" - Brings up the Load Program dialog. The same as using the File…Load "" options
from the main menu. You can load either .bas files, or Spectrum Snapshots.
Save - Saves the current program in memory. If this program is new, and has not been saved
before ("Untitled Project") then the save program dialog will be displayed prompting you for a
filename. This saves either .bas files or Spectrum Snapshots.
Run / Pause - If the current program is not running, then this starts the program from the
beginning, as if the user had typed "RUN" in the editor as a Direct Command. If the program is
already running then execution will be suspended when the current statement has been executed.
From there you can use the single step and other debugger functions.
GO TO cursor - This will start program execution from the line and statement that the editor
cursor is currently positioned at. Similar to issuing a GO TO command from the editor.
System BREAK / Continue - This will either stop the current program execution by sending a
BREAK message to the emulation, or CONTINUE from where it left off. See the CONTINUE
keyword help in the BASIC manual for more on how CONTINUE operates.
Single-step statement - When program execution is suspended, you can step through the
program one statement at a time, pausing after each so you can inspect the program flow and
variables. See the Single Step tool description for more information.
Step over statement - Will, when the program is suspended, run through the current statement
until the next statement in the program is encountered. This allows you to step past subroutines
that you don't want to have to step through.
Run to cursor - Will start execution and not stop until the program reaches the statement that the
editor cursor is resting on. The statement will not be executed - the program will be suspended
before it starts.
Add Breakpoint at cursor - Will toggle a breakpoint at the current statement which the editor
cursor lies upon. It's the same effect as double clicking a line in the editor. See the Breakpoints
section for more on breakpoints. This will open the Breakpoint Properties window so you can
edit the breakpoint's conditions.
Add Watch - Opens the Watch Properties window to allow you to add a Watch to the current
Watchlist. See the entry under Watches for more information.
Expression Evaluator - Opens the Expression Evaluator tool which lets you inspect variables
within expressions, and perform calculations using Sinclair BASIC codewords.
The character ruler
The character ruler is located at the bottom of the editor. It helps making long
strings for display on-screen. Due to how the PRINT codeword works, a string
longer than 32 characters will "wrap" round to the beginning of the next line
down. This can be useful for displaying many lines of text on one command. The
character ruler will show you at a glance how long your string is, and a red
marker will appear at any point where the 32 character boundary is reached. This
happen whenever the cursor enters a quote delimited string area in the BASIC
text.
To show or hide the character ruler, choose Character Ruler on the View menu.
Each mark on the ruler represents one character. Every eighth mark has a
number that indicates the character count from the start of the program line.
These numbers increase as you scroll to the right.
The small black arrow ( ) shows the location of the edit cursor.
String lengths
The character ruler also indicates the lengths of strings. (A string is a piece of
program text enclosed in quotation marks, such as "Welcome".)
While the edit cursor is inside a string, the character ruler displays the length
with a green bar, with a red arrow after every 32nd character. The Spectrum
screen display is 32 characters wide, so this shows where a line of text will wrap.
See also the section on the editor context menu for information on wrapping
long strings around the screen with word-wrap and other effects.
The coding teacher
The coding teacher is located at the bottom of the editor.
To show or hide the coding teacher, choose Debug Windows > Coding teacher
on the View menu.
If you don't want the coding teacher to appear automatically when BASin starts,
clear the Show coding teacher on startup check box on the BASin tab.
The top line of the coding teacher is a colour-coded template that illustrates the
syntax of the statement being edited.
Note: Variable ToolTips only appear for variables that are already present in
memory. This means that a variable must have been made (using a DIM or LET
statement) before it will produce a ToolTip.
Source Markers
Source Markers are available from the Search menu.
Source Markers are a method of managing large BASIC programs easily. You
can use these to "mark" important sections of code, and once marked, can jump
back to them from anywhere in your program. Lines and statements that have
been marked have a small green number next to them in the gutter to the left of
the line, as in the illustration above.
To set a source marker, use the Search Menu. You can also move the editor
cursor to the line or statement you want to mark, and then press CTRL-SHIFT
and a number from 0 to 9.
You can retrieve a source marker that has previously been set by using the
Search menu. You can also use CTRL and the number of the source marker you
wish to jump to.
Note: you cannot jump to a source marker that has not been previously been
defined, for obvious reasons.
You can clear all the source markers by using the Clear all option on the Search
menu. Once cleared, none of the source markers will be available.
Note: If you clear your program using NEW or by loading a new program, the
source markers will be automatically cleared.
Expression Evaluator window
The Expression Evaluator window is available from the View menu.
This window, accessed from the View Menu, provides a simple calculator for
Sinclair BASIC expressions. At the top of the window is an edit field where you
can type in your expression, which also incorporates a drop-down list consisting
of the "history" of all expressions you have typed. The expression can contain
any keywords or functions accessible to Sinclair BASIC, including any variables
you have declared either programmatically at runtime, or by Direct Command.
Upon pressing Return, or by clicking the "Evaluate" button, the expression will
be parsed for errors and executed. This is performed by starting a new instance
of Spectrum Emulation, and allowing the ROM to process the expression as
though it had the keyword PRINT inserted before it. The resulting text which
would be displayed on-screen is taken by BASin and sent to the larger "Result"
field below the edit field.
Note: expressions by their nature can contain functions such as the USR
function which can execute a section of memory as machine code. Although it's
a valid function (and returns the value in BC as the code performs it's final RET)
it can get stuck in infinite loops, or take an age to complete. This will mean that
the Evaluate Expression Window will not respond to requests for more
expressions, either at all or for a long time. To this end, you can press the
"Evaluate" button again to halt the current expression. Any result returned will
be displayed. Closing the Evaluate Expression Window will also have this effect.
Also, related to this, the Evaluation will use the same "engine" to produce the
result as the Watches (and other evaluated expressions, such as Find Window
parameters) and as such any expressions taking a long time to evaluate will
"stall" other expressions waiting to execute. However, none of them will affect
the progress of the main system emulation.
There is also the option, via the "Add as Watch" button, to add this expression as
an Expression Watch to the Watches Window.
Program Information
The Program Information window is available from the View menu.
It also gives information as to how much memory has been used in total, how
much of that is program code, and how much has been used by the variables. It
also displays the amount of free memory remaining to BASIC. This figure is
calculated using the RAMTOP system variable and so represents how much you
can use currently, and may not be taking the full memory of the Spectrum into
account.
The final line informs you which of the two flavours of Spectrum your program
is compatible with - 128k or 48k.
If you use the extended 128k commands then the pogram will be 128k only.
If you use the UDGs "T" and "U" inside strings, then it will be 48k only (as
these UDGs were not available on the 128k).
If you use neither then the program is deemed compatible with both, with one
exception - if you have files currently residing on the silicon disc, and the silicon
disc has been used then the window will warn you that the program may not be
compatible with the 48k Spectrum should you decide to utilise these files in the
future. However, as silicon disk contents are not saved to inside .bas files, and
also not to tape files, then compatibility might not be an issue.
When saving snapshots the contents of the silicon disc will be stored, and as
such if the silicon disc is in use you will not be able to save 48k snapshots.
The 48k/128k mode indicator
To help remind you which computer your program is compatible with, BASin
provides a small indicator at the bottom of the editor window. This is updated as
you create or edit your program, and appears like this...
As you enter commands into BASin, this indicator will remain in "48k mode"
until you enter a 128k command which utilises the enhanced sound (PLAY) or
the silicon disc (LOAD !, SAVE !, MERGE !, CAT ! and ERASE !).
When BASin detects these, the indicator will change...
...and when this happens you may also notice that any instances of the UDGs "T"
and "U" will change to their small-character hexadecimal equivalents.
Removing 128k commands from your program will revert it back to 48k mode.
Find window
The Find window is available from the Search menu.
This window allows you to search for text within your program. It works in a
similar way to other text editor's Find… dialogs, but has some useful behaviours
pertinent to Sinclair BASIC.
You can type the text you wish to search for into the edit field at the top of the
dialog, and set options for the search:
Direction
This sets which way BASin will search for your text - either forward
towards the end of your program, or backwards towards the beginning.
Searching backwards only makes sense when you search from the current
cursor position as the origin.
Origin
This sets where in your program BASin will begin the search - either from
the current Editor cursor position, or from the start of the program.
Lastly, you can use the "Case Sensitive" checkbox to search for an exact match
of your text, including capital or lowercase letters, or to search regardless of
letter case.
Replace window
The Replace window is available from the Search menu.
The Replace Dialog is functionally very similar to the Find Text Dialog, but
allows you to replace the found text with new text of your choosing. To this end,
there is the usual Find… options, such as the edit field for your search text, but
an additional edit field with which you can specify the text you want to replace
the found text with.
As with the Find Text Dialog (the chapter for which gives more information
about searching for text), you can specify that the text to search for is an
expression with the "Find Expression" checkbox, and also that the text to replace
it with is also an expression with the "Replace Expression" checkbox.
The Direction and Origin options are the same as for the Find Dialog, as is the
"Case Sensitive" option.
Lastly, there are the two buttons at the bottom of the window:
Replace All
This button will, regardless of direction and origin, replace all occurrences
of the search text with the replace text in your program.
Replace
File Menu
New
Load ""
Re-Load
Save
Save As...
Print
Exit
Edit Menu
Undo
Redo
Cut
Copy
Paste
Delete
Copy Listing
View Menu
Status Bar
Toolbar
Syntax Helper
Character Ruler
Program Information
Command History
Last Error
Debug Windows
Variables
Breakpoints
Watches
Log Window
Expression Evaluator
Search Menu
Find...
Replace...
Find Next
Replace Next
Source Markers
Set Marker
Get Marker
Clear All
Go to Line Number...
Go to Error
Run Menu
Run/Pause/Resume
Break/Continue
Go to Cursor
Enable Profiling
Force Break
Trace Execution
Single Step Statement
Step Over Statement
Run To Cursor
Toggle Breakpoint
Add Breakpoint...
Add Watch...
Tools Menu
BASin Options...
Token Table...
UDG Editor...
Renumber...
Help Menu
Contents
Command Help
Sinclair BASIC Manual
Error Help
About
File menu
The File menu provides commands relating to the current BASIC program and
the associated file on disk.
New
Clears the current program and variables from the editor, and also clears them
from the emulated Spectrum's memory. You will be prompted to save any
changes you may have made to your program since your last save, but this
applies only to the program itself and not any variables that may have been
altered.
LOAD ""
Re-LOAD
Save
Saves changes to the program, in the format used to load it. If no format was
specified (if the program was created from scratch) then the default .bas format
will be used.
Save As
Prompts for a filename and file type, and saves the program to disk - either as a
.bas file, or as a snapshot file. The default method is to save as a .bas file, other
types of file are specified by the extension of the filename supplied by you.
Saving "myprog.sna" will instruct BASin to use the .sna format, for example
Print
Opens the Print Preview window, ready to send the program listing to a printer.
Exit
BASin uses the .bas file format to store program text on the Clipboard.
Undo
Redo
Repeats the changes that you have undone. This command is only available
immediately after an undo.
Cut
Removes the selected text and places it on the Clipboard. The clipped text is
stored as .bas format, so any control characters in the text, or characters from the
Spectrum ASCII set will be converted to escape characters.
You can then Paste this text into say, a notepad or an email.
Copy
Copies the selected text to the Clipboard. As with the cut option, text is stored in
the .bas format.
Paste
Inserts any text found on the Windows system clipboard into the program at the
current cursor position. The text will be processed for .bas format escape codes,
and then will be inserted using one of two methods:
If the text contains no Return (CHR$ 13) characters, then it will be inserted as
one line.
If the text contains more than one line, then the Add Code Window will be
shown, with the clipboard text in the edit area as plain text. You can change this
text if you like, and it will then be checked for mistakes before being added line
by line into your program. If any of the lines will overwrite any current program
lines, then (assuming that you have enabled Line Overwrite Protection in the
relevant Options Window page) BASin will warn you with the option to stop,
ignore the line, or replace the old line in the program.
Delete
Removes the selected text. Does not store a copy of the text on the Windows
clipboard. You will lose the text forever - use with care!
Copy Listing
Copies the entire program listing to the Clipboard. Unlike a normal save in .bas
format, this does not include any variables in memory.
View menu
The View menu provides commands relating to information about your program
and to show the various debugging tools.
Toolbar
Shows or hides the toolbar which contains shortcut buttons to the more common
of BASin's editor operations.
Status Bar
Shows or hides the status bar at the bottom of the editor window.
Syntax Helper
Shows or hides the code teacher.This is a useful tool which evaluates the
"correctness" of your program line as you type - errors are highlighted in red,
enabling you to spot errors before you enter a program line.
Character Ruler
Program Information
This window will display information about your program - how large it is in
memory, how many variables you currently have declared and their usage of
available memory. Also how much memory remains available to you for
programming. Bear in mind that the system variable RAMTOP is used to
calculate this figure.
Command History
Shows or hides the Command History window - contains a list of all direct
commands which have been entered into BASin for this session.
Last Error
Displays the most recent BASIC error message and its description, in the error
dialog.
Debug Windows
Opens a submenu that allows you to show or hide the debug windows. See the
section entitled "debugging your programs" for a more in-depth discussion of
this powerful aspect of BASin.
Shows or hides the Expression Evaluator window, where you can enter a BASIC
expression and view its result.
Search menu
The Search menu provides tools for finding text in your program.
Find
Displays the Find window, where you can search the current program for a word
or phrase.
Find Next
Finds the next single occurrence of the word or phrase after the cursor position.
Replace
Displays the Replace window, where you can search the current program for a
word or phrase and replace it with another word or phrase.
Replace Next
Replaces the next single occurrence of the word or phrase after the cursor
position.
Source Markers
This menu opens a submenu which you can use to manipulate Source Markers.
Source Markers are like bookmarks in your program, and can be used to quickly
move around a very big program.
SetMarker - opens a submenu with a list of the ten markers available. Any
that have been set will be enabled. Any source markers that have not been
selected will not be available. Clicking one of these will send the editor
cursor to the statement or line associated with it.
Clear All - this option will clear any source markers you have set.
Go to Line Number
Opens a small requester which allows you to type in a line number to jump to in
the Editor. This line number does not have to be a number - you could specify an
expression (which must end up as a number, like "2+4" or "a+6") which can be
specified using any Sinclair BASIC codewords, such as functions or variable
names. For example, By setting variable "A" to 10, then typing "A" into the edit
box, BASin will evaluate the result as 10, and move the cursor to line 10.
Go to Error
Moves to the program line and statement that caused the last error.
Run menu
This menu is the main control for running your program, and most of the
debugging options are in here. Most have keyboard shortcuts. More information
on debugging can be found in the chapter headed Debugging your programs.
This item will start your program if it is not already running, and has not been
paused. Selecting this option again will put your program into pause, or debug
mode. A further click on this item will start your program again. Stopping your
program this way is not the same as using the BREAK key (the Escape key on
your keyboard). Whilst the program is stopped, it cannot be edited but various
debugging methods can be carried out.
Note: When using this item whilst the program is neither running nor paused,
you should be aware that the program will be started using a RUN direct
command, which will perform a CLEAR codeword as part of the startup. This
will remove any previously declared variables from memory.
Note: You can only break into a program between statements. This command
has no effect until the current statement finishes, even if it is a statement which
might not end soon (such as INPUT or PAUSE).
Go to cursor
Continues the program from the location of the edit cursor. This has the same
effect as typing
GO TO [line number]
and will not clear your currently declared variables.
Force BREAK
Aborts the running program and returns to the editor as it was before the last
direct command was started. Unlike System BREAK, this command has
immediate effect and works even when the running program cannot see the
Escape key. This is because BASin stores the state of your program just before
any direct command is executed, and this menu item will restore that state
when clicked.
Trace Execution
When the program is paused, or has triggered a Breakpoint, this item can be used
to move through the program one statement at a time - the program will resume
execution, and when the next statement has been executed, will pause again.
Single-stepping is one of the most powerful debugging tools.
Executes the next statement in the program, waits for the program to reach the
statement after that, and then pauses. In the case of a GO SUB statement, for
example, whereas Single Step Statement would jump to the first line of the
subroutine, this command will execute the entire subroutine and move to the
next statement on the calling line.
Run to Cursor
Runs the program up to the location of the edit cursor, and then pauses.
Toggle breakpoint
Toggles a breakpoint on the line that the cursor is currently resting upon. This
will be a simple breakpoint which will only trigger when program execution
reaches that line.
Add Breakpoint
Opens the Add Breakpoint window, where you can specify confitions and other
properties for a custom breakpoint.
Add Watch
BASin Options
Opens the Options window, where you can configure the behaviour and
appearance of BASin.
Token Table
Opens the Token Table window, which gives access to a chart of the ASCII set
used by Sinclair BASIC, including a visual selection of colour control codes,
UDGs, and keywords.
UDG Editor
Opens the UDG Editor window, which provides an easy to use way to make
User Defined Graphics in your program.
Renumber
Opens the Renumber window, where you can change the line numbering of the
current program.
Help menu
The Help menu provides help and information about BASin and Spectrum
BASIC.
Contents
Command Help
Displays help on the BASIC keyword under the cursor. Pressing F1 in the editor
has the same effect.
Displays the Spectrum BASIC manual, as corrected and modified for BASin.
Error Help
About
When using the editor, it can be useful to get help with a codeword or things
with a variable. BASin allows you to click your right mouse button within the
Editor which will bring up the a menu. Depending upon what you were pointing
at when you clicked, the menu will give you different options. Bear in mind that
if you bring up the menu for a variable, it must have been given a value by the
LET codeword before it will be recognised by BASin.
Codewords
These options are available when you select a codeword (such as PRINT).
Token Help
Opens the Spectrum BASIC manual at the entry for that codeword.
Tokenise
The Spectrum character set includes a single character, called a token, for each
codeword. It is possible (but never necessary) to include a token in a string. This
command converts the selected keyword to its token, indicated in the program
listing by a very tiny value, that can be made of letters or numbers.
Note: If you need to store a token in a string, it is usually better to use the CHR$
codeword.
You can also tokenise entire strings by using the "String Operation" menu when
right-clicking on them.
De-Tokenise
Any codeword which requires a line number as it's parameter such as RUN, GO
TO, GO SUB etc, where the line number is present will have this option
available. Using this, you can jump to the line number indicated by the
parameter. This also applies to line numbers that are calculated, i.e. GO TO
5+5 will move the editor cursor to line 10. As this is evaluated, you can use any
Sinclair BASIC expression to specify the line number. This also applies to FOR
variables, which will allow you to jump to the loop point (the statement directly
after the FOR statement). This will not find the relevant NEXT statement line, as
you can use more than one NEXT for a FOR statement.
Variables
Note: The context menu only recognises variables that are already present in
memory. This means that a variable must have been declared (using a DIM or
LET statement) before it will show up in the context menu.
Edit Variable
Opens the Variables window for the selected variable, so that you can change its
value.
String Wordwrapping
These options are available from the "Wordwrap String" when you activate the
menu on a long string - that is, one that is longer than 32 characters.
Wordwrapping is useful when a string has to be printed to the screen, but is too
long to fit into the standard 32 character wide display. By default, the text would
flow over the edge of the screen, cutting off halfway through a word if
necessary:
Clearly, this looks unacceptable. So instead, there are word wrapping options
available for these strings on the Context-Menu.
Split at 32 Chars - This option will split your string into many strings, seperated
by the ' character (the line-feed PRINT item). The split will occur at the first
space charecter before the point where the split would occur normally.
Insert Spaces - This option will, instead of splitting the string, insert space
characters before any words that will be split to force them over the 32 character
boundary. Having applied this method, our line of code now looks like this:
Note the extra space between "and" and "will". This makes sure that the word
"will" begins on a new line. It does however make your lines even longer.
Standard commands
Cut
Removes the selected text (if any) and places a copy on the windows clipboard.
The clipped text is converted to .bas format, so any control characters in the text,
or tokens from the Spectrum ASCII set will be converted to escape characters.
Copy
Copies the selected text (if any) to the Windows system clipboard in text format.
As with the Cut operation, the text will be converted to .bas format before being
placed on the clipboard.
Paste
Inserts any text found on the Windows system clipboard into the program at the
current cursor position. The text will be processed for .bas format escape codes,
and then will be inserted using one of two methods:
If the text contains no Return (CHR$ 13) characters, then it will be inserted as
one line.
If the text contains more than one line, then the Add Code Window will be
shown, with the clipboard text in the edit field as plain text. You can edit this text
to your liking, and it will then be tested for syntax validity before being inserted
line by line into your program. If any of the lines will overwrite any current
program lines, then (assuming that you have enabled Line Overwrite Protection
in the relevant Options Window page) BASin will warn you with the option to
abort the operation, ignore the line, or replace the old line in the program.
Debug
Traditionally, the Spectrum used cassette tapes for loading and saving programs
and data.
With BASin, the commands LOAD, SAVE, MERGE, and VERIFY refer to files
on your actual computer's hard disk. Full Windows paths are acceptable (such as
c:\programs\fruit.bas), but be aware that programs that load or save
with long paths will not work correctly on an original Spectrum. When no path
is specified in a filename, the most recent path is used.
You can specify an empty filename if you wish to locate the file manually
instead of typing its full path. For example, LOAD "" displays a dialogue box
where you can select a file to open.
Note that although BASin for Beginners can LOAD any of the following
formats, you can only save in the .szx format (a snapshot format) which will
allow you to run your program on a real Spectrum Vega.
Programs are saved and loaded in .bas format or Spectrum Emulation Snapshot
format. .bas format is a text representation of a BASIC program. Escape
characters can be used to indicate embedded colour commands and UDG or
graphics characters. In all load and save dialogs relating to programs, the .bas
extension is assumed, and will be added if the user omits it in the filename. In all
respects the emulated Spectrum receives the data from a .bas or snapshot file as
if it were a tape block - program files are encoded into tokenised BASIC before
being passed to the ROM for loading into the emulated memory space.
File formats
See the following topics for a detailed description of the file formats that BASin
supports:
The .bas format, which is BASin's preferred format
for programs.
The .bsc format, for code blocks.
The .bsd format, for array variable data.
The .scr format, for Spectrum screen images.
Snapshot files, which describe the complete state of
the emulated Spectrum.
Tape files, which contain sequential data blocks like a
cassette tape.
The .bas file format
A .bas (BASin program) file contains a plain-text representation of a
Spectrum BASIC program and variables. This is the preferred file format for
programs developed in BASin.
Variables
A .bas file begins with an optional variables section, which describes the
BASIC variables that were resident in memory when the program was saved.
Where v is the variable name (a$, a etc). Type would be one of Num, Str,
NumArray(), StrArray(), NumFOR. Strings would be Quote (") delimited, with
normal BASIC quote-in-quote rules applied.
For a loop counter variable, loop-line and loop-statement represent the statement
immediately after the FOR statement, i.e. the one to which program flow will
jump when the corresponding NEXT is encountered.
Auto line-number
Program
The next part of the .bas file is the actual program listing. Keywords are
stored as plain text (so e.g. PRINT is five letters), not the non-standard keyword
tokens from the Spectrum character set.
If you have selected Break multi-statement lines on BASin's Files tab, any
program line containing more than one statement is split across multiple lines in
the file, one for each statement. This is indicated by a line ending with a \
backslash, e.g.
Note: Control character escape sequences can be combined, so that for instance
\{i6p1f1} is equivalent to \{i6}\{p1}\{f1} - flashing yellow ink on
blue paper.
The escape sequences for graphics characters are as follows (note the spaces!):
\@ The @ at symbol.
\#nnn Any character, where nnn is a decimal number in the range 000 to 255.
The .bsc file format
A .bsc (BASin code) file contains the contents of a block of memory, along
with a descriptive header block. To save a code block, use the SAVE . . . CODE
syntax.
Note: The filename extension determines the format in which a code file is
saved. If the extension is .bsc, BASin saves a .bsc file. If the extension is
anything else (or missing altogether), BASin saves a raw binary file with no
header.
The LOAD . . . CODE syntax allows you to specify a start address in memory
and an optional length (in bytes). If the file is too short, BASin will load as much
code as is available. If it is too long, BASin will stop loading after the specified
length or when the top of memory is reached.
The .bsc format begins with a simple 17-byte header, identical to the header
saved by a real Spectrum. The header takes the form:
15-16 Reserved.
Bytes 17 onwards are the raw binary data that was saved.
BASin can save memory dumps as either .bsc, which includes the header
described above, or as raw bytes if the .bsc extension is absent from the
filename - e.g. SAVE "c:\BASin\Screen.scr" CODE
16384,6912 would save a raw .scr dump of the current display memory,
with no header. This can be loaded into any emulator which supports the loading
of Binary files.
The .bsd file format
A .bsd (BASin data) file contains the name and contents of a BASIC array
variable. To save variable data, use the SAVE . . . DATA syntax.
Note: It is only possible to save array variables with single-letter names, such as
a$. This was a limitation of Spectrum BASIC and is preserved in BASin for
compatibility.
The .bsd format resembles the .bsc format in that it comprises a standard
Spectrum header followed by the raw binary data for the variable. For a
discussion of how variables are represented in memory, see Chapter 24 of the
manual.
14-16 Reserved.
Bytes 17 onwards are the raw binary data that was saved.
The .scr file format
A .scr (screen) file is a memory dump of the Spectrum's display file, or screen
memory. This file format is supported by many emulators.
The display file starts at address 16384 and is 6912 bytes long. The first 6144
bytes represent the actual screen bitmap (which pixels are set and which are not),
and the remaining 768 bytes represent the attributes, or colour information,
which can be imagined as a transparent overlay.
The layout of the display file is somewhat unusual. It is split into vertical thirds,
each comprising eight rows of characters, and each character is stored in eight
(non-sequential!) bytes. The attribute data is stored in a more straightforward
way, "reading" the character cells from the top left to the bottom right.
This simple program illustrates the layout of the screen display by filling it with
consecutive bytes:
If you don't need to load your programs into other emulators, you should use the
.bas file format instead.
A snapshot describes the complete state of the emulated Spectrum at the time it
was saved, including the memory contents, port states, and register contents.
When you open a snapshot in BASin, the BASIC program, variables, and user-
defined graphics are extracted from it and converted into a tape block which the
ROM loader understands.
48k Snapshots work as expected - they are a dump of the memory and the state
of the emulation as it was when the snapshot was saved. However, due to the
fact that BASin is primarily a 48k emulation, 128k snapshots are created by
inserting your program and silicon disc contents into a 128k snapshot. This
means that when you load the snapshot, you will find yourself at the main 128k
menu. To examine your program or run it, you must choose "128 BASIC" from
this menu.
Note: The .z80 file format, developed by Gerton Lunter for his Z80 Spectrum
emulator, has gone through a series of changes, making newer files incompatible
with older versions of the emulator. You can choose your preferred version on
BASin's Files tab.
Running a program
Programs, when run, will send all their output to the Display Area. This area is
analogous to the original Television display utilised by the real Sinclair
Spectrum. The PC keyboard operates in a similar manner to the Editor window -
and thanks to more ROM modifications, any INPUT statements will be able to
use a much more friendly method of entering data into the program.
All programs and direct commands will return to the editor with an error
message, even if it is just to say that no errors have occurred. You can get further
help with error messages - the Error window and Error Help window provide
complete information about BASIC errors
Direct commands
Program lines can be typed in with a line number and will be accepted and
stored for later as part of a program. However, if you type a line with no line
number, it will be executed immediately. This is a "Direct Command". You can
also use the editor as a simple calculator - type in an expression, such as 2+3/(4-
2) and press Return. The result will be displayed in the display area.
All direct commands are "logged" in the Command History Window where they
can be re-called for repeated use.
When the command has terminated, or the expression has been evaluated, then
usually a "0 Ok" message dialog will appear, indicating that all went well.
Closing the "Error Message" dialog will return you to the editor.
Command History window
The Command History window is available from the View menu.
This window keeps a log of all Direct Commands executed by you in the Editor.
You can inspect the list by scrolling through it, and recall any of the commands
by highlighting it, and clicking the "Send To Edit" button. This will discard any
un-stored line that you may have been typing and replace it with the command
you chose. The "Close" button will hide the Command History window.
Error messages
When an error message (which includes error "0 Ok" which means that no error
happened!) BASin will pop up an Error Dialog which contains the error, along
with a short explanation of why it might have happened. Clicking the Okay
button will hide the dialog, and return you to the editor. The Continue button will
issue a CONTINUE codeword as a Direct Command and resume program
execution if possible.
You can turn this behaviour off with the checkbox at the bottom of the Error
Dialog or by using the relevant Options page.
Error window
The Error window is displayed when an error occurs in Spectrum BASIC, either
while your program is running or as a result of a direct command in the editor.
This window is also used for reports that are not technically errors, such as 0
OK and 9 STOP statement.
For a complete list of possible reports and an explanation of the numbers, see
Appendix B.
Closing the window will return you to the Editor window, and if you have asked
BASin to do so in the Options dialog, then the editor cursor will automatically
be moved to the program line/statement that caused the error
Uncheck the Notify me of this error type box if you do not want to see the
Error window when this error occurs in future. If you choose to suppress the
window for a particular report, it will overwrite the bottom two lines of the
screen instead - as on an original Spectrum. You can re-enable the Error window
for specific errors on the Error Reporting tab.
Note: In the unlikely event that the error-handling routine in Spectrum ROM is
called without a legitimate error value in the ERR NR system variable, BASin
will display the error message ? Unknown error.
Error Help window
The Error Help window is available from the Help menu.
Use the Error Help window to browse the Spectrum BASIC error messages and
their descriptions.
BASin provides many ways to help debug your programs. Debugging is the
process by which you determine where a program is not doing what it should,
and narrow down the exact "fix" needed to get it working properly. Most of the
time, this is due to an error on the your part - a spelling error, or a
misunderstanding of how certain codewords do their jobs.
This chapter deals with the methods you can use to track down bugs, and fix
them. All of these are ways to get information about your program and its
variables as the program is running. By watching this information and following
your code slowly, you can (hopefully) get an idea of what is going wrong.
There is one thing worth mentioning - the more debugging systems you enable,
the slower a program will execute. BASin will have to take time away from the
emulation of the Spectrum BASIC in order to update the various sources of
information you have asked for, which can result in choppy sound and
inconsistent program speed even on the fastest of systems.
One of the most simple debugging tools is the Program Trace. This can be
enabled from the Run Menu in the Editor, and will update the editor window as
statements execute in real time. This is quite fast and lines flash by very quickly,
but some people find that it's necessary to be able to "watch" how their program
runs.
Another good method to use is to pause the operation of your program, without
actually stopping it. Your program won't know that it's stopped, so it won't affect
it.
This can be useful - once the program is "halted" then you can step through the
code one statement at a time, and monitor the program flow and variables as you
do. BASin provides three methods of doing this:
Breakpoints
The user can suspend operation using the Run Menu in the Editor, but you'd be
hard pressed to accurately stop just where you want to. This is where
Breakpoints and Watches come in very handy indeed.
Breakpoints in BASin can get a lot more complex than this, however.
Watches
Watches are another type of debugging tool, loosely related to breakpoints, but
much more flexible. They are a list of expressions (or other types of data, such
as variable contents, system variable states, memory states etc) which are
updated after every statement executes. The Watch Window is constantly
updated as the program runs, to reflect the state of these watches.
Watches may have conditions as well. The program halts when the value of the
expression satisfies the condition.
See also:
BASin supports a number of REM directives, which are special commands that
can be activated during the running of a program by including the appropriate
REM statement.
REM directives are case-insensitive, but there must be no more than one space
between REM and the directive.
You cannot use a REM directive in a direct command - only in a program line.
REM fast
Tells BASin to start running the program as fast as possible, disregarding any
timing constraints. While not true to the behaviour of a real Spectrum, this
feature is useful for skipping through time-consuming operations.
REM slow
Tells BASin to evaluate expression (which may be string or numeric) and write
the result to the Log window.
10 REM log i
80 REM log "Reached line 80"
100 REM log FN p(j)
500 REM log "Length of b$ is " + STR$ LE
Note: If an error occurs while evaluating an expression, the error message is
written to the Log window instead.
Variables window
The Variables window is available from the View menu.
This window keeps a list of any variables that have been declared at runtime or
as a Direct Command with a LET statement. Once the variable has been
declared, it will appear in the list. The name will show at the far left of the
window, followed by its type:
You can use either a click of the right mouse button on the highlighted variable,
or use one of the two buttons at the bottom-left of the window to either edit the
variable or watch it.
If you elect to watch the variable, then a Watch will be created and added to the
Watch Window containing the variable name as it's watch-expression. You can
edit this watch with the Watch Properties window.
Editing variables brings up the variable editor. The contents of this window
depend upon the type of variable being edited.
For a simple numeric or string variable, you can alter the contents by typing a
new expression into the variable editor's edit field. This expression must be of
correct syntax, and evaluate to the type of variable being edited. This means, for
example, that any string literals you edit must be enclosed in quote (") marks,
but does grant the ability to use such expressions as A$+B$ or "Hello"(
TO 4) which will of course be evaluated when you click OK, and the result
stored in the variable.
Numeric or String arrays will present themselves as a list in the variable editor of
their contents. Clicking any of the elements will open an edit field for that
element, which again can be any expression relevant to the variable type.
Breakpoints window
The Breakpoints window is available from the View menu.
The breakpoints window lists every breakpoint that the user has set within the
program, along with some other information which can be useful when
debugging. The list has a small column to the left, which contains a checkbox.
When checked, this means that the breakpoint is active. When unchecked, the
breakpoint will be ignored and won't suspend program operation. This option
can also be set from the context menu activated by right-clicking a breakpoint in
the list. After this, the line and statement is listed, in the Line:Statement
format (i.e., 10:1 would be line ten, statement 1), along with the source of the
line in BASIC code. Any condition that has been set for the breakpoint is listed
next to this.
Finally, to the far right, is the Pass Count. This number will be incremented
when program execution reaches the breakpoint, regardless of whether or not
execution is suspended by the breakpoint. By watching this value rise, you can
see if your program is executing that line of code, and how often.
You can add a new breakpoint by either choosing the "Add Breakpoint…" menu
item (after clicking your right mouse button in the breakpoints list), or by using
the "Add New…" button. A new breakpoint will be created, and the Breakpoint
Properties Windowl open allowing you to edit the new breakpoint's attributes.
You can also call up the properties for any other breakpoint by either using the
"Properties" button, or by using the "Properties" option on that breakpoint's
context menu.
The context menu for the main list has extra functionality if no breakpoint is
highlighted, and will allow you to enable, disable or delete all the breakpoints in
the list. These items should be used with care, as they can easily make a mess of
all your debugging efforts so far. When a breakpoint is highlighted, then an extra
option appears on the menu - "View Source", which will move the Editor cursor
to the start of the line and statement that the breakpoint refers to.
Breakpoint Properties window
The Breakpoint Properties window is available from the Breakpoints window.
This window is used to set the behaviour of any of the breakpoints currently set
within your program. There are two tabs - The "Breakpoint" tab and the
"Advanced" tab.
Note: When creating a new breakpoint, this is known as the Add Breakpoint
window.
In the "Breakpoint" tab, you can set the basic options for your breakpoint. The
"Enabled" checkbox allows you to "turn off" a breakpoint, which will remain
completely inactive until you want to use it, and the "Break" checkbox lets you
choose whether or not this breakpoint should suspend program operation when it
fires. The Line and Statement number that the breakpoint will trigger at is
displayed in the two edit boxes below these options.
Advanced tab
The "Advanced" tab gives you the opportunity to add a condition to the
breakpoint. If the breakpoint is enabled, then the condition will be tested if it is
present. The condition can be any Sinclair BASIC expression, which includes
the use of variables (as long as they are defined by your program). The
expression should resolve to a numerical result, and if it does then the breakpoint
will trigger when that result is non-zero.
Finally, you can also specify a log entry which will be made when the breakpoint
fires. Bear in mind that the log text specified will only be logged if the
breakpoint is enabled, and any conditions have been met. This log text can, like
the condition, also be an expression of any type. You can indicate that this is the
case by checking the "Log Expression" checkbox below the edit field.
Watch List window
The Watch List window is available from the View menu.
Watches are another tool which, like breakpoints, are evaluated at runtime.
Unlike breakpoints, they are evaluated after every line and statement of your
program, so they can take up quite a lot of CPU time if you have many of them
present in the Watch list. Watches consist of different types - the most basic
being an expression which the user enters, and is evaluated as the program runs.
Other watch types include variable watches, system variable watches, and
watches that monitor memory addresses. This can be very handy for keeping an
eye on how your program affects the environment it runs in.
The main area of the window is the Watch List. This lists, like the Breakpoints
Window, every watch declared by you. To the left of each entry is the "Enabled"
checkbox - you can disable watches temporarily with this. The "Result" field to
the right will inform you that the Watch is disabled if you choose to do this.
After the Enabled box, the expression or type of watch is listed. Variables are
listed with a prefix "Var:", System variables are given a "SysVar:" prefix, and
memory watches are listed with a "Mem" prefix followed by the data size that
they are watching (Byte, Word or DWord). Finally the result of the watch, if it is
enabled, is shown. In the case of an expression, the result of the evaluation (or
any syntax errors in the expression) is shown. Variables will display their
contents, unless they become undefined due to a CLEAR statement for example,
where they will show the "Variable not found" error.
Managing watches
You can use the "Add New…" button to add a new watch (the Watch Properties
Window will pop up to allow you to customise the new Watch), or right-click in
an empty part of the watch list and choose the corresponding menu item. Delete
watches using the "Delete" button after highlighting a watch in the list, or again
use the context menu on your right mouse button. You can alter any watch by
selecting it and using the "Properties" button, which will bring up the Watch
Properties Window.
If you find that your watches are at odds to your program state (after you maybe
POKE'd one of your variables programmatically for example), you can force a
manual update of all watches by clicking the "Refresh" button, which again is
available on the context menu.
Watch Properties window
The Watch Properties window is available from the Watch List window.
When you create a new Watch, or edit a Watch you have already created, this
window will allow you to customise the way that the Watch behaves.
Note: When creating a new watch, this is known as the Add Watch window.
Firstly, the "Enabled" checkbox will allow you to turn on or off the watch in
question. A disabled watch will not be evaluated at runtime, and so can speed up
debugging when many watches are created but not necessarily needed at the
current time.
After this, you can choose what type of Watch you want from the "Watch Type"
drop-down list:
Expression Watches
An Expression watch will evaluate the expression you specify in the edit
field below. This can be any Sinclair BASIC expression, including variables
and memory PEEKs. Below this, you can opt to break execution (suspend
the program) if the expression evaluates to a non-zero result. This is similar
to the conditional breakpoint, but different in one important respect.
Watches are evaluated as each line and statement is executed, and so are
constantly updated. A conditional breakpoint will only be evaluated when
the specified line and statement number has been reached, so an Expression
Watch can break whenever the expression results non-zero, which can be
handy for tracking down where a particular variable is corrupted, say.
Variable Watches
These are similar to the Variable Watches, in that you can only select to
monitor a System Variable (see Chapter 25 of the Sinclair BASIC Manual
for more on these) from the drop-down list. These watches cannot break
program execution. They will be displayed in their correct format - two-
byte words, or single byte values, or lists of multi-byte contents.
These watches will monitor the contents of memory addresses. They can
display, from the address which lies in the range 0 to 65535, one byte, a
Word (two bytes) or a Dword (four bytes). This will be updated between
statements, as the other watches are. Again, these watches cannot break
program execution.
Log window
The Log window is available from the View menu.
This window displays messages logged by BASin, such as breakpoint log text
and syntax errors when pasting multiple lines from the Add Code window.
This window is opened automatically when any of the three printing options are
chosen: the Print option of the File Menu in the Editor, the Print option of the
Display menu on the Display Window, and the Send To Printer button in the ZX
Printer Output Window. It allows you to set various options as to how the output
will be printed to the PC printer.
The window is divided into two areas: the options, and the Print Preview.
The print preview area is a graphical representation of how the output will
appear on the page. The size of the image is taken from your printer's current
orientation and paper type settings, and the actual data is laid out according to
the options at the bottom of the window.
The options start with the Data Source, which is usually set by the window that
opened the dialog. You can change between the current screen, the current
BASIC program, and the ZX Printer output. Each has options of their own which
can be set.
When printing the current BASIC program, you can use the numeric field to the
left of the options area to set at which character column the lines of BASIC will
be wrapped around to the next line. The output produced by this source will be
as close to the Editor's display as possible (taking into account the line
wrapping), with the same syntax highlighting options as you have selected in the
Options Window.
When printing the current screen, you can elect at the lower left of the options
area to either grab the display "as-is", which will take the current display size
and any scaling options into account, or to take the display as the spectrum sees
it. Both options will take the border area into account when printing.
When printing the ZX Printer output, you cannot set either of the above options,
and the only options available to you are the standard set available to all three
Data Sources.
The scaling allows you to inflate or deflate the printed output. Many printers
operate at much, much higher resolutions (dots per inch, or DPI) than the ZX
Spectrum's printer could manage. For this reason, you can scale the output up or
down to enhance readability or maximise space usage.
Below the scaling option you can also select Multiple column output, which only
applies to the current BASIC program and the ZX Printer output. If there is room
on your page, BASin will allow the printed output to run in columns down the
page before heading into a new page.
This will open your printer's Preferences control panel applet, allowing you
to set paper source and orientation or quality settings. Any changes will be
reflected in the preview area at the top of the window.
Will bring up the standard windows Printer dialog, where you can set the
number of copies and the pages you wish to print before commencing the
print job. Note that you can also change the printer you are sending the job
to using this window - which can cause problems if the paper sizes and
orientation of another printer differ from the ones used in the preview.
Close
Some of these tools will do a certain amount of programming for you, others are
aids to programming. The Token Table Window, for example, makes it easier to
insert colour control characters or keyword tokens into your program, and the
Renumber Tool allows you to make your program tidier and create room for
more lines between lines that have become a bit tight in their numbering.
These tools are used by one or more of the tools or debugging utilities, and as
such are not available for use by the user except in conjunction with those parts
of BASin. However, they are documented here:
The Add Code window controls the insertion of groups of program lines.
Token Table window
The Token Table window is available from the Tools menu.
This tool opens up a window which contains a tabbed set of pages which contain
the usually hard to find characters and tokens present in the Sinclair ASCII set.
You can browse these pages to find the token you want, whereupon double
clicking it will send that character or token to the Editor window. Clicking once
on these will show a larger version, which can be useful to distinguish between
them.
The status area at the bottom of the window, below the tabs, shows which
character code (CHR$ code) corresponds to the character or control code/token
you are currently pointing at.
Alpha-numerics/Graphics
This page shows three areas of characters that are available to Sinclair BASIC -
the Character set, which contains all the characters from the space character
through to the copyright symbol.
There is a checkbox below this area, marked "Use Chars" - this, when enabled,
will instead of using the default Sinclair Character set, take the graphical
representations from the memory region which is pointed to by the CHARS
system variable. This allows you to see the characters as they would appear on-
screen.
Control codes
This page displays the colour and cursor movement characters for you to insert
into your program.
These will be sent as "Hex chars" - small custom characters which comprise the
hexadecimal equivalent of their CHR$ codes. For colour control characters, this
usually entails sending two characters to the editor - the colour control code and
it's parameter. For example, the code for setting the INK is number 16 - so that
will be sent first, followed by the ink number from 0 to 7. The Status area,
although showing the correct PRINT code for the colour controls, does not show
the Editor codes needed. The correct characters will be sent though.
Keywords
The UDG editor provides a user-friendly and intuitive graphical interface for
creating these graphics.
Editing grid
This area represents, in a large form, the 8×8 character grid used to create one
character. You can use the mouse in here to set or un-set pixels in the character.
You can select the character you want to work on by clicking in the Character
Selection Area, and any changes you make will be shown there as you make
them.
A preview of your current character is also displayed at the top right of the grid
region.
This area, to the right of the window, contains a "palette" of characters available.
When editing UDGs, this contains 21 graphics.
You can use the left mouse button in a single "click" to send a character to the
editing grid. You can also use a "drag and drop" operation on these characters:
Use the left mouse button to select a character, and without letting go of the
left mouse button, "drag" the character to another character in the selection
area to make a copy of that character in that cell.
Use the right mouse button to drag a character to exchange it with the
character in the destination cell.
Use the left mouse button to drag a character to the editing grid, to assign
that character to a particular placeholder on the grid.
Use the right mouse button to copy a character's data from one character to
the editing grid. This is the same as copying between characters on the
palette using the left button detailed above.
The main menu for the UDG/Charset editor allows you to access advanced
functions. From left to right, the menu consists of:
New
Clears all the UDGs away and lets you start afresh with a new set.
Exit
Undo
Grid
Fill
Clear
Invert
Horizontal
Vertical
Rotate
90° Left
90° Right
Shift
Left
Right
Up
Shifts the whole grid up one pixel, wrapping
around at the bottom of the grid.
Down
Characters
Cut
Copy
Paste
Retrieves any graphic stored on the Graphic Editor
clipboard, and sends it to the currently selected
graphic slot, replacing any graphic that is already
there.
Insert New
Delete
Clear
Invert
Flip
Brings up a submenu which allows you to flip the
currently selected graphic.
Horizontal
Vertical
Rotate
90° Left
90° Right
Shift
Brings up a submenu, with four options for
shifting the current character around the Editing
Grid.
Left
Right
Up
Down
This tool is very handy for any BASIC, such as Sinclair BASIC, which uses line
numbers. Whilst writing a program, you may find that you need to insert lines
between existing lines, and that after a while the numbering is so tight that there
is no more room.
This tool alleviates this problem. It will take each line number, and replace it
with the numbers you choose, which can (assuming that you set a sane Step
value) increase the number of available new lines.
You can, using the first option, elect to either renumber the whole program, or
just a portion. If you decide to renumber just a portion (the "Whole Program"
checkbox is un-checked) then the following options must be set:
From Start
The line number that begins the block of code you wish to renumber.
To End
The line number that lies at the end of the block of code you wish to
renumber.
Note: Both options must be in numerical order - the end value cannot be smaller
than the start value.
From hereon, you can set the parameters for the renumbering itself. You can use
the options:
Starting At…
This option specifies what line number the renumber should use as the first
line.
Each new line that is renumbered will be the previous line's number, plus
this amount. Setting to 10 is probably best, as it gives a nice amount of
space between the lines. Setting this to 1 will renumber sequentially as 1, 2,
3, … 10, 11, 12 etc, but will prevent you from inserting any new lines into
the program.
Only lines that contain an absolute reference to another line number will be
renumbered. Any statements, such as GO TO, GO SUB, RESTORE etc that
reference a line by a calculation, i.e.
GO TO A*10
Will not be renumbered, and again a log entry warning you of the fact will be
made. If any log entries are made, then the log window will be shown after the
renumber is complete.
Add Code window
The Add Code window appears when a group of lines is about to be inserted into
your program.
The code you paste in must be checked and inserted properly. To this end, when
BASin detects such an operation, it sends the code to the Add Code window
first.
The Add Code window displays the lines to be inserted in a simple text editor,
where you can make any changes that you require before confirming the
insertion.
If a syntax error occurs during insertion of program lines, the error will be
automatically displayed in the Log window and the remaining lines will appear
in the Add Code window for correcting.
Options window
The Options window is available from the Tools menu.
Options should not be changed by the beginner, as you can change the way that
BASin works.
This window allows you to configure the behaviour and appearance of BASin.
BASin tab.
Error reporting tab.
BASin tab
The BASin tab can be found in the Options window.
Programming aids
When the user exits BASin, the current state of the editor and the emulator is
saved in the BASin folder under the filename "Session.bin". It is safe to
delete this file, as BASin does not require it to run. When this option is enabled,
and the file exists in BASin's folder, BASin will load that state, allowing you to
continue programming where you left off.
If this box is checked, the syntax helper appears in the editor when you start
BASin. To show or hide it temporarily, use the option on the View menu.
If this box is checked, you can start program lines with a . full stop instead of a
line number. BASin will automatically choose a line number for you: the next
available multiple of 10 (at the end of a program) or a number halfway between
the last entered line and the one that follows it (in the middle of a program).
Predictive auto-typing
If this box is checked, BASin will suggest likely keywords while you are typing.
Keyword suggestions are displayed in grey ahead of the edit cursor. You can
accept a suggestion by pressing , or ignore it by continuing to type.
Note: On slower computers, BASin may perform poorly if this option is
enabled.
This editor feature helps to protect you from accidentally overwriting program
lines with new ones. By default, BASin will alert you by flashing a green cursor
at the start of the line, and making the error-beep sound. Pressing return a second
time signals to BASin that you have understood that you are about to replace a
line, and performs the replace operation. If you elect not to replace, you can edit
as normal, changing the line number to one more appropriate. There are three
methods available for this option:
Brackets completion
Whilst editing programs, graphics mode allows you to enter colour codes and
user defined graphics (UDGs). This option determines which key is used to
enable graphics mode.
Error notification
Basin can report errors exactly as the original Spectrum would have done - by
clearing the two lower lines of the Display Window and writing the error there.
This tends to corrupt the display, which can be annoying if you were working in
that area using PRINT # or INPUT #, for example. The list of checkboxes here
represents all the error messages that Sinclair BASIC can produce.
Error messages in the list that are checked will be displayed in the Error window
when they occur. Those that are unchecked will overwrite the bottom two lines
of the screen display (as on a real Spectrum).
If this box is checked, the editor will automatically move the cursor to the line
and statement where the error occurred.
Sinclair Spectrum BASIC Manual
Sinclair ZX Spectrum: BASIC Programming By Steven Vickers.
Edited by Robin Bradbeer.
Contents
Introduction
Chapter 1
A guide to the ZX Spectrum keyboard and a description of the display.
Decisions
Chapter 3
IF, STOP, =, <, >, <=, >=, <>
Looping
Chapter 4
FOR, NEXT, TO, STEP. Introducing FOR-NEXT loops
Subroutines
Chapter 5
GO SUB, RETURN
Expressions
Chapter 7
Mathematical expressions using +, -, *, /, scientific notation and variable names.
Strings
Chapter 8
Handling strings and slicing.
Functions
Chapter 9 User-definable functions and others readily available on the ZX Spectrum using DEF, LEN, STR$,
VAL, SGN, ABS, INT, SQR, FN
Chapter Mathematical functions
10 Including simple trigonometry: ↑, PI, EXP, LN, SIN, COS, TAN, ASN, ACS, ATN
Chapter Arrays
12 Strings and numeric arrays - DIM.
Chapter Conditions
13 Logical expressions: AND, OR, NOT.
Chapter Colours
16 INK, PAPER, FLASH, BRIGHT, INVERSE, OVER, BORDER
Chapter Graphics
17 PLOT, DRAW, CIRCLE, POINT
Chapter Motion
18 Animated graphics using PAUSE, INKEY$ and PEEK
Chapter BEEP
19 The sound capabilities of the ZX Spectrum using BEEP.
Chapter
The system variables
25
Appendix
The character set
A
Appendix
Reports
B
Appendix
Example programs
D
Appendix
Binary and hexadecimal
E
Whatever else you do, keep using the computer. If you have the question "What
does it do if I tell it such and such?" then the answer is easy: type it in and see.
Whenever the manual tells you to type something in, always ask yourself, "what
could I type instead?", and try out your replies. The more of your own programs
you write, the better you will understand the computer.
At the end of this programming manual are some appendices. These include
sections on the way the memory is organised, how the computer manipulates
numbers, and a series of example programs.
The keyboard
BASin uses the standard PC keyboard and a version of the ZX Spectrum 128
editor. The various modes and single-key entry system from the original 48K
Spectrum do not apply. See The keyboard for information on entering special
characters that do not appear on a PC keyboard.
While you type, your position is indicated by the cursor, a flashing block that
shows where the next character from the keyboard will be inserted. The cursor
can be moved about with the four directional arrow keys: it will automatically
jump to the end of a line rather than wander into unused space.
If any key is held down for more than about 2 or 3 seconds, it will start auto-
repeating.
When Enter is pressed, the current line is executed, entered into the program, or
used as INPUT data as appropriate, unless it contains a syntax error. In this case
the cursor changes colour (from blue to red) and moves to the approximate
position of the error, and the computer sounds a beep.
As program lines are entered, a listing is built up in the editor. You can use move
the cursor onto any line in the listing with the keys and , and edit the existing
line by typing your changes and pressing Enter.
The Esc key (and, in certain circumstances, Space) acts as a break, stopping the
computer with report D or L. This is recognised:
This has 24 lines, each 32 characters long, and is divided into two parts. The top
part is at most 22 lines and displays either a listing or program output. When
printing in the top part has reached the bottom, it all scrolls up one line; if this
would involve losing a line that you have not had a chance to see yet, then the
computer stops with the message scroll?. Pressing any of the keys n, Space
or Esc will make the program stop with report
...any other key will let the scrolling continue. The bottom part is used for
inputting commands, program lines, and INPUT data, and also for displaying
reports. The bottom part starts off as two lines (the upper one blank), but it
expands to accommodate whatever is typed in. When it reaches the current print
position in the top half, further expansions will make the top half scroll up.
Chapter 2
Chapter 2: Basic programming concepts
Summary
Programs
Line numbers
Editing programs using and
RUN, LIST
GO TO, CONTINUE, LET, INPUT, NEW, REM,
PRINT
STOP in INPUT data
Esc (BREAK on a real Spectrum)
Type in these two lines of a computer program to print out the sum of two
numbers:
20 PRINT a
10 LET a=10
Because these lines began with numbers, they were not obeyed immediately but
stored away, as program lines. You will also have noticed here that the line
numbers govern the order of the lines within the program: this is most important
when the program is run, but it is also reflected in the order of the lines in the
listing that you can see on the screen now.
15 LET b=15
and in it goes. It would have been impossible to insert this line between the first
two if they had been numbered 1 and 2 instead of 10 and 20 (line numbers must
be whole numbers between 1 and 9999), so that is why, when first typing in a
program, it is good practice to leave gaps between the line numbers. If you do
get stuck, though, BASin provides a line renumbering option on the Tools menu.
20 PRINT a+b
You could type out the replacement in full, but it is easier to move onto the
existing line and edit it in place. The quickest way to move to a line is the Go to
Line Number command on the Search menu.
Move to line 20, and keep pressing the key until the cursor moves to the end
of the line. Then type
+b (without Enter)
20 PRINT a+b
BASin has a safety feature that was not present on the original ZX Spectrum.
When you enter a new line with the same number as an existing line, the cursor
turns green and jumps to the line number to warn you. Pressing Enter a second
time will replace the old line with the new one. This behaviour can be turned off
in BASin's options.
Run the edited program using RUN and Enter and the sum will be displayed.
PRINT a, b
The variables are still there, even though the program has finished.
If you enter a line by mistake, say
12 LET b=8
it will go up into the program and you will realise your mistake. To delete this
unnecessary line, type
Lastly, type
LIST 15
15 LET b=15
20 PRINT a+b
Line 10 is not present in the listing, but it is still in your program - which you
can prove by scrolling through the program in the editor. The only effects of
LIST 15 are to produce a listing that starts at line 15, and to put the program
cursor at line 15. If you have a very long program, then LIST will probably be
a more useful way of moving the program cursor than and .
This illustrates another use of line numbers: they act as names for the program
lines so that you can refer to them, rather like the way in which variables have
names.
LIST on its own makes the listing start at the beginning of a program.
Another useful command is NEW. This erases any old programs and variables in
the computer. Now carefully type in this program, which changes Fahrenheit
temperatures to Centigrade.
10 REM temperature conversion
20 PRINT "deg F", "deg C"
30 PRINT
40 INPUT "Enter deg F", F
50 PRINT F,(F-32)*5/9
60 GO TO 40
Although GO TO has a space in it, it is really all one keyword. The space is
optional.
Now run it. You will see the headings printed on the screen by line 20, but what
happened to line 10? Apparently the computer has completely ignored it. Well, it
has. REM in line 10 stands for remark, or reminder, and is there solely to remind
you of what the program does. A REM command consists of REM followed by
anything you like, and the computer will ignore it right up to the end of the line.
By now, the computer has got to the INPUT command on line 40 and is waiting
for you to type in a value for the variable F - you can tell this because there is a
flashing cursor at the bottom of the display window. Enter a number; remember
Enter. Now the computer has displayed the result and is waiting for another
number. This is because of line 60, GO TO 40, which means exactly what it
says. Instead of running out of program and stopping, the computer jumps back
to line 40 and starts again. So, enter another temperature. After a few more of
these you might be wondering if the machine will ever get bored with this; it
won't. Next time it asks for another number, type STOP. The computer comes
back with a report H STOP in INPUT, 40:1, which tells you why it
stopped, and where (in the first command of line 40).
CONTINUE
Now type in numbers until the display starts getting full. When it is full, the
computer will move the whole of the top half of the display up one line to make
room, losing the heading off the top. This is called scrolling.
When you are tired of this, stop the program using STOP (or Esc) and return to
the listing in the editor.
Look at the PRINT statement on line 50. The punctuation in this - the comma
(,) - is very important, and you should remember that it follows much more
definite rules than the punctuation in English.
Commas are used to make the printing start either at the left hand margin, or in
the middle of the display, depending on which comes next. Thus in line 50, the
comma causes the centigrade temperature to be printed in the middle of the line.
With a semicolon, on the other hand, the next number or string is printed
immediately after the preceding one. You can see this in line 50, if the comma is
replaced by a semicolon.
Another punctuation mark you can use like this in PRINT commands is the
apostrophe ('). This makes whatever is printed next appear at the beginning of
the next line on the display but this happens anyway at the end of each PRINT
command, so you will not need the apostrophe very much. This is why the
PRINT command in line 50 always starts its printing on a new line, and it is
also why the PRINT command in line 30 produces a blank line.
If you want to inhibit this, so that after one PRINT command the next one
carries on on the same line, you can put a comma or semicolon at the end of the
first. To see how this works, replace line 50 in turn by each of
50 PRINT F,
50 PRINT F;
and
50 PRINT F
and run each version - for good measure you could also try
50 PRINT F'
The one with the comma spreads everything out in two columns, that with the
semicolon crams everything together, that without either allows a line for each
number and so does that with the apostrophe - the apostrophe gives a new line of
its own, but inhibits the automatic one.
RUN 100
Because this program inputs a string instead of a number, it prints out two string
quotes - this is a reminder to you, and it usually saves you some typing as well.
Try it once with any alias you care to make up for yourself.
Next time round, you will get two string quotes again. but you don't have to use
them if you don't want to. Try this, for example. Rub them out (with and
Backspace twice), and type
n$
Since there are no string quotes, the computer knows that it has to do some
calculation: the calculation in this case is to find the value of the string variable
called n$, which is whatever name you happen to have typed in last time round.
Of course, the INPUT statement acts like LET n$=n$, so the value of n$ is
unchanged.
n$
again, this time without rubbing out the string quotes. Now, just to confuse you,
the variable n$ has the value "n$".
If you want to use STOP for string input, you must first move the cursor back to
the beginning of the line, using .
Now look back at that RUN 100 we had earlier on. That just jumps to line 100,
so couldn't we have said GO TO 100 instead? In this case, it so happens that
the answer is yes; but there is a difference. RUN 100 first of all clears all the
variables and the display, and after that works just like GO TO 100. GO TO
100 doesn't clear anything. There may well be occasions where you want to run
a program without clearing any variables; here GO TO would be necessary and
RUN could be disastrous, so it is better not to get into the habit of automatically
typing RUN to run a program.
Another difference is that you can type RUN without a line number, and it starts
off at the first line in the program. GO TO must always have a line number.
Both these programs stopped because you typed STOP in the input line;
sometimes - by mistake - you write a program that you can't stop and won't stop
itself. Type
200 GO TO 200
RUN 200
This looks all set to go on for ever unless you pull the plug out; but there is a less
drastic remedy. Press Esc (equivalent to the Break key on a real Spectrum). The
program will stop, saying
At the end of every statement, the program looks to see if this key is pressed;
and if it is, then it stops. The Esc key can also be used when you are in the
middle of printing, or using various other bits of machinery that you can attach
to the computer - just in case the computer is waiting for them to do something
but they're not doing it.
CONTINUE in this case (and in fact in most other cases too) repeats the
statement where the program was stopped; but after the report L BREAK
into program, CONTINUE carries straight on with the next statement
after allowing for any jumps to be made.
Run the name program again and when it asks you for input type
CONTINUE
you will find that you can use n$ as input data without any trouble.
In this case CONTINUE does a jump to the INPUT command in line 110. It
disregards the report from the LET statement because that said 'OK', and jumps
to the command referred to in the previous report, the first command in line 110.
This is intended to be useful. If a program stops over some error then you can do
all sorts of things to fix it, and CONTINUE will still work afterwards.
Type
and when it asks scroll? (because it has filled up the display) press n for
'No'. The computer will give the report D BREAK - CONT repeats as
though you had typed Esc. You might at some stage find out what happens if you
press y instead of n; n, Space and Esc count as No, while everything else counts
as Yes.
Now type
23 REM
and the edit cursor jumps to a blank line just after the newly inserted line 23;
type
28 REM
and the edit cursor jumps to the new line 28. (In both cases, by typing a new line,
you have caused the editor to move to that line in the listing.)
LIST
CONTINUE
CONTINUE is a bit quirky here, because the bottom part of the display goes
blank; but you can restore normality with Esc. The reason is that LIST was the
first command in the line, so CONTINUE repeats this command. Unfortunately,
the first command in the line is now CONTINUE itself so the computer just sits
there doing CONTINUE over and over again until you stop it.
:
LIST
(bear in mind that BASin splits lines at the ":" character) for which CONTINUE
gives 0 OK (because CONTINUE jumps to the second command in the line,
which is taken to be its end) or
:
:
LIST
You have now seen the statements PRINT, LET, INPUT, RUN, LIST, GO
TO, CONTINUE, NEW and REM, and they can all be used either as direct
commands or in program lines - this is true of almost all commands in ZX
Spectrum BASIC. RUN, LIST, CONTINUE and NEW are not usually of much
use in a program, but they can be used.
Exercises
Chapter 3: Decisions
Summary
All the programs we have seen so far have been pretty predictable - they went
straight through the instructions, and then went back to the beginning again. This
is not very useful. In practice the computer would be expected to make decisions
and act accordingly. The instruction used has the form . . .
For example, use NEW to clear the previous program from the computer and type
in and run this program. (This is clearly meant for two people to play!)
IF condition THEN . . .
where the '. . .' stands for a sequence of commands, separated by colons in the
usual way. The condition is something that is going to be worked out as either
true or false: if it comes out as true then the statements in the rest of the line after
THEN are executed, but otherwise they are skipped over, and the program
executes the next instruction.
The simplest conditions compare two numbers or two strings: they can test
whether two numbers are equal or whether one is bigger than the other; and they
can test whether two strings are equal, or (roughly) one comes before the other
in alphabetical order. They use the relations =, <, >, <=, >= and <>.
1<2
-2 < -1
-3 < 1
1<0
0 < -2
are false.
Line 40 compares a and b. If they are equal then the program is halted by the
STOP command. The report 9 STOP statement, 30:3 shows that the
third statement, or command, in line 30 caused the program to halt, i.e. STOP.
Line 50 determines whether b is less than a, and line 60 whether b is greater than
a. If one of these conditions is true then the appropriate comment is printed, and
the program works its way to line 70 which tells the computer to go back to line
30 and start all over again.
The CLS, clear screen, command in line 20 was to stop the other person seeing
what you put in.
So > means 'is greater than', and is just like < but the other way round. You can
remember which is which, because the thin end points to the number that is
supposed to be smaller.
<= means 'is less than or equal to', so that it is like < except that it is true even if
the two numbers are equal: thus 2<=2 is true, but 2<2 is false.
>= means 'is greater than or equal to' and is similarly like >.
Mathematicians usually write <=, >= and <> as ≤, ≥ and ≠. They also write
things like '2<3<4' to mean '2<3 and 3<4', but this is not possible in BASIC.
Note: in some other versions of BASIC, the IF statement can have the form
Exercises
10 PRINT "x":
STOP:
PRINT "y"
When you run it, it will display x and stop with the report
Now type
CONTINUE
You might expect this to jump back to the STOP command - CONTINUE
usually repeats the statement referred to in the report. However, here this
would not be very useful, because the computer would just stop again
without displaying y. Therefore, things are arranged so that after report 9
CONTINUE jumps to the command after the STOP command - so in our
example, after CONTINUE, the computer prints y and reaches the end of
the program.
Chapter 2
Chapter 4
Chapter 4: Looping
Summary
Suppose you want to input five numbers and add them together. One way (don't
type this in unless you are feeling dutiful) is to write
10 LET total=0
20 INPUT a
30 LET total=total+a
40 INPUT a
50 LET total=total+a
60 INPUT a
70 LET total=total+a
80 INPUT a
90 LET total=total+a
100 INPUT a
110 LET total=total+a
120 PRINT total
This method is not good programming practice. It may be just about controllable
for five numbers, but you can imagine how tedious a program like this to add ten
numbers would be, and to add a hundred would be just impossible.
Much better is to set up a variable to count up to 5 and then stop the program,
like this (which you should type in):
10 LET total=0
20 LET count=1
30 INPUT a
40 REM count=number of times that a has
50 LET total=total+a
60 LET count=count+1
70 IF count<=5 THEN
GO TO 30
80 PRINT total
Notice how easy it would be to change line 70 so that this program adds ten
numbers, or even a hundred.
This sort of counting is so useful that there are two special commands to make it
easier: the FOR command and the NEXT command. They are always used
together. Using these, the program you have just typed in does exactly the same
as
10 LET total=0
20 FOR c=1 TO 5
30 INPUT a
40 REM c=number of times that a has been
50 LET total=total+a
60 NEXT c
80 PRINT total
(To get this program from the previous one, you just have to edit lines 20, 40, 60,
and 70.)
The effect of this program is that c runs through the values 1 (the initial value),
2, 3, 4 and 5 (the limit), and for each one, lines 30, 40 and 50 are executed.
Then, when c has finished its five values, line 80 is executed.
An extra subtlety to this is that the control variable does not have to go up by 1
each time: you can change this 1 to anything you like by using a STEP part in
the FOR command. The most general form for a FOR command is
where the control variable is a single letter, and the initial value, limit and step
are all things that the computer can calculate as numbers - like the actual
numbers themselves, or sums, or the names of numeric variables. So, if you
replace line 20 in the program by
then c will run through the values 1, 2.5 and 4. Notice that you don't have to
restrict yourself to whole numbers, and also that the control value does not have
to hit the limit exactly - it carries on looping as long as it is less than or equal to
the limit.
Try this program, to print out the numbers from 1 to 10 in reverse order.
You must be careful if you are running two FOR . . . NEXT loops together, one
inside the other. Try this program, which prints out the numbers for a complete
set of six spot dominoes.
10 FOR m=0 TO 6
20 FOR n=0 TO m
30 PRINT m;":";n;" ";
40 NEXT n
50 PRINT
60 NEXT m
You can see that the n-loop is entirely inside the m-loop - they are properly
nested. What must be avoided is having two FOR . . . NEXT loops that overlap
without either being entirely inside the other, like this:
Another thing to avoid is jumping into the middle of a FOR . . . NEXT loop from
the outside. The control variable is only set up properly when its FOR statement
is executed, and if you miss this out the NEXT statement will confuse the
computer. You will probably get an error report saying NEXT without
FOR or Variable not found.
There is nothing whatever to stop you using FOR and NEXT in a direct
command. For example, try:
You can sometimes use this as a (somewhat artificial) way of getting round the
restriction that you cannot GO TO anywhere inside a command - because a
command has no line number. For instance,
The step of zero here makes the command repeat itself forever.
This sort of thing is not really recommended, because if an error crops up then
you have lost the command and will have to type it in again - and CONTINUE
will not work.
Exercises
PRINT c
NEXT n
GO SUB, RETURN
Sometimes different parts of the program will have rather similar jobs to do, and
you will find yourself typing the same lines in two or more times; however this
is not necessary. You can type the lines in once, in a form known as a subroutine,
and then use, or call, them anywhere else in the program without having to type
them in again.
To do this, you use the statements GO SUB (GO to SUBroutine) and RETURN.
This takes the form
GO SUB n
where n is the line number of the first line in the subroutine. It is just like GO
TO n except that the computer remembers where the GO SUB statement was so
that it can come back again after doing the subroutine. It does this by putting the
line number and the statement number within the line (together these constitute
the return address) on top of a pile of them (the GO SUB stack).
RETURN
takes the top return address off the GO SUB stack, and goes to the statement
after it.
The GO TO statement in line 70 is very important because otherwise the program will run on
When this program is run, see if you can work out what is happening. The
subroutine starts at line 500.
A subroutine can happily call another, or even itself (a subroutine that calls itself
is recursive), so don't be afraid of having several layers.
Chapter 4
Chapter 6
Chapter 6
Summary
10 READ a,b,c
20 PRINT a,b,c
30 DATA 10,20,30
40 STOP
A READ statement consists of READ followed by a list of the names of
variables, separated by commas. It works rather like an INPUT statement,
except that instead of getting you to type in the values to give to the variables,
the computer looks up the values in the DATA statement.
20 PRINT b,c,a
10 FOR n=1 TO 6
20 READ D
30 DATA 2,4,6,8,10,12
40 PRINT D
50 NEXT n
60 STOP
When this program is RUN you can see the READ statement moving through the
DATA list. DATA statements can also contain string variables. For example:
10 READ d$
20 PRINT "The date is",d$
30 DATA "June 1st, 1982"
40 STOP
This is the simple way of fetching expressions from the DATA list: start at the
beginning and work through until you reach the end. However, you can make the
computer jump about in the DATA list, using the RESTORE statement. This has
RESTORE, followed by a line number, and makes subsequent READ statements
start getting their data from the first DATA statement at or after the given line
number. (You can miss out the line number, in which case it is as though you had
typed the line number of the first line in the program.)
10 READ a,b
20 PRINT a,b
30 RESTORE 10
40 READ x,y,z
50 PRINT x,y,z
60 DATA 1,2,3
70 STOP
In this program the data required by line 10 made a = 1 and b = 2. The
RESTORE 10 instruction reset the variables, and allowed x, y and z to be
READ starting from the first number in the DATA statement. Rerun this program
without line 30 and see what happens.
Chapter 5
Chapter 7
Chapter 7: Expressions
Summary
Operations: +, -, *, /
Expressions, scientific notation, variable names
You have already seen some of the ways in which BASin can calculate with
numbers. It can perform the four arithmetic operations +, -, * and / (remember
that * is used for multiplication, and / is used for division), and it can find the
value of a variable, given its name.
The example:
LET tax=sum*15/100
gives just a hint of the very important fact that these calculations can be
combined. Such a combination, like sum*15/100, is called an expression: so
an expression is just a short-hand way of telling the computer to do several
calculations, one after the other. In our example, the expression sum*15/100
means 'look up the value of the variable called "sum", multiply it by 15, and
divide by 100'.
Multiplications and divisions are done first. They have higher priority than
addition and subtraction. Relative to each other, multiplication and division have
the same priority, which means that the multiplications and divisions are done in
order from left to right. When they are dealt with, the additions and subtractions
come next - these again have the same priority as each other, so we do them in
order from left to right.
Although all you really need to know is whether one operation has a higher or
lower priority than another, the computer does this by having a number between
1 and 16 to represent the priority of each operation: * and / have priority 8, and
+ and - have priority 6.
This order of calculation is absolutely rigid, but you can circumvent it by using
brackets: anything in brackets is evaluated first and then treated as a single
number.
You can add together as many strings (or string variables) as you like in a single
expression, and if you want, you can even use brackets.
We really ought to tell you what you can and cannot use as the names of
variables. As we have already said, the name of a string variable has to be a
single letter followed by $; and the name of the control variable of a FOR . . .
NEXT loop must be a single letter; but the names of ordinary numeric variables
are much freer. They can use any letters or digits as long as the first one is a
letter. You can put spaces in as well to make it easier to read, but they won't
count as part of the name. Also, it doesn't make any difference to the name
whether you type it in capitals or lower case letters.
Here are some examples of the names of variables that are allowed:
t42
nOWWeaReSiX
(These last two names are considered the same, and refer to the same variable.)
These are not allowed to be the names of variables:
PRINT 2.34e0
PRINT 2.34e1
PRINT 2.34e2
and so on up to
PRINT 2.34e15
You will see that after a while the computer also starts using scientific notation.
This is because no more than fourteen characters can be used to write a number.
Similarly, try
PRINT 2.34e-1
PRINT 2.34e-2
and so on.
This proves that the computer can hold the digits of 4294967295, even though it
is not prepared to display them all at once.
BASin uses floating point arithmetic, which means that it keeps separate the
digits of a number (its mantissa) and the position of the point (the exponent. This
is not always exact, even for whole numbers. Type
PRINT 1e10+1-1e10,1e10-1e10+1
Numbers are held to about nine and a half digits' accuracy, so 1e10 is too big to
be held exactly right. The inaccuracy (actually about 2) is more than 1, so the
numbers 1e10 and 1e10+1 appear to the computer to be equal. For an even more
peculiar example, type
PRINT 5e9+1-5e9
Here the inaccuracy in 5e9 is only about 1, and the 1 to be added on in fact gets
rounded up to 2. The numbers 5e9+1 and 5e9+2 appear to the computer to be
equal.
The largest integer (whole number) that can be held completely accurately is 1
less than 32 2's multiplied together (or 4,294,967,295).
The string "" with no characters at all is called the empty or null string.
Remember that spaces are significant and an empty string is not the same as one
containing nothing but spaces.
Try:
When you press Enter, you will get the flashing red cursor that shows there is a
mistake somewhere in the line. When the computer finds the double quotes at
the beginning of "Finnegans Wake", it imagines that these mark the end
of the string "Have you finished", and it then can't work out what
'Finnegans Wake' means.
There is a special device to get over this: whenever you want to write a string
quote symbol in the middle of a string, you must write it twice, like this:
As you can see from what is printed on the screen, each double quote is only
really there once; you just have to type it twice to get it recognized.
Chapter 6
Chapter 8
Chapter 8: Strings
Summary
Slicing, using TO. Note that this notation is not standard BASIC.
There is a notation called slicing for describing substrings, and this can be
applied to arbitrary string expressions. The general form is
"abcdef"(2 TO 5)="bcde"
If you omit the start, then 1 is assumed; if you omit the finish then the length of
the string is assumed. Thus
(You can also write this last one as "abcdef"(), for what it's worth.)
A slightly different form misses out the TO and just has one number.
"abcdef"(3)="abcdef"(3 TO 3)="c"
Although normally both start and finish must refer to existing parts of the string,
this rule is overridden by another one: if the start is more than the finish, then the
result is the empty string. So
"abcdef"(5 TO 7)
"abcdef"(8 TO 7)=""
and
"abcdef"(1 TO 0)=""
The start and finish must not be negative, or you get error B Integer out
of range. This next program is a simple one illustrating some of these rules.
10 LET a$="abcdef"
20 FOR n=1 TO 6
30 PRINT a$(n TO 6)
40 NEXT n
50 STOP
Type NEW when this program has been run and enter the next program:
and then
and
PRINT a$
Notice how since the substring a$(5 TO 8) is only 4 characters long, only
the first four stars have been used. This is a characteristic of assigning to
substrings: the substring has to be exactly the same length afterwards as it was
before. To make sure this happens, the string that is being assigned to it is cut off
on the right if it is too long, or filled out with spaces if it is too short - this is
called Procrustean assignment after the inn-keeper Procrustes who used to make
sure that his guests fitted the bed by either stretching them out on a rack or
cutting their feet off.
and
PRINT a$;"."
you will see that the same thing has happened again (this time with spaces put
in) because a$() counts as a substring.
will do it properly.
Complicated string expressions will need brackets round them before they can
be sliced. For example,
"abc"+"def"(1 TO 2)="abcde"
("abc"+"def")(1 TO 2)="ab"
Exercise
Consider the sausage machine. You put a lump of meat in at one end, turn a
handle, and out comes a sausage at the other end. A lump of pork gives a pork
sausage, a lump of fish gives a fish sausage, and a lump of beef a beef sausage.
Just as you can have different machines to make different products - one for
sausages, another for dish cloths, and a third for fish-fingers and so on, different
functions will do different calculations. Each will have its own name to
distinguish it from the others.
You use a function in expressions by typing its name followed by the argument,
and when the expression is evaluated the result of the function will be worked
out.
As an example, there is a function called LEN, which works out the length of a
string. Its argument is the string whose length you want to find, and its result is
the length, so that if you type
If you mix functions and operations in a single expression, then the functions
will be worked out before the operations. Again, however, you can circumvent
this rule by using brackets. For instance, here are two expressions which differ
only in the brackets, and yet the calculations are performed in an entirely
different order in each case (although, as it happens, the end results are the
same).
STR$ converts numbers into strings: its argument is a number, and its result is
the string that would appear on the screen if the number were displayed by a
PRINT statement. Note how its name ends in a $ sign to show that its result is a
string. For example, you could say
LET a$="100"
VAL is like STR$ in reverse: it converts strings into numbers. For instance,
VAL "3.5"=3.5
In a sense, VAL is the reverse of STR$, because if you take any number, apply
STR$ to it, and then apply VAL to it, you get back to the number you first
thought of. However, if you take a string, apply VAL to it, and then apply STR$
to it, you do not always get back to your original string.
VAL is an extremely powerful function, because the string which is its argument
is not restricted to looking like a plain number - it can be any numeric
expression. Thus, for instance,
VAL "2*3"=6
or even,
VAL ("2"+"*3") = 6
There are two processes at work here. In the first, the argument of VAL is
evaluated as a string: the string expression "2"+"*3" is evaluated to give the
string "2*3". Then, the string has its double quotes stripped off, and what is
left is evaluated as a number: so 2*3 is evaluated to give the number 6.
This can get pretty confusing if you don't keep your wits about you; for instance,
(Remember that inside a string a string quote must be written twice. If you go
down into further depths of strings, then you find that string quotes need to be
quadrupled or even octupled.)
There is another function, rather similar to VAL, although probably less useful,
called VAL$. Its argument is still a string, but its result is also a string. To see
how this works, recall how VAL goes in two steps: first its argument is evaluated
as a string, then the string quotes stripped off this, and whatever is left is
evaluated as a number. With VAL$, the first step is the same, but after the string
quotes have been stripped off in the second step, whatever is left is evaluated as
another string. Thus
LET a$="99"
VAL a$
VAL "a$"
VAL """a$"""
VAL$ a$
VAL$ "a$"
VAL$ """a$"""
Some of these will work, and some of them won't; try to explain all the answers.
(Keep a cool head.)
SGN is the sign function (sometimes called signum). It is the first function you
have seen that has nothing to do with strings, because both its argument and its
result are numbers. The result is +1 if the argument is positive, 0 if the argument
is zero, and -1 if the argument is negative.
ABS is another function whose argument and result are both numbers. It
converts the argument into a positive number (which is the result) by forgetting
the sign, so that for instance
INT stands for 'integer part' - an integer is a whole number, possibly negative.
This function converts a fractional number into an integer by throwing away the
fractional part, so that for instance,
INT 3.9 = 3
INT -3.9 = -4
SQR calculates the square root of a number - the result that, when multiplied by
itself, gives the argument. For instance,
If you multiply any number (even a negative one) by itself, the answer is always
positive. This means that negative numbers do not have square roots, so if you
apply SQR to a negative argument you get an error report A Invalid
argument.
You can also define functions of your own. Possible names for these are FN
followed by a letter (if the result is a number) or FN followed by a letter
followed by $ (if the result is a string). These are much stricter about brackets:
the argument must be enclosed in brackets.
10 DEF FN s(x)=x*x:
REM the square of x
The x in brackets is a name by which you wish to refer to the argument of the
function. You can use any single letter you like for this (or, if the argument is a
string, a single letter followed by $).
After the = sign comes the actual definition of the function. This can be any
expression, and it can also refer to the argument using the name you've given it
(in this case, x) as though it were an ordinary variable.
When you have entered this line, you can invoke the function just like one of the
computer's own functions, by typing its name, FN s, followed by the argument.
Remember that when you have defined a function yourself, the argument must
be enclosed in brackets. Try it out a few times:
PRINT FN s(2)
PRINT FN s(3+4)
Once you have put the corresponding DEF FN statement into the program, you
can use your own functions in expressions just as freely as you can use the
computer's.
Note: in some dialects of BASIC you must even enclose the argument of one of
the computer's functions in brackets. This is not the case in ZX Spectrum
BASIC.
INT always rounds down. To round to the nearest integer, add .5 first - you
could write your own function to do this.
FN r(2.9) = 3 FN r(2.4) = 2
FN r(-2.9) = -3 FN r(-2.4) = -2
Compare these with the answers you get when you use INT instead of FN r.
Type in and run the following:
10 LET x=0:
LET y=0:
LET a=10
20 DEF FN p(x,y)=a+x
30 DEF FN q()=a+x*y
40 PRINT FN p(2,3),FN q()
First, a function is not restricted to just one argument: it can have more, or even
none at all - but you must still always keep the brackets.
Second, it doesn't matter whereabouts in the program you put the DEF FN
statements. After the computer has executed line 10, it simply skips over lines 20
and 30 to get to line 40. They do, however, have to be somewhere in the
program. They can't be in a command.
Third, x and y are both the names of variables in the program as a whole, and
the names of arguments for the function FN p. FN p temporarily forgets about
the variables called x and y, but since it has no argument called a, it still
remembers the variable a. Thus when FN p(2,3) is being evaluated, a has
the value 10 because it is the variable, x has the value 2 because it is the first
argument, and y has the value 3 because it is the second argument. The result is
then, 10+2*3=16. When FN q() is beinq evaluated, on the other hand.
there are no arguments, so a, x and y all still refer to the variables and have
values 10, 0 and 0 respectively. The answer in this case is 10+0*0=10.
This time, FN p(2,3) will have the value 10 because FN q will still go
back to the variables x and y rather than using the arguments of FN p.
Some BASICs (not the ZX Spectrum BASIC) have functions called LEFT$,
RIGHT$, MID$ and TL$.
10 DEF FN t$(a$)=a$(2 TO ):
REM TL$
20 DEF FN l$(a$, n)=a$( TO n):
REM LEFT$
Check that these work with strings of length 0 or 1.
Note that our FN l$ has two arguments, one a number and the other a string. A
function can have up to 26 numeric arguments (why 26?) and at the same time
up to 26 string arguments.
Exercise
FN s(x)=x*x
to test SQR: you should find that
FN s(SQR x)=x
This chapter deals with the mathematics that BASin can handle. Quite possibly
you will never have to use any of this at all, so if you find it too heavy going,
don't be afraid of skipping it. It covers the operation ↑ (raising to a power), the
functions EXP and LN, and the trigonometrical functions SIN, COS, TAN and
their inverses ASN, ACS, and ATN.
↑ and EXP
You can raise one number to the power of another - that means 'multiply the first
number by itself the second number of times'. This is normally shown by writing
the second number just above and to the right of the first number; but obviously
this would be difficult on a computer so we use the symbol ↑ instead. For
example, the powers of 2 are
2↑1=2
2↑2=2*2=4 (2 squared)
2↑3=2*2*2=8 (2 cubed)
Thus at its most elementary level, 'a↑b' means 'a multiplied by itself b times', but
obviously this only makes sense if b is a positive whole number. To find a
definition that works for other values of b, we consider the rule
a^(b+c) = a^b*a^c
(Notice that we give ↑ a higher priority than * and / so that when there are
several operations in one expression, the ↑s are evaluated before the *s and /s.)
You should not need much convincing that this works when b and c are both
positive whole numbers; but if we decide that we want it to work even when
they are not, then we find ourselves compelled to accept that
a^0 = 1
a^(-b) = 1/a^b
...which is to say, the number that you have to multiply by itself b times to get a
and finally...
a^(b*c) = (a^b)^c
If you have never seen any of this before then don't try to remember it straight
away; just remember that
a^(-1) = 1/a
and
a^(1/2) = SQR a
and maybe when you are familiar with these the rest will begin to make sense.
10 INPUT a,b,c
20 PRINT a^(b+c),a^b*a^c
30 GO TO 10
Of course, if the rule we gave earlier is true, then each time round the two
numbers that the computer prints out will be equal. (Note - because of the way
the computer works out ↑, the number on the left - a in this case - must never be
negative.)
A rather typical example of what this function can be used for is that of
compound interest. Suppose you keep some of your money in a building society
and they give 15% interest per year. Then after one year you will have not just
the 100% that you had anyway, but also the 15% interest that the building
society have given you, making altogether 115% of what you had originally. To
put it another way, you have multiplied your sum of money by 1.15, and this is
true however much you had there in the first place. After another year, the same
will have happened again, so that you will then have
1.15*1.15=1.15↑2=1.3225 times your original sum of money. In
general, after y years, you will have 1.15↑y times what you started out with.
you will see that even starting off from just £10, it all mounts up quite quickly,
and what is more, it gets faster and faster as time goes on. (Although even so,
you might still find that it doesn't keep up with inflation.)
This sort of behaviour, where after a fixed interval of time some quantity
multiplies itself by a fixed proportion, is called exponential growth, and it is
calculated by raising a fixed number to the power of the time.
10 DEF FN a(x)=a^x
Here, a is more or less fixed, by LET statements: its value will correspond to the
interest rate, which changes only every so often.
There is a certain value for a that makes the function FN a look especially
pretty to the trained eye of a mathematician: and this value is called e. BASin
has a function called EXP defined by
EXP x=e^x
Unfortunately, e itself is not an especially pretty number: it is an infinite non-
recurring decimal. You can see its first few decimal places by doing
PRINT EXP 1
LN
You may well already know how to use base 10 logarithms for doing
multiplications; these are called common logarithms. BASin has a function LN
which calculates logarithms to the base e; these are called natural logarithms. To
calculate logarithms to any other base, you must divide the natural logarithm by
the natural logarithm of the base:
loga x = LN x / LN a
PI
Given any circle, you can find its perimeter (the distance round its edge; often
called its circumference) by multiplying its diameter (width) by a number called
π. π is a Greek p, and it is used because it stands for perimeter. Its name is pi.)
The word PI on the Spectrum is taken as standing for this number - try
PRINT PI
SIN, COS and TAN; ASN, ACS and ATN
The trigonometrical functions measure what happens when a point moves round
a circle. Here is a circle of radius 1 (1 what? It doesn't matter, as long as we keep
to the same unit all the way through. There is nothing to stop you inventing a
new unit of your own for every circle that you happen to be interested in) and a
point moving round it. The point started at the 3 o'clock position, and then
moved round in an anti-clockwise direction.
We have also drawn in two lines called axes through the centre of the circle. The
one through 9 o'clock and 3 o'clock is called the x-axis, and the one through 6
o'clock and 12 o'clock is called the y-axis.
To specify where the point is, you say how far it has moved round the circle
from its 3 o'clock starting position: let us call this distance a. We know that the
circumference of the circle is 2π (because its radius is 1 and its diameter is thus
2): so when it has moved a quarter of the way round the circle, a = π/2; when it
has moved halfway round, a = π; and when it has moved the whole way round, a
= 2π.
Given the curved distance round the edge, a, two other distances you might like
to know are how far the point is to the right of the y-axis, and how far it is above
the x-axis. These are called, respectively, the cosine and sine of a. The functions
COS and SIN on the computer will calculate these.
Note that if the point goes to the left of the y-axis, then the cosine becomes
negative; and if the point goes below the x-axis, the sine becomes negative.
Another property is that once a has got up to 2π, the point is back where it
started and the sine and cosine start taking the same values all over again:
Sometimes we need to work these functions out in reverse, finding the value of a
that has given sine, cosine or tangent. The functions to do this are called arcsine
(ASN on the computer), arccosine (ACS) and arctangent (ATN).
In the diagram of the point moving round the circle, look at the radius joining the
centre to the point. You should be able to see that the distance we have called a,
the distance that the point has moved round the edge of the circle, is a way of
measuring the angle through which the radius has moved away from the x-axis.
When a = π/2, the angle is 90 degrees; when a = π the angle is 180 degrees; and
so round to when a = 2π, and the angle is 360 degrees. You might just as well
forget about degrees, and measure the angle in terms of a alone: we say then that
we are measuring the angle in radians. Thus π/2 radians = 90 degrees and so on.
You must always remember that SIN, COS and so on use radians and not
degrees. To convert degrees to radians, divide by 180 and multiply by π; to
convert back from radians to degrees, you divide by π and multiply by 180.
Chapter 9
Chapter 11
Chapter 11: Random numbers
Summary
RANDOMIZE, RND
This chapter deals with the function RND and the keyword RANDOMIZE. They
are both used in connection with random numbers, so you must be careful not to
get them mixed up. On the original Spectrum keyboard, RANDOMIZE was
abbreviated to RAND.
In some ways RND is like a function: it does calculations and produces a result.
It is unusual in that it does not need an argument.
Each time you use it, its result is a new random number between 0 and 1.
(Sometimes it can take the value 0, but never 1.)
Try
10 PRINT RND
20 GO TO 10
to see how the answer varies. Can you detect any pattern? You shouldn't be able
to; 'random' means that there is no pattern.
Actually, RND is not truly random, because it follows a fixed sequence of 65536
numbers. However, these are so thoroughly jumbled up that there are at least no
obvious patterns and we say that RND is pseudo-random.
RND gives a random number between 0 and 1, but you can easily get random
numbers in other ranges. For instance, 5*RND is between 0 and 5, and
1.3+0.7*RND is between 1.3 and 2. To get whole numbers, use INT
(remembering that INT always rounds down) as in 1+INT (RND*6), which
we shall use in a program to simulate dice. RND*6 is in the range 0 to 6, but
since it never actually reaches 6, INT (RND*6) is 0, 1, 2, 3 ,4 or 5.
The RANDOMIZE statement is used to make RND start off at a definite place in
its sequence of numbers, as you can see with this program:
10 RANDOMIZE 1
20 FOR n=1 TO 5:
PRINT RND ,:
NEXT n
30 PRINT:
GO TO 10
After each execution of RANDOMIZE 1, the RND sequence starts off again
with 0.0022735596. You can use other numbers between 1 and 65535 in the
RANDOMIZE statement to start the RND sequence off at different places.
If you had a program with RND in it and it also had some mistakes that you had
not found, then it would help to use RANDOMIZE like this so that the program
behaved the same way each time you ran it.
10 RANDOMIZE
20 PRINT RND:
GO TO 10
The sequence you get here is not very random, because RANDOMIZE uses the
time since the computer was switched on. Since this has gone up by the same
amount each time RANDOMIZE is executed, the next RND does more or less
the same. You would get better randomness by replacing GO TO 10 by GO
TO 20.
Note: Most dialects of BASIC use RND and RANDOMIZE to produce random
numbers, but not all use them in the same way.
Here is a program to toss coins and count the numbers of heads and tails.
10 LET heads=0:
LET tails=0
20 LET coin=INT (RND*2)
30 IF coin=3 THEN
LET heads=heads+1
40 IF coin=1 THEN
LET tails=tails+1
50 PRINT heads;",";tails,
60 IF tails<>6 THEN
PRINT heads/tails;
70 PRINT:
GO TO 20
The ratio of heads to tails should become approximately 1 if you go on long
enough, because in the long run you expect approximately equal numbers of
heads and tails.
Exercises
(75*(your number+1)-1)/65536
Arrays (the way the Spectrum handles string arrays is slightly non-standard).
DIM . . .
Suppose you have a list of numbers, for instance the marks of ten people in a
class. To store them in the computer you could set up a single variable for each
person. but you would find them very awkward. You might decide to call the
variables Bloggs 1, Bloggs 2, and so on up to Bloggs 10, but the
program to set up these ten numbers would be rather long and boring to type in.
However, there is a mechanism by which you can apply this idea, and it uses
arrays. An array is a set of variables, its elements, all with the same name, and
distinguished only by a number (the subscript) written in brackets after the
name. In our example the name could be b (like control variables of FOR . . .
NEXT loops, the name of an array must be a single letter), and the ten variables
would then be b(1), b(2), and so on up to b(10).
DIM b(10)
The subscript can be an arbitrary numerical expression, so now you can write
10 FOR n=1 TO 10
20 READ b(n)
30 NEXT n
40 DATA 10,2,5,19,16,3,11,1,0,6
You can also set up arrays with more than one dimension. In a two dimensional
array you need two numbers to specify one of the elements - rather like the line
and column numbers to specify a character position on the television screen - so
it has the form of a table. Alternatively, if you imagine the line and column
numbers (two dimensions) as referring to a printed page, you could have an extra
dimension for the page numbers. Of course, we are talking about numeric arrays;
so the elements would not be printed characters as in a book, but numbers. Think
of the elements of a three-dimensional array v as being specified by v (page
number, line number, column number).
DIM c(3,6)
Although you can have a number and an array with the same name, you cannot
have two arrays with the same name, even if they have different numbers of
dimensions.
There are also string arrays. The strings in an array differ from simple strings in
that they are of fixed length and assignment to them is always Procrustean -
chopped off or padded with spaces. Another way of thinking of them is as arrays
(with one extra dimension) of single characters. The name of a string array is a
single letter followed by $, and a string array and a simple string variable cannot
have the same name (unlike the case for numbers).
Suppose then, that you want an array a$ of five strings. You must decide how
long these strings are to be - let us suppose that 10 characters each is long
enough. You then say
This sets up a 5*10 array of characters, but you can also think of each row as
being a string:
LET a$(2)="1234567890"
and
PRINT a$(2),a$(2,7)
For the last subscript (the one you can miss out), you can also have a slicer, so
that for instance
Remember:
In a string array, all the strings have the same, fixed length. The DIM statement
has an extra number (the last one) to specify this length. When you write down a
subscripted variable for a string array, you can put in an extra number, or a slicer,
to correspond with the extra number in the DIM statement. You can have string
arrays with no dimensions. Type
DIM a$(10)
and you will find that a$ behaves just like a string variable, except that it always
has length 10, and assignment to it is always Procrustean.
Exercises
IF condition THEN . . .
The conditions there were the relations (=, <, >, <=, >= and <>), which
compare two numbers or two strings. You can also combine several of these,
using the logical operations, AND, OR and NOT.
One relation AND another relation is true whenever both relations are true, so
you could have a line like:
in which x only gets printed if a$="yes" and x>0. The BASIC here is so
close to English that it hardly seems worth spelling out the details. As in English,
you can join lots of relations together with AND, and then the whole lot is true if
all the individual relations are.
One relation OR another is true whenever at least one of the two relations is true.
(Remember that it is still true if both the relations are true; this is something that
English doesn't always imply.)
The NOT relationship turns things upside down. The NOT relation is true
whenever the relation is false, and false whenever it is true!
Logical expressions can be made with relations and AND, OR and NOT, just as
numerical expressions can be made with numbers and +, - and so on; you can
even put them in brackets if necessary. They have priorities in the same way as
the usual operations +, -, *, / and ↑ do: OR has the lowest priority, then AND,
then NOT, then the relations, and the usual operations.
NOT is really a function, with an argument and a result, but its priority is much
lower than that of other functions. Therefore its argument does not need brackets
unless it contains AND or OR (or both). NOT a=b means the same as NOT
(a=b) (and the same as a<>b, of course).
<> is the negation of = in the sense that it is true if, and only if, = is false. In
other words,
Persuade yourself that >= and <= are the negations of < and > respectively:
thus you can always get rid of NOT from in front of a relation by changing the
relation.
Also,
and
Using this you can work NOTs through brackets until eventually they are all
applied to relations, and then you can get rid of them. Logically speaking, NOT
is unnecessary, although you might still find that using it makes a program
clearer.
The following section is quite complicated, and can be skipped by the faint-
hearted!
Try
which you might expect to give a syntax error. In fact, as far as the computer is
concerned, there is no such thing as a logical value: instead it uses ordinary
numbers, subject to a few rules.
1. =, <, >, <=, >= and <> all give numeric results: 1 for true, and 0 for false.
Thus the PRINT command above printed 0 for '1=2', which is false, and 1
for '1<>2', which is true.
2. In
IF condition THEN . . .
the condition can be actually any numeric expression. If its value is 0, then
it counts as false, and any other value (including the value of 1 that a true
relation gives) counts as true. Thus the IF statement means exactly the
same as
IF condition <> 0 THEN . . .
3. AND, OR and NOT are also number-valued operations.
x AND y has the value x if y is true (non-zero), or 0 (false) if y is false
(zero).
x OR y has the value 1 (true), if y is true (non-zero), or x, if y is false
(zero).
NOT x has the value 0 (false), if x is true (non-zero), or 1 (true), if x is
false (zero).
4. (Notice that 'true' means 'non-zero' when we're checking a given value, but
it means '1' when we're producing a new one.)
Read through the chapter again in the light of this revelation, making sure that it
all works.
10 INPUT a
20 INPUT b
30 PRINT (a AND a>=b)+(b AND a<b)
40 GO TO 10
Each time it prints the larger of the two numbers a and b. Convince yourself that
you can think of x AND y as meaning x if y (else the result is 0) and of x
OR y as meaning x unless y (in which case the result is 1).
Notice how AND tends to go with addition (because its default value is 0), and
OR tends to go with multiplication (because its default value is 1).
You can also make string valued conditional expressions, but only using AND.
Try this program, which inputs two strings and puts them in alphabetical order.
Exercise
1. BASIC can sometimes work along different lines from English. Consider,
for instance, the English clause 'If a doesn't equal b or c'. How would you
write this in BASIC? The answer is not IF a<>b OR c nor is it IF
a<>b OR a<>c.
Chapter 12
Chapter 14
Chapter 14: The character set
Summary
The letters, digits, punctuation marks and so on that can appear in strings are
called characters, and they make up the alphabet, or character set, that BASin
uses. Most of these characters are single symbols, but there are some more,
called tokens, that represent whole words, such as PRINT, STOP, <> and so
on.
There are 256 characters, and each one has a code between 0 and 255. There is a
complete list of them in Appendix A. To convert between codes and characters,
there are two functions, CODE and CHR$.
CODE is applied to a string, and gives the code of the first character in the string
(or 0 if the string is empty).
CHR$ is applied to a number, and gives the single character string whose code is
that number.
At the top you can see a space, 15 symbols and punctuation marks, the ten digits,
seven more symbols, the capital letters, six more symbols, the lower case letters
and five more symbols. These are all (except £ and ©) taken from a widely-used
set of characters known as ASCII (standing for American Standard Codes for
Information Interchange); ASCII also assigns numeric codes to these characters,
and these are the codes that BASin uses.
The rest of the characters are not part of ASCII, and are peculiar to the ZX
Spectrum. First amongst them are a space and 15 patterns of black and white
blobs. These are called the graphics symbols and can be used for drawing
pictures. You can enter these from the keyboard, using what is called graphics
mode. If you press the graphics mode key (Num Lock, Scroll Lock, or Alt Gr -
depending on your settings) then the keys for the digits 1 to 8 will start giving
the graphics symbols: on their own they give the symbols drawn on the keys;
and with either shift pressed they give the same symbol but inverted, i.e. black
becomes white, and vice versa.
After the graphics symbols, you will see what appears to be another copy of the
alphabet from A to U. These are characters that you can redefine yourself,
although when the machine is first switched on they are set as letters - they are
called user-defined graphics. You can type these in from the keyboard by going
into graphics mode, and then using the letter keys from A to U.
BASin provides a Graphic Editor that allows you to redefine characters visually.
If, however, you want to define a new character in code, follow this recipe - it
defines a character to show pi.
1. Work out what the character looks like. Each
character has an 8×8 square of dots, each of which
can show either the paper colour or the ink colour (see
the introductory booklet). You'd draw a diagram
something like this, with black squares for the ink
colour:
BIN 00000000
BIN 00000000
BIN 00000010
BIN 00111100
BIN 01010100
BIN 00010100
BIN 00010100
BIN 00000000
(If you know about binary numbers, then it should help you to know that BIN is
used to write a number in binary instead of the usual decimal.)
These eight numbers are stored in memory, in eight places, each of which has an
address. The address of the first byte, or group of eight digits, is USR "P" (P
because that is what we chose in (ii)), that of the second is USR "P"+1, and
so on up to the eighth, which has address USR "P"+7.
USR here is a function to convert a string argument into the address of the first
byte in memory for the corresponding user-defined graphic. The string argument
must be a single character which can be either the user-defined graphic itself or
the corresponding letter (in upper or lower case). There is another use for USR,
when its argument is a number, which will be dealt with in Chapter 26.
Even if you don't understand this, the following program will do it for you:
10 FOR n=0 TO 7
20 INPUT row:
POKE USR "P"+n,row
30 NEXT n
It will stop for INPUT data eight times to allow you to type in the eight BIN
numbers above - type them in the right order, starting with the top row.
You will have noticed that we have not printed out the first 32 characters, with
codes 0 to 31. These are control characters. They don't produce anything
printable, but have some less tangible effect on the display, or they are used for
controlling something other than the display and the computer prints ? to show
that it doesn't understand them. They are described more fully in Appendix A.
Three that the display uses are those with codes 6, 8 and 13; on the whole,
CHR$ 8 is the only one you are likely to find useful.
CHR$ 6 prints spaces in exactly the same way as a comma does in a PRINT
statement; for instance
PRINT 1; CHR$ 6;2
PRINT 1,2
Obviously this is not a very clear way of using it. A more subtle way is to say
CHR$ 8 is 'backspace': it moves the print position back one place - try
The display also uses those with codes 16 to 23; these are explained in Chapters
15 and 16. All the control characters are listed in Appendix A.
Using the codes for the characters we can extend the concept of 'alphabetical
ordering' to cover strings containing any characters, not just letters. If instead of
thinking in terms of the usual alphabet of 26 letters we use the extended alphabet
of 256 characters, in the same order as their codes, then the principle is exactly
the same. For instance, these strings are in their Spectrum alphabetical order.
(Notice the rather odd feature that lower case letters come after all the capitals:
so "a" comes after "Z"; also, spaces matter.)
The relations =, <, >, <=, >= and <> are used for strings as well as for
numbers: < means 'comes before' and > means 'comes after', so that
"AA man"<"AARDVARK"
"AARDVARK">"AA man"
are both true.
<= and >= work the same way as they do for numbers, so that
is true, but
is false.
Experiment on all this using the program here, which inputs two strings and puts
them in order.
Note how we have to introduce c$ in line 20 when we swap over a$ and b$.
LET a$=b$:
LET b$=a$
This program sets up user-defined graphics to show chess pieces: P for pawn, R
for rook, N for knight, B for bishop, K for king, and Q for queen.
5 LET b=BIN 01111100:
LET c=BIN 00111000:
LET d=BIN 00010000
10 FOR n=1 TO 6:
READ p$:
REM 6 pieces
20 FOR f=0 TO 7:
REM read piece into 8 bytes
30 READ a:
POKE USR p$+f,a
40 NEXT f
50 NEXT n
100 REM bishop
110 DATA "b",0,d, BIN 00101000,BIN 01000
120 DATA BIN 01101100,c,b,0
130 REM king
140 DATA "k",0,d,c,d
150 DATA c, BIN 01000100,c,0
160 REM rook
170 DATA "r",0, BIN 01010100,b,c
180 DATA c,b,b,0
190 REM queen
200 DATA "q",0, BIN 01010100, BIN 001010
210 DATA BIN 01101100,b,b,0
220 REM pawn
230 DATA "p",0,0,d,c
240 DATA c,d,b,0
250 REM knight
260 DATA "n",0,d,c, BIN 01111000
270 DATA BIN 00011000,c,b,0
Note that 0 can be used instead of BIN 00000000.
When you have run the program, look at the pieces by going into graphics mode.
Exercises
10 INPUT a
20 PRINT CHR$ a;
30 GO TO 10
If you experiment with it, you'll find that CHR$ a is
rounded to the nearest whole number; and if a is not
in the range 0 to 255 then the program stops with
error report:
"EVIL"
"evil"
Chapter 13
Chapter 15
Chapter 15: More about PRINT and INPUT
Summary
You have already seen PRINT used quite a lot, so you will have a rough idea of
how it is used. Expressions whose values are printed are called PRINT items,
and they are separated by commas or semicolons, which are called PRINT
separators. A PRINT item can also be nothing at all, which is a way of
explaining what happens when you use two commas in a row.
There are two more kinds of PRINT items, which are used to tell the computer
not what, but where to print. For example PRINT AT 11,16;"*" prints a
star in the middle of the screen.
AT line,column
moves the PRINT position (the place where the next item is to be printed) to the
line and column specified. Lines are numbered from 0 (at the top) to 21, and
columns from 0 (on the left) to 31.
SCREEN$ is the reverse function to PRINT AT, and will tell you (within
limits) what character is at a particular position on the screen. It uses line and
column numbers in the same way as PRINT AT, but enclosed in brackets: for
instance
Characters taken from tokens print normally, as single characters, and spaces
return as spaces. Lines drawn by PLOT, DRAW or CIRCLE, user-defined
characters and graphics characters return as a null (empty) string, however. The
same applies if OVER has been used to create a composite character.
TAB column
prints enough spaces to move the PRINT position to the column specified. It
stays on the same line, or, if this would involve backspacing, moves on to the
next one. Note that the computer reduces the column number 'modulo 32' (it
divides by 32 and takes the remainder); so TAB 33 means the same as TAB
1.
As an example,
is how you might print out the heading of a contents page on page 1 of a book.
10 FOR n=8 TO 23
20 PRINT TAB 8*n;n;
30 NEXT n
This shows what is meant by the TAB numbers being reduced modulo 32. For a
more elegant example, change the 8 in line 20 to a 6.
When the printing reaches the bottom of the screen, it starts to scroll upwards
rather like a typewriter. You can see this if you do
CLS:
FOR n=1 TO 30:
PRINT n:
NEXT n
and then do
PRINT 99
a few times.
If the computer is printing out reams and reams of stuff, then it takes great care
to make sure that nothing is scrolled off the top of the screen until you have had
a chance to look at it properly. You can see this happening if you type
CLS:
FOR n=1 TO 100:
PRINT n:
NEXT n
When it has printed a screen full, it will stop, writing scroll? at the bottom
of the screen. You can now inspect the first 22 numbers at your leisure. When
you have finished with them, press y (for 'yes') and the computer will give you
another screen full of numbers. Actually, any key will make the computer carry
on except N (for 'no'), Space or Esc. These will make the computer stop running
the program with a report D BREAK - CONT repeats.
The INPUT statement can do much more than we have told you so far. You
have already seen INPUT statements like
in which the computer prints the caption How old are you? at the bottom
of the screen, and then you have to type in your age.
First, an obvious extra INPUT item is the variable whose value you are to type
in age in our example above. The rule is that if an INPUT item begins with a
letter, it must be a variable whose value is to be input.
Second, this would seem to mean that you can't print out the values of variables
as part of a caption; however, you can get round this by putting brackets round
the variable. Any expression that starts with a letter must be enclosed in brackets
if it is to be printed as part of a caption.
Any kind of PRINT item that is not affected by these rules is also an INPUT
item. Here is an example to illustrate what's going on:
LET my age = INT (RND * 100):
INPUT ("I am ";my age;".");"How old are you?", your age
my age is contained in brackets, so its value gets printed out. your age is
not contained in brackets, so you have to type its value in.
Everything that an INPUT statement writes goes to the bottom part of the
screen, which acts somewhat independently of the top half. In particular, its lines
are numbered relative to the top line of the bottom half, even if this has moved
up the actual television screen (which it does if you type lots and lots of INPUT
data).
(just press Enter each time it stops.) When This is line 2. is printed,
the lower part of the screen moves up to make room for it; but the numbering
moves up as well, so that the lines of text keep their same numbers.
INPUT LINE a$
then the computer will not give you the string quotes that it normally does for a
string variable, although it will pretend to itself that they are there. So if you type
in
cat
as the INPUT data, a$ will be given the value cat. Because the string quotes
do not appear on the string, you cannot delete them and type in a different sort of
string expression for the INPUT data. Remember that you cannot use LINE for
numeric variables.
The control characters CHR$ 22 and CHR$ 23 have effects rather like AT
and TAB. They are rather odd as control characters, because whenever one is
sent to the television to be printed, it must be followed by two more characters
that do not have their usual effect: they are treated as numbers (their codes) to
specify the line and column (for AT) or the tab position (for TAB). You will
almost always find it easier to use AT and TAB in the usual way rather than the
control characters, but they might be useful in some circumstances. The AT
control character is CHR$ 22. The first character after it specifies the line
number and the second the column number, sothat
PRINT AT 1,c;
You can use POKE to stop the computer asking you scroll? by doing
POKE 23692,255
every so often. After this it will scroll up 255 times before stopping with
scroll?. As an example, try
Exercises
10 FOR m=4 TO 1:
BRIGHT m
20 FOR n=1 TO 14
30 FOR c=4 TO 7
40 PAPER c:
PRINT " ";:
REM 4 coloured spaces
50 NEXT c:
NEXT n:
NEXT m
60 FOR m=0 TO 1:
BRIGHT m:
PAPER 7
70 FOR c=0 TO 3
80 INK c:
PRINT c;" ";
90 NEXT c:
PAPER 0
100 FOR c=4 TO 7
110 INK c:
PRINT c;" ";
120 NEXT c:
NEXT m
130 PAPER 7:
INK 0:
BRIGHT 0
This shows the eight colours (including white and black) and the two levels of
brightness that BASin can produce. Here is a list of them for reference.
0 - black
1 - blue
2 - red
3 - purple, or magenta
4 - green
6 - yellow
7 - white
On a black and white television, these numbers are in order of brightness.
To use these colours properly, you need to understand a bit about how the picture
is arranged.
The picture is divided up into 768 (24 lines of 32) positions where characters can
be printed, and each character is printed as an 8×8 square of dots like that below
for a. This should remind you of the user-defined graphics in Chapter 14, where
we had 0s for the white dots and 1s for the black dots.
The character position also has associated with it two colours: the ink, or
foreground colour, which is the colour for the black dots in our square, and the
paper, or background colour, which is used for the white dots. To start off with,
every position has black ink and white paper so writing appears as black on
white.
The character position also has a brightness (normal or extra bright) and
something to say whether it flashes or not - flashing is done by swapping the ink
and paper colours. This can all be coded into numbers, so a character position
then has
When you print something on the screen, you change the dot pattern at that
position; it is less obvious, but still true, that you also change the attributes at
that position. To start off with you do not notice this because everything is
printed with black ink on white paper (and normal brightness and no flashing),
but you can vary this with the INK, PAPER, BRIGHT and FLASH statements.
Try
PAPER 5
and then print a few things: they will all appear on cyan paper, because as they
are printed the paper colours at the positions they occupy are set to cyan (which
has code 5).
any printing will set the corresponding attribute at all the character positions it
uses. Try some of these out. You should now be able to see how the program at
the beginning worked (remember that a space is a character that has INK and
PAPER the same colour).
There are some more numbers you can use in these statements that have less
direct effects.
8 can be used in all four statements, and means 'transparent' in the sense that the
old attribute shows through. Suppose, for instance, that you do
PAPER 8
No character position will ever have its paper colour set to 8 because there is no
such colour; what happens is that when a position is printed on, its paper colour
is left the same as it was before. INK 8, BRIGHT 8 and FLASH 8 work the
same way for the other attributes.
9 can be used only with PAPER and INK, and means 'contrast'. The colour (ink
or paper) that you use it with is made to contrast with the other by being made
white if the other is a dark colour (black, blue, red or magenta), and black if the
other is a light colour (green, cyan, yellow or white).
INK 9:
FOR c=0 TO 7:
PAPER c:
PRINT c:
NEXT c
A more impressive display of its power is to run the program at the beginning to
make coloured stripes, and then doing
INK 9:
PAPER 8:
PRINT AT 0,8;:
FOR n=1 TO 1080:
PRINT n;:
NEXT n
The ink colour here is always made to contrast with the old paper colour at each
position.
Colour television relies on the rather curious fact that the human eye can only
really see three colours - the primary colours, blue, red and green. The other
colours are mixtures of these. For instance, magenta is made by mixing blue
with red - which is why its code, 3, is the sum of the codes for blue and red.
To see how all eight colours fit together, imagine three rectangular spotlights,
coloured blue, red and green, shining at not quite the same place on a piece of
white paper in the dark. Where they overlap you will see mixtures of colours, as
shown by this program (note that ink spaces are obtained by using either Shift
with 8 when in graphics mode):
10 BORDER 0:
PAPER 0:
INK 7:
CLS
20 FOR a=1 TO 6
30 PRINT TAB 6; INK 1; "nnnnnnnnnnnnnn
REM 18 ink squares
40 NEXT a
50 LET dataline=20
60 GO SUB 1000
70 LET dataline=210
80 GO SUB 1000
90 STOP
200 DATA 2,3,7,5,4
210 DATA 2,2,6,4,4
1000 FOR a=1 TO 6
1010 RESTORE dataline
1020 FOR b=1 TO 5
1030 READ c:
PRINT INK c;"nnnnnn";:
REM 6 ink squares
1040 NEXT b:
PRINT:
NEXT a
1050 RETURN
There is a function called ATTR that finds out what the attributes are at a given
position on the screen. It is a fairly complicated function, so it has been relegated
to the end of this chapter.
There are two more statements, INVERSE and OVER, which control not the
attributes, but the dot pattern that is printed on the screen. They use the numbers
0 for off and 1 for on in the same way as FLASH and BRIGHT do, but those
are the only possibilities. If you do INVERSE 1, then the dot patterns printed
will be the inverse of their usual form: paper dots will be replaced by ink dots
and vice versa. Thus a would be printed as
If (as at switch-on) we have black ink and white paper, then this a will appear as
white on black - but we still have black ink and white paper at that character
position. It is the dots that have changed.
The statement
OVER 1
10 OVER 1
20 FOR n=1 TO 32
30 PRINT "o"; CHR$ 8;"""";
40 NEXT n
(notice the control character CHR$ 8 which backs up one space.)
There is another way of using INK, PAPER and so on which you will probably
find more useful than having them as statements. You can put them as items in a
PRINT statement (followed by ;), and they then do exactly the same as they
would have done if they had been used as statements on their own, except that
their effect is only temporary: it lasts as far as the end of the PRINT statement
that contains them. Thus if you type
INK and the rest when used as statements do not affect the colours of the lower
part of the screen, where commands and INPUT data are typed in. The lower
part of the screen uses the colour of the border for its paper colour and code 9 for
contrast for its INK colour, has flashing off, and everything at normal
brightness. You can change the border colour to any of the eight normal colours
(not 8 or 9) using the statement
BORDER colour
When you type in INPUT data, it follows this rule of using contrasting ink on
border coloured paper; but you can change the colour of the captions written by
the computer by using INK and PAPER (and so on) items in the INPUT
statement, just as you would in a PRINT statement. Their effect lasts either to
the end of the statement, or until some INPUT data is typed in, whichever
comes first. Try
There is one more way of changing the colours by using control characters -
rather like the control characters for AT and TAB in Chapter 15.
These are each followed by one character that shows a colour by its code: so (for
instance)
PRINT INK 9; . . .
On the whole, you would not bother to use these control characters because you
might just as well use the colour items. However, one very useful thing you can
do with them is put them in programs: this results in different parts being listed
in different colours, to set them apart from each other or even just to look pretty.
You must put them in after the line number, or they will just get lost.
To get these into the program, you have to enter them from the keyboard. Note
that control characters tend to be less useful in BASin than on a real Spectrum,
because BASin already uses colour for syntax highlighting.
Its two arguments are the line and column numbers that you would use in an AT
item, and its result is a number that shows the colours and so on at the
corresponding character position on the television screen. You can use this as
freely in expressions as you can any other function.
The number that is the result is the sum of four other numbers as follows:
For instance, if the character position is flashing and normal with yellow paper
and blue ink then the four numbers that we have to add together are 128, 0,
8*6=48 and 1, making 177 altogether. Test this with
Exercises
1. Try
2. Type
BORDER 0:
PAPER 0:
INK 0:
CLS
In this chapter we shall see how to draw pictures with BASin. The part of the
screen you can use has 22 lines and 32 columns, making 22 × 32 = 704 character
positions. As you may remember from Chapter 16, each of these character
positions is made of an 8 by 8 square of dots, and these are called pixels (picture
elements).
A pixel is specified by two numbers, its coordinates. The first, its x coordinate,
says how far it is across from the extreme left-hand column. (Remember, x is a
cross.) The second, its y coordinate, says how far it is up from the bottom (wise
up). These coordinates are usually written as a pair in brackets, so (0,0), (255,0),
(0,175) and (255,175) are the bottom left-, bottom right-, top left- and top right-
hand corners.
The statement
Here is a rather more interesting program. It plots a graph of the function SIN (a
sine wave) for values between 0 and 2π.
To help you with your pictures, the computer will draw straight lines, circles and
parts of circles for you, using the DRAW and CIRCLE statements.
DRAW x,y
The starting place of the line is the pixel where the last PLOT, DRAW or
CIRCLE statement left off (this is called the PLOT position; RUN, CLEAR,
CLS and NEW reset it to the bottom left hand corner, at (0,0)), and the finishing
place is x pixels to the right of that and y pixels up. The DRAW statement on its
own determines the length and direction of the line, but not its starting point.
PLOT 0,100:
DRAW 80,-35
PLOT 90,150:
DRAW 80,-35
Notice that the numbers in a DRAW or PLOT statement can be negative.
You can also plot and draw in colour, although you have to bear in mind that
colours always cover the whole of a character position and cannot be specified
for individual pixels. When a pixel is plotted, it is set to show the full ink colour,
and the whole of the character position containing it is given the current ink
colour. This program demonstrates this:
10 BORDER 0:
PAPER 0:
INK 7:
CLS:
REM black out screen
20 LET x1=0:
LET y1=0:
REM start of line
30 LET c=1:
REM for ink colour, starting blue
40 LET x2=INT (RND*256):
LET y2=INT (RND*176):
REM random finish of line
50 DRAW INK c;x2-x1,y2-y1
60 LET x1=x2:
LET y1=y2:
REM next line starts where last one f
70 LET c=c+1:
IF c=8 THEN
LET c=1:
REM new colour
80 GO TO 40
The lines seem to get broader as the program goes on, and this is because a line
changes the colours of all the inked in pixels of all the character positions that it
passes through. Note that you can embed PAPER, INK, FLASH, BRIGHT,
INVERSE and OVER items in a PLOT or DRAW statement just as you could
with PRINT and INPUT. They go between the key word and the coordinates,
and are terminated by either semicolons or commas.
An extra frill with DRAW is that you can use it to draw parts of circles instead of
straight lines, by using an extra number to specify an angle to be turned through:
the form is
DRAW x,y,a
x and y are used to specify the finishing point of the line just as before and a is
the number of radians that it must turn through as it goes - if a is positive it turns
to the left, while if a is a negative it turns to the right. Another way of seeing a is
as showing the fraction of a complete circle that will be drawn: a complete circle
is 2π radians, so if a = π it will draw a semicircle, if a = 0.5 × π a quarter of a
circle, and so on.
For instance suppose a = π. Then whatever values x and y take, a semicircle will
be drawn. Run
10 PLOT 100,100:
DRAW 50,50, PI
start at (100,100)
The drawing starts off in a south-easterly direction, but by the time it stops it is
going north-west: in between it has turned round through 180 degrees, or π
radians (the value of a).
Run the program several times, with PI replaced by various other expressions
e.g. -PI, PI/2, 3*PI/2, PI/4, 1, 0.
The last statement in this chapter is the CIRCLE statement, which draws an
entire circle. You specify the coordinates of the centre and the radius of the circle
using
Just as with PLOT and DRAW, you can put the various sorts of colour items in at
the beginning of a CIRCLE statement.
The POINT function tells you whether a pixel is ink or paper colour. It has two
arguments, the coordinates of the pixel (and they must be enclosed in brackets);
and its result is 0 if the pixel is paper colour, 1 if it is ink colour. Try
CLS:
PRINT POINT (0,0):
PLOT 0,0:
PRINT POINT (0,0)
Type
PAPER 7:
INK 0
and let us investigate how INVERSE and OVER work inside a PLOT
statement. These two affect just the relevant pixel, and not the rest of the
character positions. They are normally off (0) in a PLOT statement, so you only
need to mention them to turn them on (1).
PLOT - this is the usual form. It plots an ink dot, i.e. sets the pixel to show the
ink colour.
PLOT INVERSE 1; - this plots a dot of ink eradicator, i.e. it sets the pixel to
show the paper colour.
PLOT OVER 1; - this changes the pixel over from whatever it was before: so
if it was ink colour it becomes paper colour, and vice versa.
As another example of using the OVER statement fill the screen up with writing
using black on white, and then type
This will draw a fairly decent line, even though it has gaps in it wherever it hits
some writing. Now do exactly the same command again. The line will vanish
without leaving any traces whatsoever. This is the great advantage of OVER 1.
If you had drawn the line using
PLOT 0,0:
DRAW 255,175
PLOT 0,0:
DRAW INVERSE 1;255,175
PLOT 0,0:
DRAW OVER 1;250,175
This doesn't quite work, because the pixels the line uses on the way back are not
quite the same as the ones that it used on the way down. You must undraw a line
in exactly the same direction as you drew it.
One way to get unusual colours is to speckle two normal ones together in a
single square, using a user-defined graphic. Run this program:
Exercises
2. Try to draw circles using SIN and COS (if you have
read Chapter 10, try to work out how). Run this:
3. Try
CIRCLE 100,87,80:
DRAW 50,50
10 PLOT 0,87:
DRAW 255,0
20 PLOT 127,0:
DRAW 0,175
30 INPUT s, e$
35 LET t=0
40 FOR f=0 TO 255
50 LET x=(f-128)*s/128:
LET y=VAL e$
60 IF ABS y>87 THEN
LET t=0:
GO TO 100
70 IF NOT t THEN
PLOT f,y+88:
LET t=1:
GO TO 100
80 DRAW 1,y-old y
100 LET old y=INT (y+.5)
110 NEXT f
Quite often you will want to make the program take a specified length of time,
and for this you will find the PAUSE statement useful.
PAUSE n
stops computing and displays the picture for n frames of the television (at 50
frames per second in Europe or 60 in America). n can be up to 65535, which
gives you just under 22 minutes; if n=0 then it means 'PAUSE for ever'.
A pause can always be cut short by pressing a key (note that Esc will cause a
break as well). You have to press the key down after the pause has started.
There is a much more accurate way of measuring time. This uses the contents of
certain memory locations. The data stored is retrieved by using PEEK. Chapter
25 explains what we're looking at in detail. The expression used is
This gives the number of seconds since the computer was turned on (up to about
3 days and 21 hours, when it goes back to 0).
The numbers PEEK 23674, PEEK 23673 and PEEK 23672 are held
inside the computer and used for counting in 50ths of a second. Each is between
0 and 255, and they gradually increase through all the numbers from 0 to 255;
after 255 they drop straight back to 0.
The one that increases most often is PEEK 23672. Every 1/50 second it
increases by 1. When it is at 255, the next increase takes it to 0, and at the same
time it nudges PEEK 23673 up by 1. When (every 256/50 seconds) PEEK
23673 is nudged from 255 to 0, it in turn nudges PEEK 23674 up by 1.
This should be enough to explain why the expression above works.
Now, consider carefully: suppose our three numbers are 0 (for PEEK 23674),
255 (for PEEK 23673) and 255 (for PEEK 23672). This means that it is
about 21 minutes after switch-on - our expression ought to yield
(65536*0+256*255+255)/50 = 1310.7
But there is a hidden danger. The next time there is a 1/50 second count, the
three numbers will change to 1, 0 and 0. Every so often, this will happen when
you are half way through evaluating the expression: the computer would
evaluate PEEK 23674 as 0, but then change the other two to 0 before it can
peek them. The answer would then be
(65536*0+256*0+0)/50 = 0
1800000=65536*27+256*119+64
In countries with mains frequencies of 60 Hertz these programs must replace '50'
by '60' where appropriate.
The function INKEY$ (which has no argument) reads the keyboard. If you are
pressing exactly one key (or a Shift key and just one other key) then the result is
the character that that key normally gives; otherwise the result is the empty
string.
Remember that unlike INPUT, INKEY$ doesn't wait for you. So you don't
type Enter, but on the other hand if you don't type anything at all then you've
missed your chance.
Exercises
10 PAUSE 0
20 PRINT INKEY$;
30 GO TO 10
BEEP, PLAY
Depending upon which model you are using, the Spectrum had two methods of
generating sound. The original 48k model comes equipped with a loudspeaker,
which is driven by the BEEP command. It is capable of outputting a single
channel of sound (i.e, no more than one note at a time).
The 128k Spectrums have, as well as the loudspeaker, a sound chip called the
AY-3-8912. This chip is capable of generating much more complex sounds, and
can play up to three of them at once. The chip is driven using the PLAY
command. Note that using the PLAY command will indicate to BASin that you
are working on a 128k program. For information about this, and limitations the
128k BASIC has, see here.
where, as usual, 'duration' and 'pitch' represent any numerical expressions. The
duration is given in seconds, and the pitch is given in semitones above middle C
using negative numbers for notes below middle C.
Here is a diagram to show the pitch values of all the notes in one octave on the
piano:
To get higher or lower notes, you have to add or subtract 12 for each octave that
you go up or down.
The simplest way to compose a tune in BASin is to use the BEEP Composer, but
here are some tips for creating a tune in code.
If you have a piano in front of you when you are programming a tune, this
diagram will probably be all that you need to work out the pitch values. If,
however, you are transcribing straight from some written music, then we suggest
that you draw a diagram of the stave with the pitch value written against each
line and space, taking the key into account.
When you run this, you should get the funeral march from Mahler's first
symphony, the bit where the goblins bury the US Cavalry man.
Suppose for example that your tune is written in the key of C minor, like the
Mahler above. The beginning looks like this:
and you can write in the pitch values of the notes like this:
We have put in two ledger lines, just for good measure. Note how the E flat in
the key signature affects not only the E in the top space, flattening it from 16 to
15, but also the E on the bottom line, flattening it from 4 to 3. It should now be
quite easy to find the pitch value of any note on the stave.
If you want to change the key of the piece, the best thing is to set up a variable
key and insert key+ before each pitch value: thus the second line becomes
20 BEEP 1,key+0:
BEEP 1,key+2:
BEEP .5,key+3:
BEEP .5,key+2:
BEEP 1,key+0
Before you run a program you must give key the appropriate value - 0 for C
minor, 2 for D minor, 12 for C minor an octave up, and so on. You can get the
computer in tune with another instrument by adjusting key, using fractional
values.
You also have to work out the durations of all the notes. Since this is a fairly
slow piece, we have allowed one second for a crotchet and based the rest on that,
half a second for a quaver and so on.
More flexible is to set up a variable crotchet to store the length of a crotchet and
specify the durations in terms of this. Then line 20 would become
20 BEEP crotchet,key+0:
BEEP crotchet,key+2:
BEEP crotchet/2,key+3:
BEEP crotchet/2,key+2:
BEEP crotchet,key+0
(You will probably want to give crotchet and key shorter names.)
By giving crotchet appropriate values, you can easily vary the speed of the piece.
Remember that because there is only one loudspeaker in the computer you can
only play one note at a time, so you are restricted to unharmonized tunes. If you
want any more you must sing it yourself.
Try programming tunes in for yourself - start off with fairly simple ones like
'Three Blind Mice'. If you have neither piano nor written music, get hold of a
very simple instrument like a tin whistle or a recorder, and work the tunes out on
that. You could make a chart showing the pitch value for each note that you can
play on this instrument.
Type:
This will play notes as high as it can, and then stop with error report B
Integer out of range. You can print out n to find out how high it did
actually get.
Try the same thing, but going down into the low notes. The very lowest notes
will just sound like clicks; in fact the higher notes are also made of clicks in the
same way, but faster, so that the ear cannot distinguish them.
Only the middle range of notes are really any good for music; the low notes
sound too much like clicks, and the high notes are thin and tend to warble a bit.
10 BEEP .5,0:
BEEP .5,2:
BEEP .5,4:
BEEP .5,5:
BEEP .5,7:
BEEP .5,9:
BEEP .5,11:
BEEP .5,12:
STOP
This plays the scale of C major, which uses all the white notes on the piano from
middle C to the next C up. The way this scale is tuned is exactly the same as on a
piano, and is called even-tempered tuning because the pitch interval of a
semitone is the same all the way up the scale. A violinist, however, would play
the scale very slightly differently, adjusting all the notes to make them sound
more pleasing to the ear. He can do this just by moving his fingers very slightly
up or down the string in a way that a pianist can't.
The natural scale, which is what the violinist plays, comes out like this:
20 BEEP .5,0:
BEEP .5,2.039:
BEEP .5,3.86:
BEEP .5,4.98:
BEEP .5,7.02:
BEEP .5,8.84:
BEEP .5,10.88:
BEEP .5,12:
STOP
You may or may not be able to detect any difference between these two; some
people can. The first noticeable difference is that the third note is slightly flatter
in the naturally tempered scale. If you are a real perfectionist, you might like to
program your tunes to use this natural scale instead of the even-tempered one.
The disadvantage is that although it works perfectly in the key of C, in other
keys it works less well - they all have their own natural scales - and in some keys
it works very badly indeed. The even-tempered scale is only slightly off, and
works equally well in all keys.
This is less of a problem on the computer, of course, because you can use the
trick of adding on a variable key.
Some music - notably Indian music - uses intervals of pitch smaller than a
semitone. You can program these into the BEEP statement without any trouble;
for instance the quartertone above middle C has a pitch value of .5.
The second number in this determines the length of the beep (try various values
between 0 and 255). When it is 0, the beep is so short that it sounds like a soft
click.
If you are interested in doing more with sound from the Spectrum, like hearing
the sound that BEEP makes on something other the internal speaker, you will
find that the signal is present on both the 'MIC' and the 'EAR' sockets. It will be
at a higher level on the 'EAR' socket, but otherwise they are the same. You may
use this to connect an earphone or a pair of headphones to your Spectrum. This
will not cut out the internal loudspeaker. If you are really keen to make a lot of
noise you could connect it up to an amplifier - the 'MIC' socket will probably
give about the right level - or you could record the sound onto tape and get the
Spectrum to play along with itself.
You will not damage the Spectrum even if you short-circuit the 'MIC' or 'EAR'
sockets, so experiment to find which gives the best output for what you want to
do.
The PLAY command allows you to make more complex pieces of music.
However, it is a 128k only command, and will not run on a standard 48k
Spectrum. See the chapter on BASin and the 128k for more details about this.
In the examples that follow, it is important that you type in the string expressions
exactly as shown in upper case and lower case letters, ie. the example "ga"
should not be typed in as "Ga", "gA" or "GA".
Type in this command (don't worry about what it means just yet)...
PLAY "ga"
Two notes were played - the second slightly higher than the first. The difference
between the notes is called a tone. Now try...
PLAY "g$a"
Again there were two notes played - the first one was the same as the previous
example, but there was less of a jump to the second. If you didn't hear the
difference, then try the first example followed by the second again. The second
example has half the difference between notes, and this is called a semitone.
PLAY "gD"
This sort of difference is called a fifth, and occurs quite often in music of all
types. With that example ringing in your ears, type...
PLAY "gG"
Although (hopefully) you noticed that there was a much bigger difference that
time than for the fifth, the two notes somehow sounded much more similar. This
is called an octave, and is the point at which music starts to 'repeat itself'. Don't
worry about that unduly, just remember what an octave sounds like.
PLAY is much more flexible than BEEP - it can play up to three voices in
harmony with all manner of effects, and gives a much higher quality of sound.
It's also much easier to use. For example, to play A above middle C for half a
second, type in...
PLAY "a"
... and to play the C major scale (which needed a program to itself before), use...
PLAY "cdefgabC"
Notice that the last C in the example above is in upper case. This tells the PLAY
command to play it in an octave higher than the lower case c. A scale, by the
way, is the term used for a set of notes between two Cs. Why major? There are
two main classes of scale, major and minor, and this is just musical shorthand for
describing the two different sets. Just for interest, the C minor scale sounds like
this...
PLAY "cd$efg$a$bC"
10 LET o$="O5"
20 LET n$="DECcg"
30 LET a$=o$+n$
40 PLAY a$
There are a few new things in this program. Firstly, PLAY is just as happy with a
string variable as with a string constant. In other words, providing that a$ has
been set up beforehand, PLAY a$ works just as well as PLAY
"O5DECcg". In fact, using variables in PLAY statements has distinct
advantages, and we shall be doing this from now on.
Notice also that the string a$ has been 'built up' by combining two smaller
strings o$ and n$. While this doesn't make much difference at this sort of level,
PLAY can cope with strings many thousands of notes long, and the only sensible
way of creating and editing those strings from BASIC is to combine lots of
smaller strings in this way.
Now run the above program. Edit line 10 so that "O5" becomes "O7", and
run it again, or if you want to make a big spaceship, make it "O2". If you don't
specify an octave number for a particular string, then BASin assumes that you
want octave 5. Here is a diagram of the notes and octave numbers which
correspond to the standard even-tempered music scale.
There is a lot of overlap, so for example, "O3D" is the same as "O4d". This
makes it easier to write tunes without having to change octave all the time. Some
of the notes in the lowest octaves (0 and 1) aren't very accurate for technical
reasons, and so the computer just makes a brave attempt at getting as close as
possible.
PLAY can also handle many different lengths of note. Edit the program above so
that line 10 is now...
10 LET o$="2"
... and run it. Then alter the setting of o$ between "1" and "9". The note
length can be changed anywhere in a string by including a number between 1
and 9, and this is effective for all subsequent notes until a new number is
encountered. Each of these nine note lengths has a specific musical name, and
looks different when written down in musical notation. The following table
shows which is which...
2 Dotted semi-quaver
3 Quaver
4 Dotted quaver
5 Crotchet
6 Dotted crotchet
7 Minim
8 Dotted minim
9 Semi-breve
PLAY can also cope with triplets, which are three notes played in the time for
two. Unlike simple note lengths, the triplet number only applies for the three
notes immediately following, and then the previous note length number resumes.
The triplet numbers are as follows...
10 Triplet semi-quaver
11 Triplet quaver
12 Triplet crotchet
PLAY is quite happy about being told to 'shut up'! A timed period during which
no notes play is called a rest, and the "&" is used to signify this. The length of
the rest it produces is the same as the current note length. To demonstrate, edit
lines 10 and 20 to...
10 LET o$="O4"
20 LET n$="DEC&cg;"
Two notes played together without a break are called tied notes, which are
signified in a PLAY command by an _ underline, so a crotchet c and a minim c
tied together would be "5_7c". (The second value is then used as the note
length for all subsequent notes, as before.)
There are 2 occasions when the ambiguity creeps in. Say that a piece of music
needs octave 6 and a note length of 2, then...
10 LET o$="O62"
...seems a good bet - but no! The computer will find the O and try to read the
number following it. When it finds 62, it will stop with the report n Out of
range. In cases like this, there is a 'dummy note' called N that just serves to
split things up, so line 10 should be...
10 LET o$="O6N2"
The volume can be set between 0 (minimum) and 15 (maximum) using "V"
followed by a number. In practice, only 10 to 16 are likely to be useful, as 1-9
are too soft unless the computer is being used with an amplifier. As previously
mentioned, BEEP is louder than a single channel of PLAY, but if all three
channels play a note at volume 15, then it should be at the same level as a not
produced by BEEP.
Playing more than one channel at the same time is very simple; you just separate
lists of notes by commas. Try this new program...
10 LET a$="O4cCcCgGgG"
20 LET b$="O6CaCe$bd$bD"
30 PLAY a$,b$
In general, there is no difference between the three channels, and any string of
notes can be put onto any channel. The overall speed of the music, the tempo,
must be in the string assigned to channel A (the first string after PLAY),
otherwise it will be ignored. To set tempo in beats (crotchets) per minute, use
"T" followed by a number between 60 and 240. The standard value is 120, or
two crotchets per second. Modify the program above to...
5 LET t$="T120"
10 LET a$=t$+"O4cCcCgGgG"
20 LET b$="O6CaCe$bd$bD"
30 PLAY a$,b$
10 LET a$=t$+"O4(cC)(gG)"
PLAY treats it just the same as the old line 10. If you include a closing bracket,
(with no matching opening bracket) then the string up to that point is repeated
indefinitely. This is useful for rhythm effects and basslines. To demonstrate, try
this (you'll have to use the ESC key to stop the sound)...
PLAY "O4N2cdefgfed)"
...and...
PLAY "O4N2cd(efgf)ed)"
If you set up an infinitely repeating bassline, and then play a melody with it, then
it would be nice if the bassline stops when the melody does. There is a device to
do this - of PLAY comes across "H" (for Halt) in any of the strings it is playing,
then it stops all sound immediately. Run the following program (again, you'll
have to use ESC to stop it)...
10 LET a$="cegbdfac"
20 LET b$="O4cC)"
30 PLAY a$,b$
10 LET a$="cegbdfaCH"
So far we've only used notes which start and stop at one level of volume. BASin
can alter athe volume of a note while it is playing, so it can start loud and die
away like a piano, or rise and fall like a dog growling. To turn these effects on,
use "W" (for Waveform) followed by a number between 0 and 7, together with
"U" for each channel you want to use the effect on. Any channel with a volume
setting ("V") will not respond to "U". This table shows graphically how the
volume changes for each setting...
4 Repeated decay.
5 Repeated attack.
6 Repeated attack-decay.
7 Repeated decay-attack.
This program plays the same note with each effect in turn, so you can compare
them against the diagram above.
10 LET a$="UX1000W0C&W1C;&W2C;&W3C;&W4C;&W5C;&W6C;&W7C;
20 PLAY a$
The U turns on effects, and the W selects which waveform to use. There's also an
"X1000". The X sets how long the effect will last for (from 0 to 65535). If you
don't include an X then BASin will choose the longest value. Waveforms that
settle down (0 to 3 in the table above) after the initial part, work best with X
settings of about 1000, whereas repetetive effects (4-7) are more effective with
short values like 300. Try varying the X setting in the program above to get some
idea of how each works.
The PLAY command isn't limited to pure musical notes. There are also three
"white noise" generators (white noise is a sound which is like an un-tuned FM
radio or TV), and any of the three channels can play notes, white noise, or a
mixture of both. To select a mix of noise and note, you may use "M" followed
by a number between 1 and 63. You can work out which number to use from the
following table...
Tone Channels Noise Channels
A B C A B C
Number 1 2 4 8 16 32
Write down the numbers corresponding to the effects you want, and then add
them together. If you wanted A to be noise, B to be tone, and C to be both tone
and noise, then add 8, 2, 4, and 32 together to get 46 (the order of the channels is
the order of the strings which follow the PLAY command). The best effects can
be obtained with the A channel - don't be afraid to experiment.
The PLAY command will simply 'hop over' any comments in the string.
MIDI programming
The original 128k models of the Spectrum had the ability to control an external
MIDI device. BASin emulates this by allowing your programs to drive your
MIDI soundcard. For information about setting up this feature, see the relevant
options page.
If you have an electronic musical instrument with MIDI, then you can control it
using PLAY. Up to 8 channels of music can be sent to synthesisers, drum
machines or sequencers. The PLAY command is constructed exactly as
described so far in this section, except that each string should include a "Y"
followed by a number between 1 and 16. The number after the Y controls which
channel the music data is assigned to. Up to eight strings can be used; the first
three strings will still be played through the normal Spectrum output, so you
might want to turn down the volume. You can also send MIDI programming
codes via the PLAY command, using "Z" followed by the code number. Key
velocities (loudness) are calculated and sent at 8 times the V setting (so "V6"
will send 48 as a key velocity).
So, to send a little tune (in four part harmony) to a four-voice synthesiser (after
consulting your synth's handbook to find out how to allocate MIDI channels to
different voices), you would use the PLAY command with four strings, each
starting with a Y followed by a number. This example program illustrates the
PLAY command in some of its full glory...
10 LET a$="Y1T100O2(((1CCg$b))(($E$E$b$D))((GGDF))))"
20 LET b$="Y2O5N&&&&C;$bfG)"
30 LET c$="Y3O4((3C&)C&1CCDD(3$E&)$E&1$E$EEE(3F&)F&1FF$
40 LET d$="Y4N9&&&&&&&&(9EGF7b5CD))"
50 PLAY a$,b$,c$,d$
Summary table
Finally, here is a brief list of the parameters that can be used in the string of a
PLAY command, together with any values they may take...
String Function
a..g,
Specifies the pitch of the note within the current octave range.
A..G
$ Specifies that the note which follows must be flattened.
# Specifies that the note which follows must be sharpened.
O Specifies the octave number to be used (followed by 0 to 8).
1..12 Specifies the length of notes to be used.
& Specifies that a rest is to be played.
_ Specifies that a tied note is to be played.
N Separates two numbers.
V Specifies the volume to be used (followed by 0 to 15).
W Specifies the volume effect to be used (followed by 0 to 7).
U Specifies that volume effects are to be used in the string.
X Specifies the duration of the volume effect (followed by 0 to 65535).
T Specifies the tempo of the music (followed by 60 to 240).
() Specifies that the enclosed phrase is to be repeated.
!! Specifies that the enclosed text is to be skipped over.
H Specifies that the PLAY command must stop.
M Specifies the channel(s) to be used (followed by 0 to 63).
Y Specifies that a MIDI channel is to be used (followed by 1 to 16).
Z Specifies MIDI programming code (followed by code number).
Exercises
1. Rewrite the Mahler program so that it uses FOR loops to repeat the bars.
2. Program the computer so that it plays not only the funeral march, but also
the rest of Mahler's first symphony.
Chapter 18
Chapter 20
Chapter 20: File storage
Summary
Loading and saving work differently in BASin than on a real ZX Spectrum. See
Loading and saving files.
It is also recommended that you read the sections on LOAD, SAVE, VERIFY
and MERGE. These sections will acquaint you with how those commands work.
When you have read them, then come back here for more information as to the
things you can do with these commands.
We have seen that LOAD deletes the old program and variables in the computer
before loading in the new ones from disk; there is another command, MERGE,
that does not. MERGE only deletes an old program line or variable if it has to
because there is a new one with the same line number or name. Type in the 'dice'
program in Chapter 11 and save it on disk, as "dice". Now enter and run the
following:
1 PRINT 1
2 PRINT 2
10 PRINT 10
20 LET x=20
and then proceed as for the verification, but replacing VERIFY "dice" with
MERGE "dice"
If you list the program you can see that lines 1 and 2 have survived, but lines 10
and 20 have been replaced by those from the dice program. x has also survived
(try PRINT x).
You have now seen simple forms of the four statements used with the file
system:
VERIFY checks the program and variables in a file against those already in the
computer.
LOAD clears the computer of all its program and variables, and replaces them
with new ones read in from a file.
MERGE is like LOAD except that it does not clear out an old program line or
variable unless it has to because its line number or name is the same as that as
that of a new one from the file.
In each of these, the keyword is followed by a string: for SAVE this provides a
name for the program on disk, while for the other three it tells the computer
which program to load. There are a couple of twists to all this.
You can provide the empty string instead of a filename; then the computer
prompts you to browse for a file on disk. (On a real ZX Spectrum, the empty
string indicates the next file on the cassette tape - regardless of its filename - and
cannot be used with SAVE.)
A program saved using this is recorded in such a way that when it is read back
by LOAD (but not MERGE) it automatically jumps to the line with the given
number, thus running itself.
So far, the only kinds of information we have stored on disk have been programs
together with their variables. There are two other kinds as well, called arrays and
bytes.
Arrays are dealt with slightly differently:
String is the name that the information will have on disk and works in exactly
the same way as when you save a program or plain bytes.
The array name specifies the array you want to save, so it is just a letter or a
letter followed by $. Remember the brackets afterwards; you might think they
are logically unnecessary but you still have to put them in to make it easier for
the computer.
Be clear about the separate roles of string and array name. If you say (for
instance)
then SAVE takes the array b from the computer and stores it on disk under the
name "Bloggs". When you type
the computer will look for a number array stored on disk under the name
"Bloggs" and check it against the array b in the computer.
finds the array on disk, and then - if there is room for it in the computer - deletes
any array already existing called b and loads in the new array from disk, calling
it b.
You can save character (string) arrays in exactly the same way. When you load
in a character array, the computer will delete not only any previous character
array with the same name, but also any string with the same name.
Byte storage is used for pieces of information without any reference to what the
information is used for - it could be television pictures, or used-defined graphics,
or something you have made up yourself. It is shown using the word CODE, as
in
The unit of storage in memory is the byte (a number between 0 and 255), and
each byte has an address (which is a number between 0 and 65535). The first
number after CODE is the address of the first byte to be stored on disk, and the
second is the number of bytes to be stored. In our case, 16384 is the address of
the first byte in the display file (which contains the television picture) and 6912
is the number of bytes in it, so we are saving a copy of the television screen - try
it. The name "picture" works just like the names for programs.
Here length is just a safety measure; when the computer has found the bytes on
disk with the right name, it will still refuse to load them in if there are more than
length of them - since there is obviously more data than you expected it could
otherwise overwrite something you had not intended to be overwritten. It gives
the error report R File loading error. You can miss out length, and
then the computer will read in the bytes however many there are.
Start shows the address where the first byte is to be loaded back to - this can be
different from the address it was saved from, although if they are the same you
can miss out the start in the LOAD statement.
CODE 16384,6912 is so useful for saving and loading the picture that you
can replace it with SCREEN$ - for instance:
BASin supports a number of different file formats. You can indicate the format
you wish to use by providing a filename extension.
BASin provides emulation of the Spectrum 128k and +2's Silicon Disk (or RAM
Disk). Be aware that using the Silicon Disk has it's own requirements related to
the use of other 128k commands. See the section on 128k commands in BASin
for more information.
Anything you can do with SAVE, LOAD or MERGE for files saved from BASin,
you can do with the silicon disk that's built into the 128k Spectrum models. This
acts like the usual cassette, or hard disk in BASin (with a couple of extra
commands), with the exception that it's about 64kb in size, very fast, and loses
its contents when BASin is reset or quit (However, it does survive the NEW
command). You use the commands in exactly the same way you would in normal
operation - simply add an exclamation mark ! between the command and its
associated string. So where you would type...
SAVE "squares"
SAVE !"squares"
There are two extra commands for use with the silicon disk. The first one is...
CAT !
...which gives you a list of all the programs or data files that are stored on the
disc.
ERASE !"filename"
Perhaps the most obvious use of the silicon disc is to store chunks of BASIC
program which can be merged (using MERGE !) into a smaller program, in
sequence. This makes it possible to write about 90kb of BASIC program, and
hold it in the emulated memory (to do this, the program structure has to be well
defined).
One of the more interesting uses of the silicon disk is in animation, where a
series of pictures can be defined by a 'slow' BASIC program and stored in the
silicon disk, then called back to the screen at high speed. The following program
gives a taste of this; doubtless you can do better...
10 INK 5:
PAPER 0:
BORDER 0:
CLS
20 FOR f=1 TO 10
30 CIRCLE f*20,150,f
40 SAVE !"ball"+STR$(f) CODE 16384, 204
50 CLS
60 NEXT f
70 FOR f=1 TO 10
80 LOAD !"ball"+STR$(f) CODE
90 NEXT f
100 BEEP 0.01,0.01
110 FOR f=9 TO 2 STEP -1
120 LOAD !"ball"+STR$(f) CODE
130 NEXT f
140 BEEP 0.01,0.01
150 GO TO 70
160 REM use GO TO 160 to clear pictures
170 FOR f=10 TO 1 STEP -1
180 ERASE !"ball"+STR$(f)
190 NEXT f
Note that in line 40 of this program, the two numbers following CODE are the
address in memory of the start of the screen, and the length of the top third of it.
By only saving and loading the top third, the overall speed is maintained. Lines
160 to 190 are there if you break (using ESC) out of the program, modify the
circle drawing bit, and try to save a new set of pictures. So before doing that,
type GO TO 160 to clear out the silicon disc. (Always try to delete files
backwards so the last file to be saved will be the first to be deleted. This saves
the computer a lot of juggling about, and is much faster).
Summary
Below is a complete summary of the four statements used in this chapter. Name
stands for any string expression, and refers to the name under which the
information is stored on disk. It should consist of ASCII printing characters.
Unlike the original ZX Spectrum, BASin permits filenames to be longer than 10
characters.
There are four sorts of information that can be stored on disk: program and
variables (together), number arrays, character arrays and straight bytes.
When you provide the empty string instead of a filename, BASin prompts you
for the file to be opened or saved.
SAVE
GO TO line number
2. Bytes:
is equivalent to
4. Verify:
VERIFY name
2. Bytes:
is equivalent to
3. Arrays:
LOAD
Loads new information fron disk, deleting old information from memory.
LOAD (!)name
2. Bytes:
3. Arrays:
MERGE
Loads new information from disk without deleting old information from
memory.
MERGE (!)name
1. Bytes:
Not possible
2. Arrays:
Not possible
Exercises
followed by
Note: Using the ZX Printer support in conjunction with certain 128k commands
can have undersirable results. See the section on BASin and the 128k Spectrum
for more details. If you are making use of 128k commands, you should avoid the
use of the ZX Printer.
This chapter covers the BASIC statements needed to operate the ZX printer.
BASin emulates the ZX printer: you can view, save, and print the results from
the ZX printer output window.
The first two statements, LPRINT and LLIST, are just like PRINT and
LIST, except that they use the printer instead of the television. (The L is an
historical accident. When BASIC was invented it usually used an electric
typewriter instead of a television, so PRINT really did mean print. If you
wanted masses of output you would use a very fast line printer attached to the
computer, and an LPRINT statement meaning 'Line printer PRINT'.)
COPY
Note that COPY doesn't work with one of the listings that the computer puts up
automatically, because that is cleared whenever a command is obeyed. You must
either use LIST first, or use LLIST and forget about COPY.
You can always stop the printer when it is running by pressing the Esc key.
If you execute these statements without the printer attached, it should lose all the
output and carry on with the next statement.
Try this:
Now change TAB n to AT 31-n,n still using LPRINT. This time you will
get just a single line of symbols. The reason for the difference is that the output
from PRINT is not printed straight away, but arranges in a buffer store a picture
one line long of what the computer will send to the printer when it gets round to
it. The printing takes place
Exercise
Chapter 20
Chapter 22
Chapter 22: Other equipment
Note: BASin does not currently support the hardware and extra keywords listed
here.
There is other equipment that you will be able to attach to the Spectrum.
The ZX Microdrive is a high speed mass storage device, and is much more
flexible in the way it can be used than a cassette recorder. It will operate not only
with SAVE, VERIFY, LOAD and MERGE, but also with PRINT, LIST,
INPUT and INKEY$.
The network is used for connecting several Spectrums so that they can talk to
each other - one of the uses of this is that you then need only one Microdrive to
serve several computers.
The RS232 interface is a standard connection that allows you to link a Spectrum
with keyboards, printers, computers and various other machines even if they
were not designed specifically for the Spectrum.
These will use some extra keywords that cannot be used without the extra
attachments: they are OPEN #, CLOSE #, MOVE, ERASE, CAT and
FORMAT.
Chapter 21
Chapter 23
Chapter 23: IN and OUT
Summary
OUT, IN
The processor can read from and (at least with RAM) write to memory by using
PEEK and POKE. The processor itself does not really care whether memory is
ROM, RAM or even nothing at all; it just knows that there are 65536 memory
addresses, and it can read a byte from each one (even if it's nonsense), and write
a byte to each one (even if it gets lost). In a completely analogous way there are
65536 of what are called I/O ports (standing for Input/Output ports). These are
used by the processor for communicating with things like the keyboard or the
printer, and they can be controlled from the BASIC by using the IN function
and the OUT statement.
IN address
It has one argument, the port address, and its result is a byte read from that port.
writes the given value to the port with the given address. How the address is
interpreted depends very much on the rest of the computer; quite often, many
different addresses will mean the same. On the Spectrum it is most sensible to
imagine the address being written in binary, because the individual bits tend to
work independently. There are 16 bits, which we shall call (using A for address)
Here A0 is the 1s bit, A1 the 2s bit, A2 the 4s bit and so on. Bits A0, A1, A2, A3
and A4 are the important ones. They are normally 1, but if any one of them is 0
this tells the computer to do something specific. The computer cannot cope with
more than one thing at a time, so no more than one of these five bits should be 0.
Bits A6 and A7 are ignored, so if you are a wizard with electronics you can use
them yourself. The best addresses to use are those that are 1 less than a multiple
of 32, so that A0,...A4 are all 1. Bits A8, A9 and so on are sometimes used to
give extra information.
The byte read or written has 8 bits, and these are often referred to (using D for
data) as D7, D6,...., D1, D0. Here is a list of the port addresses used.
There is a set of input addresses that read the keyboard and also the EAR socket.
In the byte read in, bits D0 to D4 stand for the five keys in the given half row -
D0 for the outside key, D4 for the one nearest the middle. The bit is 0 if the key
is pressed, 1 if it is not. D6 is the value at the EAR socket.
Port address 254 in output drives the loudspeaker (C4) and the MIC socket (D3),
and also sets the border colour (D2, D1 and D0).
Port address 251 runs the printer, both in reading and writing: reading finds out
whether the printer is ready for more, and writing sends out dots to be printed.
Port addresses 254, 247 and 239 are used for the extra devices mentioned in
Chapter 22.
Run this program
10 FOR n=0 TO 7:
REM half-row number
20 LET a=254+256*(255-2↑n)
30 PRINT AT 0,0; IN a:
GO TO 30
and play around by pressing keys. When you get bored with each half-row, press
BREAK and then type
NEXT n
The control, data and address busses are all exposed at the back of the Spectrum,
so you can do almost anything with a Spectrum that you can with a Z80.
Sometimes, though, the Spectrum hardware might get in the way. Here is a
diagram of the exposed connections at the back:
Chapter 22
Chapter 24
Chapter 24: The memory
Summary
CLEAR
Deep inside the computer, everything is stored as bytes, i.e. numbers between 0
and 255. You may think you have stored away the price of wool or the address of
your fertilizer suppliers, but it has all been converted into collections of bytes
and bytes are what the computer sees.
BASin's debugging tools allow you to work with the memory and system
variables.
Each place where a byte can be stored has an address, which is a number
between 0 and FFFFh (so an address can be stored as two bytes), so you might
think of the memory as a long row of numbered boxes, each of which can
contain a byte. Not all the boxes are the same, however. In the standard 16K
RAM machine, the boxes from 8000h to FFFFh are simply missing altogether.
The boxes from 4000h to 7FFFh are RAM boxes, which means you can open the
lid and alter the contents, and those from 0 to 3FFFh are ROM boxes, which
have glass tops but cannot be opened. You just have to read whatever was put in
them when the computer was made.
To inspect the contents of a box, we use the PEEK function: its argument is the
address of the box, and its result is the contents. For instance, this program prints
out the first 21 bytes in ROM (and their addresses):
To change the contents of a box (if it is RAM), we use the POKE statement. It
has the form
where 'address' and 'new contents' stand for numeric expressions. For instance, if
you say
POKE 31000,57
to prove this. (Try poking in other values, to show that there is no cheating.) The
new value must be between -255 and +255, and if it is negative then 256 is
added to it.
The ability to poke gives you immense power over the computer if you know
how to wield it, and immense destructive possibilities if you don't. It is very
easy, by poking the wrong value in the wrong address, to lose vast programs that
took you hours to type in. Fortunately, you won't do the computer any permanent
damage.
We shall now take a more detailed look at how the RAM is used, but don't bother
to read this unless you're interested.
The memory is divided into different areas (shown on the big diagram) for
storing different kinds of information. The areas are only large enough for the
information that they actually contain, and if you insert some more at a given
point (for instance by adding a program line or variable) space is made by
shifting up everything above that point. Conversely, if you delete information
then everything is shifted down.
The display file stores the television picture. It is rather curiously laid out, so you
probably won't want to PEEK or POKE in it. Each character position on the
screen has an 8×8 square of dots, and each dot can be either 0 (paper) or 1 (ink)
and by using binary notation we can store the pattern as 8 bytes, one for each
row. However, these 8 bytes are not stored together. The corresponding rows in
the 32 characters of a single line are stored together as a scan of 32 bytes,
because this is what the electron beam in the television needs as it scans from the
left hand side of the screen to the other. Since the complete picture has 24 lines
of 8 scans each, you might expect the total of 172 scans to be stored in order, one
after the other; you'd be wrong. First come the top scans of lines 0 to 7, then the
next scans of lines 0 to 7, and so on to the bottom scans of lines 0 to 7; then the
same for lines 8 to 15; and then the same for lines 16 to 23. The upshot of all this
is that if you're used to a computer that uses PEEK and POKE on the screen,
you'll have to start using SCREEN$ and PRINT AT instead, or PLOT and
POINT.
The attributes are the colours and so on for each character position, using the
format of ATTR. These are stored line by line in the order you'd expect.
The printer buffer stores the characters destined for the printer.
The system variables contain various pieces of information that tell the computer
what sort of state the computer is in. They are listed fully in the next chapter, but
for the moment note that there are some (called CHANS, PROG, VARS, E LINE
and so on) that contain the addresses of the boundaries between the various areas
in memory. These are not BASIC variables, and their names will not be
recognized by the computer.
The Microdrive maps are only used with the Microdrive. Normally there is
nothing there.
The channel information contains information about the input and output
devices, namely the keyboard (with the lower half of the screen), the upper half
of the screen, and the printer.
Note that, in contrast with all other cases of two byte numbers in the Z80, the
line number here is stored with its more significant byte first: that is to say, in the
order that you write them down in.
A numerical constant in the program is followed by its binary form, using the
character CHR$ 14 followed by five bytes for the number itself.
The variables have different formats according to their different features. The
letters in the names should be imagined as starting off in lower case.
The elements with a given first subscript are ordered in the same way using the
second subscript, and so on down to the last.
As an example, the elements of the 3*6 array b in Chapter 12 are stored in the
order b(1,1) b(1,2) b(1,3) b(1,4) b(1,5) b(1,6) b(2,1) b(2,2) ... b(2,6) b(3,1) b(3,2)
... b(3,6).
The calculator is the part of the BASIC system that deals with arithmetic, and
the numbers on which it is operating are held mostly in the calculator stack.
The machine stack is the stack used by the Z80 processor to hold return
addresses and so on.
The byte pointed to by RAMTOP has the highest address used by the BASIC
system. Even NEW, which clears the RAM out, only does so as far as this - so it
doesn't change the user defined graphics. You can change the address RAMTOP
by putting a number in a CLEAR statement:
This
Using CLEAR in this way, you can either move RAMTOP up to make more
room for the BASIC by overwriting the user defined graphics, or you can move
it down to make more RAM that is preserved from NEW.
Type NEW, then CLEAR 23800 to get some idea of what happens to the
machine when it fills up.
One of the first things you will notice if you start typing in a program is that
after a while the computer stops accepting any more input. It means the
computer is chock a block and you will have to empty it slightly. There are two
error messages with roughly the same meaning, 4 Out of memory and G
No room for line.
You can adjust the length of the error beep by poking a number into address
23608. The usual length has number 64.
Suppose you write m in the binary scale. Because it is a fraction, it will have a
binary point (like the decimal point in the scale of ten) and then a binary fraction
(like a decimal fraction); so in binary:
a half is written .1
a quarter is written .01
three quarters is written .11
a tenth is written .000110011001100110011 ... and so on.
With our number m, because it is less than 1, there are no bits before the binary
point, and because it is at least 0.5, the bit immediately after the binary point is a
1.
These are called system variables, and have names, but do not confuse them with
the variables used by the BASIC. The computer will not recognize the names as
referring to system variables, and they are given solely as mnemonics for we
humans.
Poking system variables in the BASin editor will not always have the desired
effect, because there is a layer of abstraction between BASin and the emulated
ZX Spectrum memory.
X The variables should not be poked because the system might crash.
The number in column 1 is the number of bytes in the variable. For two bytes,
the first one is the less significant byte, the reverse of what you might expect. So
to poke a value v to a two byte variable at address n, use
Time (in 50ths of a second, in 60ths of a second in N. America) that a key must be
1 23561 REPDEL held down before it repeats. This starts off at 35, but you can POKE in other
values.
Nl 23565 K DATA Stores 2nd byte of colour controls entered from keyboard.
N2 23566 TVDATA Stores bytes of coiour, AT and TAB controls going to television.
256 less than address of character set (which starts with space and carries on to the
2 23606 CHARS copyright symbol). Normally in ROM, but you can set up your own in RAM and
make CHARS point to it.
1 23610 ERR NR 1 less than the report code. Starts off at 255 (for 1) so PEEK 23610 gives 255.
Statement number in line to be jumped to. Poking first NEWPPC and then NSPPC
23620 NSPPC
forces a jump to a specified statement in a line.
Border colour * 8; also contains the attributes normally used for the lower half of
1 23624 BORDCR
the screen.
X2 23633 CURCHL Address of information currently being used for input and output.
Address of the next character to be interpreted: the character after the argument of
X2 23645 CH ADD
PEEK, or the newline at the end of a POKE statement.
2 23647 X PTR Address of the character after the ? syntax error marker in traditional 48K BASIC.
Address of area used for calculator's memory. (Usually MEMBOT, but not
N2 23656 MEM
always.)
X1 23659 DF SZ The number of lines (including one blank line) in the lower part of the screen.
2 23660 S TOP The number of the top program line in automatic listings.
2 23670 SEED The seed for RND. This is the variable that is set by RANDOMIZE.
3 byte (least significant first), frame counter. Incremented every 20ms. See Chapter
3 23672 FRAMES
18.
Address of 1st user defined graphic. You can change this for instance to save space
2 23675 UDG
by having fewer user defined graphics.
X2 23680 PR CC Full address of next position for LPRINT to print at (in printer buffer).
2 23682 ECHO E 33 column number and 24 line number (in lower half) of end of input buffer.
Counts scrolls: it is always 1 more than the number of scrolls that will be done
23692 SCR CT before stopping with scroll? If you keep poking this with a number bigger
than 1 (say 255), the screen will scroll on and on without asking you.
1 23693 ATTR P Permanent current colours, etc (as set up by colour statements).
Used for transparent colours, etc. Any bit that is 1 shows that the corresponding
1 23694 MASK P
attribute bit is taken not from ATTR P, but from what is already on the screen.
N1 23695 ATTR T Temporary current colours, etc (as set up by colour items).
Calculator's memory area; used to store numbers that cannot conveniently be put
N30 23698 MEMBOT
on the calculator stack.
2 23728 Used for the NMI in the +3 and +2A, and by the Interface 1.
This program tells you the first 22 bytes of the variables area:
10 FOR n=0 TO 21
20 PRINT PEEK (PEEK 23627+256*PEEK 23628
30 NEXT n
Try to match up the control variable n with the descriptions above. Now change
line 20 to
This tells you the first 22 bytes of the program area. Match these up with the
program itself.
Chapter 24
Chapter 26
Chapter 26: Using machine code
Summary
This chapter is written for those who understand Z80 machine code, the set of
instructions that the Z80 processor chip uses. If you do not, but would like to,
there are plenty of books about it. You want to get one called something along
the lines of "Z80 machine code [or assembly language] for the absolute
beginner", and if it mentions the Spectrum, so much the better.
ld bc, 99
ret
which loads the bc register pair with 99. This translates into the four machine
code bytes 1, 99, 0 (for ld bc, 99) and 201 (for ret). (If you look up 1 and
201 in Appendix A, you will find ld bc, NN - where NN stands for any two
byte number - and ret.)
When you have got your machine code program, the next step is to get it into the
computer. (An assembler would probably do this automatically.) You need to
decide whereabouts in memory to put it, and the best thing is to make extra
space for it between the BASIC area and the user defined graphics.
Suppose, for instance, that you have a 16K Spectrum. To start off with, the top
end of RAM has
If you type
CLEAR 32499
this will give you a space of 100 (for good measure) bytes starting at address
32500.
To put in the machine code program, you would run a BASIC program
something like
10 LET a=32500
20 READ n:
POKE a,n
30 LET a=a+1:
GO TO 20
40 DATA 1,99,0,201
(This will stop with report E Out of DATA when it has filled in the four
bytes you specified.)
To run the machine code, you use the function USR but this time with a numeric
argument, the starting address. Its result is the value of the bc register on return
from the machine code program, so if you do
The return address to the BASIC is stacked in the usual way, so return is by a
Z80 ret instruction. You should not use the iy and i registers in a machine code
routine.
You can save your machine code program easily enough with
and then
Chapter 25
Appendix A
Appendix A: The character set
This is the complete Spectrum character set, with codes in decimal and hex. If
one imagines the codes as being Z80 machine code instructions, then the right
hand columns give the corresponding assembly language mnemonics. As you
are probably aware if you understand these things, certain Z80 instructions are
compounds starting with CBh or EDh; the two right hand columns give these.
8 08 ex af,af' rrc b
10 0A ld a,(bc) rrc d
11 0B dec bc rrc e
33 ! 21 ld hl,NN sla c
35 # 23 inc hl sla e
36 $ 24 inc h sla h
37 % 25 dec h sla l
39 , 27 daa sla a
40 ( 28 jr z,DIS sra b
42 * 2A ld hl,(NN)sra d
43 + 2B dec hl sra e
44 , 2C inc ll sra h
45 - 2D dec l sra l
47 / 2F cpl sra a
48 0 30 jr nc,DIS
49 1 31 ld sp,NN
50 2 32 ld (NN),a
51 3 33 inc sp
52 4 34 inc (hl)
53 5 35 dec (hl)
54 6 36 ld (hl),N
55 7 37 scf
56 8 38 lr c,DIS srl b
58 : 3A ld a,(NN) srl d
59 ; 3B dec sp srl e
63 ? 3F ccf srl a
[prefixes
221 INVERSE DD instructions set 3,l
using ix]
[prefixes
253 CLEAR FD instructions set 7,l
using iy]
254 RETURN FE cp N set 7,(hl)
Chapter 26
Appendix B
Appendix B: Reports
These appear in the Error window whenever the computer stops executing some
BASIC, and explain why it stopped, whether for a natural reason, or because an
error occurred.
The report has a code number or letter so that you can refer to the table here, a
brief message explaining what happened and the line number and statement
number within that line where it stopped. (A command is shown as line 0. Within
a line, statement 1 is at the beginning, statement 2 comes after the first colon or
THEN, and so on.)
Here is a table showing all the reports. It also tells you in what circumstances the
report can occur, and this refers you to Appendix C. For instance error A
Invalid argument can occur with SQR, IN, ACS and ASN and the
entries for these in Appendix C tell you exactly what arguments are invalid.
Any
0 OK Successful completion, or jump to a line number bigger than any existing. This report does not
change the line and statement jumped to by CONTINUE.
NEXT NEXT
1 without The control variable does not exist (it has not been set up by a FOR statement), but there is an
FOR ordinary variable with the same name.
Any
For a simple variable this will happen if the variable is used before it has been assigned to in a
Variable LET, READ or INPUT statement or loaded from tape or set up in a FOR statement. For a
2
not found
subscripted variable it will happen if the variable is used before it has been dimensioned in a
DIM statement or loaded from tape.
Subscripted variables, Substrings
Subscript
3 A subscript is beyond the dimension of the array, or there are the wrong number of subscripts.
wrong
If the subscript is negative or bigger than 65535, then error B will result.
INPUT, PRINT AT
Out of
5 An INPUT statement has tried to generate more than 23 lines in the lower half of the screen.
screen
Also occurs with PRINT AT 22, . . .
RETURN RETURN
7 without
GO SUB There has been one more RETURN than there were GO SUBs.
End of
8 Microdrive, etc operations
file
STOP STOP
9
statement After this, CONTINUE will not repeat the STOP, but carries on with the statement after.
A
Invalid SQR, LN, ASN, ACS, USR (with string argument)
argument The argument for a function is no good for some reason.
RUN, RANDOMIZE, POKE, DIM, GO TO, GO SUB, LIST, LLIST, PAUSE, PLOT,
Integer
B out of CHR$, PEEK, USR (with numeric argument), Array access
range When an integer is required, the floating point argument is rounded to the nearest integer. If
this is outside a suitable range then error B results. For array access, see also error 3.
Out of READ
E
DATA You have tried to READ past the end of the DATA list.
Invalid SAVE
F
file name SAVE with name empty or longer than 10 characters (on an original Spectrum).
INPUT
STOP in Some INPUT data started with STOP, or - for INPUT LINE - was pressed. Unlike the
H
INPUT case with report 9, after report H CONTINUE will behave normally, by repeating the
INPUT statement.
FOR FOR
I without There was a FOR loop to be executed no times (e.g. FOR n=1 TO 0) and the
NEXT corresponding NEXT statement could not be found.
Invalid
J I/O Microdrive, etc operations
device
Invalid
INK, PAPER, BORDER, FLASH, BRIGHT, INVERSE, OVER; also after one of the
K corresponding control characters.
colour
The number specified is not an appropriate value.
Any
BREAK
Break pressed. This is detected between two statements. The line and statement number in the
L into
report refer to the statement before Break was pressed, but CONTINUE goes to the statement
program
after (allowing for any jumps to be done), so it does not repeat any statements.
FN
FN
P without
DEF A user-defined function was called but no corresponding definition could be found.
FN
Parameter
Q Wrong number of arguments, or one of them is the wrong type (string instead of number or
error
vice versa).
File
R loading
VERIFY, LOAD or MERGE
error A file on disk could not be read in, or would not verify.
The following reports are 128k only, and will only appear when using one of the
128k commands. They are not common to the 48k Spectrum, hence their code
appearing in reports in lower case.
a MERGE error
MERGE !
MERGE ! would not execute for some reason - either size or file type wrong.
MERGE !, LOAD !
Wrong file
b A file of inappropriate type was specified during silicon disc operation, for instance a
type
CODE file in LOAD ! "name".
c CODE error
LOAD ! "file" CODE
The size of the file would overrun the top of memory.
d
Too many PLAY
brackets Too many brackets around a repeated phrase in one of the arguments.
e
File already SAVE !
exists The file name specified has already been used.
ERASE !
f Invalid name
The file name specified is empty or above 10 characters in length.
FORMAT
i Invalid device The device name following the FORMAT command does not exist or orrespond to a
physical device.
Invalid note
PLAY
k PLAY came across a note or command it didn't recognise, or a command that was in lower
name
case.
l
Number too PLAY
big A parameter for a command is an order of magnitude too big.
m
Note out of PLAY
range A series of sharps or flats has taken a note beyond the range of the sound chip.
PLAY
n Out of range A parameter for a command is too big or too small. If the error is very large, error "l"
results.
Appendix A
Appendix C
Appendix C
Part 1: A description of the ZX Spectrum for reference
In the original paper version of this manual, the first section of this appendix was
a repeat of that part of Chapter 1 concerning the keyboard and display.
Each character position has attributes specifying its paper (background) and ink
(foreground) colours, a two-level brightness, and whether it flashes or not. The
available colours are black, blue, red, magenta, green, yellow and white.
The edge of the screen can be set to any of the colours using the border
statement.
A character position is divided into 8×8 pixels and high resolution graphics are
obtained by setting the pixels individually to show either the ink or paper colour
for that character position.
Temporary parameters are set up by PAPER, INK, etc, items, which are
embedded in PRINT, LPRINT, INPUT, PLOT, DRAW and CIRCLE
statements, and also by PAPER, INK, etc control characters when they are
printed to the television - they are followed by a further byte to specify the
parameter value. Temporary parameters last only to the end of the PRINT (or
whatever) statement, or, in INPUT statements, until some INPUT data is
needed from the keyboard, when they are replaced by the permanent parameters.
PAPER and INK parameters are in the range 0 to 9. Parameters 0 to 7 are the
colours used when a character is printed:
0 Black
1 Blue
2 Red
3 Magenta
4 Green
5 Cyan
6 Yellow
7 White
When a TAB control character is received by the television, two more bytes are
expected to specify a tab stop n (less significant byte first). This is reduced
modulo 32 to n0 (say), and then sufficient spaces are printed to move the printing
position into column n0. When a comma control character is received, then
sufficient spaces (at least one) are printed to move the printing position into
column 0 or column 16. When an Enter control character is received, the
printing position is moved on to the next line.
The printer
Output to the ZX printer is via a buffer one line (32 characters) long, and a line
is sent to the printer
The AT control changes the printing position using the column number, and
ignores the line number.
The printer is affected by INVERSE and OVER controls (and also statements)
in the same way as the screen is, but not by PAPER, INK, FLASH or
BRIGHT.
The printer will stop with error B if Esc is pressed. If the printer is absent the
output will simply be lost.
Numbers are stored to an accuracy of 9 or 10 digits. The largest number you can
get is about 1038, and the smallest (positive) number is about 4×10-39.
A number is stored in floating point binary with one exponent byte e (1≤e≤255),
and four mantissa bytes m (1/2≤m<1). This represents the number m×2e-128.
Since 1/2≤m<1, the most significant bit of the mantissa m is always 1. Therefore
in actual fact we can replace it with a bit to show the sign - 0 for positive
numbers, 1 for negative.
Small integers have a special representation in which the first byte is 0, the
second is a sign byte (0 or FFh) and the third and fourth are the integer in twos
complement form, the less significant byte first.
Numeric variables have names of arbitrary length, starting with a letter and
continuing with letters and digits. Spaces and colour controls are ignored and all
letters are converted to lower-case letters.
Numeric arrays have names a single letter long, which may be the same as the
name of a simple variable. They may have arbitrarily many dimensions of
arbitrary size. Subscripts start at 1.
Strings are completely flexible in length. The name of a string consists of a
single letter followed by $.
String arrays can have arbitrarily many dimensions of arbitrary size. The name is
a single letter followed by $ and may not be the same as the name of a string.
All the strings in a given array have the same fixed length, which is specified as
an extra, final dimension in the DIM statement. Subscripts start at 1.
1. empty or
2. numerical expression or
3. optional numerical expression TO optional numerical
expression
and is used in expressing a substring either by
If the slicer is a numerical expression with value m, then the result is the mth
character of s$ (a substring of length 1).
If the slicer has the form (iii), then suppose the first numerical expression has the
value m (the default value is 1), and the second, n (the default value is the length
of s$).
Functions
ATTR Gives the number whose binary form codes the attributes of a line.
OR Logical disjunction.
SCREEN$ Gives the character that appears on the screen at the given position.
STR$ Gives the string of characters that would be displayed if a numeric expression were printed.
Calls a machine code subroutine, or gives the address of the first bit pattern for a user-defined
USR
graphic.
VAL$ Gives the value of a string expression evaluated as a numeric expression and converted back to a
string.
- Subtraction
* Multiplication
/ Division
= Equals
> Greater than
<= Less than or equal Both operands must be of the same type. The result is a number: 1 if the comparison
to
holds and 0 if it does not
Operation Priority
↑ 10
*, / 8
NOT 4
AND 3
OR 2
Statements
Note that arbitrary expressions are allowed everywhere (except for the line
number at the beginning of a statement).
CONTINUE Continues the program, starting where it left off last time it stopped.
COPY Sends a copy of the top 22 lines of display to the printer.
GO TO Jumps to a line.
IF Conditional execution.
NEW Starts the BASIC system off anew, deleting program and variables.
PAUSE Stops computing for the specified number of frames or until a key is pressed.
REM No effect.
Appendix B
Manual credits
Sinclair ZX Spectrum: BASIC Programming By Steven Vickers.
Edited by Robin Bradbeer.
This manual is freely distributable but must not be distributed without this
notice.
ABS gives the absolute magnitude of a numeric value, that is the value without a
positive or negative sign.
50 LET x=ABS(y-z)
Example
The command
displays 34.2.
Format
ABS num-const
ABS num-var
ABS (num-expr)
See also
Chapter 9.
ACS Arc CoSine
Function
The value following ACS (y*z above) is the cosine of the required angle and
may range from -1 to 1. ACS the returns the value of the angle in radians. To
convert radians to degrees, multiply the value returned by ACS by 180/PI.
Example
The command
Format
ACS num-const
ACS num-var
ACS (num-expr)
See also
Chapter 10.
AND
Logical Operator/Function
As a logical operator, AND links two conditions in a statement where the truth
of the whole is to be tested, for example
Only if both conditions are true will the computer display "Correct". If either or
both conditions are false, then the whole combination is false and in this
example, the program proceeds to the next line.
AND as a function
AND returns the first value (y) if the second (z) is not equal to 0, and returns 0 if
the second value(z) is 0.
AND may also operate on a string value providing it precedes AND. A numeric
value must always follow AND, for example
AND returns the first value (b$) if the second (z) is non-zero and a null string
("") if the second value (z) is 0.
Note that the BASIC assigns a value of 1 to a true condition and 0 to a false
condition, and recognises any non-zero value as true and 0 as false. It does not
evaluate combinations of numeric values in accordance with standard truth
tables.
Examples
If the two conditions in line 60 are true then the numeric variable correct is
assigned a value of 1. The score is increased by 10 and a$ becomes "Correct". If
either of the conditions is false, then correct has a value of 0; score is
unchanged, and a$ becomes "Out Of Time Or Not Correct".
Format
See also
Chapter 13.
ASN Arc SiNe
Function
The value following ASN (y*z above) is the sine of the required angle and it
may range from -1 to 1. ASN then returns the value of the angle in radians. To
convert radians to degrees, multiply the value returned by ASN by 180/PI.
Example
The command
Format
ASN num-const
ASN num-var
ASN (num-expr)
See also
Chapter 10.
AT
PRINT item
How to use AT
The first value following AT (21 above) defines the row component of the new
position. This is rounded down to the nearest integer if necessary, and may range
from 0 to 21. The second value is also rounded down if necessary and may then
range from 0 to 31, and defines the column of the new position. Any characters
then displayed will start at this new position.
In an INPUT statement, AT will change the position on the lower screen that
new prompts appear. The first value moves the prompt position up as it
increases. The second value changes the column as above.
Format
AT int-num-expr, int-num-expr
See also
The value following ATN (y*z above) is the cosine of the required angle and
may range from -1 to 1. ATN the returns the value of the angle in radians. To
convert radians to degrees, multiply the value returned by ATN by 180/PI.
Example
The command
Format
ATN num-const
ATN num-var
ATN (num-expr)
See also
Chapter 10.
ATTR ATTRibutes
Function
ATTR gives the attributes of a specified character position on the screen. These
are the ink and paper colours, brightness and flash status of the character at the
position.
The first value following ATTR (v above) may range from 0 to 23 and is the line
number of a position on the screen. The second value (h above) may range from
0 to 31, and is the column number of the position. ATTR then returns a number
from 0 to 255. This number is the sum of the attributes at the specified position,
and is made up as follows:
Ink colour (0 to 7)
Bright (64)
Flashing (128)
Example
PRINT ATTR(11,16)
ATTR returns one byte in which bit 7 (most significant) is 1 for flashing or 0 for
normal, bit 6 is 1 for bright or 0 for normal, bits 5 to 3 are the paper colour (in
binary) and bits 2 to 0 are the ink colour.
Format
BEEP makes the loudspeaker produce a single note of a given duration and
pitch.
80 BEEP x,y
The first value (x) may range from 0 to 10 and defines the duration of the note in
seconds. The second value (y) may range from -60 to 69 and defines the pitch of
the note in semitones below middle C if negative and above middle C if positive.
Example
The command
BEEP 0.5,1
Format
See also
Chapter 19.
BIN BINary number
BIN turns a binary number into a decimal number.
BIN returns the decimal value of the binary number. It is commonly used in
conjunction with POKE and USR as above for creating user-defined graphics
characters, with 1 signifying a pixel of ink colour, and 0 a pixel of paper colour.
Example
The command
Format
BIN [1][0]
See also
Chapter 14.
BORDER
Statement/Command
BORDER specifies the colour of the border around the screen display area.
30 BORDER RND*7
The value following BORDER is rounded to the nearest integer and specifies the
colour of the border as follows:
0 Black
1 Blue
2 Red
3 Magenta
4 Green
5 Cyan
6 Yellow
7 White
Note that BORDER also sets the paper colour of the lower part of the screen.
Unlike INK and PAPER, a BORDER statement cannot be embedded (inserted)
in a PRINT statement.
Format
BORDER int-num-expr
See also
Chapter 16.
BRIGHT
Statement/Command
80 BRIGHT 1
The value following BRIGHT is rounded to the nearest integer if necessary and
may then be either 0, 1 or 8. A value of 1 causes all characters subsequently
displayed by PRINT or INPUT statements to appear in a brighter ink and paper
colour, and a value of 8 causes bright character positions to remain bright and
normal character positions to remain normal when new characters are printed
there. BRIGHT followed by 0 cancels both BRIGHT 1 and BRIGHT 8 so that all
characters subsequently displayed are normal.
The effect of BRIGHT is then local and applies only to the characters displayed,
point plotted or line drawn by the display statement. Note that BRIGHT 1
brightens the paper colour of the whole character position of 8×8 pixels if any
pixel in the position in plotted in an ink colour.
Format
Chapter 16.
CAT CATalogue
Microdrive file handling command.
The 128k Silicon Disc used the CAT command to list the contents of the disc to
the screen. Files are displayed sequentially in alphabetical order - and start on-
screen at the current PRINT position, using one line per file. The format of the
CAT for this purpose is...
CAT !
See also
Chapter 20
128k Commands in BASin
CHR$ CHaRacter string
Function
The characters and keywords available on the keyboard plus any user-defined
graphics make up the BASIC character set. By using CHR$ and a code number,
each one can be obtained as a string. The character set also contains several
display codes that affect the display of characters. These codes can be brought
into operation on characters displayed by using PRINT before CHR$. The
complete character set can be found here.
80 PRINT CHR$ x
Values from 1 to 31 either return control codes or are not used. CHR$ 6 (PRINT
comma), 8 (back space) and 13 (new line or ENTER) affect displays on the
screen if inluded in a PRINT statement. CHR$ may be followed by the code
value and a semicolon, for example
A B
Another way of using CHR$ control codes is to form a composite string
containing them. The statement
Codes 16 to 23 affect colour and position and each may be used in a composite
string together with CHR$ followed by a colour code value from 0 to 7 for
CHR$ 16 (INK control) and CHR$ 17 (PAPER), or by 0 or 1 for CHR$ 18 to
CHR$ 21 (FLASH, BRIGHT, INVERSE, and OVER controls). The command
displays BASin in flashing red and yellow. Alternatively, as above, each plus (+)
sign may be replaced by a semicolon.
CHR$ 22 (AT control) is followed by two CHR$ values to indicate the line and
column numbers. The command
CHR$ 23 (TAB control) is also followed by two values in the same way. The
second value is normally 0 and the first gives the TAB position. The command
Note that only these controls are available. Using PRINT CHR$ with a keyword
value greater than 164 simply displays the keyword and does not bring it into
operation.
Format
See also
Chapter 14.
CIRCLE
Statement/Command
80 CIRCLE x,y,z
Each of the three values is rounded to the nearest integer if necessary. CIRCLE
then draws a circle on the high resolution graphics grid in the current ink colour.
The first two values (x,y) define the horizontal and vertical coordinates of the
centre, and the third value (z) defines the length of the radius. The dimensions
must be such that the circle does not extend beyond the display area.
Example
The command
CIRCLE 128,88,87
Format
See also
Chapter 17.
CLEAR
Statement/Command
CLEAR deletes the current values of all variables, freeing the memory space that
the values occupied and space as far as RAMTOP, the top address of the BASIC
system area. CLEAR may also be used to reset RAMTOP.
50 CLEAR
CLEAR then delets the values that are currently assigned to all variables,
including arrays. It also executes CLS and RESTORE to clear the screen and
restore the data pointer to the first item of data. In assition, the PLOT position is
reset to the bottom left-hand corner of the display area and the GO SUB stack is
cleared.
Note that CLEAR is not required before re-dimensioning arrays as DIM deletes
an existing array of the same name. Note also that RUN executes CLEAR.
CLEAR 65267
Clear then executes CLEAR as above and also sets RAMTOP, the highest
address of the BASIC system area, to the given value. RAMTOP is normally set
at 65367 in BASIC, and lies below the area reserved for user-defined graphics.
NEW clears out the memory as far as RAMTOP, so using CLEAR to lower
RAMTOP (by 100 bytes in the above example) provides more memory that is
immune from NEW. Raising RAMTOP gives more space for BASIC at the
expense of user-defined graphics. Note that the GO SUB stack is then located at
RAMTOP.
Format
CLEAR [num-expr]
See also
Chapter 24.
CLOSE #
Microdrive file-handling command
CLS CLear Screen
Statement/Command
CLS clears all text and graphics from the display area leaving it blank in the
current paper (background) colour.
The display area (but not the border) is then cleared to the colour selected by the
previous PAPER statement or command or to the default paper colour of white.
Note that CLS must be used after PAPER and before PRINT or any other display
statement to produce a coloured background over the whole display area.
Format
CLS
See also
Chapter 15.
CODE
Function
CODE gives the code number of a character in the BASIC character set (see here
for the complete set).
SAVE/LOAD/VERIFY CODE
CODE is used in a different way with SAVE, LOAD and VERIFY. See their
respective entries for more information.
Format
CODE string-const
CODE string-var
CODE (string-expr)
See also
Chapter 14.
CONTINUE
Command
If a program stops, CONTINUE can be used to restart the program from the
point at which it stopped. If an error has occurred to halt the program, then it
must be rectified before CONTINUE will allow the program to resume.
Format
CONTINUE
See also
Chapter 2.
COPY
Command/Statement
If a program listing appears on the screen, it can be printed by using the COPY
provided it was produced by a LIST command or statement. Note that a listing
will appear in the screen on pressing ENTER after a program has been
completed or stopped, but this 'automatic' listing cannot be printed with COPY.
Format
COPY
See also
Chapter 21.
COS COSine
Function
Note that COS returns a negative value for angles from 90 to 270 degrees and a
positive value for angles from 0 to 90 and 270 to 360 degrees.
Example
The command
Format
COS num-const
COS num-var
COS (num-expr)
See also
Chapter 10.
DATA
Statement
DATA provides a list of items of data within a program. These items may be
values or variables or strings to be displayed, for example. Each item is assigned
to a variable by a READ statement.
Assignment is carried out in the order in which items of data appear in the
program, but RESTORE can be used to begin assignment at the first DATA item
on or following a program line.
50 DATA 31,"JAN",28,"FEB"
Each constant is then assigned to a variable by a READ statement that reads the
DATA. The DATA statement may be positioned anywhere in the program. The
number, kind (numeric or string) and order of the constants must correspond to
the number of times the READ statement is executed and the kind and order of
variables in the READ statement. The list of data may be split up into several
DATA statements if there are too many items to fit into one statement.
Example
10 FOR n=1 TO 2
20 READ x,a$
30 PRINT a$,x;" days"
40 NEXT n
50 DATA 31,"JAN",28,"FEB"
displays
JAN 31 days
FEB 28 days
50 DATA d,m$,d-3,"FEB"
DATA may also be used with LOAD, SAVE and VERIFY to store arrays on
tape. See LOAD DATA, SAVE DATA and VERIFY for more information.
Format
See also
Chapter 6.
DEF FN DEFine FuNction
Statement
DEF FN enables the user to define a function that is not available as a keyword.
A variety of parameters can be passed to the function in an FN statement, which
calls the function and may return either a numeric or string value as a result.
The letter following DEF FN (r above) is a name that identifies the function. The
variables may also only be single letters. Note that in both cases, the BASIC
does not distinguish between capital and lower-case letters.
The expression that follows the equals sign uses the variables (x and y above) to
define the function.
50 PRINT FN r(3,4)
The values in the brackets are passed to the function in the same order as the
variables in the DEF FN statement. Thus, in this example, x is assigned a value
of 3 and y a value of 4. FN evaluates the expression and returns the value.
DEF FN may also be followed by a letter and a pair of brackets only, for
example
The value currently assigned to the variable (x above) is passed to the function
when it is called by FN. In this case, FN r() returns the value currently assigned
to x rounded to the nearest integer.
DEF FN and FN may also be used the same way to define and call a string
function. In this case, the function name is a single letter followed by $ and one
or more of the variables in the statement is a letter followed by $. A
corresponding string expression forms the definition, for example
The string expression following the equals sign in this example is a string slicer,
and x and y are the first and last characters of a section of b$. FN must be
followed by the function name and, in brackets, a string value together with any
other parameters that are to be passed to the function. In this case, the command
PRINT FN a$("FUNDAMENTAL",1,3)
PRINT FN a$("FUNDAMENTAL",5,8)
displays AMEN.
Format
Chapter 9.
DIM DIMension
Statement
10 DIM x(10)
20 DIM z(20,5)
In the first case, a one-dimensional array is created containing ten elements with
subscripts from 1 to 10. The array has the name x and the subscripted variables
are x(1) to x(10) inclusive. Any existing array of the same name is deleted,
and the variables are each assigned a value of 0. Note that in dimensioning an
array, the BASIC does not distinguish between names with capital and lowercase
letters - variable x(2) is the same as X(2). However, simple numeric
variables having the same letter as an array name (x or X) can coexist and may
be used separately if required.
DIM is used in the same way as with numeric arrays except that a single letter
followed by $ is used for the array name. Furthermore, an extra value must be
added to the dimension values in brackets in order to define the length of each
string. For example
30 DIM a$(20,5)
90 DIM b$(20,5,10)
When string values are assigned to a string array, they are padded out with
spaces at the end of the string or truncated to the defined length if necessary.
The elements of a string array are identified by the array name followed, in
brackets, by one or more numeric values giving the subscript number(s). For
example, element a$(2) may be "SMITH" and element b$(12,4) may be
"DERBYSHIRE". However, an extra value may be added to define a particular
character in a string. In these examples, a$(2,2) would be "M" (the second
character in "SMITH"), and b$(12,4,5) would be "Y".
This array has only one element, which is c$, and its length is fixed at the
defined value (15 characters).
Format
See also
Chapter 12.
DRAW
Statement/Command
40 DRAW x,y
A straight line is then drawn on the high-resolution graphics grid from from the
position defined by the previous PLOT statement or the previous DRAW
statement, whichever is last. Both values following DRAW are rounded to the
nearest integer if necessary. The first value (x above) defines the horizontal
distance from this position, and the second value (y) the vertical distance. These
values are negative if the line is to go to the left or down respectively, and the
position reached must be within the display area.
40 DRAW x,y,z
The third value (z above) defines the angle (in radians) through which the line
turns as it is drawn. The line turns to the left if this is positive, and to the right if
it is negative. Values of PI or -PI produce a circle.
Example
10 PLOT 127,50
20 DRAW 70,-100
30 DRAW -140,0
40 DRAW 70,100
Format
See also
Chapter 17.
ERASE
Microdrive file handling command.
Use ERASE with the 128k Silicon Disc to delete files previously saved onto it.
It is recommended that you delete files in reverse order of their creation, i.e the
last to be saved should be the first to be deleted - this will save a lot of time
spent deleting many files. The format for the ERASE command is...
ERASE ! filename
See also
Chapter 20
Keyword Reference - CAT
128k Commands in BASin
EXP EXPonent
Function
60 LET y=EXP x
Example
The command
PRINT EXP 1
Format
EXP num-const
EXP num-var
EXP (num-expr)
See also
Chapter 10.
FLASH
Statement/Command
FLASH causes character positions to flash, making ink and paper colours
alternate at a constant rate.
50 FLASH 1
The value is rounded to the nearest integer if necessary and may then be either 0,
1 or 8. A value of 1 causes all characters subsequently displayed by PRINT or
INPUT to flash. A value of 8 causes flashing character positions to remain
flashing and normal character positions to remain normal when new characters
are printed there. FLASH followed by 0 cancels both FLASH 1 and FLASH 8 so
that all characters subsequently displayed are normal.
The effect of the FLASH is then local and applies only to the characters
displayed, point plotted or line drawn by the display statement. Note that
FLASH 1 causes the whole 8×8 pixel position to flash if any pixel is plotted in
an ink colour.
Format
FLASH int-num-expr[;]
See also
Chapter 16.
FN FuNction
Function
How to use FN
The parameters are then passed to the function called "r". FN then returns the
result. If no parameters are to be passed, then the pair of brackets must still be
included, for example
70 PRINT FN r()
In this case, the function uses the values currently assigned to its variables.
FN calls a string function the same way, except that $ must be added after the
letter (see DEF FN).
FN does work recursively, but care should be taken not to cause an infinite
recursion and eventual memory waste.
Format
See also
Chapter 9.
FOR
Statement/Command
FOR is always used with the keywords TO and NEXT to create a FOR-NEXT
loop. This structure enables a section of the program to repeat a given number of
times.
FOR always forms a statement with TO. FOR is followed by a letter, an equals
sign, and then two numeric values separated by TO, for example
60 FOR a=1 TO 9
The letter (a above) forms a control variable. The statements that are to be
repeated follow, and one or more of these normally makes use of the control
variable. The loop then ends with a NEXT statement, in which NEXT is
followed by the control variable, for example
90 NEXT a
On execution, FOR deletes any variable of the same name as the control variable
and assigns it an initial value equal to the value before TO (1 above). The
statements are then executed with the control variable having this value. On
reaching NEXT, the value of the control variable is increased by 1. If this value
is less than or equal to the value after TO (the limit value 9 above), the program
returns to the FOR statement and the FOR-NEXT loop is repeated. If the control
variable has a greater value than the limit value, then the loop ends and the
program continues with the statement after NEXT.
In the above example, the loop is repeated nine times with the control variable a
increasing from 1 to 9. On leaving the loop, a has a value of 10.
Note that the BASIC does not distinguish between capital and lower-case letters
when naming the control variable.
Using STEP in a FOR-NEXT loop
The control value is increased by the step value (2 above) until it is greater than
the limit value. The control variable a has successive values of 1, 3, 5, 7 and 9
and leaves the loop with a value of 11.
A negative step value causes the control variable to decrease. In this case, the
initial value must be greater than the limit value and the loop ends when the
value of the control variable is less than the limit value, for example
The value of a decreases from 9 to 1 and leaves the loop with a value of 0.
Nesting loops
One or more FOR-NEXT loops may be placed inside each other, a procedure
called "nesting" loops. The order of the control variables in the NEXT
statements must be the reverse of the of the order of the control variables in the
FOR statements. FOR-NEXT loops may be nested to any depth, that is as many
loops as required may be placed inside each other.
Format
See also
Chapter 4.
FORMAT
Microdrive file handling command.
GO SUB GO to SUBroutine
Statement/Command
GO SUB 1000
A subroutine ends with RETURN, and the program then branches back to the
statement following the GO SUB statement. Subroutines may be nested so that
one is reached from another, in which case the RETURN sends the program back
to the statement following the last GO SUB statement executed.
Whenever GO SUB is executed, its line number is placed on the GO SUB stack
in memory. If two or more GO SUBs are executed before RETURN, their line
numbers stack up so that the last number is on top of the stack. RETURN always
takes the top line number from the stack and goes to this line to continue the
program.
Note that error 4 (Out of memory) can occur if there are not enough RETURN
statements.
Format
GO SUB int-num-expr
See also
Chapter 5.
GO TO
Statement/Command
How to use GO TO
60 GO TO 350
Format
GO TO int-num-expr
See also
Chapter 2.
IF
Statement/Command
If is always used with THEN to prompt a decision that affects subsequent action.
To do this, the computer tests something to find out whether or not it is true. If it
is true, then one course of action follows. If it is untrue, another occurs.
80 IF x THEN GO TO 250
240 IF a$="NO" THEN PRINT "THE END": STOP
The BASIC gives a true condition a value of 1 and a false condition a value of 0.
It recognises any non-zero value as true and 0 as false. A variable can be
assigned the value of a condition by a statement such as
70 LET x=a$="NO"
Note that, unlike in some other BASICs, THEN cannot be ommitted before GO
TO.
Format
See also
Chapter 3.
IN
Function
IN checks the status of the keyboard and other input and output devices. It reads
a byte from a given port address that indicates the status of the device connected
to the port.
How to use IN
The value following IN may range from 0 to 65535 inclusive, and specifies the
port address that is to be read. IN then returns the byte read from this port.
Keyboard addresses
The keyboard has eight addresses, each of which may contain one of five
different bytes depending on which key is pressed. The addresses are 65278,
65022, 64510, 63486, 61438, 57342, 49150 and 32766. Byte values at these
addresses may be 175, 183, 187, 189 or 190.
Format
IN num-const
IN num-var
IN (num-expr)
See also
Chapter 23.
INK
Statement/Command
INK specifies the foreground colour in which the characters are displayed, points
plotted and lines and curves drawn.
INK May be used as a direct command but is normally used to form a statement
in a program. It is followed by a numeric value, for example
70 INK x
The value following INK is rounded to the nearest integer and may range from 0
to 9. The following foreground colours are then given.
0 Black
1 Blue
2 Red
3 Magenta (Purple)
4 Green
5 Cyan (Blue-Green)
6 Yellow
7 White
8 Transparent
9 Contrasting Black or White
INK 8 specifies that the existing colour remains unchanged at any position on
the screen where INK 8 is used. INK 9 causes the ink colours to be either black
or white so that it shows up against the paper (background) colour.
When INK forms a statement alone, as above, the colour is global and all
subsequent displays occur in this foreground colour. INK may also be embeeded
in display statements formed by PRINT, INPUT, PLOT, DRAW and CIRCLE.
INK follows the keyword but precedes the data or display parameters; it is
followed by the same values and a semicolon, for example
The effect of INK is then local and applies only to the characters displayed, point
plotted or line drawn by the display statement, this example drawing a green
circle. Thereafter the ink colour reverts to the global colour or default colour of
black.
Format
See also
Chapter 16.
INKEY$ INput KEY string
Function
70 LET a$=INKEY$
130 IF INKEY$="N" THEN STOP
On execution, INKEY$ returns the character given by the key that is being
pressed at that instant. If no key is being pressed, then INKEY$ returns a null
(empty) string (""). Note that INKEY$ distinguishes between capital and lower-
case letters and other shifted and un-shifted characters. (Use IN to detect any key
without distinguishing characters).
Unlike INPUT, INKEY$ does not wait but goes immediately to the next
statement. It is therefore normally placed inside a loop that repeats until the
required key is pressed.
Example
This line suspends operation until the Y key is pressed (without CAPS SHIFT or
CAPS LOCK).
60 IF INKEY$<>"y" THEN GO TO 60
Format
INKEY$
See also
Chapter 18.
INPUT
Statement/Command
60 INPUT x
70 INPUT a$
The computer then waits until either a number or a string is entered. The value is
displayed at the beginning of the bottom line as it is keyed in. On pressing
ENTER, the value is assigned to the named variable and the program continues.
An INPUT statement may include more than one variable and will display
characters to form a prompt. This is done in exactly the same way as with
PRINT, using quote marks to enclose the prompt characters and semicolons or
commas as necessary to separate items. Display statements such as INK, FLASH
and PAPER may be embedded, for example
INPUT LINE may be used with string variables only. Normally, INPUT with a
string variable causes a pair of quotes to be displayed. As the string is keyed in,
it appears between the quotes. To remove these quotes, use INPUT LINE
followed by the string variable. If a prompt is required, it is placed between the
INPUT and LINE, for example
Format
See also
INT changes non-integers (numbers that are not whole numbers) into integers or
whole numbers.
70 LET x=INT y
An expression must be enclosed in brackets. INT then returns the value rounded
down to an integer.
Example
The command
displays
45 -8
Format
INT num-const
INT num-var
INT (num-expr)
See also
Chapter 9.
INVERSE
Statement/Command
70 INVERSE 1
The value following INVERSE is rounded to the nearest integer and may then be
either 0 or 1. INVERSE 1 causes all subsequent displays made by PRINT and
INPUT to be produced using these colours. INVERSE 0 restores the ink and
paper colours to normal.
Note that INVERSE can be embedded (inserted) within display statements in the
same way as INK. However, if used with PLOT, DRAW or CIRCLE then
INVERSE 1 causes a line or point to be plotted in the paper colour so it
disappears.
Format
INVERSE int-num-expr
See also
Chapter 16.
LEN LENgth of string
Function
50 LET x=LEN a$
Example
Format
LEN string-const
LEN string-var
LEN (string-expr)
See also
Chapter 9.
LET
Statement/Command
60 LET x=x+1
80 LET a$="Correct"
Note that simple variables are undefined until assigned values by LET, READ or
INPUT. Array variables however are initialised to 0 or a null string ("") by
DIM.
Format
See also
Chapter 2.
LINE
Modifier
LINE is used in INPUT statements to remove the quote marks around string
inputs, and with SAVE to force a saved program to autostart after loading.
In an INPUT statement with a string variable, you can remove the quotation
marks around the input area and type STOP to break into a program. By using
LINE before the variable, the quotation marks are removed, for example
displays the prompt after "What is your name? " without any quotes.
LINE can also be used in a SAVE statement to save your program in such a
manner as it auto-runs after re-loading. LINE follows the filename in a SAVE
statement, and is followed by a numeric value, for example
When a program is saved in this way, the value following LINE is rounded down
to the nearest integer if necessary, and then may range from 1 to 9999. When the
program is re-loaded, it will automatically start from that line number, or the line
after if it does not exist. Note that when starting, a GO TO is performed, so
variables are not cleared and the screen display is also not cleared.
Format
See also
Chapter 15; INPUT; SAVE
LIST
Command/Statement
LIST
the first page of the listing appears and subsequent pages will scroll up the
screen at the touch of any key except N, the space bar or BREAK at the
"Scroll?" prompt.
LIST may also be followed by a line number, in the form of a numeric value, for
example
LIST 100
The value following LIST is then rounded to the nearest integer if necessary, and
the listing commences at this line. If there is no line with this number then the
listing commences at the next line.
Format
LIST [int-num-expr]
See also
Chapter 2.
LLIST Line printer List
Command/Statement
LLIST is used in exactly the same way as LIST (see LIST for further details).
Note that the screen display does not change as the listing is printed.
Format
LLIST [int-num-expr]
See also
Chapter 21.
LN Logarithm (natural)
Function
LN gives the natural logarithm (the logarithm to base e) of a value. It acts as the
inverse of EXP.
How to use LN
60 LET x=LN y
Format
LN num-const
LN num-var
LN (num-expr)
See also
Chapter 10.
LOAD
Command/Statement
LOAD "filename"
On execution, the program currently in memory, and all the values of its
variables, are deleted. The BASIC then searches for the named program and
loads it when it is located. Note that the computer distinguishes between capital
and lower-case letters in program names.
LOAD ""
Then the BASIC loads the first complete program that it locates. Note: In
BASin, LOAD "" will bring up the Windows file requester for you to locate a
program to load yourself.
LOAD can also be used to access a file stored on the 128k Spectrum's silicon
disc. To do this, insert a ! character between the keyword LOAD and the
filename, for example
LOAD can be used to load types of data other than programs; see the help
entries for LOAD CODE, LOAD DATA and LOAD SCREEN$ for further
information.
Format
LOAD string-expr
See also
Chapter 20.
LPRINT makes Sinclair-type printers print an item of data in the same way that
PRINT causes the item to appear on the screen.
When output to the printer, the items are printed in the same format as PRINT
would cause them to be displayed on the screen. An LPRINT statement or
command may also include TAB, certain CHR$ controls, INVERSE and OVER
statements and control codes with the same effect as PRINT. An AT statement
may also be included, but the line number is ignored, and the item of data
printed at the given column position on the same line.
Format
See also
Chapter 21.
MERGE
Statement/Command
The filename following MERGE is the name of the program to be merged with
the program currently in memory. This name is subject to the same restrictions
as program names used with LOAD. MERGE then loads the new program
without first deleting the existing program. However, the new program
overwrites any lines in the existing program that have the same line numbers as
lines in the new program, and variables with the same name are also overwritten.
MERGE can also be used to access a file stored on the 128k Spectrum's silicon
disc. To do this, insert a ! character between the keyword MERGE and the
filename, for example
MERGE !"bar"
Format
MERGE string-expr
See also
Chapter 20.
NEW clears the BASIC memory area (the area as far as RAMTOP) removing
any program currently in this part of memory.
Format
NEW
See also
Chapter 2.
NEXT
Statement/Command
90 NEXT a
In Sinclair BASIC, the control variable must be included. See FOR for further
details of FOR-NEXT loops.
Format
NEXT letter
See also
Chapter 4.
NOT
Logical Operator
NOT is used to reverse the truth of a condition so that a false condition becomes
true and vice-versa.
or
When NOT is followed by a condition (x=y+z above), the BASIC first assigns a
value of 1 to the condition if it is true and 0 if it is false. NOT then acts as a
function, reversing the value produced, so that the reverse of the condition can
be tested. Note that a condition should be enclosed in brackets if it contains
AND or OR.
Format
NOT cond
NOT num-expr
See also
Chapter 13.
OPEN#
Microdrive file-handling command.
OR
Logical Operator/Function
How to use OR
If any of the conditions is true, then the overall combination is true. In the line
above, one of the conditions (INKEY$="N" and INKEY$="n") becomes true as
soon as the N key is pressed, regardless of whether CAPS SHIFT or CAPS
LOCK is operating or not. The whole combination is then true and the program
stops.
OR as a function
40 LET x=y OR z
This is useful in arithmetic. In the following example, the fare is halved if the
age is less than 14.
Note that the BASIC does not evaluate combinations of numeric values in
accordance with standard truth tables.
Format
cond OR cond
num-expr OR num-expr
See also
Chapter 13.
OUT OUTput to port
Statement/Command
OUT sends a byte to a given input/output port address in order to drive an output
device.
40 OUT 254,3
Both values are rounded to the nearest integer. The first value (254 above) may
then range from 0 to 65535 and is the port address. The second value (3) may
range from 0 to 255 and this is the byte to be sent to the port address.
Bits 0 to 2 of the byte output to port 254 set the border colour; the above
example therefore turns the border magenta. Bit 3 at this address drives the MIC
output, and bit 4 the loudspeaker (for BEEP). Port address 251 drives the printer
and ports 254, 247 and 239 are used with other peripherals.
Format
OUT int-num-expr,int-num-expr
See also
Chapter 23.
OVER
Statement/Command
OVER is used to overprint one character on another. It can also be used to plot
points or draw lines or curves in a paper colour instead of an ink colour.
80 OVER 1
The value following OVER is rounded to the nearest integer and may then be
either 0 or 1. OVER 0, which is the default (preset) state, causes any character to
obliterate a previous character at the same character position and replace it.
OVER 1 causes any two characters displayed at the same character position to
be combined.
However, note that characters are combined so that the paper colour is given
where the ink colours overlap.
OVER may be used with PLOT, DRAW and CIRCLE. Without OVER, lines and
curves can overlap each other, but they must have the same ink colour otherwise
the ink colour in the whole character position changes where they cross. If
OVER 1 is used, lines or curves produce the paper colour where they overlap or
meet characters. Plotting points or drawing lines or curves again in exactly the
same position with OVER 1 cases them to disappear.
Format
OVER int-num-expr
See also
Chapter 16.
PAPER
Statement/Command
PAPER is used to select the paper or background colour used for the screen
display. This may be either the colour of the background of the whole display
area, or the colour behind individual characters, points and lines that appear in
single character positions.
80 PAPER x
The value following PAPER is rounded to the neaerst integer and it may then
range from 0 to 9. The paper colours that are given are the same as those given
by INK. Paper colours may also be global or may be made local by embedding
(inserting) them in display statements in exactly the same way as ink colours.
See INK for further details.
Format
PAPER int-num-expr[;]
See also
Chapter 16.
PAUSE
Statement/Command
The value following PAUSE is rounded to the nearest integer and may then
range from 0 to 65535. It defines the delay that occurs as this number of frames
of the television picture, so that a value of 50 produces a pause of 1 second in th
UK and europe where the frame frequency is 50Hz.
However, note that any pause may be cut short by pressing any key and that
PAUSE 0 gives an unlimited pause that lasts until a key is pressed.
Format
PAUSE int-num-expr
See also
Chapter 18.
PEEK
Function
PEEK gives the value of the byte stored at a particular location in the memory.
80 LET x=PEEK(256*y)
Example
The number of frames of the display that have occurred since the program was
last reset is stored at addresses 23672 to 23674. As the frames are produced at a
regular rate, PEEKing these locations gives a method of measuring time. The
following line displays the time in seconds since the last reset (less any time
spent in producing sounds).
Format
PEEK int-num-const
PEEK int-num-var
PEEK (int-num-expr)
See also
PI gives the value of pi (π) for use in calculations. Pi is the ratio of the
circumference of a circle to its diameter.
How to use PI
DRAW 255,0,-PI
Format
PI
See also
Chapter 10.
PLOT
Statement/Command
50 PLOT 128,87
Both values following PLOT are rounded to integers if necessary. The first value
may then range from 0 to 255 and defines the horizontal coordinate of a position
on the screen. The second value may range from 0 to 175 and defines a vertical
coordinate. A pixel is then normally plotted in the current ink colour at the
defined position - in the above example at the centre of the screen.
These four keywords and INK or PAPER may also be embedded (inserted)
within a PLOT statement in the same way as with PRINT, for example
Their effect is the same but is then local and limited to statement. If colour
statements are embedded this way then the character position on the low-
resolution screen which is occupied by the point plotted will be affected by the
colour changes and assume the given values.
Note that PLOT also defines the starting position of the next DRAW statement.
Format
See also
Chapter 17.
PLAY
Statement/Command
PLAY outputs multi-channel sound effects and music using the 128k Spectrum's
AY-3-8912 sound chip. PLAY is a 128k command and as such introduces certain
limitations to the BASIC you can use.
10 PLAY "ccc","ⅇ","&&g;"
The values following PLAY must equate to strings, and must contain specific
characters. Musical notes are represented by their alphabetical names, with the
current octave in lower-case, with upper-case representing one octave higher.
Note lengths are measured in crotchets, and may range from 1 to 9. Notes to be
played in triplets (three notes played in the time of two) are preceded by 10, 11
and 12 for triplets in semi-quavers, quavers, and crotchets.
String Function
a..g,
Specifies the pitch of the note within the current octave range.
A..G
$ Specifies that the note which follows must be flattened.
# Specifies that the note which follows must be sharpened.
O Specifies the octave number to be used (followed by 0 to 8).
1..12 Specifies the length of notes to be used.
& Specifies that a rest is to be played.
_ Specifies that a tied note is to be played.
N Separates two numbers.
V Specifies the volume to be used (followed by 0 to 15).
W Specifies the volume effect to be used (followed by 0 to 7).
U Specifies that volume effects are to be used in the string.
X Specifies the duration of the volume effect (followed by 0 to 65535).
T Specifies the tempo of the music (followed by 60 to 240).
() Specifies that the enclosed phrase is to be repeated.
!! Specifies that the enclosed text is to be skipped over.
H Specifies that the PLAY command must stop.
M Specifies the channel(s) to be used (followed by 0 to 63).
Y Specifies that a MIDI channel is to be used (followed by 1 to 16).
Z Specifies MIDI programming code (followed by code number).
For further details, see also Chapter 19 of the Sinclair BASIC manual.
Format
See also
Chapter 19.
POINT
Function
POINT is used to find out whether the colour at a particular position on the high-
resolution screen is either an ink colour or a paper colour. POINT does not check
the actual colour itself.
The two values following POINT are rounded to integers if necessary. The first
value may range from 0 to 255 and defines the horizontal coordinate of a pixel
on the screen. The second value may range from 0 to 175 and defines the vertical
component of the coordinate. POINT the returns 1 if the pixel at the defined
position is ink colour or 0 if it is paper colour.
Format
POINT (int-num-expr,int-num-expr)
See also
Chapter 17.
POKE
Statement/Command
POKE is used to change the value of the byte at a particular address in memory.
Values are normally POKEd to memory locations in order to produce actions not
given by BASIC keywords.
POKE 23609,255
The two values following POKE are rounded to the nearest integers if necessary.
The first value may then range from 0 to 65535 and is an address in RAM (Note:
The BASIC ROM inhabits the range from 0 to 16384 and is read-only, so
POKEing to that range will have no effect). The second value may range from
-255 to 255 and is the byte to be written to the defined address.
In the above example, 255 is POKEd to address 23609, which controls the sound
produced when a key is pressed. A value of 255 gives a long beep instead of the
normal click, with other values producing a shorter beep.
Format
POKE int-num-expr,int-num-expr
See also
Chapter 14.
PRINT
Statement/Command
PRINT displays data on the screen. The data may be any single character or a
sequence of characters. A PRINT statement may incorporate other keywords to
define the position and colour of the data.
PRINT may be used alone or it may be followed by data. This data may be in the
form of any numeric or string expressions, or a mixture of these.
When using PRINT with data, two or more separate items must each be
separated by a semicolon, comma or apostrophe.
Certain other keywords may be inserted in any order between PRINT and the
data, provided each statement formed by the keyword ends in a semicolon.
These keywords are CHR$, TAB, AT, INK, PAPER, FLASH, BRIGHT,
INVERSE or OVER.
PRINT alone or followed by a null string ("") displays a blank line and moves
the print-position to the beginning of the next line.
PRINT followed by a string constant (any characters within double quote marks)
displays the characters as they appear between the quote marks. The command
PRINT "3/542/76/32"
displays
3/542/76/32
Very large numbers and very small numbers are displayed in a shorter scientific
notation, as two figures separated by the letter E. This indicates a number in
which the first part (the mantissa) is multiplied by 10 to the power of the second
part (the exponent). The command
PRINT 3/542/76/21
3.4680798E-6
PRINT 1;2;3
displays
123
PRINT 1,2,3
displays
1 2
3
PRINT 1'2'3
displays
1
2
3
PRINT may be followed by TAB, a numeric value, a semicolon and then an item
of data, for example
The value following TAB (x above) is rounded to the nearest integer if necessary
and is then divided by 32 and the remainder returned to give a value of between
0 and 31. The item of data is then displayed at this column position in the same
or the next line.
50 PRINT AT l,c;"Data"
The first value (l above) may range from 0 to 21 and defines the number of the
line or row in which the data will be displayed. The second value (c above) may
range from 0 to 31 and defines the number of the column in which the first
character or digit of the data will be displayed. Non-integer values are accepted
and rounded to the nearest integer. The command
PRINT AT 11,16;"*"
PRINT may also be followed by one or more CHR$ functions. See CHR$ for
more details.
The item of data is then displayed with the attributes specified by the colour
keyword(s). These attributes are local and only apply to the item displayed.
Following execution of the PRINT statement, they revert to their default or
previously declared global values.
Format
See also
RANDOMIZE 1
10 RANDOMIZE
Format
RANDOMIZE [int-num-expr]
See also
Chapter 11.
READ
Statement/Command
READ is used in conjuntion with DATA to assign values to variables using the
values in a DATA statement.
20 READ a$,x
When READ is first executed, it takes the same number of values as there are
variables from the first DATA list and assigns the values to the variables in order.
When READ is next executed, the next set of DATA values is assigned to the
variables named in the READ statement and so on.
Format
See also
Chapter 6.
REM REMark
Statement
REM is used to put remarks or reminders into your program. These may be the
title and author of the program, and explanations of lines in the program such as
the purpose of a variable. The remarks play no part in the running of the program
and can be seen only in the listing.
REM forms either a line of its own in a program or the last statement in a line. It
is followed by any remark that can be keyed in as required, for example
When the BASIC encounters REM, it ignores everything that follows REM on
the line.
Format
See also
Chapter 2.
RESTORE
Statement/Command
RESTORE is used in conjunction with READ and DATA to make READ take
values from a particular DATA statement instead of the first or next DATA
statement in the program.
The value is rounded down to the nearest integer if necessary, and should then be
the number of a line in the program containing a DATA statement. Following
RESTORE, the next READ statement will assign the value contained in this
DATA statement. If the numbered line does not exist or does not contain a DATA
statement, then READ goes to the next DATA statement after this line. If there
are no further DATA statements in the program, then error E (Out of DATA)
results.
Format
RESTORE [int-num-expr]
See also
Chapter 6.
RETURN
Statement/Command
RETURN is used to terminate a subroutine and return the computer to the main
program or a previous subroutine.
1080 RETURN
On execution, the program branches to the statement following the last GO SUB
executed.
Format
RETURN
See also
Chapter 5.
RND RaNDom number
Function
60 LET x=RND
RND then returns a random number less than 1 and greater than or equal to 0.
Many of the BASIC's statements and functions, such as INK and CHR$, round
numbers to the nearest integer and RND may be used with them directly, for
example
INK RND*7
produces an ink colour at random. Others require integers and any whole number
from 1 to x is given by
INT (RND*x)+1
To generate a random integer from 0 to x, use
INT (RND*x+0.5)
Format
RND
See also
Chapter 11.
RUN
Command/Statement
RUN 50
If no value follows RUN then the program runs from the first line. If a value is
included, it is rounded down to the nearest integer if necessary and the program
then runs from this line. If the line does not exist, the program runs from the next
line in the program. Note that RUN performs CLEAR before running the
program, so that variable values are are erased. To avoid this, use GO TO
followed by a line number.
If a program has been saved using LINE, then it runs automaticaly on loading
and RUN is not required.
Format
RUN [int-num-expr]
See also
Chapter 2.
SAVE
Statement/Command
SAVE "filename"
The filename may contain up to ten characters. Specifying an empty or null ("")
filename will bring up a windows requester to prompt you for a filename. On
execution, the message
Automatic running
The value following LINE is rounded down if necessary, and should then be
either 1 or the number of a line in the program. The program is then sent to the
file in the same way as a normal SAVE. On loading, the program starts
automatically from the line having defined the line number or, if no such line
exists, from the next line in the program. In practice, using LINE 1 causes the
whole program to run automatically.
Note that an auto-running program will not clear variables or the screen
(effectively, the program uses a GO TO instead of a RUN to start the program).
SAVE can also be used to store a file on the 128k Spectrum's silicon disc. To do
this, insert a ! character between the keyword SAVE and the filename, for
example
You can use any of the commands used with SAVE such as CODE, DATA or
SCREEN$.
The silicon disc stores just under 64kb of data, and is very useful for rapid access
to stored information which would otherwise take up too much memory.
SAVE can also store other types of data - sections of memory and variable arrays
can be stored, and SAVE also has a special command to save the screen display.
See SAVE CODE, SAVE DATA, and SAVE SCREEN$ for further information
Format
See also
Chapter 20.
The values following SCREEN$ are rounded down to the nearest integer if
necessary. The first value (l above) may then range from 0 to 21 and gives the
line (or row) number of a position on the screen. The second value (c above)
may range from 0 to 31 and gives the column number of the position. SCREEN$
then returns the character displayed at this position as a string constant (the
character in quote marks, "X" above for example). If no character is present (or
recognisable) at this position, SCREEN$ returns a null (empty) string ("").
SCREEN$ cannot detect user-defined graphics unless they are identical to
regular alpha-numeric characters.
Note that SCREEN$ may also be used with SAVE and LOAD to store the screen
display in a file and also to load it from that file. See SAVE SCREEN$ and
LOAD SCREEN$ for further details.
Format
See also
Chapter 15.
SGN SiGN
Function
50 LET x=SGN y
Format
SGN num-const
SGN num-var
SGN (num-expr)
See also
Chapter 9.
SIN SINe
Function
80 LET x=SIN y
A expression must be enclosed in brackets. The value following SIN is the angle
in radians, and SIN returns the sine of the angle. Degrees can be converted into
radians by multiplying by PI/180.
Note that SIN returns a positive value for angles between 0 and 180 degrees, and
a negative value for angles between 180 and 360 degrees.
Example
The command
Format
SIN num-const
SIN num-var
SIN (num-expr)
See also
Chapter 10.
SQR SQare Root
Function
70 LET x=SQR y
Format
SQR num-const
SQR num-var
SQR (num-expr)
See also
Chapter 9.
STEP
See FOR, also Chapter 4.
STOP
Statement/Command
650 STOP
9 STOP statement
appears with the line and statement at which the program halted.
Format
STOP
See also
Chapter 2, Chapter 3.
STR$ STRing
Function
90 LET a$=STR$ x
Format
STR$ num-const
STR$ num-var
STR$ (num-expr)
See also
Chapter 9.
TAB TABulate
PRINT/INPUT modifier
TAB changes the position on a line that PRINT and INPUT items appear.
The value following TAB is rounded down to the nearest integer if necessary,
and may range from 0 to 31 - values greater than 31 will be divided by 32 and
the remainder used as the TAB value. Any characters subsequently displayed
will appear at that column on the screen.
TAB can also be used in exactly the same manner with INPUT items.
Format
TAB int-num-expr
See also
Note that TAN returns a positive value for angles between 0 and 90 degrees. For
angles between 90 and 180 degrees and angles between 270 and 360 degrees,
TAN returns a negative value.
Format
TAN num-const
TAN num-var
TAN (num-expr)
See also
Chapter 10.
THEN
Statement
If the condition (x=0 above) is true then the program PRINTs "YOU LOSE!"
and then executes a STOP statement. If x is any other value then neither of the
statements following THEN will be executed, and the program will continue on
to the next line.
Format
See also
Chapter 3.
TO
String Slicer
TO has two different uses in BASIC. It is used in conjunction with FOR to set up
a FOR-NEXT loop (see FOR for further details) and it is also used in string
slicing (the splitting up of strings into smaller sub-strings).
TO is used to define the first and last characters of a sub-string within a main
string. TO is preceded by a string value, an opening bracket, then an optional
numeric value. It is followed by an optional numeric value and then a closing
bracket, for example
80 PRINT a$(4 TO 7)
A string expression must also be enclosed in brackets. The string value (a$
above) is the string that is to be sliced. The two numeric values (4 and 7) define
the positions of the first and last characters of the sub-string within the string.
TO then returns the sub-string (characters 4 to 7 inclusive, of a$).
The first numeric value has a default value of 1 and the second has a default
value equal to the position of the last character in the string. The first value can
therefore be omitted if the sub-string begins with the first character in the string,
and the second value can be omitted if the sub-string ends with the last character
in the string.
Format
See also
Chapter 4, Chapter 8.
USR User SubRoutine
Function
USR is used to call a machine code subroutine that has been placed in memory
at a specified address. It is also used to place the data for a user-defined graphics
character in the reserved locations at the top of the memory.
the string value following USR may be a single letter ranging from A to U, or a
to u, capital letters not being distinguished from lower-case letters.
USR then returns the starting address of one of the 21 sections of memory
reserved for user-defined graphics. Each section contains eight addresses to
which eight bytes are POKEd to create one graphics character. The bytes may be
given in decimal form or in binary (see BIN).
Format
USR int-num-const
USR int-num-var
USR (int-num-expr)
USR string-const
USR string-var
USR (string-expr)
See also
VAL changes a string with a numeric value contained within into a number.
70 LET x=VAL a$
The value of the string constant or variable is stripped of its quotation marks,
and must then be a numeric value. VAL then evaluates this, returning it as a
numeric value.
Examples
If a$ has the value "435" then the above statement assigns a value of 435 to x.
However, VAL can also evaluate expressions, for example
10 INPUT a$,x
20 PRINT VAL a$
Format
VAL string-const
VAL string-var
VAL (string-expr)
See also
Chapter 9.
VAL$ VALue (string)
Function
The value of the string variable is stripped of its quotation marks, and must then
be a string expression. VAL$ evaluates the expression and returns the value as a
string constant.
Examples
10 INPUT a$,x$
20 PRINT VAL$ a$
The string value that is assigned to a$ should be an expression using x$, for
example "x$+x$". A string value is then assigned to x$, for example "DO".
VAL$ strips the quotes of the value of a$ to get x$+x$ and evaluates it using
the value assigned to x$, displaying the result DODO.
Format
VAL$ string-var
VAL$ string-const
VAL$ (string-expr)
VERIFY
Command/Statement
VERIFY checks that a program has been correctly stored following SAVE.
VERIFY "filename"
When the VERIFY process is started, the name of every file is displayed and any
program found that has the same name is compared with the program in
memory. If the two are found to be the same, byte for byte, the report
0 OK, 0:1
is given.
VERIFY CODE can be used in exactly the same way as LOAD CODE to verify
that a section of memory information has been stored correctly. VERIFY DATA
works in the same way as LOAD DATA to check that an array has been stored
without error. See LOAD CODE and LOAD DATA for further details.
Format
VERIFY string-expr
VERIFY string-expr CODE [int-num-expr] [,int-num-expr]
VERIFY string-expr DATA letter[$]()
See also
Chapter 20.
Contact Retro Computers Ltd
By email
Should you have any questions about BASin then you should send a message to
the publisher.
http://everychildcancode.com/contact-us/
You can contact Retro Computers Ltd via Facebook and Twitter:
https://www.facebook.com/retrocomputersltd
https://twitter.com/sinclairzxvega
Credits
BASin was written by Paul Dunn. The help files were written by Paul E
Collins and Paul Dunn, with contributions from Andrew Owen, and were
compiled into Microsoft HTML Help format by Paul E Collins.
BASin would not have been possible without the invaluable help of all those
who reported bugs, suggested features, and assisted with the coding. The author
would especially like to thank the SPIN team (Mark Boyd, Woody, and
Damien Guard) for their help and encouragement - notably Mark Boyd's
contributions to the user interface and assembler, Woody's help with the main
emulation core, and Damien's help with the user interface - and for creating such
fantastic fonts for the editor to use.
On start-up, the Editor will appear, and after a short pause, the display will run
through the Spectrum ROM's start-up sequence. The display will go from white,
to black (with red vertical lines) and finally back to white with the message
at the bottom. The Editor will then become active, ready for programming.
Display capabilities
For BASIC programming purposes, the Spectrum display has three distinct
regions:
BASin, by default, displays the Spectrum screen as a 320 × 240 pixel bitmap. On
a higher display resolution, this can make the display appear quite small. To
circumvent this limitation, the display window can be re-sized, by using the
mouse to grab the strip between the editor and the display area. Aspect ratio is
always preserved.
To learn about the resolution and colour depth of the Spectrum display, see What
is a Sinclair Spectrum?.
Editor Fonts tab
The Editor Fonts tab can be found in the Options window.
BASin's editor can use other fonts if you wish, rather than the standard sinclair
font. These fonts are any file (either a binary dump or a .bsc file) which holds
768 bytes. This data is then used to form the font used by the editor.
Fonts can be created and edited using the UDG Editor. They can also be loaded
by your programs and used (with a little modification to the CHARS system
variable) as the default font by BASIC.
Font Folder
BASin will, on startup and when the options window opens, search for fonts that
can be used by the editor. BASin will search the folder specified here, and
recurse any subdirectories in that folder. The list of fonts gathered will be used in
the Font Filename option.
If no fonts can be found, the only option available to you will be the default
Sinclair Font which is built into BASin and into the ROM.
Clicking the Font Filename list-box will bring up a small tree-view of all the
folders in the Font Folder, and all the fonts found in them. Folders with no fonts
will not be shown. You can scroll through the list and find a font which you like
the look of, and select it to activate it.
You can get a preview image of your font at the bottom of the window. This will
show all 96 characters used in the character set. As you can see, some fonts are
not really suitable for use in the editor, but will look very nice in the right
context - perhaps a game.
Syntax Highlighting
As you work in BASin, with Syntax highlighting enabled you will notice that
some words are coloured differently. This is more than just cosmetic - you can
identify errors (especially with variables) in your code quite easily this way.
You can enable or disable syntax highlighting with the checkbox below the fonts
list. Setting the options opens a new window:
The options here are applicable for each element that you can highlight. The
checkbox next to each item can turn on or off highlighting for that element, and
the colour palette below chooses the colour you want for that item. You can also
choose for it to be either bold-faced or Italicised.
Symbols - Any symbol character - i.e., from ASCII 33, "!" character
through to 127, the Copyright symbol.
Variables - Variables that are valid, and have a corresponding entry in the
VARS space in memory.
Strings - All string literals - any string of any characters enclosed in quote
marks.
Each file on a tape comes, most usually, in two parts. The “header” gives
information to the Spectrum about the file that is coming from the tape, such as
the name, the type of data (a program, a memory block or a variable) and the
size of the data. Following this header is the main body of the file.
Note: It is worth mentioning that BASin treats each header and body pair as a
single file, unless the data has no header in which case it is flagged as
“headerless”.
Because the data saved to the tape image is a direct copy of the bytes saved, it is
trivial to just “inject” the data back to memory – after all, the header provides
information about where it came from originally. Unfortunately, the .tap format
cannot reproduce the sounds made by the newer, faster loaders employed by
games companies in their nigh-on constant fight to get quicker load times and
prevent software piracy. The .tzx format, however, can reproduce any sound the
Spectrum can produce. The .tzx format, as far as BASin is concerned, is very
similar to the .tap format – it just adds a couple of extra bytes to the blocks with
some more detailed information about it.
For the technically minded, the .tap format for a block is as follows:
2 Flag byte (0 for a header, 255 for the body of the file)
3..xx These bytes are the data of the block itself - either the header or the main body
1..2 The length of the pause after this block in milliseconds (1000ms default)
5 Flag byte (0 for a header, 255 for the body of the file)
6..xx These bytes are the data of the block itself - either the header or the main body
13..14 Auto Start Variable a..z Variable a..z Start Address Various
Note that the Number and String variable types have their “name” from A to Z
stored in one byte – the high byte at position 14, and do not use the byte at
position 13. Programs store their length twice – once for the whole block and
once for just the BASIC text, without the variables.
Files tab
The Files tab can be found in the Options window.
Files in BASin can be manipulated in various ways, and as these options become
available, they can be set here. For this release, the options are:
Snapshots
The .z80 format was developed by Gerton Lunter for his spectrum
emulator, Z80. This format underwent a few revisions as his emulator gained
new features, and the different versions are backwardly incompatible with
eachother. For this reason, you can elect to save your .z80 Snapshots
using any of the major revision types. The most common nowadays is probably
the v3.5 option.
When saving a snapshot, BASin will examine your program and silicon disc (if
it has been used) and decide which hardware model to use to save (48k or 128k).
This can be overriden here by choosing to save as one particular type (if there is
a choice) or to ask you before it saves.
.bas files
Lines with more than one statement can be made more readable in .bas
files (particularly when reading them in a text editor) by splitting the
statements up so that only one statement occupies each line. This is done by
appending a backslash ("\") character to the end of each line, after the trailing
colon (":"). This will not affect the way that BASin handles this file in the
future, it is provided for better readability only.
Trap LOAD/MERGE/VERIFY
This will toggle BASin's ability to load directly from tape images held in the
Tape Creator Window, instead of loading files from your PC's Hard Disk. This
can be useful for loading a complete tape into memory without having to
manually extract the files first. While this option is enabled, you will not be able
to load files from disk.
This option will, when loading from a tape, automatically rewind the tape when
it reaches the end, by setting the current tape position in the Tape Creator
Window to the first block. Be aware that continuous LOAD commands will
continue to load from the tape until the user BREAKs the operation with the
ESC key.
SAVE CODE
Statement/Command
The filename following SAVE may contain up to ten characters. The two values
following CODE are each rounded down to the nearest integer if necessary. The
first then gives the starting address (16384 above) of the information in the
memory, and the second value (6912) gives the number of bytes that are to be
sent to the file in the same way as a program, using SAVE.
The information saved by the above command is the screen display area.
Format
See also
Chapter 20.
LOAD CODE
Command/Statement
LOAD CODE is used to load a section of memory with information that has
been stored in a file. The information consists of a set of bytes, and these are sent
to a set of addresses in memory. LOAD CODE can be used to load a display, or
to load information for user-defined graphics, for example.
The filename following LOAD is the name of the information to be loaded and
is subject to the same restrictions as program names (see LOAD. LOAD CODE
then searches for the named information and when found, displays Bytes:
followed by the name. The BASIC then loads the bytes into memory at the
addresses from which they were saved. Any existing information is overwritten.
The values following CODE are rounded to the nearest integer and then define
the starting address (16384 above) at which the named information is to be
loaded, and the number of bytes (6912) that are to be sent to locations beginning
at this address. If the number is wrong, the tape loading error report is given. If
only one value follows CODE, it defines the starting address from which all the
bytes are to be located.
The above example can also be carried out by the keywords LOAD SCREEN$.
For details on storing bytes, see SAVE CODE.
Format
See also
Chapter 20.
SAVE DATA
Statement/Command
SAVE DATA stores an array variable in a file. The array can then be loaded
using LOAD DATA.
The array's filename may contain up to ten characters. The letter or letter$
following DATA us the name of the array in the program that is to be stored in a
file. The array is then sent to the file in the same was as a program is using
SAVE.
Format
See also
Chapter 20.
System Variables window
The System Variables window is available from the View menu.
This window allows the user to inspect and modify the contents of the System
Variables used by the BASIC to monitor certain aspects of the program. The list
shows the contents of all the variables, and updates as dictated by the user. You
can elect, using the drop down box at the bottom left of the window, to update:
You can get an explanation of each variable by hovering the mouse over it's
entry and waiting for the ToolTip to appear.
You can edit any of the variables by either right clicking and choosing "Edit this
Sysvar", or by clicking the "Edit" button at the bottom of the window. In the
main, this will produce an editor very similar to the Variables Window's editor
for numeric variables, except in the case of the longer multi-byte system
variables (such as STRMS) which will open the Memory Viewer in edit mode at
the location of this variable.
Lastly, you can elect to add any of the variables to the Watch Window by right
clicking and choosing "Watch this Sysvar".
ZX printer output window
The ZX printer output window is available from the View menu.
This window holds all output sent to the ZX Printer via the LLIST, LPRINT and
COPY commands, along with any commands that have their output sent to the
printer stream.
Note: This window will only accept printer output when it is visible (open). If it
is closed, then the printer will be "Offline" and will not display any new printer
data until it is opened again.
BASin can accelerate the ROM printing commands, by trapping the stream of
bytes to be sent to the printer and converting them into graphics a lot quicker
than by just trapping individual pixels. This behaviour can be turned on or off in
the BASin Options Window, using the Emulation Tab. Also in that section of the
options is an option to save the current printer output when you quit BASin - and
to automatically reload it when you next start up.
Along the bottom of the window are a set of buttons which provide functionality
for working with the printed output. These, from left to right, are:
Buttons
Opens the Print Preview Window with the ZX Printer output ready configured to
print.
This button will simulate the "tearing off" of the paper currently printed, and
give you a fresh clean output sheet. You will be given the option to save the
output as a Windows Bitmap (.bmp) file before it is cleared.
The ROM COPY command does not include the lower two lines of the display
when printing. This button will swiftly send the entire display to the printer.
There is a choice of two methods when using this button - the first will send just
the Display File area of the Spectrum's memory, with no attributes. This is very
similar to the way the ROM's COPY command works. The other option will
send the attributes too, to get a colour screen grab.
Close
Closes the ZX Printer Output window. Note that when the printer window is
closed, the printer is classed as "offline" and no further output will be sent to it.
The Display Window menu
This menu controls the size and visibility of the display window, and provides an
option to print the contents of the display window.
Note: In the display window, text can only be selected with the keyboard - not
with the mouse. Using the mouse is planned for a future release of BASin.
The current display can be sent as-is to the Print Preview Window for sending to
your PC printer. The display will be sent exactly as it appears in the display
window including any scaling effects.
Appendix D: Example programs
This appendix contains some example programs.
The first of these programs requires a date to be input and gives the day of the
week which corresponds to this date.
5 RANDOMIZE
10 FOR m=1 TO 6:
REM for 6 throws
20 LET c=0:
REM initialize coin total to 0
30 FOR n=1 TO 3:
REM for 3 coins
40 LET c=c+2+INT (2*RND)
50 NEXT n
60 PRINT " ";
70 FOR n=1 TO 2:
REM 1st for the thrown hexagram, 2nd
80 PRINT "___";
90 IF c=7 THEN
PRINT " ";
100 IF c=8 THEN
PRINT " ";
110 IF c=6 THEN
PRINT "X";:
LET c=7
120 IF c=9 THEN
PRINT "0";:
LET c=8
130 PRINT "___ ";
140 NEXT n
150 PRINT
160 INPUT a$
170 NEXT m:
NEW
To use this, type it in and run it, and then press Enter five times to get the two
hexagrams. Look these up in a copy of the Chinese Book of Changes. The text
will describe a situation and the courses of action appropriate to it, and you must
ponder deeply to discover the parallels between that and your own life. Press
Enter a sixth time, and the program will erase itself this is to discourage you
from using it frivolously.
Many people find the texts are always more apt than they would expect on
grounds of chance; this may or may not be the case for you. In general,
computers are pretty godless creatures.
Here is a program to play 'Pangolins'. You think up an animal, and the computer
tries to guess what it is, by asking you questions that can be answered 'yes' or
'no'. If it's never heard of your animal before, it asks you to give it some question
that it can use next time to find out whether someone's given it your new animal.
5 REM Pangolins
10 LET nq=100:
REM number of questions and animals
15 DIM q$(nq,50):
DIM a(nq,2):
DIM r$(1)
20 LET qf=8
30 FOR n=1 TO qf/2-1
40 READ q$(n):
READ a(n,1):
READ a(n,2)
50 NEXT n
60 FOR n=n TO qf-1
70 READ q$(n):
NEXT n
100 REM start playing
110 PRINT "Think of an animal.","Press
120 PAUSE 0
130 LET c=1:
REM start with 1st question
140 IF a(c,1)=0 THEN
GO TO 300
150 LET p$=q$(c):
GO SUB 910
160 PRINT "?":
GO SUB 1000
170 LET inn=1:
IF r$="y" THEN
GO TO 210
180 IF r$="Y" THEN
GO TO 210
190 LET inn=2:
IF r$="n" THEN
GO TO 210
200 IF r$<>"N" THEN
GO TO 150
210 LET c=a(c,inn):
GO TO 140
300 REM animal
310 PRINT "Are you thinking of"
320 LET P$=q$(c):
GO SUB 900:
PRINT "?"
330 GO SUB 1000
340 IF r$="y" THEN
GO TO 400
350 IF r$="Y" THEN
GO TO 400
360 IF r$="n" THEN
GO TO 500
370 IF r$="N" THEN
GO TO 500
380 PRINT "Answer me properly when I'm"
GO TO 300
400 REM guessed it
410 PRINT "I thought as much.": GO TO 8
500 REM new animal
510 IF qf>nq-1 THEN
PRINT "I'm sure your animal is very
GO TO 800
520 LET q$(qf)=q$(c):
REM move old animal
530 PRINT "What is it, then?":
INPUT q$(qf+1)
540 PRINT "Tell me a question which dis
550 LET p$=q$(qf):
GO SUB 900:
PRINT " and"
560 LET p$=q$(qf+1):
GO SUB 900:
PRINT " "
570 INPUT s$:
LET b=LEN s$
580 IF s$(b)="?" THEN
LET b=b-1
590 LET q$(c)=s$(TO b):
REM insert question
600 PRINT "What is the answer for"
610 LET p$=q$(qf+1):
GO SUB 900:
PRINT "?"
620 GO SUB 1000
630 LET inn=1:
LET io=2:
REM answers for new and old animals
640 IF r$="y" THEN
GO TO 700
650 IF r$="Y" THEN
GO TO 700
660 LET inn=2:
LET io=1
670 IF r$="n" THEN
GO TO 700
680 IF r$="N" THEN
GO TO 700
690 PRINT "That's no good. ":
GO TO 600
700 REM update answers
710 LET a(c,inn)=qf+1:
LET a(c,io)=qf
720 LET qf=qf+2:
REM next free animal space
730 PRINT "That fooled me."
800 REM again?
810 PRINT "Do you want another go?":
GO SUB 1000
820 IF r$="y" THEN
GO TO 100
830 IF r$="Y" THEN
GO TO 100
840 STOP
900 REM print without trailing spaces
905 PRINT " ";
910 FOR n=50 TO 1 STEP -1
920 IF p$(n)<>" " THEN
GO TO 940
930 NEXT n
940 PRINT p$(TO n);:
RETURN
1000 REM get reply
1010 INPUT r$:
IF r$="" THEN
RETURN
1020 LET r$=r$(1):
RETURN
2000 REM initial animals
2010 DATA "Does it live in the sea",4,2
2020 DATA "Is it scaly",3,5
2030 DATA "Does it eat ants",6,7
2040 DATA "a whale", "a blancmange", "a
Here is a program to draw a Union Flag.
Here is a program to play hangman. One player enters a word, and the other
guesses.
5 REM hangman
10 REM set up screen
20 INK 0:
PAPER 7:
CLS
30 LET x=240:
GO SUB 1000:
REM draw man
40 PLOT 238,128:
DRAW 4,0:
REM mouth
100 REM set up word
110 INPUT w$:
REM word to guess
120 LET b=LEN w$:
LET v$=" "
130 FOR n=2 TO b:
LET v$=v$+" "
140 NEXT n:
REM v$=word guessed so far
150 LET c=0:
LET d=0:
REM guess & mistake counts
160 FOR n=0 TO b-1
170 PRINT AT 20,n;" ";
180 NEXT n:
REM write 's instead of letters
200 INPUT "Guess a letter ";g$
210 IF g$="" THEN
GO TO 200
220 LET g$=g$(1):
REM 1st letter only
230 PRINT AT 0,c;g$
240 LET c=c+1:
LET u$=v$
250 FOR n=1 TO b:
REM update guessed word
260 IF w$(n)=g$ THEN
LET v$(n)=g$
270 NEXT n
280 PRINT AT 19,0;v$
290 IF v$=w$ THEN
GO TO 500:
REM word guessed
300 IF v$<>u$ THEN
GO TO 200:
REM guess was right
400 REM draw next part of gallows
410 IF d=8 THEN
GO TO 600:
REM hanged
420 LET d=d+1
430 READ x0,y0,x,y
440 PLOT x0,y0:
DRAW x,y
450 GO TO 200
500 REM free man
510 OVER 1:
REM rub out man
520 LET x=240:
GO SUB 1000
530 PLOT 238,128:
DRAW 4,0:
REM mouth
540 OVER 0:
REM redraw man
550 LET x=146:
GO SUB 1000
560 PLOT 143,129:
DRAW 6,0, PI/2:
REM smile
570 GO TO 800
600 REM hang man
610 OVER 1:
REM rub out floor
620 PLOT 255,65:
DRAW -48,0
630 DRAW 0,-48:
REM open trapdoor
640 PLOT 238,128:
DRAW 4,0:
REM rub out mouth
650 REM move limbs
655 REM arms
660 PLOT 255,117:
DRAW -15,-15:
DRAW -15,15
670 OVER 0
680 PLOT 236,81:
DRAW 4,21:
DRAW 4, 21
690 OVER 1:
REM legs
700 PLOT 255,66:
DRAW -15,15:
DRAW -15,-15
710 OVER 0
720 PLOT 236,60:
DRAW 4,21:
DRAW 4,-21
730 PLOT 237,127:
DRAW 6,0,-PI/2:
REM frown
740 PRINT AT 19,0;w$
800 INPUT "again? ";a$
810 IF a$="" THEN
GO TO 850
820 LET a$=a$(1)
830 IF a$="n" THEN
STOP
840 IF a$(1)="N" THEN
STOP
850 RESTORE:
GO TO 5
1000 REM draw man at column x
1010 REM head
1020 CIRCLE x,132,8
1030 PLOT x+4,134:
PLOT x-4,134:
PLOT x,131
1040 REM body
1050 PLOT x,123:
DRAW 0,-20
1055 PLOT x,101:
DRAW 0,-19
1060 REM legs
1070 PLOT x-15,66:
DRAW 15,15:
DRAW 15,-15
1080 REM arms
1090 PLOT x-15,117:
DRAW 15,-15:
DRAW 15,15
1100 RETURN
2000 DATA 120,65,135,0,184,65,0,91
2010 DATA 168,65,16,16,184,81,16,-16
2020 DATA 184,156,68,0,184,140,16,16
2030 DATA 204,156,-20,-20,240,156,0,-16
Appendix C
Appendix E
Appendix E: Binary and hexadecimal
This appendix describes how computers count, using the binary system.
Most European languages count using a more or less regular pattern of tens - in
English, for example, although it starts off a bit erratically, it soon settles down
into regular groups:
and so on, and this is made even more systematic with the Arabic numerals that
we use. However, the only reason for using ten is that we happen to have ten
fingers and thumbs.
Instead of using the decimal system, with ten as its base, computers use a form
of binary called hexadecimal (or hex, for short), based on sixteen. As there are
only ten digits available in our number system we need six extra digits to do the
counting. So we use A, B, C, D, E and F. And what comes after F? Just as we,
with ten fingers, write 10 for ten, so computers write 10 for sixteen. Their
number system starts off:
Hex English
0 nought
1 one
2 two
: :
: :
9 nine
just as ours does, but then it carries on
A ten
B eleven
C twelve
D thirteen
E fourteen
F fifteen
10 sixteen
11 seventeen
: :
: :
9 twenty five
1A twenty six
1B twenty seven
: :
: :
1F thirty one
20 thirty two
21 thirty three
: :
: :
9E one hundred and fifty ei
9F one hundred and fifty ni
A0 one hundred and sixty
A1 one hundred and sixty on
: :
B4 one hundred and eighty
: :
FE two hundred and fifty fo
FF two hundred and fifty fi
100 two hundred and fifty si
If you are using hex notation and you want to make the fact quite plain, then
write 'h' at the end of the number, and say 'hex'. For instance, for one hundred
and fifty eight, write '9Eh' and say 'nine E hex'.
You will be wondering what all this has to do with computers. In fact, computers
behave as though they had only two digits, represented by a low voltage, or off
(0), and a high voltage, or on (1). This is called the binary system, and the two
binary digits are called bits: so a bit is either 0 or 1.
To convert hex to binary, change each hex digit into four bits, using the table
above.
To convert binary to hex, divide the binary number into groups of four bits,
starting on the right, and then change each group into the corresponding hex
digit.
For this reason, although strictly speaking computers use a pure binary system,
humans often write the numbers stored inside a computer using hex notation.
The bits inside the computer are mostly grouped into sets of eight, or bytes. A
single byte can represent any number from nought to two hundred and fifty five
(11111111 binary or FF hex), or alternatively any character in the ZX Spectrum
character set. Its value can be written with two hex digits.
Two bytes can be grouped together to make what is technically called a word. A
word can be written using sixteen bits or four hex digits, and represents a
number from 0 to (in decimal) 2562 = 65535.
A byte is always eight bits, but words vary in length from computer to computer.
You can only use 0's and 1's for this, so the number must be a non negative
whole number; for instance you can't write 'BIN -11' for minus three - you
must write '-BIN 11' instead. The number must also be no greater than
decimal 65535 - i.e. it can't have more than sixteen bits.
ATTR really was binary. If you convert the result from ATTR into binary, you
can write it in eight bits.
The colour codes also use binary: each code written in binary can be written in
three bits, the first for green, the second for red and the third for blue.
Black has no light at all, so all the bits are 0 (off). Therefore the code for black is
000 in binary, or nought.
The pure colours, green, red and blue have just one bit 1 (on) out of the three.
Their codes are 100, 010 and 001 in binary, or four, two and one.
The other colours are mixtures of these, so their codes in binary have two or
more bits 1.
Appendix D
GO SUB stack window
The GO SUB stack window is available from the View menu.
The GO SUB stack is a region of memory which keeps track of where your
program came from when it executes a GO SUB command. When a RETURN
is subsequently executed, the last location stored on this "stack" is taken off, and
program execution is sent to that location. This enables you to run subroutines in
your program to take the tedium out of doing repetitive functions, and to
organise things into blocks of code. As each GO SUB is executed, this stack
grows in size. Correspondingly, each RETURN executed will shrink the stack.
line-number:statement-number
Click Show Source to jump to the selected line and statement in the editor.
BEEP Composer window
The Beep Composer window is available from the Tools menu.
This tool is not yet fully implemented. When finished, it will allow you to
compose music visually, using staff notation, and convert it to BEEP statements.
Sound tab
The Sound tab can be found in the Options window.
Sound settings
You can use the options here to turn on or off the Beeper or Editor sounds, and
what type of Editor sounds you want to hear.
Beeper/AY
If this box is checked, BASin plays sounds produced by the BEEP command or
by manipulation of port $FE (254) in machine code, and also the AY chip's
output from the AY's registers or the PLAY command. If it is not checked,
beeper and AY sound is muted, but the emulated Spectrum still pauses while it is
being played.
Editor sounds
If this box is checked, the editor generates a click for each keypress, a high beep
when a program line is successfully entered, and a low beep when a line is
rejected because it contains a syntax error, or already exists.
MIDI Device
BASin can, when emulating the PLAY command, drive any MIDI device
attached to your PC. Generally, this will be your sound card but you can use this
menu to choose any device you have - this includes keyboards, drum machines
etc. Choosing "None" will disable MIDI output.
Volume
This part of the sound options provides a simple slider which allows you to set
the volume of the sounds produced by BASin. To the left is the minimum, or
silent volume, and to the right of the slider is the maximum. This affects all
sound within both the Editor Window and the main emulated sound from your
programs.
Quality settings
Here you can set how accurate and smooth the sound made by BASin is. Higher
settings will result in much crisper, cleaner sounds at the expense of greatly
increased CPU usage, whereas lower quality will sound much more coarse, but
will consume less CPU time.
Frequency (Hz)
This setting, at either 44100, 22050 or 11250 samples per second (Hertz, or Hz)
will set how often BASin "samples" the beeper port to create the sound. Higher
settings will consume more CPU time, but will produce much higher quality
sound.
Bit depth
The bit depth can be either 8 or 16 bit, which increases the range of volume
granularity that BASin can produce. This setting will use more CPU at 16 bit
than at 8 Bit, but will probably have very little effect on sound quality as the
Spectrum's Beeper is only capable of a square-wave type sound, which has no
graduated volume setting.
Stereo
This will allow you to choose either stereo or monaural output. This, like the bit
depth, will not have much impact other than increased CPU output if set to
stereo, as the Spectrum was not a stereo capable computer. Some Russian clones
which incorporate the AY chip of the 128k Spectrum can output stereo sound,
but in line with the original Spectrum 128k, BASin's AY output via the PLAY
command is mono.
DSound Synch
Enabling this item will tell BASin to synchronise the speed of the emulation
with the "play cursor" in the internal Directsound buffers. This can, on good
soundcards with good drivers, provide very accurate timings with the least
stuttering in the sound. However, not all drivers are created equal, and some can
mis-report the position of the "play cursor" or even omit it altogether. If you find
that BASin runs very slowly, you can try disabling this option to see if it helps. If
it does, then you really need to get a decent soundcard. On-board soundcards are
the main culprits in this case.
Buffering options
BASin does not output sound directly to the soundcard as it is produced by your
program. Instead, it builds a "buffer" of sound samples which, when full, is then
sent out to the soundcard for playing. Smaller buffers result in quicker response,
but the transport to the soundcard can consume a relatively large amount of CPU
time. Larger buffers require less processing time, but there may be a small, but
noticeable lag before the sound plays.
Users are encouraged to experiment with these settings to find the best for their
tastes/tolerances and system hardware.
This is the overall amount of time that will be buffered, in frames per second, of
sound before it is sent to the soundcard. Smaller values require more CPU time,
but if this is available then the sound will be much more responsive and remain
better synchronised to the display. This will be more noticeable with machine
code sound routines, such as sound effects. A larger buffer will require less CPU
time to process, but will conversely affect the response of rapid sound effects.
This setting will also contribute in some ways to the speed and fluidity of the
emulation and display update speed.
Sound latency
Some sound cards have trouble outputting sound at a rapid rate, and on some
computers the CPU may have trouble keeping up with your buffer settings. This
can be alleviated by setting a higher latency, but be warned that the higher the
latency, the larger the "lag" between emulation and sound synchronisation. Lag
experienced due to this option will be more noticeable than lag created by a
larger sound buffer.
LOAD DATA
Statement/Command
LOAD DATA is used to load arrays from files. The arrays are stored using SAVE
DATA.
On execution, the BASIC searches for the named array. When found, the
message Number array: or Character array: followed by the
name appears and the array is loaded. Any array currently in memory having the
same letter name (n or n$ above) is deleted, and a new array having this letter
name and the values stored in the file is created. Note that with character arrays,
any string variable currently in memory having the same letter name is also
deleted.
Format
See also
Chapter 20.
LOAD SCREEN$
Statement/Command
The filename following LOAD is the name that is given to the screen
information in the file, and it is subject to the same restrictions as program
names used with LOAD. The BASIC then searches for the named information
and when found, loads it first into the display file and then the attributes section
of the memory. The picture slowly builds up in the current ink and paper colours
and then the attributes (true colours and so on) are added.
Format
See also
Chapter 20.
SAVE SCREEN$
Statement/Command
SAVE SCREEN$ stores the screen display in a file. It can be loaded back into
the computer at a later date using LOAD SCREEN$.
The filename may have up to ten characters. The display is then sent to the file
in the same way as a program is with SAVE.
Format
See also
Chapter 20.
Tape Creator window
The Tape Creator window is available from the Tools menu.
The main list in the window contains the blocks that will make up the tape, in
the order that they will appear. You should start by either:
Adding a program block, then adding other blocks for that program to load,
or
To add a block, you need to click the "Add" button, or use the "Block" menu
item, and choose from the menu that appears:
From File...
Opens the Windows file requester, from where you can load any one of
either .bas files, .bsc files, .bsd files, Snapshots (both .sna and
.z80), .scr files, .tzx/.tap files, and raw binary files which will be
added as CODE blocks. When you open a .tzx or .tap file, all the
compatible blocks found within will be added to the end of the list.
From Current…
This menu has a set of sub-items which allow you to import from your
current program:
Program
This option will send the current program area (with variables) to the
tape creator as a PROGRAM block.
Screen
This option will send the current screen as a .scr file to the tape creator
list. This will be a 6912 byte CODE block, and is a straight memory
dump of the emulated screen display.
Memory Block
This option will open the Add Memory Block window, where you can
specify the size and location of the memory block you want to add to
the tape as a CODE block.
As you add blocks, they will appear in the main list. You can get the properties
of these blocks by using the Block Menu item, or by clicking the "properties"
button below the list.
As blocks are added, you can delete them with the "Delete" button, or move
them up/down through the list with the up/down arrow buttons. You can cut,
copy and paste the blocks by utilising the Edit Menu.
You can use the Block Menu item to save these blocks out as their corresponding
File Formats using the Save As… option.
When you have added all the blocks your program needs, then you can hit the
"Build" button to create a tape image. The Windows file requester will appear,
prompting you for a filename. The extension you supply dictates the type of file
created - a ".tap" filename will create a file of the older "TAP" format, which
although less capable than the TZX format, will load into a greater number of
emulators. The TZX format is much more flexible, but in BASin has no
advantages over the TAP format. You can save files of this type by specifying a
".tzx" extension. The TZX file format is used as a default if you fail to specify an
extension, and this format is to be preferred in the interests of phasing out the
obsolete TAP format.
The file menu gives you options for loading and saving the tape images you use.
This will open the standard windows file requester and prompt you to load
a new .tzx or .tap file. This will clear any tape image held in memory.
Like the Open Tape Image… option, this option will prompt you to load a
.tzx or .tap file, but will not clear the current tape image - it will add the
blocks from the new file to the end of the current tape file.
Save Image
Saves any changes you may have made to the current tape image. If this
image has not been saved previously, you will be prompted for a filename.
Save Image As…
Allows you to specify the name that the image will be saved under, which
can be useful when editing tapes which you want to make copies of.
Exit
Closes the Tape Creator tool, but leaves the current tape image intact within
memory, for tape streaming purposes.
The edit menu gives functionality for copying and pasting blocks, to enable you
to manage the list order and content.
Cut Block
Removes the currently selected block from the image, but takes a copy and
places it on the internal clipboard first.
Copy Block
Takes a copy of the currently selected block and places that copy on the
internal clipboard.
Paste Block
Delete Block
Removes the currently selected block from the tape image, and does not
take any copies of that block before it does so. Handle with care.
The block menu gives you methods of working with the blocks themselves, from
adding them through to converting them to files external to the tape image. This
can be useful for "ripping" a block out (say for example, a 768 byte font image)
for later use in a BASIC program.
Opens the Windows file requester, from where you can load any one of
either .bas files, .bsc files, .bsd files, Snapshots (both .sna and .z80), .scr
files, .tzx/.tap files, and raw binary files which will be added as CODE
blocks. When you open a .tzx or .tap file, all the compatible blocks found
within will be added to the end of the list.
This menu has a set of sub-items which allow you to import from your
current program:
Program
This option will send the current program area (with variables) to the
tape creator as a PROGRAM block.
Screen
This option will send the current screen as a .scr file to the tape creator
list. This will be 6912 bytes long, and is a straight memory dump of
the emulated screen display.
Memory Block
This option will open the Add Memory Block window, where you can
specify the size and location of the memory block you want to add to
the tape as a CODE block.
Save As…
Allows you to save the currently selected block as one of the BASin
supported types- for instance, you can save Program blocks as .bas files,
Code blocks as .bsc files, and variables as .bsd files. Certain types can also
be saved as raw bytes. You will be prompted for a filename to save the
block under, and in these circumstances your choice of file extensions will
determine what you can save the blocks as.
Move Up
Move Down
Moves the selected memory block down one place in the list.
Properties
Opens the Block properties dialog where you can set the parameters of each
block that appears in your tape image. The options present here are
explained in more detail elsewhere in the Tape Block Properties Window
help section.
One of BASin's other tape manipulation features is the ability to stream data to
your program from tape image files. These options enable or disable this
behaviour.
LOAD/MERGE/VERIFY Commands
When checked, this option instructs BASin that all LOAD, MERGE and
VERIFY commands executed by the user are to gather their data not from
files on your hard disk, but from the current tape image held in the Tape
Creator Window.
SAVE Commands
When checked, this option instructs BASin that all SAVE commands
executed by the user are to send their data not to files on your hard disk, but
to the end of the current tape image held in the Tape Creator Window.
Memory Viewer window
The Memory Viewer window is available from the View menu and the System
Variables window.
Note: Editing the memory incorrectly can corrupt your BASIC program or cause
the emulated Spectrum to crash.
At the top of the window, you will notice that there is a drop-down list attached
to an edit field. From the drop-down list, you can choose from any one of the
System Variables, and the display area will move to the address pointed to by
that SysVar. For example, you could choose the PROG system variable, and the
display will show the start of the area of memory that contains your program.
You can also choose from a list of any variables that are stored in the VARS area
of memory, and inspect the structure of those. It may help to refer to Chapter 24
of the Sinclair BASIC Manual, which lists how variables and programs are
stored in memory in much more detail. An interesting feature that you may use
often is the program line locator - simply type in a line number followed by the
statement number (in Line:Statement format, i.e. "10:1") and the display will
move to that line's tokenised representation in memory.
Having chosen a region to jump to, you must click the "Go" button to the right
of the edit field to actually move to that location.
You can also use the "Find" button to search memory for whatever string of
characters you have typed into the edit field.
You can edit the memory by either typing in the hexadecimal codes into the left-
hand pane of the window, or by typing in regular ASCII codes into the right-
hand pane. All changed memory locations are coloured in dark red.
At the bottom of the window is a small status area, which shows the current
address that you are examining, and the contents of that address in both byte and
word format.
Emulation tab
The Emulation tab can be found in the Options window.
If this box is checked, the IN keyword can be used to read the emulated
Spectrum keyboard at hardware level - for example, to detect multiple keys
being pressed at once.
Speed tuning
Determine the speed of the emulated Z80 processor (approximately 3.5 MHz on
a true Spectrum,or 69888 TStates per frame). Beware that excessibley speeding
BASin up can cause the display to stop responding, and for the sound to break
up if your PC is not fast enough.
ZX printer emulation
To simulate a real printer, BASin can save the state of the "paper" that the ZX
Printer uses, as a continuous sheet, or roll of paper. This option will save the
current printer output when you quit BASin, and re-load it when you start a new
BASin session. The file is saved in BASin's folder, as "Printer.bin".
Accelerate printing
All ROM Commands for printing such as LPRINT, LLIST, COPY and the
printer streams pass through a particular point in the ROM which sends a
complete line of 32 characters to the printer. BASin can trap this and send all the
characters in one go, which considerably accelerates printing. This option will
turn this behaviour on and off. Machine code routines which utilise this ROM
entry point will also benefit from this behaviour, but it is not guaranteed to work
with all machine code routines, especially if they don't supply the right values.
Display tab
The Display tab can be found in the Options window.
Scaling options
Here you can configure how BASin scales the Display Window when the user
resizes. The options affect display update performance in various ways, so
experiment to find the settings that best suit your display and PC hardware.
If this box is checked, the width and height of the display window always keep
their standard PAL ratio of 4:3, and the border expands to fill any remaining
space. To set this option temporarily, choose Display Window > Force 1:1
Aspect on the View menu.
This, when enabled, will only allow scaling to occur at exactly 1x, 2x, 3x etc of
the display. Any scaling in-between will not occur, for example at 150% (1.5x),
and borders will be added to make up the extra space in the window. This option
is enabled when using some scalers - the Hq2x, Super 2xSAI, Super Eagle, and
Scale2x types, as they can in most cases only scale at 2 or 3 times normal size.
These types make educated guesses as to what the scaling should look like, so
some distortion can occur in dithered graphics.
Scaling method
This option dictates how BASin will scale the Display Window when it is
enlarged beyond 100% of the original (320x240) size. BASin does not employ
DirectDraw or OpenGL acceleration. The options are:
Frameskip
Determines how often BASin updates the display. Setting this to 1 always
updates the display immediately; setting it to 2 only renders every other frame;
and so on. A larger value increases performance but reduces the smoothness of
the display.
Selecting this option will set BASin to update only when the emulation is
waiting for synchronisation to the 50hz frequency - i.e. when the engine is
idling. This will allow a smooth emulation with, depending on the speed of your
PC hardware, a reasonable display update speed. This is managed by sending all
display functions to a separate thread, which waits until Windows gives it a slice
of CPU time to work with. As the new thread is set to a lower priority than the
emulation, then only when the emulation is idling does the display get priority.
Note: On slower hardware with large scaling applied, this option can freeze the
display or cause a rather jerky update.
Embellishments
These extra options are cosmetic only, and will not affect the speed or the quality
of the display. They can be enabled or disabled according to the tastes of the
user.
Scanlines simulation
If this box is checked, BASin adds dark lines to the display that simulate the
scan lines on a portable TV set. (The original Spectrum was generally used with
a TV set, not a computer monitor.)
If this box is checked, the display is given a rounded rectangle shape, which
more closely resembles an old 14" television set.
Working with Tape image files
Note: Detailed information about the two types of tape file format that BASin
understands can be found here.
There are two methods which BASin provides for managing Sinclair Spectrum
tape image files, which are predominantly used by emulators. These files are
intended to be a compressed representation of the sounds which the Spectrum
produces when saving files, and to this end can be very complex to use. BASin,
through the use of modified emulation, employs these tape images as storage
areas where you can store files created from BASIC programs and memory data
blocks.
The simplest method of creating and working with tape files is to use the Tape
Creator tool, which is found in BASin's Tools Menu. You should read the
documentation for this tool if you are at all unsure as to how to use tape image
files. It allows you to add, remove and create new tape blocks from programs
either in-memory or from .bas files, and to add blocks from memory chunks, and
to save certain types of variables.
The other method for working with tape files within BASin is to use "streaming"
where the actions of LOAD, SAVE, MERGE and VERIFY commands are
redirected to a tape image rather than files on your hard drive. The Files Tab in
the Options dialog has two switches, which allow you to turn this behaviour on
or off. When active, for example, a LOAD "" command will (instead of bringing
up a file requester asking for a file to load) attempt to load a block from the
current tape image. If no tape image has been created and "attached", then the
file requester will be used. If tape SAVE streaming is active, then any SAVE
command issued by the user will send the saved data directly to the tape, adding
it on to the end of the tape image. This behaviour is very close to that of
Spectrum Emulators in general.
The tape image formats that BASin supports are the .tzx and the .tap formats.
The .tap format is supported completely - but only the .tzx format's ROM block
type (ID type 16) is supported by BASin. This is because BASin intercepts ROM
routines for loading and saving, rather than monitoring the EAR bit of port $FE
(which is where tape-sounds would normally be arriving in a real Spectrum). As
such, complex loaders that employ the more exotic blocks of the .tzx format will
fail to be recognised, or indeed even acknowledged as existing at all. Support for
headerless tape blocks is provided, however.
The original tapes stored files sequentially, and the position of the tape head in
the tape drive, along the tape, dictated which file would be loaded next. In
BASin, this is indicated in the Tape Creator tool by the small cassette-tape icon
that appears to the left of the block list. This icon indicates which block will be
loaded next by a streamed tape operation.
Tape Block Properties window
The Tape Block Properties window is available from the Tape Creator tool.
This window allows you to view the properties of any tape blocks found in the
Tape Creator window. Some block types can be modified - the information
contained in the tape header is customisable.
For more information about tape file headers, see the Tape image file formats
section.
Program Blocks
Program blocks are listed with the prefix "Program:" and contain images of the
program as it exists in the PROG memory area, with any variables that have
been declared. Options available to set are the filename that appears as the block
loads, and the Autostart line number - when the program is loaded, then that line
will be executed automatically as though a GO TO command had been issued.
CODE Blocks
CODE blocks are listed with the prefix "Bytes:" and are an image of an area of
memory. They must typically be loaded using the LOAD "" CODE direct
command, and the only optional parameter you can set (aside from the filename)
is the start address that the block will be loaded into.
Array Blocks
Array Blocks are listed with the prefix "Number Array:" or "String Array:" and
hold the contents of either a string, a string array, or a numeric array. You can set
the filename for these blocks, but there are no other options that you can set.
Note: The original ROM file loader could only accept up to ten characters for a
filename, and so the tape images that BASin produces inherit this limitation.
Add Memory Block window
The Add Memory Block window is accessible from the Tape Creator tool.
This window is used to specify a memory block to add to the Tape Creator
Window. Here you can specify the location and size (using the two edit fields) of
the memory block you wish to copy onto your tape image.
Start Address
This is the location in the emulated memory model that you wish to copy your
block from. This value can range from 0 to 65535.
Length
This value specifies the length of the memory block you want to copy. Bear in
mind that there is a maximum size of 65535 bytes, but only enough bytes to
copy from the Start Address up to this limit will be copied.