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:

        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.

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---> <---->
  ^
sign bit
8-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.

22.1.2 Floating-Point Statements

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

22.1.3 Floating-Point Functions

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

22.1.4 Floating-Point Operators

! 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>

22.1.5 Floating-Point Variables

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

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 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

22.1.7 Three-Dimensional Plotting

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

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:
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.

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 0

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 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:

22.3.1. Lower Text Space

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.

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 #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.

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 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

22.4.3 Writing to a Port

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.

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&#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.

Next chapter