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:
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 1.
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---> <----> ^
sign bit8-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 possible 32-bit integers in the standard integer BASIC can be floated without loss of accuracy.
FDIM | Floating-point dimension |
Allocates space after the end of text for the floating-point arrays %@@ and %AA to %ZZ. Example:
FDIM %JJ(5)
allocates space for elements %JJ(0) to %JJ(5), a total of 30 bytes.
FIF | 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:
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 sequential file whose handle is specified by its argument. Example:
FPUTA,2"32+1
FUNTIL | Floating-point until | FU. |
As UNTIL, except no connectives (OR or AND) are allowed. Matches with DO statement. Example:
D0%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 $TOP1 3.14159265
ABS | Absolute value |
Returns the absolute value of a floating-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:
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 | Float | 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 | C. |
Returns -1, 0, or 1 depending on whether its floating-point argument is negative, zero, or positive respectively.
SIN | Sine |
Returns sine of an angle in radians. Example:
FPRINT SIN PI 0.0
SQR | Square root |
Returns square root of argument. Example:
FPRINT SQR 2 1.41421356
TAN | Tangent | T. |
Returns tangent of angle in radians. Example:
FPRINT TAN PI 0.0
VAL | Value of a string | 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
! | Floating 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 integer | {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>
The floating-point variables %0 and %A to %Z are stored from #2800 onwards, five bytes per variable, thus taking a total of 135 bytes. Thus, for example, a floating-point vector:
%!#2800
may be set up whose elements:
%!(#2800+0), %!(#2800+5), %!(#2800+10)
will correspond to the variables:
%@, %A, %B ... etc.
For example, the floating-point variables may be initialised to zero by executing:
FOR J=0 TO 26*5 STEP 5 %!(#2800+z)=0 NEXT J
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 0 7 PRINT"PLOT OF SIN AND TAN FUNCTIONS" 9 %t=2*PI/64 10 %V=0 12 FOR Z=0 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=0TO359 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
The following program plots a perspective view 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 160 % -%S+%N*%N;%Q=SQR%T 200 FORX=-10TO10 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 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. %O -- Distance of point from eye. %Q,%R,%S,%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
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: la 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: 0 Green Grey 1 Yellow White 2 Blue Black 3 RedBlack
COLOUR 0 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 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.
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 0
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 0 memory, from #0000 to #0400, and 1K of VDU and text-space memory, occupying between #8000 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 follows:
Addresses: Area: #0000-#0400 Block zero RAM #2800-#3C00 Lover text space #8000-#9800 Graphics space/Upper text space
The following staqes in expansion are recommended:
Extra memory can be added starting at #2800 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 #2900 to allow space between #2800 and #2900 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 text area is used it is only possible to use the lower graphics modes. The lower text area permits all graphics modes to be used.
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.
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 #B800 DB Data Register A #B801 DA Data Direction Register B #B802 DDRB Data Direction Register A #B803 DDRA Timer 1 low counter, latch #B804 T1CL Timer 1 high counter #B805 T1CH Timer 1 low latch #B806 T1LL Timer 1 high latch #B807 T1LH Timer 2 low counter, latch #B808 T2CL Timer 2 high counter #B809 T2CH Shift Register #B80A SR Auxiliary Control Register #B80B ACR Peripheral Control Register #B80C PCR Interrupt Flag Register #B80D IFR Interrupt Enable Register #B80E IER Data Register A #B80F DA
On BREAK all registers of the VIA are reset to 0 (except Tl, T2 and SR). This places all peripheral lines in the input state, disables the timers, shift register, etc. and disables interrupts.
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.
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 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 #208) to WRCVEC+3; e.g.:
!#208=!#208+3
The following program illustrates how to write to one of the VIA's output ports from a BASIC program:
10 !#208=!#208+3 20 ?#B80C=0 30 ?#B802=#FF 40 INPUT J 50 ?#B800=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.
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&#FFFF 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.