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:
54
32
10
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:
78
A

    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