18 ATOM Operating System
18.1 Keyboard
18.1.1 Teletype/Typewriter Nodes
After switching on, or typing BREAK, the ATOM is in teletype mode. In
this mode all the alphabetic keys produce upper case letters, and the
SHIFT key is used to obtain the lower-case letters. This mode is most
convenient for normal operation of the ATOM because all commands are
typed in upper case.
When entering documents which contain mixed lower and upper case
it is convenient to have the ATOM keyboard behave like a standard
typewriter; i;e. for the alphabetic keys to produce lower case, and
upper case when shifted. This state may be obtained by typing the LOCK
key. The mode is cancelled by typing LOCK a second time. Note that the
LOCK key only affects the alphabetic keys, A -- Z.
18.1.2 SHIFT Key
All but one of the 128 ASCII codes are available from the ATOM
keyboard. The code which cannot be obtaiqed appears as a back-arrow on
the display.
The codes which can be obtained, but which are not marked on the
keyboard, are as follows:
SHIFT + Displayed as ASCII character Code in hex
@ Inverted @ \ #60
A Inverted A a #61
. . . .
. . . .
Z Inverted Z z #7A
[ Inverted [ { #7B
\ Inverted \ | #7C
] Inverted ] } #7D
^ Inverted ^ ~ #7E
18.1.3 Control Codes
The following list gives all the control codes that perform special
functions on the ATOM. They are all available from the keyboard, by
typing CTRL with the specified key, or from programs.
STX (CTRL-B, 2) Start printer
This code, which is not sent to the printer, starts the printer output
stream. All further output is sent to the printer as well as the VDU
until receipt of an ETX code.
ETX (CTRL-C, 3) End printer
Ends the printer output stream.
ACK (CTRL-F, 6) Start screen
_131_
Starts the output stream to the VDU screen, and resets the VDU to
character mode. This code is sent to the VDU on BREAK.
BELL (CTRL-G, 7) Bleep
Causes the output stream to make a 1/2 second bleep on the internal
speaker.
BS (CTRL-H, 8) Backspace
Moves the cursor back one position.
HT (CTRL-I, 9) Horizontal tab
Moves the cursor forward one position.
LF (CTRL-J, 10) Linefeed
Moves the cursor down one line.
VT (CTRL-K, 11) Vertical tab
Moves the cursor up one line.
FF (CTRL-L, 12) Formfeed
Clears the screen, moves the cursor to the top left-hand corner, and
sets the VDU to character mode.
CR (CTRL-M, 13) Return
Moves tle cursor to the start of the current line.
SO (CTRL-N, 14) Page mode on
Turns on paged mode, and resets the line count to zero. Every time the
screen in scrolled the line count is incremented. In paged mode the
UDU will wait for a key to be typed every time the line count reaches
16.
SI (CTRL-O, 15) Page mode off
Turns off paged mode. This is the mode set on BREAK and on power-up.
NAK (CTRL-U, 21) End screen
Ends the output stream to the VDU; the only code recognised when in
this condition is ACK.
CAN (CTRL-X, 24) Cancel
Deletes the line currently being typed, and returns the cursor to the
start of the following line. Only happens in BASIC's input modes.
ESC (CTRL-[, 27) Escape
Causes an escape from an executing BASIC program. If typed twice,
resets the VDU to character mode.
RS (CTRL-^, 30) Home cursor
Moves the cursor to the top left-hand corner of the screen.
18.4 Screen Editing
Three keys on the ATOM keyboard have special functions, and are used
in conjunction with the SHIFT key for screen editing. Their functions
_132_
are:
Cursor up
SHIFT Cursor down
Cursor right
SHIFT Cursor left
COPY Read character under cursor
Pressing the first four key combinations move the cursor around the
screen but do not send any new characters down the input channel. They
may be typed at any time and will have no effect on the ATOM, or on
programs; they just determine where the cursor is positioned.
The COPY key will read the character under the cursor, and
transmit that character to the input stream; the effect is the same as
if that character had been typed at the keyboard. After reading a
character the cursor is automatically moved one place to the right.
For example, suppose we wanted to edit a piece of stored text.
First the text is listed as shown:
>LIST
10 PIECE OF TEXTUAL MATERIAL
>IMG SRC="block.gif">
After listing the program the cursor is positioned after the prompt,
as shown. First move the cursor vertically upwards, using the ) key,
until it is opposite the line we wish to edit:
>LIST
10 PIECE OF TEXTUAL MATERIAL
Now use the COPY key to read the correct part of the line:
>LIST
10 PIECE OFTEXTUAL MATERIAL
>
Note that the cursor inverts every character it passes over. If any
inverted characters are present in the text, these will be un-inverted
by the cursor.
Now type in the corrected part of the line:
>LIST
10 PIECE OF CAKEAL MATERIAL
>
As no more of the old line is required the return key is pressed, and
the program may be listed again to verify that the editing gave the
correct result.
The key may be used to omit parts of the old line that are no
longer required and SHIFT may be used to backspace the cursor in
order to make room for inserting extra characters in the line.
If you change your mind while editing a line, type CTRL-X (cancel)
and the old line will be unchanged.
18.5 The VDU
The character display shows the contents of memory from #8000 to
#81FF, mapped one character cell per byte. The address of the top
_133_
left-hand cell is 48000, and the address of the Cth column in the Lth
line is simply:
08000+32*L+C
where 0<=C<=31 and 0<=L<=15, and L=O, C=O corresponds to the top
left-hand character position.
The value stored in the memory cell determines the character
displayed. All 256 different possible codes produce different
displayed characters (with two exceptions), and the codes are assigncd
as follows:
Hex Code: Characters:
000 -- 41F 0 to <- (including alphabet)
420 -- #3F space to ? (including digits)
040 -- #7F white graphics symbols
#80 -- #9F inverted 0 to <-
IAO -- #BF inverted space to ?
OCO -- #FF grey graphics symbols
The complete character set is displayed by executing:
FOR N=O TO 255; N?#8000=N; NEXT N
which will generate the display shown below:
The graphics symbols consist of a block divided into 6 pixels, the
state of each pixel being determined by the lower 6 bits of the byte,
as follows:
If the bit is set, the corresponding pixel is grey or white; if the
bit. is clear the pixel is black. Note that #20 and #40, and #7F and
#A0 give the same graphics patterns.
Note that in all cases except #20 to #3F the code stored in the
cell differs from the ASCII code for the character displayed. If C is
the ASCII code for the character to be displayed, the code to be
stored in the cell is obtained by:
C=C+#20; IF C<#80 THEN C=C:#60
Similarly, to obtain the ASCII code for a character from the value V
stored in the screen memory, execute:
IF V<#80 THEN V=V:#60
V=V-#20
_134_
18.6 Changing Text Spaces
The 'text space' is the region of memory used by the ATOM for storing
the text of programs. On switching on, or pressing BREAK, the ATOM is
initialised with a fixed text space at address 08200 in the unexpanded
ATOM, or at #2900 in the ATOM with extra memory in the lower text
space. However, it is possible to change the value of the text-space
pointer so that text can be entered and stored in different areas of
memory. It is even possible to have several different programs
resident concurrently in memory, in different text spaces.
The memory location 18 (decimal) contains a pointer to the first
page of the BASIC text. This value is refered to by the system in the
following cases:--
1. During line editing in direct mode
2. During a SAVE statement; the save parameters are ?18*256 and TOP
3. During a LOAD command; a new program is loaded to ?18*256
4. During the execution of a GOTO or GOSUB statement or a RUN
statement, labels with known values being the exception.
Changing ?18 in programs permits a BASIC program in one text area
to call subroutines in a BASIC program in another text area. The value
of TOP will not change with use like this, so its use as a memory
space allocator and pointer to the end of text in the line editor must
be watched carefully.
18.6.1 Calling Subroutines in Different Text Spaces
The following example shows the entering of a subprograrn and main
program in different text spaces. First enter a subroutine in the
first text space:
?18=#82
NEW
10 PRINT"TEXT AREA ONE"'
20 RETURN
Now change the value of the text-space pointer and enter a progran; to
call this subroutine into the second text space:
?18=#83
NEW
10 REM CALL SUBROUTINE IN 082
20 ?18=#82
30 GOSUB 10
40 REM PROVE YOU'RE BACK
50 PRINT"TEXT AREA TWO"'
60 GOSUB 10
70 ?18=#83;REM BACK FOREVER
80 END
Now run the program:
RUN
TEXT AREA ONE
TEXT AREA TWO
TEXT AREA ONE
Note that switching back to the first text space by typing:
?18=#82
will not change the value of TOP:
PRINT & TOP’
8398
_135_
To reset TOP, type:
END
PRINT 6 TOP'
8225
18.7 Renumberinq Programs
The following routine can be used to renumber the line-numbers of a
program or piece of text. The program and renumber routine must both
be ie memory at the same time, in different text spaces. Note that the
renumber program only renumbers the line numbers; it does not renumber
numbers in GOTO or GOSUB statements.
18.7.1 Renumbering in the Expanded ATOM
In an expanded ATOM, with the default text space at 02900, the
renumber routine can conveniently be entered at 08200 by typing:
?18=#82
NEW
before loading it from tape, or entering it from the keyboard.
1 REM Renumber
10 INPUT"TEXT SPACE TO RENUMBER"Z
15 Z=Z*256
20 INPUT"START AT"A,"STEP"B
30 ?18=Z/256
40 IFZ?1=255 END
50 DOZ?1=A/256;Z?2=A;A=A+B
55 Z=Z+3+LEN(Z+3)
60 UNTILZ?1=255;END
The program to be renumbered should be in the default text space, #29.
Then RUN the program, and reply to the prompts as follows:
TEXT SPACE TO RENUMBER ?#29
START AT?10
STEP?10
The program will switch back to the usual text space, and the
renumbered program can be listed.
18.7.2 Renumbering Using the Screen Memory
In an unexpanded ATOM there may be no space in the upper text space to
load the renumber program. However, with care, it can be loaded from
tape, or typed in, and executed in the area of memory that is
displayed on the VDU. The size of the program is about OAO bytes,
which will occupy memory corresponding to about 6 lines of the
display. Provided that the cursor is kept below the sixth line of the
display, and is not allowed to reach the bottom line of the display
when it will cause scrolling, the VDU memory can be safely used as a
temporary text space in this way.
First type:
?18=#80
to set the text space to the screen area of memory. Move the cursor to
the 6th. line of the display using the ) edit key, and type:
LOAD "RENUMBER"
Alternatively, enter the program from the keyboard in the usual way.
The top few lines of the display will be filled with strange
_136_
characters, corresponding to the text of the program stored directly
in the screen memory. Now type:
RUN
and reply to the prompts of the renumber program as follows (or, as
desired):
TEXT SPACE TO RENUMBER?082
START AT?10
STEP?10
When the program has run the screen can be allowed to scroll,
corrupting the renumber program, and you can list the renumbered
program.
18.8 Trapping Errors
The memory locations 16 and 17 contain a pointer, low byte in 16, high
byte in 17, to the start of a BASIC program which is entered whenever
an error occurs. In direct mode they are set to point at a program in
the interpreter which reads:
@=1;P.$6$7'"ERROR "?O;@=8;IF?1\?2P." LINE"!1& #FFFF
0 P.';E.
Location 0 contains the error number and locations 1 and 2 contain the
line number where the interpreter thinks it occurred. Programs
intended to handle errors should store the value of !1 since it is
changed whenever a return is executed. The first character in a text
space that can be pointed to by ?16 and ?17 is at the start of the
text space plus three, and this is the first character of the listed
program. All interpreter stacks are cleared after an error but the
values of labels are not forgotten.
18.8.1 On Error Goto
To provitie a GOTO on an error it is necessary to provide a string
containing the GOTO statement, and write the address of this string in
locations 16 and 17. For example, to provide a jump to line 170 on an
error:
10 DIM A(8)
20 $A="GOTO 170"
30 ?16=A; ?17=A&4FFFF/256
18.8.2 Calqulator Program
The followinc program simulates a desk-top calculator; it will
evaluate any expression which is typed in, and any error will cause
the message "BAD SYNTAX" to be printed out. The program uses integer
BASIC statements, but could easily be modified to use the
floating-point extension:
10 E=TOP; $E="P.""BAD SYNTAX""';G.30"
20 ?16=E; ?17=E/256
30 @=0; DO IN.A; P.$320"="A; U.0
_137_
_138_
19 Cassette Operating
System
The Cassette Operating System, or COS, saves and loads data to and
from tape using the Computer Users Tape Standard (CUTS), which is also
known as Kansas City Standard. Data is coded as audio tones on the
tape. A logic O consists of 4 cycles of a 1.2 kHz tone, and a logic 1
consists of 8 cycles of a 2.4 kHz tone. Each byte of data is preceeded
by a logic zero start bit, and is terminated by a logic 1 stop bit.
Each bit lasts for 3.33 mS, giving an operating speed of 300
bits/second.
19.1 Named Files
Named files are stored as a number of blocks, each of which is 256
bytes or less, and includes a checksum over all the bytes in the
block. Each block is identified by a name header, and includes the
start address for loading that block, the execution address for that
block, and the number of bytes in that block minus one.
19.2 Unnamed Files
Unnamed files are stored as a two-byte start address, a two-byte end
address, and end minus start bytes of data. An unnamed file could have
no name at all (when using *LOAD and *SAVE), or it may have a zero
length name denoted by "". Unnamed files may thus be used anywhere
that named files could be used. The format of an unnamed file on tape
corresponds to the format of an Acorn System One computer.
19.3 Commands
All COS commands start with an asterisk to distinguish them from BASIC
commands. Note the difference between SAVE and *SAVE, and LOAD and
*LOAD:
SAVE creates text files from the ATOM's text space. No start address
is specified. The execution address is automatically set to IC2B2, the
entry point to BASIC.
*SAVE saves a block of memory whose start and end addresses must be
specified.
LOAD loads text files to the current text space.
*LOAD loads a block of memory to a fixed address, or to an address
specified in the command.
*CAT Catalogue tape
The *CAT command gives a catalogue of a tape. Each block of a named
file will appear in the catalogue as follows:
FILENAME SSSS EEEE NNNN BB
where FILENAME is the name of the file
SSSS is the start address of the block
EEEE is the execution address of the file (used by RUN)
NNNN is the block number, startinq at zero
and BB is the number of data bytes in the block, minus one.
All the numbers are in hexadecimal.
_139_
Unnamed files will appear in the catalogue as:
SSSS LLLL
where SSSS is the start address
and LLLL is the last address, plus one. Again, both numbers are in
hexadecimal.
*LOAD Load file *L.
To load a named file the syntax is:
*LOAD "FILENAME" XXXX
where XXXX is a hexadecimal address specifying where the data is to be
loaded. If XXXX is omitted the data will be loaded back to the address
from which it was originally saved. On pressing RETURN the system will
reply:
PLAY TAPE
The cassette recorder should be played, and the ATOM's space nar
pressed to indicate that this has been done.
The COS will display the names of any files that are encountered
on the tape before the specified file is found. When the file is found
it will be loaded and on completion the '>' prompt will reappear.
If the file to be loaded is part way past the tape heads the COS
will display:
REWIND TAPE
The tape should then be rewound and the space bar pressed again, to
which the COS will regly:
PLAY TAPE
and the loading process can be repeated.
To load an unnamed file the syntax is:
*LOAD "" XXXX or
*LOAD XXXX
where XXXX is again the optional, hexadecimal, start address. Since
there is no name search the space bar should only be pressed during
the hiqh-tone leader, and the first file encountered will be loaded.
Unnamed files consist of a single block, a R there is no error
checking; however they provide the fastest way of aving and loading
data or programs.
CTRL and SHIFT
During loading and *CAT:
CTRL will cause a return to the ATOM '>' prompt. If pressed during
loading an error message will be given to indicate that part of the
file being loaded was lost.
SHIFT will override the search for the high-tone leader, and can thus
be used to load and catalogue files with very short periods of
high-tone leader.
Note that there is no way to exit from SAVE or *SAVE except by BREAK.
*SAVE Save file *S.
To save a named file on tape the syntax is:
*SAVE "FILENAME" SSSS LLLL EEEE
where FILENAME is the filename of up to 16 characters
_140_
SSSS is the start address
LLLL is the end address plus one
EEEE is the optional execution address
The execution address is used by the RUN command, and if omitted will
default to the start address.
On pressing return the COS will respond with:
RECORD TAPE
The tape recorder should now be started in record mode, and the space
bar pressed to indicate that this has been done. Once started, SAVE
cannot be aborted except by BREAK.
To save an unnamed file the syntax is:
*SAVE "" SSSS LLLL or
*SAVE SSSS LLLL
where SSSS and LLLL are as above, and the data will be saved as one
continuous block.
*MON Enable messages *M.
The usual condition after switch-on and BREAK is for the messages:
PLAY/RECORD/REWIND TAPE
to be produced. The MON command may be used to enable messages if they
have been disabled.
*NOMON Disable messages *N.
This command turns off messages produced by the COS.
*PLOAD Finish loading *F.
The normal LOAD command demands that files are loaded from the start
of the first block, and will request that the tape be rewound if
started in the middle of the file. FLOAD allows loading to commence
from the start of any block in the file, and the syntax of the command
is:
FLOAD "FILENAME" SSSS
where SSSS is an optional start address specifying the address to
which the start of the first block is loaded if relocation is
required.
FLOAD is useful after a checksum error has been encountered. The
tape may be stopped and rewound to any point before the block that
produced the error. FLOAD is then used to allow loadinq to continue,
and the block headers will ensure that the blocks are being loaded in
the correct place.
*RUN Load and execute machine code file *R.
The syntax of this command is:
RUN "FILENAME" SSSS
The function is exactly as for LOAD, but on completion of loading
execution is transferred to the execution address specified when the
file was created. The optional start address SSSS may be used to
relocate the file. The execution address is not affected by
relocation.
_141_
*DOS Link to Disk Operating System *D.
This command initialises the Disk Operating System, if present, by
linking to #EOOO.
19.4 Errors
The following error messages are given for errors in commands to the
COS; i.e. for commands starting with '*':
SUM
ERROR 6 Checksum error
COM?
ERROR 48 Command error
NAME
ERROR 118 Name error
SYN?
ERROR 135 Syntax error
ERROR 165 Premature exit from loading
19.5 Appending Text from Several Files
A BASIC or Assembler subroutine may often be required for several
different programs. In this case it is possible to store the
subroutine text on a separate file, and append this text to the text
in memory every time the subroutine is needed in a program.
The subroutine text should be entered in memory on its own, and
should be written with fairly high line numbers, such as 9000-9999.
The subroutine is then saved as usual; e.g.:
SAVE "SUB9"
A later date a program is written which needs a copy of this
subroutine. First check that the program does not use any line numbers
above the first line of the program. Then find the address of the end
of the program by typing:
PRINT &TOP-2
Remember that this address will be in hexadecimal. Now, using *LOAD,
load the subroutine into memory starting at the address printed out in
the above step:
*LOAD "SUB9" XXXX
where XXXX is the address that was printed out. Finally, to reset TOP
to the end of the subroutine, type:
END
Any number of text files can be appended in this way, but note
that, unless the resulting text is to be renumbered, the parts
appended should use line numbers which are larger than any line number
in the text file already in memory.
_142_
20 BASIC Statements,
Functions, and Commands
All the ATOM BASIC statements, functions, and commands are listed in
the following pages in alphabetical order. Following each name is,
where applicable, an explanation of the name and the shortest
abbreviation of that name. The following symbols will be used; these
are defined more fully in Chapter 26:
<variable> -- one of the variables A to Z, or 0.
<factor> -- a variable, a constant, a function, an array, an
indirection, or an expression in brackets, any of which may optionally
be preceded by a + or -- sign; e.g.:
A, -1234, ABS(12), AA(3), !A, (2*A+B).
<expression> -- any arithmetic expression; e.g.:
A+B/2*(27-R)&H.
<relational expression> -- an expression, or a pair of expressons
linked by a relational operator; e.g.:
A, A>=B, $A="CAT"
<testable expression> -- any number of <relational expressions>
connected by AND or OR; e.g.:
A>B AND C>D.
<string right> -- a quoted string, or an 8xpression optionally preceded
by a dollar; e.g.:
"STRING", $A.
ABS Absolute value A.
This function returns the absolute value of its argument, which is a
<factor>. ABS will fail to take the absolute value of the maximum
negative integer, -2147483648, since this has no corresponding
positive value. The most common use of ABS is in conjunction with RND
to produce random numbers in a specified range, see RND. Example:
PRINT ABS-1,ABS(-1),ABS1,ABS(1)'
1 1 1 1
AND Relational AND A.
This symbol provides the logical AND operation between two <relational
expression>s. Its form is <relational expression a> AND <relational
expression b> and the result will be true only if both <relational
expression>s are true. AND has the same priority as OR. Example:
IF A=B AND C=D PRINT"EQUAL PAIRS"'
_143_
BGET Byta get B.
This function returns a single byte from a random file. The form of
the instruction is:
BGET <factor>
where <factor> is the file’s handle returned by the FIN function. The
next byte from the random file is returned as the least significant
byte of the value, the other three bytes being zero. In the DOS the
sequential pointer will be moved on by one and the operating system
will cause an error if the pointer passes the end of the file.
Example:
A=FIN"FRED"
PRINT "THE FIRST BYTE FROM FRED IS "BGET A'
BPUT Byte put B.
This statement sends a single byte to a random file. The form of the
statement is:
BPUT <factor>, <expression>
where <factor> is the file's handle returned by the FOUT function; the
<expression> is evaluated and its least significant byte is sent to
the random file. If you are using the DOS, the random file's
sequential pointer will be moved on by one and the operating system
will cause an error if the length of the file exceeds the space
allowed. Example:
A=FOUT"FRED"
BPUT A, 23
CH Change character to number CH
This function returns the number representing the first ASCII
character of the string supplied as its argument. It differs from
straight use of the ’?' operator in that it can take an immediate
string argument or an <expression>. Examples:
PRINT CH""'
13 (value of string terminatinq character)
PRINT CH"BETA"'
66
S=TOP;$S="BETA"
PRINT ?S/CH$S,CHS'
66 66 66
PRINT S?LENS,CH$S+LENS'
65 65
CLEAR Clear graphics screen CLEAR
This statement clears the screen and initialises the display for the
graphics mode specified its argument:
CLEAR O : Screen is 64*48 (semi-graphics mode)
CLEAR 1 : Screen is 128*64
CLEAR 2 : Screen is 128*96
CLEAR 3 : Screen is 128*192
CLEAR 4 : Screen is 256*192
In graphics modes 1 to 4 an error will be caused if the text space and
graphics area conflict.
_144_
COUNT Count of characters printed C.
This function returns the number of characters printed since the last
return, and is thus the column position on a line at which the next
character will be printed. COUNT is useful for positioning table
elements etc. Example:
DO PRINT"=";UNTIL COUNT=20
====================>
DIM Dimension statement DIM
This statement automatically allocates space after the end of the text
for arrays or strings. DIM causes an error if used in direct mode.
Associated with DIM is a 16 bit location referred to as the 'f"ee
space pointer'. The RUN statement sets this pointer to the value of
TOP. A declaration:
DIM A(Q)
sets A to the current value of the free space pointer, and the pointer
is moved up by (Q+1) bytes. A declaration:
DIM AA(Q)
allocates space for an array AA with elements AA(0) to AA(Q), and
moves the value of the free space pointer up by 4*(Q+1) bytes.
A special use of DIM is to set the value of P for assembling:
DIM P(-1)
sets P to the current value of the free space pointer, without
changing the pointer's value. Several items may be dimensioned in one
DIM statement:
DIM A(2),AA 45,BB(67),CC(F,'
DRAW Draw line to absolute position DRAW
The statement DRAW A,B is equivalent to PLOT 5,A,B.
DO Start of DO...UNTIL loop DO
This statement is part of the DO...UNTIL control expression. As the
BASIC interpreter passes DO it saves that position and will return to
it if the UNTIL statement's condition is false. No more than 11 active
DO statements are allowed. See UNTIL for examples.
END End of program E.
This statement has two functions:
1. Termination of an executing program
2. Resetting the value of TOP to point to the first free byte after
the program text.
END can be used in direct mode to set TOP. Programs can have as many
END statements as required and they do not need to have an END
statement as a last line, although an error will be caused on
execution past the end of the program. See also TOP. Example:
IF SZ="FINISH" END; REM conditional end
EXT Extent of random file E.
In the DOS this function returns the EXTent (length) of a random file
in bytes. The file can be either an input or an output file, and the
form of the instruction is
_145_
EXT<factor>
where factor is the file's handle found using either FIN or FOUT.
In the COS, execution of this function results in an error.
Example:
A=FIN"FRED"
PRINT "FRED IS "EXT(A)" BYTES LONG"'
FIN Find input F.
In the DOS this function initialises a random file for input (with
GET, BGET, and SGET) and updating (with PUT, BPUT, and SPUT), and
returns a number which uniquely represents the file. This 'file
handle' is used in all future referencas to the file. Zero is returned
if the file does not exist. The file handle is only a byte long (1 --
255) and can be stored in variables or using ! or ?. Usage of a file
handle not given by the operating system will result in an error.
In the COS the message PLAY TAPE will be printed, and the system
will wait for any key to be pressed.
FOR Start of FOR...NEXT loop F.
This statement is the first part of the FOR...NEXT loop, which allows
a section of BASIC text to be executed several times. The form of the
FOR statement is:
FOR (a) = (b) TO (c) STEP (d)
where (a) is the CONTROL VARIABLE which is used to test for loop
completion
(b) is the initial value of the control variable
(c) is the limit to the value of the control variable
(d) is the step size in value of the control variable for each
pass of the loop; if omitted, it is assumed to be 1.
Items (b) (c) (d) are <expression>s; they are evaluated only once,
when the FOR statement is encountered, and the values are stored for
later reference by the NEXT statement. No more than 11 nested FOR
statements ara allowed by the interpreter. Examples:
FOR Z=O TO 11
FOR 0=X TO Y
FOR U=-7 TO O
FOR G=(X+1)*2 TO Y-100
FOR J=O TO 9 STEP 3
FOR K=X+1 TO Y+2 STEP I
FOR Q=-10*ABSX TO -20*ABSY STEP -ABSQ
FOUT Find output FO.
In the DOS this function initialises a random file for output (with
PUT, BPUT, and SPUT), and returns a number which uniquely specifies
the output file. This 'file handle' is used in all future references
to the file. Zero will be returned there is a problem associated with
using the file as an output file; e.g.:
(a) write protected file
(b) write protected disc
(c) insufficient space in directory
(d) file already in use as an input file
(e) insufficient memory space
The number returned is only a byte long (1-255) and can be stored in
variables or using ! or ?. Usage of a number not given by the
_146_
operating system will result in an error.
In the C3S the message RECORD TAPE will be printed, and any key
waited for. Example:
A=FOUT"FRED"
IF A=O PRINT ”WE HAVE A PROBLEM WITH FRED"'
GET Get word from file G.
This function reads a 32 bit word from a random file and returns its
value. The form of the instruction is:
GET<factor>
where <factor> is the file's handle found with the FIN function. The
first byte fetched from the file becomes the least significant byte of
the value.
In the the DOS the random file's sequential pointer will be moved
on by 4 and the operating system will cause an error if the pointer
passes the end of the file. Example:
A=FIN"FREDH
PRINT "THE FIRST WORD FROM FRED IS "GET A’
GOSUB Go to subroutine GOS.
This statement gives the ability for programs to call sub programs.
The GOSUB statement stores its position so that it can come bark later
on execution of a RETURN statement. Like GQTO it ran be followed by an
<factor> whose value is a line number, or by a label. No more than 14
GOSUB statements without RETURNs are allowed. Example:
10 GOSUB a
20 GOSUB a
30 END
100aPRINT"THIS IS A SUB PROGRAM"'
200 RETURN
When RUN this will print.:
THIS IS A SUB PROGRAM
THIS IS A SUB PROGRAM
GOTO Go to line G.
This statement overrides the sequential order of proqram statement
execution. It can be used after an IF statement to give a conditional
change in the proqram execution. The form of the statement is either:
GOTO <factor>
or GOTO <label>
The GOTO statement can transfer to either an unlabelled line, by
specifying the line's number, or to a labelled line, by specifying the
line's labei.. Examples:
10 IF A=O PRINT"ATTACK BY KLINGON "Z;GOTO x
20 PRINT"YOU ARE IN QUADRANT "X Y
30x PRINT'"STARDATE "T'
100m INPUT"CHOICE "A
110 IF A<1 OR A>9 PRINT"!!!!!"; GOTO m
120 GOTO(A*200); REM GO EVERYWHERE !
_147_
<
IF If statement IF
This statement is the main control mechanism of BASIC. It is followed
by a <testable expression> which is a single byte. If TRUE (non-zero)
the remainder of the line will be interpreted; if FALSE (zero)
execution will continue on the next line. After the <testable
expression> IF can be followed by one of two different options:
1. The symbol THEN, followed by any statement.
2. Any statement, provided that the statement does not begin with T or
a unary operator '!' or '?'.
Examples:
IF A<3 AND B>4 THEN C=26
IF A<3 IF B>4 C=26; REM equivalent condition to abave
IF A>3 OR B<4 THEN C=22; REM complementary condition to above
IF A>3 AND $S="FRED" OR C=22; REM AND and OR have equal priority
INPUT Input statement IN.
This statement receives data from the keyboard. The INPUT statement
consists of a list of items which can be:
(a) a string delimited by "quotes
(b) any ' new-line symbols
(c) a <variable> or a $<expression> separated from succeeding
items by a comma.
Items (a) and (b) are printed out, and for each item (c) a '?' is
printed and the the program will wait for a response. If the item is a
<variable> the response can be any valid <expression> if the item
was a $<expression> the response is reated as a stririg and will be
located in memory starting at the address given by evaluating the
<expression> If an invalid response is typed, no chanqe to the
original is made. Example:
INPUT"WHAT IS YOUR NAME "$TOP,"AND HOW OLD ARE YOU "A
When RUN this will produce:
WHAT IS YOUR NAKE ?FRED
AND HOW OLD ARE YOU ?100
LEN Length of string L.
This function returns the number of characters in a string. The
argument for LEN is a <factor> which points to the first character in
the string. Valid strings have between O and 255 characters before a
terminating return; invalid strings for which the terminating return
is not found after 255 characters will return length zero. Example:
$TOP="FRED";PRINT"LENGTH OF "$TOP" IS "LEN TOP'
LET Assignment statement omit
This statement is the assignment statement and the word LET is
optional. There are two types of assignment statement:
l. Arithmetic
LET<variable>lt;expression>
<variable>lt;factor>lt;expression>
<variable>lt;factor>lt;expression>
!<factor>lt;expression>
?<factor>lt;expression>
2. String movement
_148_
LET$<expression>string right>
In each case the value of the right hand side is evaluated, and then
stored as designated by the left hand side. The word LET is not legal
in an array assignment.
LINK Link to machine code subroutine LI.
This statement causes execution of a machine code subroutine at a
specified address. Its form is:
LINK <factor>
where <factor> specifies the address of the subroutine. The
processor's A, X and Y registers will be initialised to the least
significant bytes of the BASIC variables A, X and Y, and the decimal
mode flag will be cleared. The return to the interpreter from the
machine code program is via an RTS instruction. Examples:
Q-TOP; !Q=06058; LINK Q; REM clear interrupt flag
Q-ZOP; !Q=06078; LINK Q; REM set interrupt flag
LINK IFFE3;REM wait for key to be pressed
LIST List BASIC text L.
This command will list program lines in the current text area. It can
be interrupted by pressing ESC and can take any of these forms:
LIST list all lines
LIST 10 list line 10
LIST , 40 list all lines up to 40
LIST 100 , list all lines from 100
LIST 10,40 list all lines between 10 and 40
LOAD Load BASIC program LO.
This command will load a BASIC program into the current text area. Tts
form is:
LOAD <string right>
and it will pass the string to the operating system and request the
operating system to complete the transfer before returning (in case
the transfer is by interrupt or dire<t memory access). Then the text
area is scanned through to set the value of TOP; if the file was
machine code or data and not a valid BASIC program the prompt may not
reappear. Example:
LOAD"FRED"
MOVE Move to absolute position MOVE
The statement MOVE A,B is equivalent to PLOT 4,A,B.
NEW Initialise text area N.
This command inserts an 'end of text' marker at the start of the text
area, and changes the value of TOP accordingly. The OLD command
provides an immediate recovery.
NEXT Terminator of FOR...NEXT loop N.
This statement is half of the FOR...NEXT control loop. When the word
NEXT is encountered, the interpreter increases the value of the
control variable by the step size, and if the control variable has not
exceeded the loop termination value control is transfered back to the
statement after the FOR statement; otherwise exa¿tion proceeds to the
_149_
statement after the NEXT statement. The NgXT statement optionally
takes a <variable> which will cause a return to the same level of
nesting as the FOR statement with the same control variable, or an
error if no such FOR state¿ent is active. Examples:
@=2
FOR Z=O TO 9; PRINT Z; NEXT; PRINT'
O 1 2 3 4 5 6 7 8 9
FOR Z=O TO 9 STEP 2; PRINT Z; NEXT Z;PRINT’
O 2 4 6 8
FOR Z=O TO 9; PRINT Z; NEXT Y
O
ERROR 230
>
OLD Recover text area OLD
This statement executes ?(?18*256+1)=0;END to recover a text space
after typing NEW. If the first line number in the text area is greater
than 255 it will be changed by the OLD statemènt.
OR Relational OR OR
This symbol provides the logical OR operation between two <relational
expressions> Its form is <relational expression a> OR <relational
expression b> and the result will be true (non-zero) if either
<relational expression> is true. OR has the same priority as AND.
Example:
IF A=B OR C=D PRINT"At least one pair equal"'
PLOT Plot statement PLOT
This statement takes three arguments: a parameter that determines how
to plot, and a pair of relative or absolute cartesian coordinates. The
first parameter is as follows:
O plot line relative to last point with no change in pixels
1 as O but set pixels
2 as O but invert pixels
3 as O but clear pixels
4 plot line to absolute position with no change in pixels
5 as 4 but set pixels
6 as 4 but invert pixels
7 as 4 but clear pixels
8 plot point relative to last point with no change in pixel
9 as 8 but set pixel
10 as 8 but invert pixel
11 as 8 but clear pixel
12 plot point at absolute position with no change in pixel
13 as 12 but set pixel
14 as 12 but invert pixel
15 as 12 but clear pixel
PRINT Print statement P.
This statement outputs results and strings to the screen.. A PRINT
statement consists of a list of the following items:
(a) a string delimited by "quotes, which will be printed.
(b) any ' symbols which will cause a 'newline'.
_150_
(c) the character '&' which forces hexadecimal numerical print
out until the next comma.
(d) an <expression> whose value is printed out in either decimal
or hexadecimal, right hand justified in a field width defined by
'@'
(e) a $<expression>; if the value of the <expression> is between
O and 255, the ASCII character corresponding to that value will
be printed out; otherwise the string pointed to by that value
will be printed out.
Examples:
PRINT '
PRINT"Hello"'
Hello
PRINT 1'
1
PRINT 1'2'3'
1
2
3
PRINT"40*25="40*25'
40*25= 1000
PRINT$CH"e"'
e
PRINT$12
DO INPUT"Who are you "$TOP;PRINT"Hi "$TOP’; UNTIL $TOP=""
Who are you ?fred
Hi fred
Who are you ?
PRINT&0 10 20 30'
O A 14 1E
PTR Pointer of random file PTR
In the DOS this function and statement allows the manipulation of the
pointers in sequential files. Its form is:
PTR<factor>
where <factor> is the file's handle found using FIN or FOUT, and it
may appear on the left hand side of an equal sign or in an expression.
In the COS PTR will cause an error. Fxamples:
A=FIN"FRED"
PRINT PTR AI
O
PTRA=PTRA+23
PUT Put word to random file PUT
This statement sends a four byte word to a sequential output file. The
form of the instruction is:
PUT <factor> , <expression>
where <factor> is the file's handle returned by the FOUT function. The
<expression> is evaluated and sent, least significant byte first, to
the sequential output file. The seguential output file's pointer will
be moved on by four and the operating system will cause an error if
the length of the file exceeds the space allowed. Example:
A=FOUT"FRED"
PUT A , 123456
_151_
REM Remark REM
This statement causes the interpreter to ignore the rest of the line,
enabling comments to be written into the program. Alternatively
comments can be written on lines branched around by a GOTO statement.
RETURN Return from subroutine R.
This statement causes a return to the last encountered GOSUB
statement. See GOSUB for examples.
RND Random number R.
This function returns a random number between -2147483648 and
2147483647, generated from a 33 bit pseudo-random binary sequence
generator which will only repeat after over eight thousand million
calls. The sequence is not initialised on entering the interpreter,
but locations 8 to 12 contain the seed, and can be set using '!' to a
chosen startinq point. To produce random numbers in some range A to B
use:
ABSRND%(B-A)+A
RUN Execute BASIC text from beginninq RUN
This statement will cause the interpreter to cornmence execution at the
lowest numbered line of the current text area. Since it is a
statement, it may be used in both direct mode and programs.
SAVE Save BASIC text space SA.
This statement will cause the current contents of the memory between
the start of the text area, given by ?18*256, and the value of TOP, to
be saved by the operating system with a specified name. The operating
system is not requested to wait until the transfer is finished before
returning to the interpreter. Example:
SAVE"FRED"
SGET String get S.
This statement reads a string from a random file. The form of the
statement is:
SGET <factor>, <expression>
where <factor> is the file's handle returned by the FIN function. The
<expression> is evaluated to form an address, and bytes are taken from
the sequential input file and put in memory at consecutive locations
starting at that address, until a 'return' is read. The sequential
input file's pointer will be moved on by the length of the string plus
one and the operating system will cause an error if the pointer passes
the end of the input file.
SHUT Finish with random file SH.
In the DOS this statement closes random input or output files. The
form of the statement is:
SHUT <factor>
where <factor> is the file's handle found with either FIN or FOUT. If
it is an output file any information remaining in buffer areas in
memory is written to the file. If the <factor> has value zero, all
current sequential files will be closed. In the COS this statement is
ignored.
_152_
SPUT String put SP.
This statement writes a string to a random file. The form of the
instruction is:
SPUT <factor> <string right>
where <factor> is the file's handle returned by the FOUT function.
Every byte of the string, including the terminating 'return'
character, is sent to the file. In the DOS the random file's
sequential pointer will be moved on by the length of the string plus
one, and the operating system will cause an error if the length of the
file exceeds the space allowed; Example:
A=FOUT"FRED"
SPUT A , "THIS IS FILE FRED"
STEP Step specifier in FOR statement S.
This symbol is an optional parameter in the FOR statement, used to
specify step sizes other than the default of +1. It is followed by an
<expression> which is evaluated and its value stored along with the
other FOR parameters. See FOR for examples.
THEN Connective in IF statement omit
This symbol is an option in the IF statement; it can be followed by
any statement.
TO Limit specifier in POR statement TO
This symbol is required in a FOR statement to specify the limit which
is to be reached before the FOR..NEXT loop can be terminated. See FOR
for examples.
TOP First free byte T.
This function returns the address of the first free byte after the end
of a stored BASIC program. Its value is adjusted during line editing
and by the END statement and LOAD command. It is vital for TOP to have
the correct value (set by END) before using the line editor. See also
END.
UNTIL Terminator of DO...UNTIL loop U.
This statement is part of the DO..UNTIL repetitive loop. UNTIL takes a
<testable expression> and will return control to the character after
DO if this is zero (false), otherwise execution will continue with the
next statement. Examples:
DO PRINT"O";UNTIL O; REM do forever
DO PRINT"$"; UNTIL COUNT=20; PRINT'
####################
DO INPUT"Calculation "A; PRINT"Answer is "A'; UNTIL A=12345678
Calulation ?2*3
Answer is 6
Calculation ?A
Answer is 6
Calculation ?12345678
Answer is 12345678
WAIT Wait statement WAIT
This statement waits until the next 60 Hz vertical sync pulse from the
CRT controller. The statement has two uses: to give a delay of one
_153_
sixtieth of a second, and to wait until flyback so that a subsequent
graphics command will not cause noise on the screen. Examples:
FOR Z=l TO 60; WAIT; NEXT; REM wait a second.
MOVE 0,0; WAIT; DRAW 8,8; REM noise-free plotting
_154_
21 BASIC Characters and
Operators
This section lists all the ATOM BASIC special characters and
operators. They are followed by a description of the character or
operator, and its name enclosed in {} brackets. Lower case characters
in < brackets refer to the syntax definition in Chapter 26.
21.1 Special Characters
Line terminator {RETURN}
This character is used to terminate a statement or command, or a line
input to the INPUT statement, and as the terminator for strings.
Cancel input {CAN (CTRL-X)}
This character will, when typed from the keyboard, delete the current
input buffer and give a new line.
Escape {Esc}
This character, typed on the keyboard, will stop any BASIC program and
return to direct mode. BASIC checks for escape at every statement
terminator. Typing escape when in direct mode resets the screen to
character mode.
The ESC key can be disabled from a program by executing:
?#B000=10
Separator {space}
This character is stored intact to allow formatting of programs. Space
may be used anywhere except:
l. In control words.
2. After the # {hash} symbol.
3. Between line number and label.
It may be necessary to insert spaces to avoid ambiguity as, for
example, in:
FORZ=V TOW STEPX
Here a separator character is needed between V and T, and similarly
between W and S, to eliminate the possibility of a function called
VTOWSTEP.
" String delimiter {double quote}
This character is used as the delimiting character whenever a string
is to be part of a BASIC statement (i.e. everywhere except when
inputting strings with an INPUT statement). If you wish to include
in a string it should be written "". The simple rule for valid strings
is that they have an even number of "characters in them.
_155_
' New line {single quote}
This character may be used in PRINT and INPUT statements to generate a
new line by generating both CR and LF codes. The value of COUNT will
be set to zero.
( ) {round brackets}
These characters provide a means of overriding the normal arithmetic
priority of the operators in an <expression>. The contents of brackets
are worked out first, starting with the innermost brackets.
, Separator {comma}
This character is used to separate items in PRINT and INPUT
statements.
. {stop}
This character is used to allow a shorter representation for some of
the key-words, thus using less memory space to store the program.
; Statement terminator {semi-colon}
This character is the statement terminator used in multi-statement
lines.
@ Numeric field width {at}
This character is a variable which controls the PRINT statement. It
specifies the number of spaces in which a number will be printed,
right justified. If the field size is too small to print the number,
the number is printed in full without any extra spaces; thus field
sizes of O and 1 give the same result of minimum-width printing. The -
siqn is printed in front of a negative number and counts towards the
number of characters in the number. On initial entry into BASIC, any
error, or following use of the LIST statement or assembler, 0 is set
to 8. Example:
@=5;PRINT1,12,123,1234,12345,123456'
1 12 123 123412345123456
a - z Labels
These characters provide a very fast means of transferring control
with the GOTO and GOSUB statements. A line may be labelled by putting
one of a-z immediately after the line number (no blanks are allowed
before the label). Transfer to a labelled line is achieved by a GOTO
or GOSUB statement followed by the required label. Example:
10a PRINT"looping"'
20 GOTO a
>RUN
looping
looping
looping
21.2 Operators
! Word indirection {pling}
This character provides word indirection. It can be both a binary and
a unary operator and appear on the left-hand side of an equal siqn as
well as in <expression>s.
_156_
As a unary operator on the LEFT of an equals sign it takes a
<factor> as an argument and will treat this as an address. The
<expression> on the right of the equals sign is evaluated and then
stored, startinq with the least siqnificant byte, in the four
locations starting at this address. Example:
!A=012345678
will store values in memory as follows:
78 |
56 |
34 |
12 |
A |
A+1 |
A+2 |
A+3 |
As a binary operator on the LEFT of an equals sign it. takes two
arguments; a <variable> on the left and a <factor> on the right. These
two values are added together to create the address, and the value is
stored at this address as above. Example:
A!B=012345678
As a unary operator in an <expression> it takes a <factor> as an
argument and will treat this as an address. The value is that
contained in the four bytes at this address. For examplé, if the
contents of memory are as follows:
18 |
00 |
00 |
00 |
A |
A+1 |
A+2 |
A+3 |
Then the value printed by
PRINT !A
will be 24 (decimal).
As a binary operator in an <expression> it takes two arguments, a
<factor> on either side. The sum of these two values is used as the
address, as above. Example:
PRINT A!B
# Hexadecimal constant {hash or pound}
This character denotes the start of a hexadecimal value in
<factor>. It cannot be followed by a space and there is no check made
for overflow of the value. The valid hexadecimal characters are O to 9
and A to F.
$ String pointer {dollar}
This character introduces a pointer to a string; whenever it
appears it can be followed by an <expression>. In a PRINT statement,
if the pointer is less than 256, the ASCII character corresponding to
the value of the pointer will be printed. Dollar can be used on the
left of an equals sign as well as anywhere a string can be used. If
the only choice allowed is either a dollar or a string in double
quotes, then it is possible to omit the dollar. Strings may contair. up
to 255 characters. Examples:
IF$A=$B........ string equality test
IF$A="FRED".... string equality test
$A="JIM"....... move string JIM to where A is pointing
$A=$B.......... copy B's string to where A points
_157_
PRINT$A........ print the string A is pointinq at
PRINT$A+1...... print the string (A+1) is pointing at
PRINT$64....... print ASCII character 64 i.e. 0
% Remainder {percent}
This character is the operation of signed remainder between two
values. Its form is <factor a>%<factor b>. The sign of the result is
the same as the sign of the first operand.
& Hexadecimal/AND {ampersand}
This character has two distinct uses:
1. To print hexadecimal values in the PRINT statement . Its form here
is as a prefix in front of the particular print item which is to be
printed in hexadecimal.
2. As the operation of bitwise logical AND between two values. Its
form here is <factor a>&<factor b> and the result is a 32 bit word,
each bit of which is a logical AND between corresponding bits of the
operands.
* Multiply {star}
This character is the operation of signed multiplication between two
32 bit values. Its form is <factor a>*<factor b>.
+ Add {plus}
This character has two similar uses:
l. As the unary operation "do not change sign". Its form here is
+<factor>.
2. As the operation of addition between two 32 bit values. Its form
here is <term a>+<term b>.
Subtract (minus}
This character has two similar uses:
1. As the unary operation of negate. Its form here is -<factor>, and
the result is O -- <factor>.
2. As the operation of subtraction between two 32 bit values. Its form
here is <term a>-<term b> and the result is found by subtracting <term
b> from <term a>.
/ Divide {slash}
This character is the operation of signed division between two 32 bit
values. Its form is <factor a>/<factor b> and the result is found by
dividing <factor a> by <factor b>.
: Exclusive-OR {colon}
This character is the operation of bitwise logical exclusive-OR
between two 32 bit <term>s. Its form is <term a>:<term b> and the
result is a 32 bit word each bit of which is the exclusive-OR of
corresponding bits in <term a> and <term b>.
< Less-than {left trianqular bracket}
This character is the relational operator "less than" betveen two
<expression>s. Its form is <expression a> < <expression b> and it
returns a truth value, of 'true' if <expression a> is less than
_158_
<expression b> and 'false' otherwise, which can be tested by IF and
UNTIL statements.
= Equals {equal}
This character has two uses:
l. As the relational operator "equal to" between two <expression>s.
Its form is <expression a> = <expression b> and it returns a truth
value, of 'true’ if <expression a> is equal to <expression b> and
'false' otherwise, which can be tested by IF and UNTIL statements.
2. As the assignment operation "becomes". The object on the left hand
side is assigned the value of the right hand side. There are three
similar uses of this:
1. Arithmetic Example:
<variable>=<expresSion> A=2
<variable>!<factor><expression> A!J=3
<variable>?<factor>=<expression> A?J=4
!<factor>=<expression> !J=5
?<factor>=<expression> ?J=6
<array element>=<expression> w(1)=7
2. String movement
$<expression>=<string right> $A="FRED"
3. FOR statement
FOR<variable>=<expression>.... FOR A=O TO..
> Greater-than {right triangular bracket}
This character is the relational operator "greater than" between two
<expression>s. Its form is <expression a> > <expression b> and it
returns a logical value, of 'true' if <expression a> is greater than
<expression b> and 'false' otherwise, which can be tested by IF and
UNTIL statements.
? Byte indirection {query}
This character provides byte indirection. It can be either a binary or
a unary operator and appear on the left-hand of an equals sign as well
as in <expression>s.
As a unary operator on the LEFT of an equals sign it takes a
<factor> as an argument and will treat this as an address; the
<expression> on the right of the equals sign is evaluated and its
least significant byte is stored at that address. Example:
?A=012345678
will store into memory as follows:
As a binary operator on the LEFT of an equals sign it takes two
arguments, a <variable> on the left and a <factor> on the right. These
two values are added together to create the address where the value
will be stored as above. Example:
A?B=012345678
As a unary operator in an <expression> it takes a <factor> as an
_159_
argument and will treat this as an address; the value is a word whose
most significant three bytes are zero and whose least significant byte
is the contents of that address. Example:
PRINT ?A
As a binary operator in an <expression. it takes two arguments, a
<factor> on either side. The sum of these two values is the address
used as above. Example :
PRINT A?B
\ OR {inverted backslash}
This character is the binary operation of bitwise logical OR between
two 32 bit <term>s. Its form is <term a>g<term b> and the result is a
32 bit word each bit of which is an or operation between corresponding
bits of <term a> and <term b>.
<> Not equal {left & right triangular brackets}
This symbol is the relational operator "not equal to" betyeen two
<expression>s. Its form is <expression a> < <expression b> and it
returns a truth value, of 'true' if <expression a> is not equal to
<expression b> and 'false' otherwise, which can be tested by IF and
UNTIL statements.
<= Less or equal {left triangular bracket, equal}
This symbol is the relational operator "less than or egual" between
two <expression>s. Its form is <expression a> < <expression b> and it
returns a truth value, of 'true' if <expression a> is less than or
egual to <expression b> and 'false' otherwise, which can be tested by
IF and UNTIL statements.
>= Greater or equal {right triangular bracket, equal}
This symbol is the relational operation "greater than or equal to"
between two <expression>s. Its form is <expression a> >= <expression
b> and it returns a truth value, of 'true' if <expression a> is
greater than or equal to <expression b> and false otherwise, which can
be tested by IF and UNTIL statements.
_160_
22 Extending the ATOM
22.1 Floating-Point Extension to BASIC
The ATOM's BASIC can be extended to provide floating-point arithmetic,
and many scientific functions, simply by inserting an extra 4K ROM
chip into a socket on the ATOM board (see Technical Manual). The
floating-point extension adds 27 new variables, %@ and %A to %Z, 27
floating-point arrays %@@ and %AA to %ZZ, and the following special
statements and functions to the existing integer BASIC, including a
statement for plotting in the ATOM's four-colour graphics modes:
Floating-Point Statements
COLOUR, FDIM, FIF, FINPUT, FPRINT, FPUT, FUNTIL, STR.
Floating-Point Functions
ABS, ACS, ASN, ATN, COS, DEG, EXP, FGET, FLT, HTN, LOG, PI, RAD, SGN,
SIN, SQR, TAN, VAL.
Floating-Point Operators
The extension ROM does not in any way alter the operation of the
existing BASIC statements, functions, or operators, and floating-point
arithmetic may be mixed with integer arithmetic in the same line.
All the extension-ROM statements and functions, except COLOUR and
FLT, and all the extension-ROM operators, expect floating-point
expressions as their arguments.
Whenever the context demands a floating-point expression, or
factor, all calculations are performed in floating-point arithmetic
and all integer functions and variables are automatically floated. An
integer expression may be explicitly floated with the FLT function,
which takes an integer argument. For example:
FPRINT FLT(2/3)
will print 0.0 because the division is performed in integer
arithmetic and then floated. Therefore:
FPRINT FLT(PI)
will convert PI to an integer, and then float it, printing 3.00000000.
When the context demands an integer expression, or factor, all
calculations are performed in integer arithmetic, and floating-point
functions will be automatically converted to integers. For example:
PRINT SQR(10)
will print 3. Floating-point expressions used in an integer context
must be fixed by the '%' operator. For example:
PRINT %(3/2+1/2)
will print 2, since the expression is evaluated using floating-point
arithmetic and then fixed, whereas:
_161_
PRINT 3/2+1/7
will print 1, since in each case integer division is used.
Since there are both integer and floating-point versions of the
ABS function, the context will determine how its argument is
evaluated. For example:
PRINT ABS(2/3+1/3)
will print 0, whereas:
FPRINT ABS(2/3+1/3)
will print 1.00000000. The floating-point function may be obtained in
an integer context by prefixing it with the '%' operator. Thus:
PRINT %ABS(2/3+1/3)
will print l.
22.1.1 Floating-Point Representation
Each floating-point number occupies five bytes; a four-byte mantissa
and a one-byte exponent:
------------------------------------
| | | | | |
.| 0 | 1 | 2 | 3 | 4 |
^------------------------------------
| ^<--31 bits of mantissa---> <----
| | 8-bit
| sign bit exponent
|
assumed position of binary point
The mantissa is stored in sign and magnitude form. Since it will
always be normalized, it logically always has a '1' as its top bit.
This position is therefore used to store the sign. The exponent is an
ordinary 8-bit signed number. A higher precision is used for internal
calculations to preserve accuracy. The representation provides about
9.5 significant figures of accuracy, and allows for numbers in the
range 1E-38 to 1E+38 approximately. All the possibla 32-bit integers
in the standard integer BASIC can be floated without loss of accuracy.
22.1.2 Floating-Point Statements
FDIM Floatinq-point dimension
Allocates space after the end of text for the floating-point arrays
%00 and %AA to %ZZ. Example:
FDIM %JJ(5)
allocates space for elements %JJ(0) to %JJ(5), a total of 30 bytes.
PIP Floating-point IF
Same syntax as IF, but connectives such as AND and OR are not allowed.
Example:
FIF %A < %B FPRINT %A "IS LOWER THAN "%B
FINPUT Floating-point input FIN.
Exactly as INPUT, but takes a floating-point variable or array
element, and does not allow strings to be input. Example:
_162_
FINPUT"Your weight "%A
FPRINT Floating-point print FP.
Exactly as PRINT except that no $ expressions are allowed, and all
expressions are treated as floating-point expressions. Floating-point
numbers are printed out right justified in a field size determined by
the value of 0. Example:
FPRINT"You are "%H" metres tall"''
FPUT Floating-point put
FPUT writes the 5 bytes representing a floating-point number to the
seguential file whose handle is specified by its argument. Example:
FPUTA,2^32+1
FUNTIL Ploating-point until FU.
As UNTIL, except no connectives (OR or AND) are allowed. Matches with
DO statement. Example:
DO%A=%A+.1;FUNTIL%A>2
STR Convert to string
STR converts a floating-point expression into a string of characters.
It takes two arguments, the floating point expression, and an integer
expression which is evaluated to give the address wher the string is
to be stored. Example:
STR PI, TOP
PRINT $TOP'
3.14159265
22.1.3 Floating-Point Punctions
ABS Absolute value
Returns the absolute value of a floatirg-point argument. Example:
FPRINT ABS -2.2
2.20000000
ACS Arc cosine
Returns arc cosine of argument, in radians. Example:
FPRINT ACS 1
0.0
ASN Arc sine
Returns arc sine of argument, in radians. Example:
FPRINT ASN 1
1.57079633
ATN Arc tangent
Returns arc tangent of argument, in radians. Example:
FPRINT ATN 1
7.85398163E-1
COS Cosine C.
Returns cosine of angle in radians. Example:
_163_
FPRINT COS 1
5.40302306E-1
DEG Radians to degrees D.
Converts its argument from radians to degrees. Example:
FPRINT DEG PI
180.000000
EXP Exponent E.
Returns exponent (i.e. e^<factor>). Example:
FPRINT EXP 1
2.71828183
FGET Floating-point GET
Same as GET, but reads five bytes from a serial file and returns a
floating-point number.
FLT Ploat F.
Takes an integer argument and converts it to a floating-point number.
Example:
FPRINT FLT(4/3)
1.00000000
HTN Hyperbolic tangent H.
Returns the hyperbolic tangent of an angle in radians. Example:
FPRINT HTN 1
7.61594156E-l
LOG Natural logarithm L.
Returns the natural logarithm of its argument. Example:
FPRINT LOG 1
0.0
PI
Returns the constant pi. Example:
FPRINT PI
3.14159265
RAD Degrees to radians R.
Converts its argument from degrees to radians. Example:
FPRINT RAD 90
1 57079632
SGN Sign
Returns -1, 0, or 1 depending on whether its floating-point argument
is negative, zaro, or positive respectively.
SIN Sine
Returns sine of an angle in radians. Example:
FPRINT SIN PI
0.0
_164_
SQR Square root
Returns square root of argument. Example:
FPRINT SQR 2
1.41421356
TAN Tanqent T.
Returns tangent of angle in radians. Example:
FPRINT TAN PI
0.0
VAL Value of strinq V.
Returns a number representing the string converted to a number. If no
number is present, zero will be returned. VAL will read up to the
first illegal character, and cannot cause an error. Example:
FPRINT VAL "2.2#"
2.20000000
22.1.4 Ploatinq-Point Operators
! Floatinq-point indirection {pling}
The floating-point indirection operation makes it possible to set up
vectors of floating-point numbers. The operator returns the five bytes
at the address specified by its operand. For example, to set up a
floating-point vector of three elements:
DIM A(14); %!A=PI; %!(A+5)=3; %!(A+10)=4
Convert to inteqer {percent}
The unary % operator converts its floating-point argument to an
integer. For example:
PRINT %(3/2+1/2)
2
Raise to power {up arrow}
Binary operator which raises its left-hand argument to the power of
its right-hand argument; both arguments must be floating-point
factors.
Example:
FPRINT 2^32
4.29496728E9>
22.1.5 Floating-Point Variables
The floating-point variables %@ and %A to %Z are stored from 02800
onwards, five bytes per variable, thus taking a total of 135 bytes.
Thus, for example, a floating-point vector:
%!02800
may be set up whose elements:
%!(#2800+O), %!(#2800+5), %!(#2800+10)
will correspond to the variables:
%@, %A, %B ... etc.
For example, the floating-point variables may be initialised to zero
_165_
by executing:
FOR J=O TO 26*5 STEP 5
%!(#2800+z)=0
NEXT J
22.1.6 Examples
The following program plots curves of the sine and tangent functions,
using the floating-point routines.
1 REM Sine and Tangent
5 PRINT $30 ; CLEAR O
7 PRINT"PLOT OF SIN AND TAN FUNCTIONS"
9 %t=2*PI/64
10 %V=O
12 FOR Z=O TO 64
15 %V=%V+%I
20 PLOT13,Z,(22+%(22*SIN%V))
25 PLOT13,Z,(22+TAN%V)
30 NEXT
100 END
Program size: 206 bytes
The following program plots a cycloid curve:
1 REM Cycloid
10 %Z=60
20 CLEAR2
30 FORQ=OT0359
40 %S=RAD Q
50 %R=%Z*SIN(%S*2)
60 PLOT13,%(%R*SIN%S+64.5),%(%R*COS%S+48.5)
70 NEXT
80 END
Program size: 142 bytes
22.1.7 Three-Dimensional Plotting
The following program plots a perspective viaw of a saddle curve, with
any desired viewing point. The program is a floating-point version of
the program in Section 11.5.2.
1 REM Saddle Curve
100 FINPUT"CHOOSE VIEW POSlTION"'”X=”%L,"Y="%M,"Z="%N
110 FINPUT"LOOKING TOWARDS"'"X="%A,"Y="%B,"Z=”%C
115 %L=%L-%A;%M=%M-%B;%N=%N-%C
120 W=4;CLEAR4
150 %S=%L*%L+%M*%M;%R=SQR%S I
160 % -%S+%N*%N;%Q=SQR%T
200 FORX=-10T010
210 Y=-10;GOS.c;GOS.m
220 FORY=-9T010;GOS.c;GOS.p;N.;N.
230 FORY=-10T010
240 X=-10;GOS.c;GOS.m
250 FORX=-9T010;GOS.c;GOS.p;N.;N.
260 END
400pW=5
410m%U=%X-%A;%V=%Y-%B;%W=%Z-%C
420 %0=(%T-%X*%L-%Y*%M-%Z*%N)*%R
_166_
425 FIF %0<0.1 W=4
430 G=%{400*(%Y*%L-%X*%M)*%Q/%0)+128
440 H=%(500*(%Z*%S-%N*($X*%L+%Y*$M))/%0)+96
460 PLOTW,G,H;W=4;R.
600c%Y=Y;%X=X
610 %2=.05*(%Y*%Y-%X*%X);R.
Description of Program:
100-110 Input view position and shifted origin.
115 Shift view position for new origin.
120 Clear screen and get ready to move.
150-160 Set up constants for plot projection.
200-250 Scan X,Y plane.
400 p: Entry for drawing.
410 m: Entry for moving; also shift coordinates for new origin.
420 Calculate how far away X,Y,Z is from eye.
425 Avoid plotting too close.
430-440 Project image onto plane.
460 Move or draw and return.
600 c: Define function to be plotted.
Variables:
G,H -- Plot position on screen
W -- 4 for move, 5 for draw.
X,Y -- Used to scan X,Y plane.
%A,%B,%C -- Position centred on screen.
%L,%M,%N -- View position.
%0 -- Distance of point from eye.
%Q,%R,SS,%T -- Constants for projection.
%U,%V,SW -- 3D coordinates referred to new origin.
%X,%Y,%Z -- 3D coordinates of point being plotted
Program size: 594 bytes
22.2 Colour Graphics Extension -- COLOUR
The extension ROM also contains routines for plotting in the colour
graphics modes. The following colour graphics modes are available:
Mode: Resolution. Memory:
X: Y:
1a 64 64 1 K
2a 128 64 2 K
3a 128 96 3 K
4a 128 192 6 K
The graphics modes are obtained by specifying the CLEAR statement
followed by the mode number (without the 'a'), and the COLOUR
statement to determine which colour is to be plotted. The parameter to
the COLOUR statement determines the colour as follows; on a black and
white television or monitor the colours will be displayed as shades of
grey:
Value: Colour: Grey scale:
O Green Grey
1 Yellow White
2 Blue Black
3 Red Black
COLOUR O corresponds to the background colour.
When a colour has been specified, all subsequent DRAW statements
will draw lines in that colour. The PLOT statement will 'set' lines
_167_
and points in that colour, will always ’clear' to the background
colour, and will always 'invert' to a different colour, irrespective
of the current COLOUR.
22.2.1 Random Coloured Lines
The following simple program illustrates the use of the COLOUR command
by drawing coloured lines between randomly-chosen points on the
screen.
10 REM Random Coloured Lines
20 CLEAR 4
30 DO COLOUR RND
40 DRAW(ABSRND%128),(ABSRND%192)
50 UNTIL O
22.3 Memory Expansion
The ATOM's memory can be expanded, on the same board, in units of 1K
bytes (1024 bytes) up to a maximum on-board memory capacity of 12K
bytes. Refer to the Technical Manual for details of how to insert the
extra memory devices. The unexpanded ATOM contains 1K of Block O
memory, from #0000 to 00400, and 1K of VDU and text-space memory,
occupying between 08000 and #8400. The lower half is used by the VDU
and graphics mode 0, and the upper half forms the BASIC text-space
starting at $8200 and giving 512 free bytes for programs. The three
different areas of RAM that can be fitted on the main circuit board
are referred to as fol1ows:
Addresses: Area:
#0000-#0400 Block zero RAM
#2800-03COO Lover text space
#8000-09800 Graphics space/Upper text space
The following staqes in expansion are recommended:
22.3.1. Lower Text Space
Extra memory can be added starting at 02800 in the lower text space.
If memory is present in this text space BASIC will automatically be
initialised using this region as its text space. The text space starts
at 42900 to allow space between 02800 and 02900 for the floating-point
variables, but if the floating-point scientific package is not being
used the extra memory between #2800 and #2900 can be used for the text
space by typing:
?18=#28
NEW
A total of 5K of memory can be added in the extra text space.
There are two advantages in using the lower text space for programs:
1. Whenever the graphics memory is accessed noise will be generated on
the screen. Although this noise is slight under most circumstances, it
can become annoying when running machine-code programs assembled in
the upper text area, which is shared with the graphics area. Moving to
the lower text area will eliminate this noise.
2. When the upper tqxt area is used it is only possible to use the
lower graphics modes. The lower text area permits all graphics modes
to be used.
_168_
22.3.2 Graphics Space
Memory can be added in the graphics area from #8400 up to #9800,
providing a total of 6K of graphics memory. This will make the higher
graphics modes available, or can be used for programs in the graphics
space.
22.4 Versatile Interface Adapter
A Versatile Interface Adapter, or VIA, can be added to the ATOM to
provide two eight-bit parallel I/O ports, together with four control
lines, a pair of interval timers for providing real time interrupts,
and a serial to parallel or parallel to serial shift register. Both
eight-bit ports and the control lines are connected to side B of the
Acorn Bus connector.
Each of the 16 lines can be individually programmed to act as
either an input or an output. The two additional control lines per
port can be used to control handshaking of data via the port, and to
provide interrupts. Several of the' lines can be controlled directly
from the interval timers for generating programmable frequency square
waves or for counting externally generated pulses. Only the most basic
use of the VIA will be explained here; for more of its functions
consult the VIA data sheet (available from Acorn Computers). The VIA
registers occur in the following memory addresses:
Register: Address: Name:
Data Register B OB800 DB
Data Register A #B801 DA
Data Direction Register B 4B802 DDRB
Data Direction Register A OB803 DDRA
Timer 1 low counter, latch gB804 T1CL
Timer 1 high counter OB805 T1CH
Timer 1 low latch OB806 T1LL
Timer 1 high latch OB807 TlLH
Timer 2 low counter, latch OB808 T2CL
Timer 2 high counter OB809 T2CH
Shift Register OBSOA SR
Auxiliary Control Register OBSOB ACR
Peripheral Control Register OBSOC PCR
Interrupt Flag Register OBSOD IFR
Interrupt Enable Register gBSOE IER
Data Register A OBSOF DA
On BREAK all registers of the VIA are reset to O (except Tl, T2 and
SR). This places all peripheral lines in the input state, disables the
timers, shift register, etc. and disables interrupts.
22.4.1 Printer Interface
Port A has a high current output buffer leading to a 26-way printer
connector to produce a Centronics-type parallel interface, capable of
driving most parallel-interface printers with the software already in
the operating system. Printer output is enabled by printing a CTRL-B
character, and disabled by printing a CTRL-C character; see Section
18.1.3.
22.4.2 Parallel Input/Output
To use the ports in a simple I/O mode with no handshake, the Data
Direction Register associated with each I/O register must be
programmed. A byte is written to each of the DDR's to specify which
lines are to be inputs and outputs. A zero in a DDR bit causes the
_169_
corresponding bit in the I/O register to act as an input, while a one
causes the line to act as an output. Writing to the data register (DA
or DB) will affect only the bits which have been programmed as
outputs, while reading from the data register will produce a byte
composed of the current status of both input and output lines.
In order to use the printer port for ordinary I/0, the printer
software driver should be removed from the output stream by setting
the vector WRCVEC (address 0208) to WRCVEC+3; e.g.:
!#208=!0208+3
22.4.3 Writinq to a Port
The following program illustrates how to write to one of the VIA's
output ports from a BASIC program:
10 !4208=!0208+3
20 ?#B80C=O
30 ?#B802=0FF
40 INPUT J
50 ?OBSOO=J
60 GOTO 40
Description of Program:
10 Remove printer drive from port B.
20 Remove all handshaking.
30 Program all lines as outputs.
50 Output byte.
22.4.4 Timing to 1 Microsecond
The following program demonstrates how the VIA's timer 2 can be used
to measure the execution-time of different BASIC statements to the
nearest microsecond. The same method could be used to time events
signalled by an input to one of the ports:
10 REM Microsecond Timer
20 B=#B808
30 !B=65535
40 X=Y
50 B?3=32; Q=!B&0FFFF
60 PRINT 65535-Q-1755 "MICROSECONDS"'
70 END
Description of Program:
20 Point to timer 2 in VIA.
30 Set timer to maximum count.
40 Line to be timed; if absent, time should be 0.
50 Turn off timer; read current count.
60 Print time, allowing for time taken to read count.
_170_
23 Mnemonic Assembler
The ATOM mnemonic assembler is a full 6502 assembler; by virtue of its
close relationship with the BASIC interpreter the mnemonic assembler
provides many facilities found only on assemblers for much larger
computers, including conditional assembly and macros.
23.1 Location Counter -- P
The assembler uses the BASlC variable P as a location counter to
specify the next free address of the program being assembled. Before
running the assembler P should be set to the address of a free area of
memory. This will normally be the free space above the program, and
may be conveniently done with the statement:
DIM P(-1)
which sets P to the address of the first free location in memory after
the program, effectively reserving zero bytes for it. Note that P
should be the last variable dimensioned.
The location counter may also appear in the operand field of
instructions. For example:
LDX 00
DEX
BNE P-1
RTS
will cause a branch back to the DEX instruction. The program gives a
1279-cycle delay.
23.2 Assembler Delimiters '[' and ']'.
All assembler statements are enclosed inside square brackets '[' and
'J'. When RUN is typed each assembler statement is assembled, the
assembled code is inserted directly in memory at the address specified
by P, the value of P is incremented by the number of bytes in the
instruction, and a line of the assembler listing is printed out. A
typical line of the listing might be:
120 2A31 6D 34 12 :LL1 ADC #1234
^ ^ ^ ^ ^ ^
| | | | | |
| | | | | mnemonic statement
| | | | assembler label
| | | instruction data/address
| location counter
statement line number.
Note that '#' denotes a hexadecimal number.
23.3 Labels
Any of the array variables AA-ZZ may be used as labels in the
assembler. The label is specified by preceding the array element by a
_171_
colon ':'. Note that the brackets enclosing the array subscript may be
omitted. The labels must be declared in a DIM statement.
The effect of a label is to assign the value of the location
counter, P, at that point to the label variable. The label can then be
used as an argument in instructions. For example the following proqram
will assemble a branch back to the DEX instruction::
10 DIM ZZ(2),P(-1)
20[
30 LDX 00
40:ZZ1 DEX
50 BNE ZZ1
60 RTS
70]
80 END
23.4 Comments
Assembler instructions may be followed by a comment, separated from
the instruction by a space:
101 LDA 07 bell character
Alternatively a statement may start with a '\' backslash, in which
case the remainder of the statement is ignored:
112 \ routine to multiply two bytes
23.5 Backward References
When an assembler program is assembled, by typing RUN, backward
references are resolved automatically the first time the assembler is
RUN, because the associated labels receive their values before their
value is needed by the instruction.
23.6 Forward References
In a forward reference the la4el appears as the argument to an
instruction before its value is known. Therefore two passes of the
assembler are required; one to assign the correct value to the label,
and the second to use that value to generate the correct instruction
codes.
On the first pass through the assembler branches containing
forward references will give the warning message:
OUT OF RANGE:
indicating that a second pass is needed. The second byte of the branch
will be set to zero.
23.7 Two-Pass Assembly
A two-pass assembly can be achieved simply by typing RUN twice before
executing the machine code program. Alternatively it is possible to I
make the two-pass assembly occur automatically by incorporating the
statements to be assembled within a FOR...NEXT loop. The following
program assembles instructions to perform a two-byte increment:
10 REM Two-Pass Assembly
20 DIM M(3),JJ(2)
30 FOR N=1 TO 2
40 PRINT '"PASS "N
50 DIN P(-1)
55[
60:JJO INC M
_172_
70 BNE JJ1
80 INC M+1
90:JJ1 RTS
100]
110 NEXT N
120 INPUT L
130 !M=L
140 LINK JJO
150 P. &!M
160 END
Note that the statement DIM P(-1) is enclosed within the loop so that
P is reset to the correct value at the start of each pass.
The listing produced by this program is as follows; note that the
first pass is unable to resolve the reference to JJ1 in the
instruction of line 70:
PASS 1
55 29DE
60 29DE EE CE 29 :JJ0 INC M
OUT OF RANGE:
70 29E1 DO 00 BNE JJ1
80 29E3 EE CF 29 INC M+1
90 29E6 60 :JJ1 RTS
PASS 2
55 29DE
60 29DE EE CE 29 :JJ0 INC M
70 29E1 DO 03 BNE JJ1
80 29E3 EE CF 29 INC M+1
90 29E6 60 :JJ1 RTS
23.8 Suppression of Assembly Listinq
The assembly listing may be suppressed by disabling the output stream
with a NAK character, and enabling it again with an ACK at the end of
the assembly. The codes for NAK and ACK are 21 and 6 respectively. The
following program assembles instructions to print an "X” using a call
to the operating-system write-character routine, OSWRCH at OFFF4:
10 REM Turn off Assembly Listing
20 DIM P(-1)
30 PRINT $21; REM TURN OFF
40[LDA 0058; JSR OFFF4; RTS;]
50 PRINT $6 ; REM TURN ON
60 LINK TOP
70 END
23.9 Executing Programs
The LINK statement should be used to transfer control from a BASIC
program to a machine-code program. The operation of the LINK statement
is as follows:
1. The low-order bytes of the BASIC variables A, X, and Y are
transferred to the A, X, and Y registers respectively.
2. Control is transferred to the address given after the LINK
statement.
The argument to the LINK statement will normally either be TOP,
when no arrays have been declared in the space after the program, or a
_173_
label corresponding to the entry-point in the assembler program (which
need not be the first instruction in the program). For examples see
the example programs in this chapter, and in Chapter 17.
23.10 Breakpoints
During debugging of a machine-code program it may be convenient to
discover whether sections of the program are being executed. A
convenient way to do this is to insert breakpoints in the program. The
BRK instruction (op-code 000) is used as a breakpoint, and execution
of this instruction will return control to the system, with the
message:
ERROR XX LINE LL
where XX is two greater than the lower byte of the program counter, in
decimal, where the BRK occurred, and the line number is the last BASIC
line executed before the BRK occurred. Any number of BRK instructions
may be inserted, and the value of the program counter in the ERROR
message will indicate which one caused the break.
To provide more information on each BRK, such as the contents of
all the processor's registers, the break vector can be altered to
indirect control to a user routine, as shown in the following section.
23.10.1 Breakpoint Routine
The BRK instruction can be used to show which parts of a machine-code
routine are being executed. By adding a small assembler program it is
possible to keep a record of the register contents when the BRK
occurred, and, if required, print these out.
The memory locations #202 and #203 contain the address to which
control is transferred on a BRK instruction. This address can be
redefined to point to a routine which will save the register contents
in a vector K. The registers are saved as follows:
PCL PCH A X Y S P
K:O 1 2 3 4 5 6
After the registers have been saved in the vector K, the routine jumps
to the standard BRK handler, the address previously in locations #202
and #203:
10 REM Print Registers on BRK
30 DIM K(6),AA(1),A(8),P(-1)
35 B=?0202+256*?0203
40 ?16=A;?17=A&gFFFF/256;$A="GOT0150"
45[
50:AAO STA K+2; STX K+3
60 PLA; STA K+6; PLA; STA K
80 PLA; STA K+1
90 STY K+4; TSX; STX K+5
100 JMP B
110]
120 REM INSTALL BRK ROUTINE
130 ?0202=AAO; ?0203=AAO&OFFFF/256
135 GOTO 200
140 REM PRINT REGISTERS
150 0=5
160 PRINT" PC A X Y S P"'
170 PRINT&!K&lFFFF-2;FORN=2T06
_174_
175 0=3
180 PRINT&K?N;N.
190 PRINT1; END
200 REM DEMONSTRATE USE
210[
220:AA1 LDA 0#12; LDX 0434
230 LDY 0056; BRK
240]
250 REN EXECUTE TEST PROGRAM
260 LINK AA1
Description of Program:
30 Declare vectors and array
35 Set B to BRK handler address
40 Point error line handler to "GOTO 150"
50-100 Assemble code to save registers in vector K
130 Point BRK handler to register-save routine.
150-190 Print out vector K, with heading.
220-240 Assemble test program to give a BRK
260 Execute test program.
Variables:
$A -- String to contain BASIC line.
AA(0..1) -- Labels for assembler routines.
AAO -- Entry point to routine to save registers in vector K.
AA1 -- Entry point to test program.
B -- Address of BRK routine.
K?0..6 -- Vector to hold registers on BRK.
lf this program is compiled, the following will be printed out after
the assembler listing:
PC A X Y S P
2B60 12 34 56 FD 35
23.11 Conditional Assembly
The simplest facility is conditional assembly; the assembler source
text can contain tests, and assemble different statements depending on
the outcome of these tests. This is especially useful where slightly
different versions of a program are needed for many different
purposes. Rather than creating a different source file for each
different version, a single variable can determine the changes using
conditional assembly. For example, two printers are driven from a
parallel port. They differ as follows:
1. The first printer needs a 12 microsecond strobe, and true data.
2. The second printer needs an 8 microsecond strobe and inverted data.
The variable V is used to denote the version number (1 or 2). H
contains the address of the 8-bit output port, and the top bit of
location H+1 is the strobe bit; D is the address of the data to be
output.
10 DIM P(-1)
20 H=#B800; D=#80
300[ LDA D;]
310 IF V=2 [ EOR #FF invert;]
320[ STA H to port
330 LDA @#80
340 STA H+1
360 NOP strobe delay;]
_175_
370 IF V=l [ NOP; NOP extra delay;]
380[ LDA 00
390 STA H+1
400]
410 END
If this segment of the program is first executed with V=l the
assembled code is as required for printer 1:
>V=l;RUN
300 29BB A5 80 LDA D
320 29BD 8D 00 BS STA H to port
330 29CO A9 80 LDA @#80
340 29C2 8D 01 B8 STA H+1
360 29C5 EA NOP strobe delay
370 29C6 EA NOP
370 29C7 EA NOP extra delay
380 29C8 A9 00 LDA @0
390 29CA 8D 01 B8 STA H+1
Extra NOP instructions have been inserted to give the required strobe
delay. If now the program is executed with V=2 the code generated is
suitable for printer 2:
>V=2;RUN
300 29BB A5 80 LDA D
310 29BD 45 FF EOR OFF invert
320 29BF SD 00 BS STA H to port
330 29C2 A9 80 LDA @#80
340 29C4 8D 01 BS STA H+1
360 29C7 EA NOP strobe delay
380 29C8 A9 00 LDA @0
390 29CA 8D 01 B8 STA H+1
An instruction to invert the data has been added before writing it to
the port.
Conditional assembly is also useful for the insertion of extra
instructions to print out intermediate values during debugging; thesc
statements will be removed when the proqram is finally assembled. To
do this a logical variable, D in the following example, is given the
value 1 (true) during debugging and the value O (false) otherwise. If
D=l a routine to print the value of the aecumulator in hex is
assembled, and calls to this routine are inserted at two relevant
points in the test program:
10 REM P"int Hex Digits
20 DIM GG(3),P(-1)
30 IF D=O GOTO m
50[
55 \ print hex digit
60:GG1 AND @#F
70 CMP @#A; BCC P+4
80 ADC @6; ADC @#30
90 JMP #FFF4
95 \ print A in hex
100:GG2 PHA; PHA; LSRA; LSRA
110 LSRA; LSRA; JSR GG1
120 PLA; JSR GG1; PLA; RTS
130]
140mREM main program
_176_
150[
170:GGO CLC; ADC 0040;J
190 IF D [ JSR GG2;]
200[
210 BEQ GG3; SBC 0010;]
220 IF D [ yJSR GG2;]
230[
240:GG3 RTS;]
250 END
For debugging purposes this program is assembled by typing:
>D=1
>RUN
>RUN
The program can then be executed for various values of A by typing:
A=#12; LINK GGO
The final version of the program is assembled, without the debugging
aids, by typing:
>D=O
>RUN
>RUN
23.12 Macros
Macros permit'a name to be associated with a number of assembler
instructions. This name can then be used as an abbreviation for those
instructions; whenever the macro is called, the effect is as if the
corresponding lines of assembler had been inserted at that point.
In their simplest form macros just save typing. For example, the
seguence:
LSR A; LSR A; LSR A; LSR A
occurs freguently in assembler programs (to shift the upper nibble of
the accumulator into the lower nibble), but it is not worth making the
instructions into a subroutine. A macro, with the name s in the
following example, can be set up as follows:
1000s[LSR A; LSR A; LSR A; LSR A;]
1010 RETURN
Then the above four instructions can be replaced by the following call
to the macro s:
GOSUB s
23.12.1 Nacro Parameters
The great power of macros lies in the ability to pass parameters to
them so that the assembler lines they generate will be determined by
the values of the parameters.
The simplest type of parameter would simply be an address; for
example, the macro r below will rotate right any location, zero page
or absolute, whose address is passed over in L:
2000r[ROR L: ROR L; ROR L; ROR L:]
2010 RETURN
A typical call in a proqram might be:
L=#80; GOSUB r
_177_
The following program illustrates the use of two macros. Macro i
increments a 16-bit number in locations J and J+1. Macro c performs an
unsigned compare between two 16-bit numbers in J,J+1 and K,K+1. The
program uses these two macros to move a block of memory from one
starting address to a lower starting address.
10 REM Block Move
20 DIM LL(2),P(100)
30 F=#80; L=#82; T=#84
40[:LLO LDY @0
45:LL1 LDA (F),Y; STA (T),Y;J
50 J-T; GOSUB i'
60 J=F; GOSUB i
70 K=L; GOSUB c
80[ BNE LL1; RTS;]
90
100 REM TRY IT OUT
110 REM F=first address
112 REM L=last address
114 REM T=address moved to (T<F)
120 !F=#500;!L=#800;!T=#400
130 LINK LL0
140 END
8000
8100 REM MACRO -- INC J,J+1
8105i[INC J; BNE P+4+(J>254)&1
8110 INC J+1;]
8120 RETURN
8130
8140 REM MACRO -- CMP J,J+1 WITH K,K+1
8145c[LDA J+1," CMP K+1
8150 BNE P+6+(J>255)61+(K>255)&1
8160 LDA J; CMP K;)
8170 RETURN
Note that both macros are designed to work whether J and K are
absolute addresses or zero-page addresses; to avoid the need for
labels in these macros they test for the size of the address, and
generate the correct argument for the branch instruction. The
expression:
(J>255)&1
has the value 1 if J is greater than 255, and the value O if J is 255
or less.
23.12.2 In-Line Assembly
In critical sections of programs, where speed is important, it may be
necessary to code repetitative calculations by actually repeating the
instructions as many times as necessary, rather than using a loop,
thereby avoiding the overhead associated with the loop calculations.
The following macro compiles a routine to multiply a 7-bit number in
the A register by a fractional constant between O/256 and 255/256. The
numerator of the constant is passed to the macro in C:
1 REM Fractional Multiplication
5 J=#80; DIM P(-1)
10 C=#AA
20 GOSUBm
30 [STA J;RTS;]
_178_
40 INPUT A
50 LINK TOP
60 P.&A,&?J
70 END
2000mREM macro -- multiply by constant
2010 REM A = A * C/256
2020 REM uses J
2030 B=080
2040 [STA J;LDA 00;]
2050 DO [LSR J;]
2060 IF C&B<>0 [CLC;ADC J;)
2070 C=(C*2)FF; UNTIL C=0
2080 RETURN
The macro is tested with C=#AA. In this case the code produced will
be:
2040 2A42 85 80 STA J
2040 2A44 A9 00 LDA @0
2050 2A46 46 80 LSR J
2060 2A48 18 CLC
2060 2A49 65 80 ADC J
2070 2A4B 46 80 LSR J
2070 2A4D 46 80 LSR J
2060 2A4F 18 CLC
2060 2A50 65 80 ADC J
2070 2A52 46 80 LSR J
2070 2A54 46 80 LSR J
2060 2A56 18 CLC
2060 2A57 65 80 ADC J
2070 2A59 46 80 LSR J
2070 2A5B 46 80 LSR J
2060 2A5D 18 CLC
2060 2A5E 65 80 ADC J
2080 2A60 85 80 STA J
2080 2A62 60 RTS
_179_
_180_
2 4 Assernbler Mnemonics
The followinq section lists all the instruction mnemonics in
alphabetical order. Each instruction is accompanied by a description
of the instruction, a symbolic representation of the action performed
by the instruction, a diagram showing the status-register flags
affected by the instruction, and a list of the permitted addressing
modes for the instruction.
The following symbols are used in this section:
Symbol: Definition:
+ Addition
- Subtraction
& Logical AND
\ Logical OR
: Logical Exclusive-OR
! Push onto hardware stack
^ Pull from hardware stack
= Assignment
M Memory location
(PC+1) Contents of location after op-code
@ Immediate addressing mode --
~ No change to flag
% Change to flag
1 Set
0 Cleared
A Accumulator
X X Index Register
Y Y Index Register
PC Program Counter
PCL Low byte of Program Counter
PCH High byte of Program Counter
ADC Add memory to accumulator with carry ADC
A,C=A+M+C N Z C I D V
% % % ~ ~ %
Addressing Assembler Format Bytes Cycles
Immediate ADC 0 Oper 2 2
Zero Page ADC Oper 2 3
Zero Page,X ADC Oper,X 2 4
Absolute ADC Oper 3 4
Absolute,X ADC Oper,X 3 4*
Absolute,Y ADC Oper,Y 3 4*
(Indirect,X) ADC (Oper,X) 2 6
(Indirect),Y ADC (Oper),Y 2 5*
* Add 1 if page boundary crossed.
_181_
AND AND memory with accumulator AND
A=A&M N Z C I D V
% % ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Immediate AND 0 Oper 2 2
Zero Page AND Oper 2 3
Zero Page,X AND Oper,X 2 4
Absolute AND Oper 3 4
Absolute,X AND Oper,X 3 4*
Absolute,Y AND Oper,Y 3 4*
(Indirect,X) AND (Oper,X) 2 6
(Indirect),Y AND (Oper),Y 2 5*
* Add 1 if page boundary crossed.
ASL Arithmetic shift left one bit (memory or accumulator) ASL
N Z C I D V
C <-- 7 6 5 4 3 2 1 O <-- O % % % ~ ~ ~
Addressing Assembler Format Bytes Cycles
Accumulator ASL A 1 2
Zero Page ASL Oper 2 5
Zero page,X ASL Oper,X 2 6
Absolute ASL Oper 3 6
Absolute,X ASL Oper,X 3 7
BCC Branch on carry clear BCC
Branch if C=O N Z C I D V
~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Relative BCC Oper 2 2*
* Add 1 if branch occurs to same page
Add 2 if branch occurs to different page
BCS Branch on carry set BCS
Branch if C=l N Z C I D V
~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Relative BCS Oper 2 2*
* Add 1 if branch occurs to same page
Add 2 if branch occurs to different page
BEQ Branch on result zero BEQ
Branch if Z=l N Z C I D V
~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Relative BEQ Oper 2 2*
* Add 1 if branch occurs to same page
Add 2 if branch occurs to different page
_182_
BIT Test bits in memory with accumulator BIT
A&M, N=M7, V=M6 N Z C I D V
M7% ~ ~ ~ M6
Bit 6 and 7 are transferred to the status register. If the result of
A&M is zero then Z=1, otherwise Z=O.
Addressing Assembler Format Bytes Cycles
Zero Page BIT Oper 2 3
Absolute BIT Oper 3 4
BNI Branch on result minus BMI
Branch if N=l N Z C I D V
~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Relative BMI Oper 2 2*
* Add 1 if branch occurs to same page
Add 2 if branch occurs to different page
BNE Branch on result not zero BNE
Branch if Z=O N Z C I D V
~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Relative BNE Oper 2 2*
* Add 1 if branch occurs to same page
Add 2 if branch occurs to different page
BPL Branch on result plus BPL
Branch if N=O N Z C I D V
~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Relative BPL Oper 2 2*
* Add 1 if branch occurs to same page
Add 2 if branch occurs to different page
BRK Force break BRR
Forced interrupt; PC+2 ! P ! N Z C I D V
~ ~ ~ 1 ~ ~
Addressing Assembler Format Bytes Cycles
Implied BRK 1 7
A BRK command cannot be masked by setting I.
BVC Branch on overflow clear BVC
Branch if V=O N Z C I D V
~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Relative BVC Oper 2 2*
* Add 1 if branch occurs to same page
Add 2 if branch occurs to different page
_183_
BVS Branch on overflow set BVS
Branch if V=l N Z C I D V
~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Relative BVS Oper 2 2*
* Add 1 if branch occurs to same page
Add 2 if branch occurs to different page
CLC Clear carry flag CLC
C=O N Z C I D V
~ ~ 0 ~ ~ ~
Addressing Assembler Format Bytes Cycles
Implied CLC 1 2
CLD Clear decimal mode CLD
D=O N Z C I D V
~ ~ ~ 0 ~ ~
Addressing Assembler Format Bytes Cycles
Implied CLD 1 2
CLI Clear interrupt disable bit CLI
I=O N Z C I D V
~ ~ ~ 0 ~ ~
Addressing Assembler Format Bytes Cycles
Implied CLI 1 2
CLV Clear overflow flag CLV
v =O N Z C I D V
~ ~ ~ ~ ~ 0
Addressing Assembler Format Bytes Cycles
Implied CLV 1 2
CMP Compare memory and accumulator CMP
A-M N Z C I D V
% % % ~ ~ ~
Addressing Assembler Format Bytes Cycles !
Immediate CMP @ Oper 2 2
Zero Page CMP Oper 2 3
Zero Page,X CMP Oper,X 2 4
Absolute CMP Oper 3 4
Absolute,X CMP Oper,X 3 4*
Absolute,Y CMP Oper,Y 3 4*
(Indirect,X) CMP (Oper,X) 2 6
(Indirect),Y CMP (Oper),Y 2 5*
* Add 1 if page boundary crossed.
CPX Compare memory and index register X CPX
X-M N Z C I D V
% % % ~ ~ ~
Addressing Assembler Format Bytes Cycles
Immediate CPX @ Oper 2 2
Zero Page CPX Oper 2 3
Absolute CPX Oper 3 4
_184_
CPY Compare memory and index reqister Y CPY
Y-M N Z C I D V
% % % ~ ~ ~
Addressing Assembler Format Bytes Cycles
Immediate CPY @ Oper 2 2
Zero Page CPY Oper 2 3
Absolute CPY Oper 3 4
DEC Decrement memory by one DEC
M=M-1 N Z C I D V
% % ~ ~ ~ ~
Addressinq Assembler Format Bytes Cycles
Zero Page DEC Oper 2 5
Zero Page,X DEC Oper,X 2 6
Absolute DEC Oper 3 6
Absolute,X DEC Oper,X 3 7
DEX Decrement index reqister X by one DEX
X=X-1 N Z C I D V
% % ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Implied DEX 1 2
DEY Decrement index register Y by one DEY
Y=Y-1 N Z C I D V
% % ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Implied DEY 1 2
EOR Exclusive-OR memory with accvmulator EOR
A=A:M N Z C I D V
% % ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Immediate EOR @ Oper 2 2
Zero Page EOR Oper 2 3
Zero Page,X EOR Oper,X 2 4
Absolute EOR Oper 3 4
Absolute,X EOR Oper,X 3 4*
Absolute,Y EOR Oper,Y 3 4*
(Indirect,X) EOR (Oper,X) 2 6
(Indirect),Y EOR (Oper),Y 2 5*
* Add 1 if page boundary crossed.
INC Increment memory by one INC
M=M+1 N Z C I D V
% % ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Zero Page INC Oper 2 5
Zero Page,X INC Oper,X 2 6
Absolute INC Oper 3 6
Absolute,X INC Oper,X 3 7
_185_
INX Increment index reqister X by one INX
X=X+1 N Z C I D V
% % ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Implied INX 1 2
INY Increment index register Y by one INY
Y=Y+1 N Z C I D V
% % ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Implied INY 1 2
JMP Jump to new location JMP
PCL= ( PC+1 ) N Z C I D V
PCH=(PC+2) ~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Absolute JMP Oper 3 3
Indirect JMP (Oper) 3 5
JSR Jump to subroutine savinq return address JSR
PC+2 !, PCL=(PC+1) N Z C I D V
PCH=(PC+2) ~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Absolute JSR Oper 3 6
LDA Load accumulator with memory LDA
A=M N Z C I D V
% % ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Immediate LDA @ Oper 2 2
Zero Page LDA Oper 2 3
Zero Page,X LDA Oper,X 2 4
Absolute LDA Oper 3 4
Absolute,X LDA Oper,X 3 4*
Absolute,Y LDA Oper,Y 3 4*
(Indirect,X) LDA (Oper,X) 2 6
(Indirect),Y LDA (Oper),Y 2 5*
* Add 1 if page boundary crossed.
LDX Load index register X with memory LDX
X=M N Z C I D V
% % ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Immediate LDX @ Oper 2 2
Zero Page LDX Oper 2 3
Zero Page,Y LDX Oper,Y 2 4
Absolute LDX Oper 3 4
Absolute,Y LDX Oper,Y 3 4*
* Add 1 when page boundary crossed
_186_
LDY Load index register Y with memory LDY
Y=M N Z C I D V
% % ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Immediate LDY @ Oper 2 2
Zero Page LDY Oper 2 3
Zero Page,X LDY Oper,X 2 4
Absolute LDY Oper 3 4
Absolute,X LDY Oper,X 3 4*
* Add 1 when page boundary crossed
LSR Logical shift right one bit (memory or accumulator) LSR
N Z C I D V
O --> 7 6 5 4 3 2 1 O --> C % % % ~ ~ ~
Addressing Assembler Format Bytes Cycles
Accumulator LSR A 1 2
Zero Page LSR Oper 2 5
Zero page,X LSR Oper,X 2 6
Absolute LSR Oper 3 6
Absolute,X LSR Oper,X 3 7
NOP No operation NOP
N Z C I D V
~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Implied NOP 1 2
ORA OR memory with accumulator ORA
A=A\M N Z C I D V
% % ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Immediate ORA @ Oper 2 2
Zero Page ORA Oper 2 3
Zero Page,X ORA Oper,X 2 4
Absolute ORA Oper 3 4
Absolute,X ORA Oper,X 3 4*
Absolute,Y ORA Oper,Y 3 4*
(Indirect,X) ORA (Oper,X) 2 6
(Indirect),Y ORA (Oper),Y 2 5*
* Add 1 if page boundary crcssed.
PHA Push accumulator on stack PHA
A ! N Z C I D V
~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Implied PHA 1 3
PHP Push processor status on stack PHP
P ! N Z C I D V
~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Implied PHP 1 3
_187_
PLA Pull accumulator from stack PLA
A" N Z C I D V
% % ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Implied PLA 1 4
PLP Pull processor status from stack PLP
P" N Z C I D V
from stack
Addressing Assembler Format Bytes Cycles
Implied PLP 1 4
ROL Rotate left one bit (memory or accumulator) ROL
N Z C I D V
+- 7 6 5 4 3 2 1 O <-- C <--+ % % % ~ ~ ~
| |
+-------------------------------+
Addressing Assembler Format Bytes Cycles
Accumulator ROL A 1 2
Zero Paqe ROL Oper 2 5
Zero page,X ROL Oper,X 2 6
Absolute ROL Oper 3 6
Absolute,X ROL Oper,X 3 7
ROR Rotate right one bit (memory or accumulator) ROR
N Z C I D V
+--> C --> 7 6 5 4 3 2 1 O -+ % % % ~ ~ ~
| |
+-----------------------------+
Addressing Assembler Format Bytes Cycles
Accumulator ROR A 1 2
Zero Page ROR Oper 2 5
Zero page,X ROR Oper,X 2 6
Absolute ROR Oper 3 6
Absolute,X ROR Oper,X 3 7
RTI Return from interrupt RTI
P^ PC^ N Z C I D V
from stack
Addressing Assembler Format Bytes Cycles
Implied RTI 1 6
RTS Return from subroutine RTS
PC^ N Z C I D V
~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Implied RTS 1 6
_188_
SBC Subtract memory from accumulator with carry SBC
A,C=A-N-(C-1) N Z C I D V
% % % ~ ~ %
Addressing Assembler Format Bytes Cycles
Immediate SBC O Oper 2 2
Zero Page SBC Oper 2 3
Zero Page,X SBC Oper,X 2 4
Absolute SBC Oper 3 4
Absolute,X SBC Oper,X 3 4*
Absolute,Y SBC Oper,Y 3 4*
(Indirect,X) SBC (Oper,X) 2 6
(Indirect),Y SBC (Oper),Y 2 5*
* Add 1 if page boundary crossed.
SEC Set carry flaq SEC
C=1 N Z C I D V
~ ~ 1 ~ ~ ~
Addressing Assembler Format Bytes Cycles
Implied SEC 1 2
SED Set decimal mode SED
D=1 N Z C I D V
~ ~ ~ ~ 1 ~
Addressing Assembler Format Bytes Cycles
Implied SED 1 2
SEI Set interrupt disable bit SEI
I=1 N Z C I D V
~ ~ ~ 1 ~ ~
Addressing Assembler Format Bytes Cycles
Implied SEI 1 2
STA Store accumulator in memory STA
M=A N Z C I D V
~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Zero Page STA Oper 2 3
Zero Page,X STA Oper,X 2 4
Absolute STA Oper 3 4
Absolute,X STA Oper,X 3 5
Absolute,Y STA Oper,Y 3 5
(Indirect,X) STA (Oper,X) 2 6
(Indirect),Y STA (Oper),Y 2 6
STX Store index register X in memory STX
M=X N Z C I D V
~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Zero Page STX Oper 2 3
Zero Page,Y STX Oper,Y 2 4
Absolute STX Oper 3 4
_189_
STY Store index reqister Y in memory STY
M=Y N Z C I D V
~ ~ ~ ~ ~ ~
Addressinq Assembler Farmat Bytes Cycles
Zero Page STY Oper 2 3
Zero Page,X STY Oper,X 2 4
Absolute STY Oper 3 4
TAX Transfer accumulator to index register X TAX
X=A N Z C I D V
~ ~ ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Implied TAX 1 2
TAY Transfer accumulator to index register Y TAY
Y=A N Z C I D V
% % ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Implied TAY 1 2
TSX Transfer stack pointer to index register X TSX
X=S N Z C I D V
% % ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Implied TSX 1 2
TXA Transfer index register X to accumulator TXA
X=A N Z C I D U
% % ~ ~ ~ ~
Addressing Assembler Format Bytes Cycles
Implied TXA 1 2
TXS Transfer index register X to stack pointer TXS
X=S N Z C I D V
% % ~ ~ ~ ~
--
Addressing Assembler Format Bytes Cycles
Implied TXS 1 2
TYA Transfer index register Y to accumulator TYA
Y=A N Z C I D V
% % ~ ~ ~ ~
--
Addressing Assembler Format Bytes Cycles
Implied TYA 1 2
_190_
25 Operating System
Routines and Addresses
25.1 Input/Output Routines
The ATOM operating system contains several routines which can be
called by user programs to provide input and output facilities. The
routines are defined so that they are compatible with the other Acorn
operating systems; in particular, if the ATOM is expanded to include a
Disk Operating System the same routines will automatically function
with the disk.
OSCLI Command line interpreter
This subroutine interprets a string of characters at address 00100 and
terminated by carriage return as an operating system command. Detected
errors are met with a BRK. All processor registers are used, and the
decimal-mode flag is set to binary on exit.
OSWRCH Write character
This subroutine sends the byte in the accumulator to the output
channel. Control characters are normally recognised as detailed in
Section 18.1.3. All registers are preserved.
OSCRLF Carriage return -- line feed
This subroutine generates a line feed followed by a carriage return
using OSWRCH. On exit A will contain #OD, N and Z will be 0, and all
other registers are preserved.
OSECHO Read character with echo
This subroutine reads a byte using OSRDCH and then writes it out using
OSWRCH. The routine converts carriage returns to a line feed followed
by a carriage return. On exit A will contain the byte read, N, Z, and
C are undefined, and all other registers are preserved.
OSRDCH ReaQ character
This subroutine reads a byte from the input channel and returns it in
A. The state of N, Z, and C is undefined; all other reqisters are
preserved.
OSLOAD Load file
This subroutine loads a complete file into a specified area of memory.
On entry X must point to the following data in zero page:
X+O address of string of characters, terminated by OOD, which is the
file name.
X+2 Address in memory of the first byte of the destination.
X+4 Flag byte: if bit 7 = O use the file's start address.
All processor registers are used. A break will occur if the file
cannot be found. In interrupt or DMA driven systems a wait until
completion should be performed if the carry flag was set on entry.
_191_
OSSAVE, Save file
This subroutine saves all of an area of memory to a specified file. On
entry X must point to the following data in zero page:
X+O Address of string of characters, terminated by OOD, which is the
file name.
X+2 Address for data to be reloaded to.
X+4 Execution address if data is to be executed
X+6 Start address of data in memory
X+8 End address + 1 of data in memory
The data is copied by the operating system without being altered. All
registers are used. In interrupt or DMA driven operating systems a
wait until completion should be performed if the carry flag was set on
entry. A break will occur if no storage space large enough can be
found.
OSBPUT Put byte
This subroutine outputs the byte in the accumulator to a sequential
write file. Registers X and Y are saved. In the ATOM operatinq system
interrupts are disabled during OSBPUT but interrupt status is restored
on exit. In the Disk Operating System the file's sequential file
pointer will be incremented after the byte has been saved.
OSBGET Get byte
The subroutine returns, in A, the next byte from a sequential read
file. Registers X and Y are retained. In the ATOM operating system
interrupts are disabled during OSBGET but interrupt status is restored
on exit. In the Disk Operating System the file's sequential fila
pointer will be incremented after the byte has been read.
OSFIND Find file
This subroutine returns, in A, a 'handle' for a file. The X register
points to zero page locations containing the address of the first
character of the file name; the file name is terminated by a OOD byte.
The 'handle' is zero if the file does not exist; otherwise it is a
byte uniquely specifying the file. If the file is to be used for
sequential input the carry should be set, or if for sequential output
the carry should be clear. In the ATOM operating system the file
handle is set to 13, and the message ”PLAY TAPE" or "RECORD TAPE" is
produced. In the Disk Operating Systam the file's sequential pointer
is set to zero.
OSSHUT Shut file
This subroutine removes a reference to a file whose handle is in the Y
register. If a handle of zero is supplied, all files are shut. In the
ATOM operating system the call does nothing.
The following subroutines are not used in the cassette system, and
cause an error if called:
OSRDAR Read file's arguments
OSSTAR Store file's arguments
25.2 Operating System Calls
The following table gives the addresses of all the operating system
calls:
_192_
Address: Subroutine: Instruction:
#FFCB OSSHUT JMP (SHTVEC)
#FFCE OSFIND JMP (FNDVEC)
#FFD1 OSBPUT JMP (BPTVEC)
#FFD4 OSBGET JMP (BGTVEC)
#FFD7 OSSTAR JMP (STRVEC)
#FFDA OSRDAR JMP (RDRVEC)
#FFDD OSSAVE JMP (SAVVEC)
#FFED OSLOAD JMP (LODVEC)
#FFE3 OSRDCH JMP (RDCVEC)
#FFE6 OSECHO JSR OSRDCH
#FFE9 OSASCI CMP @#0D
#FFEB BNE OSWRCH
#FFED OSCRLF LDA @#0A
#FFEF JSR OSWRCH
#FFF2 LDA @#0D
#FFF4 OSWRCH JMP (WRCVEC)
#FFF7 OSCLI JMP (COMVEC)
The operating system calls are all indirected via addresses held in
RAM, and these addresses may be changed to the addresses of
user-supplied routines. The addresses are initialised on reset as
follows:
Address: Subroutine: Function:
#0200 NMIVEC NMI service routine
#0202 BRKVEC BRK service routine
#0204 IRQVEC IRQ service routine
#0206 COMVEC Command line interpreter
#0208 WRCVEC Write character
#020A RDCVEC Read character
#020C LODVEC Load file
#020E SAVVEC Save file
#0210 RDRVEC Error
#0212 STRVEC Error
#0214 BGTVEC Get byte from tape
#0216 BPTVEC Put hyte to tape
#0218 FNDVEC Print message
#021A SHTVEC Dummy
A call to one of the routines OSRDAR or OSSTAR will cause the message:
COM?
to be output, followed by a BRK.
25.3 Interrupts
The following action is taken on interrupts:
NMI PHA
JMP (NMIVEC)
IRQ/BRQ STA 0FF
PLA
PHA
AND @#10 which interrupt was it
BNE BRK
LDA 4FF
PHA
JMP (IRQVEC)
BRK LDA OFF
_193_
PLP
PHP
JMP (BRKVEC)
Note that the accumulator is pushed before the jump occurs.
25.4 Block Zero RAM Locations
Hexadecimal: Decimal: Function:
#0 O Error number
#1, #2 1, 2 BASIC line number.
#s - #c 8 - 12 Random number seed
#10, 011 16, 17 Pointer to BASIC error handler
#12 18 Text-space pointer
#00 - 06F O - 111 BASIC zero-page workspace
#70 - 07F 112 - 143 Floating-point workspace
#80 - #AF 144 - 175 Free
#BO - 0FF 176 - 255 Cassette system workspace
#FE 254 Character not sent to printer
#100 - 013F 256 - 319 Input line buffer
#140 - g17F 320 - 383 Strinq processing & INPUT statement buffer
#180 - 01FF 344 - 511 Stack
#200 - 021B 512 - 539 Operating system vectors
#21C - 023F 540 - 575 Free
#240 - g3FF 576 - 1023 BASIC workspace
#3FE, #3FF 1022, 1023 Address of point-plotting routine
25.5 Input/Output Port Allocations
The 8255 Programmable Peripheral Interface Adapter contains three
8-bit ports, and all but one of these lines is used by the ATOM.
Port A - #B000
Output bits: Function:
O -- 3 Keyboard row
4 -- 7 Graphics mode
Port B - #B001
Input bits: Function:
O -- 5 Keyboard column
6 CTRL key (low when pressed)
7 SHIFT keys {low when pressed)
Port C - #B002
Output bits: Function:
O Tape output
1 Enable 2.4 kHz to cassette output
2 Loudspeaker
3 Not used
Input bits: Function:
4 2.4 kHz input
5 Cassette input
6 REPT key (low when pressed)
7 60 Hz sync signal (low during flyback)
The port C output lines, bits O to 3, may be used for user
applications when the cassette interface is not being used.
_194_
25.6 Memory Map
The following diagram shows how the ATOM's address space is allocated.
Sections shown shaded are present in the minimal-system ATOM. The map
includes the addresses of devices on the Acorn cards, which may be
fitted inside the ATOM case.
#0000 |
Block Zero RAM |
#0400 |
Teletext VDU RAM |
#0800 |
VDU CRT Controller |
#0900 |
|
#0A00 |
Optional FDC |
#0A80 |
|
#1000 |
Peripherals space |
#2000 |
Catalogue buffer |
#2200 |
Sequential File buffers |
#2800 |
Floating point variables |
#2900 |
Extension Text space RAM |
#3C00 |
Off-board Extension RAM |
#8000 |
VDU Screen RAM |
#8200 |
Graphics Mode 1 |
#8400 |
Graphics Mode 2 |
#8600 |
Graphics Mode 3 |
#8C00 |
Graphics Mode 4 |
#9800 |
|
#A000 |
Optional Utility ROM |
#B000 |
PPIA I/O Device |
#B800 |
Optional VIA I/O Device for Printer Interface |
#C000 |
ATOM BASIC Interpreter |
#D000 |
Optional Extension ROM |
#E000 |
Optional Disk Operating System |
#F000 |
Assembler |
|
Cassette Operating System |
_195_
_196_
_197_
_198_
26 Syntax Definition
This syntax definition is written in B.N.F., or Backus-Naur Form, with
some additions. In the places where a proper definition in B.N.F.
would be far too long, a description has been used. The rules are:
Things in triangular <> brackets are defined things, "syntactic
entities", everything else is itself
The ::= symbol is read as "is defined".
The | sign is read as OR: one of the alternatives must be true.
Concatenation of things is read as "followed by".
The ^ sign is read as "any number of".
The {} brackets allow concatenations to be grouped together.
26.1 BASIC Syntax Definition
26.1.1 Basic Symbols
! " # $ % & ' ( ) * + , - . / O 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C
D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l
m n o p q r s t u v w x y z [ \ < < > @@ AA BB CC CH DD DO EE FF GG
HH II IF JJ KK LL MM NN OO OR PP QQ RR SS TO TT UU VV WW XX YY ZZ ABS
AND DIM END EXT FIN FOR GET LEN LET NEW OLD PTR PUT REM RND RUN TOP
BGET BPUT DRAW FOUT GOTO LINK LIST LOAD MOVE NEXT PLOT SAVE SGET SHUT
SPUT STEP THEN WAIT CLEAR COUNT GOSUB INPUT PRINT UNTIL RETURN
No multi-character basic symbols may include blanks; otherwise
blanks may be used freely to improve the readability of the program.
The character '.' can be used to provide a shorter representation of
all multi-character basic symbols.
<asciic>::={ascii characters excluding carriage return}
<digit>::=0|1|2|3|4|5|6|7|8|9
<hex digit>::=<digit>|A|B|C|D|E|F
<positive number>::=<digit><digit>^
such that <positive number> is less than 2147483648
<hex number>::=<hex digit><hex digit>^
<integer field size>::=@
<p-variable>::=<integer field size>|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q
|R|S|T|U|V|W|X|Y|Z
<variable>::=<p-variable>{character which is not <p-variable> or .}
<array name>::=@@|AA|BB|CC|DD|EE|FF|GG|HH|II|JJ|KK|LL|MM|NN|OO|PP|QQ
|RR|SS|TT|UU|VV|WW|XX|YY|ZZ
_199_
<label>::=a|b|c|d|e|f|q|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z
<conjunction>::=AND|OR
<relation operation>::=<|>|<=|>=|=|<>
<expression operator>::=+|-|\|:
<term operator>::=*|/|%|&|!|?
<factor>::=+<unary plus>|-<unary plus>|<unary plus>
<unary plus>::=<variable>|<positive number>|#<hex number>|
(<testable expression>)|!<factor>|?<factor>)TOP|COUNT
|RND|ABS<factor>|LEN<factor>|CH<string right>
|PTR<factor>|EXT<factor>|GET<factor>|BGET<factor>|
FIN<string right>|FOUT<string right>|
<array name><factor>
<term>::=<factor>{<term operation><factor>}^
<expression>::=<term>{<expression operator><term>}^
<relnl expression>::=<expression>|<expression><relation operation>
<exression>|$<expression>=<string right>
<testable expression>::=<relnl expression>{<conjunction>
<relnl expression>}^
<delimit quote>::="{any ascii character not a "}
<string right>::=<expression>|$<expression>|"<asciic>^<delimit quote>
<sd>::=<statement delimiter>::={carriage return}|;
<working let>::={{{<variable>|!<factor>|?<factor>|<variable>!<factor>|
<variable>?<factor>}=<expression>}|$<expression>=
<string right>}<sd>
<let statement>::=LET<working let><sd>|<working let><sd>
<vector statement>::=<array name><factor>=<expression>
<printable string>::={'|"<asciic>^<delimit quote>}^
<input section>::=<printable string>{<variable>|$<expression>|{null}}
<input statement>::=INPUT<input section>{,<input section>}^<sd>
<return statement>::=RETURN<sd>
<new command>::=NEW<sd>
<old statement>::=OLD<sd>
<link statement>::=LINK<factor><sd>
<OS statement>::=*<asciic>^
_200_
<plot statement>::=PLOT<factor>,<factor>,<factor><sd>
<draw statement>::=DRAW<factor>,<factor><sd>
<move statement>::=MOVE<factor>,<factor><sd>
<clear statement>::=CLEAR<factor><sd>
<wait statement>::=WAIT<sd>
<go entity>::=<label>|<factor>
<goto statement>:: GOTO<go entity><sd>
<gosub statement>:: GOSUB<go entity><sd>
<end statement>::=END<sd>
<enter assembler statement>::=[
<do statement>::=DO
<until statement>::=UNTIL<testable expression><sd>
<next statement>::=NEXT<sd>|NEXT<variable><sd>
<half for>::=FOR<variable>=<expression>TO<expression>
<for statement>::=<half for><sd>|<half for)<STEP<expression><sd>
<dim section>::=<variable)<factor>|<array name><factor>
<dim statement>::=DIM<dim section>{,<dim section>}^<sd>
<save statement>::=SAVE<string right><sd>
<load command>::=LOAD<string right><sd>
<run statement>::=RUN<sd>
<list command>::=LIST<sd>|LIST<positive number><sd>|
LIST,<positive number><sd>|LIST<positive number>,<sd>|
LIST<positive number>,<positive number><sd>
<if statement>::=IF<testable expression>{THEN<statement>|<statement>}
<print comma>::={nothing, if possible}|,
<print statement>::=PRINT{<printable string>{<expression>|
$<expression>|{nothing}}<print comma>}^<sd>
<enter line command>::=<positive number><asciic>"(carriage return}
<put statement>::=PUT<factor>,<expression><sd>
<bput statement>::=BPUT<factor>,<expression><sd>
<sput statement>::=SPUT<factor>,<string right><sd>
<sget statement>::=SGET<factor>,<expression><sd>
_201_
<ptr statement>::=PTR<factor>=<expression><sd>
<null statement>::=<sd>
26.2 Assambler Syntax Definition
This uses the same syntax as Section 26.1, and refers to some of the
syntactic entities given there. Basic symbols may not be abbreviated;
spaces may be used freely to improve readability.
26.2.1 Basic Symbols
( ) , : @ A X Y \ ] ADC AND ASL BCC BCS BEQ BIT BMI BNE BPL BRK BVC
BVS CLC CLD CLI CLV CMP CPX CPY DEC DEX DEY EOR INC INX INY JMP JSR
LDA LDX LDY LSR NOP ORA PHA PHP PLA PLP ROL ROR RTI RTS SBC SEC SED
SEI STA STX STY TAX TAY TSX TXS TXA TXS TYA
<set label statement>::=<two chars>:<label name><assembler statement>
<comment statement>::=<two chars>\<comment field>
<back to basic>::=]
<empty statement>::=<two chars><sd>
<two chars>::=<asciic>|<asciic><asciic>|{no character at all}
<comment field>::={ascii until <sd>}
<immed>::=@<expression>
<indexX>::=<expression>,X
<indexY>::=<expression>,Y
<group1>::=<indexX>|<indexY>|(<indexX>)|(<expression>),Y|<expression>
<branch>::={BCC|BCS|BEQ|BMI|BNE|BPL|BVC|BVS}<expression>
<memory to A>::=ADC|AND|CMP|EOR|LDA|ORA|SBC{<group1>(<immed>}
<A to memory>::=STA<group1>
<single byte A>::={ASL|LSR|ROL|ROR}A
<single byte>::=<single byte A>|BRK|CLC|CLD|CLI|CLV|DEX|DEY|INX|INY
|NOP|PHA|PHP|PLA|PLP|RTI|RTS|TAX|TAY|TSX|TXA|TXS|TYA
<read modify write>::={ASL|DEC|INC|LSR|ROL|ROR}{<indexX>|<expression>}
<bit>::=BIT<expression>
<cp>::={CPX|CPY}{<immed>(<expression>}
<jmp>::=JMP{<expression>|(<expression>)}
<jsr>::=JSR<expression>
<ldx>::=LDX{<immmed>|<indexY>|<expression>}
202
<HR>
<A NAME="203"></A>
<ldy>::=LDY{<immmed>|<indexX>|<expression>}
<stx>::=STX{<indexY|<expression>}
<sty>::=STY{<indexX>|<expression>}
<assembler statement>::={<branch>|<memory to A>|<A to memory>
|<single byte>|<read modify write>|<bit>|<cp>|<jmp>|<jsr>
|<ldx>|<ldy>|<stx>|<sty>|<comment field>
_203_
_204_
27 Error Codes
The following list of errors includes BASIC errors, COS errors, and
errors generated by the extension ROM. Note that it is possible tc
obtain errors not on this list by executing a BRK in a machine-code
program.
2 Too many GOSUBs
The largest permitted depth of subroutine nesting is 14. This error
means that more than 14 GOSUB statements have been executed without
matching RETURN statements. Example:
10 GOSUB 10
20 END
6 SUM Checksum error
When loading a named file from tape, each block is followed b, a
checksum byte; if the checksum does not agree with this byte, this
error is given. The rause of checksum errors is usually a damaged
tape, or incorrect volume on playback. The remaining blocks of a
damaged tape can be retrieved using FLOAD.
18 Too many DO statements
The largest permitted number of nested DO...UNTIL loops is 11. This
limit has been exceeded.
29 Unknown or missing function
The statement contains a sequence of characters which are not the name
of a function. Example:
10 J=RAN+10 (where RND was intended).
20 FPRINT $A (string variables not permitted in FPRINT)
30 Array too large in DIM statement
The DIM statement checks that there is valid merrory at the last
element of each array in the DIM statement. This error implies that
there is no RAM at the end of the array being dimensioned.
31 RETURN without GOSUB
A HETUHN was found in the main proqram. RETURN is only meaningful in a
subroutine.
39 Attempt to use variable in LIST
The LIST command may only be used with constants as its arguments.
Example:
LIST A,B
_205_
48 COM? Command error
The command following the '*' was not a legal COS command. Example:
*MEM (command does not exist)
69 Illegal FDIM statement
Only the floating-point array variables %AA to %ZZ may be dimensioned
in an FDIM statement. Example:
10 FDIM %A(2)
Attempt to use FDIM in direct mode.
76 Assembler label error
The characters following the ':' character are not a legal label.
Legal labels are two letters followed by a number optionally in
brackets. Example:
10:LOOP JMP LOOP
91 No hexadecimal number after '#'
The characters immediately following the '#' symbol must be legal
hexadecimal characters 0-9 or A-F. Spaces are not permitted. Example:
10 PRINT #J
94 Unknown command, invalid statement terminator; missinq END
The statement has not been recognised as a legal BASIC statement. The
error may also be caused by an illeqal character after a valid
statement, or by an attempt to execute past the end of the program.
Example:
10 LIST (LIST is not allowed in a program)
20 s A=B (no space permitted between label and line number)
An array appears in an INPUT statement; only simple variables are
permitted. Example:
25 INPUT AA(2)
95 Floating-point item missing or malformed
An unexpected character was encountered during the interpretation of a
floating-point statement. Example:
10 FUNTIL O (argument must be a relational expression)
20 FIF A PRINT "OK" (logical variables not allowed)
109 Number too large
Attempt to enter a number which is too large to be represented in
BASIC. Example:
20 J=9999999999 1
Error also occurs if the largest negative number is entered:
30 J=-2147483648
even though this number can be represented internally. To input this
number, use the hexadecimal form #80000000.
111 Missing variable in FOR; too many FOR statements
The control variable in a FOR...NEXT loop must be one of the simple
variables A to Z. Example:
_206_
35 FOR CC(1)=1 TO 10
The maximum permitted number of nested FOR...NEXT loops is 11; this
number has been exceeded.
118 NAME Name error
The filename specified in a LOAD, SAVE, *LOAD, *SAVE, or *FLOAD
command was not a legal COS filename. Example:
SAVE "THIS FILENAME IS TOO LONG"
123 Illegal argument to floating-point function
Examples:
12 A=SQR(-1) (square root of a negative number)
24 B=ASN(2) (arcsine of number outside range -1 to 1)
127 Line number not found in GOTO or GOSUB
The line number specified in a GOTO cr GOSUB was not found. Example:
10 GOTO 6
15 N=6; GOTO N (where there is no line 6)
128 Argument to SIN, COS or TAN too large
The largest angle that may be specified in the SIN, COS or TAN
functions is about 8.3E6.
129 Division by zero, protected RAM in graphics mode
A number was divided by zero. Example:
10 J=J/(A-B) (where A and B were egual)
A CLEAR command specified a graphics mode that would have destroyed
BASIC's text space. Example:
10 ?18=#90 ;REM Move text space
20 CLEAR 4
134 Array subscript out of range
An array element was specified with a neqative subscript, or has not
been dimensioned before use. Example:
10 DIM AA(4)
20 AA(-2)=7
135 SYN? Syntax error
A COS command was recognised, but was followed by illegal parameters.
Example:
*SAVE "FRED" (start and end addresses omitted)
149 Floating-point array subscript out of range
A floating-point array element was specified with a negative
subscript. Example:
10 %AA(-2)=0
152 GOSUB without RETURN; FOR without NEXT
The GOSUB statement, when used in direct mode, must be followed by a
semicolon. Example:
_207_
GOSUB 10
The FOR statement was used in direct mode without a NEXT statement.
156 Assembler error: illeqal type
The argument specified for the operation is illegal. Example:
30 LDA @300 (constant greater than 8 bits)
50 STA (J,Y) (not a legal addressing mode)
70 BIT @23 (immediate addressing not available with BIT)
This error is also generated if a JMP or JSR is assembled with a
zero-page address. This may occur, by chance, on the first pass of a
forward-reference JMP or JSR; in this case the value of the label
should be initialised to P before assembling. Example:
40 JMP #34 (jumps into page zero are not permitted)
157 Label not found
A label, a-z, was specified in a GOTO or GOSUB, but no statement
starting with that label was found. Example:
40 GOTO s
159 Unmatched quotes in PRINT or INPUT
Strings in PRlNT statements, or entered in INPUT statements, should
have an even number of '"' quotation marks. Example:
PRINT "THIS IS A QUOTE:""
165 Loading interrupted
The CTRL key will escape from a load-from-tape operation, with this
error message being produced.
169 Floating-point result too large
The result of a floating-point calculation was larger than about
1.7E38. Example:
20 FPRINT TAN(PI/2)
174 Significant item missing or malformed
An unexpected character was encountered during the interpretation of a
statement. Example:
10 GOTO 2O (O mistyped as zero; should be GOTO)
20 FOR J TO 4 (expected '=' after J)
30 FOR J=l STEP 1 TO 4 (order should be TO ... STEP)
40 LET AA(1)=2 (LET is illegal with arrays)
191 LOG or power of zero or a negative number
The argument to the floating-point function LOG, or the operator
must be greater than zero. Examples:
10 %A=-1^2
30 %B=LOG(0)
198 UNTIL with no DO
An UNTIL statement was encountered without a DO being active. Example:
20 IF A=1 DO A=A+1
30 UNTIL A=3 (if A<>1 the DO is not executed)
_208_
200 Unmatched quotes in string
Strings appearing in a program should have an even number of
quotation marks.
208 Unrecognised mnemonic in assembler
The mnemonic is not a legal 6502 assembler operation. Example:
20 ADD @20 (only ADC instruction available)
30 .BYTE (assembler directives are not available)
216 Illegal DIM statement
The list of variables in the DIM statement contained an illegal entry.
Example:
20 DIM A(2,3) (only one-dimensional arrays allowed)
30 DIM AA(-2) (negative array size)
Attempt to use DIM in direct mode.
230 NEXT without matching FOR
If a control variable is specified in a NEXT statement then the
variable must match the control variable in the corresponding FOR
statement. Example:
50 FOR N=1 TO 10
20 FOR J=1 TO 10
30 PRINT "*"
40 NEXT N
50 NEXT J
A NEXT statement was encountered without any FOR statement being
active.
238 Argument to EXP too large
The calculation of the EXP function gave a result that was too large.
Example:
10 FPRINT EXP(100)
248 Not enough room to insert line
The line just entered has used up all the available memory. More
memory can be released by shortening all the command names if this has
not already been done.
_209_
210