


Electride 2.0
A small interpreter with datatypes, for pic32mx

S. Oliver  2014, 2015

Document version: bld3a





0. Contents, prefaces, acknowledgements

1. Overview

2. Getting started : Hello World

3. Summary of operation

4. Variables, datatypes, arrays

    Integer (INTEGER*4, INTEGER*2,INTEGER*1)
    Floating point (REAL, DOUBLE)
    Character (CHARACTER*1, CHARACTER*x)

5. Operators, intrinsic functions

    +,-,*,/,**
    SIN,COS,TAN,ASIN,ACOS,ATAN,ALOG,EXP,
    SQRT,ABS,RAND,<,<=,=,!=,>=,>,&,|,
    IFIX,FLOAT,SNGL,DBLE,ATOI,ATODB


6. Subroutines and functions

    SUBROUTINE
    FUNCTION

7. Program Control 
 
    CALL
    CONTINUE
    (DIMENSION)
    DO
    DO WHILE - END DO
    END
    GO TO
    IF
    IF THEN - ELSE IF - ELSE - END IF
    RETURN
    STOP

8. Input, Output, Format

    READ
    PRINT
    WRITE

    FORMAT

9. Wired LCD and Port I/O 

    LCD (16x2)
      LCDSTRT
      LCDPRNT
      LCDNWLN

    Port Bit access
      BRxx Bit Read 
      BDxx Bit Down 
      BUxx Bit Up   

    Port Word access ( future )
      WRPx Word Read 
      WWPx Word write 

    Port Access masking ( future )
      QPRx Qualify Port mask for Read  
      QPWx Qualify Port mask for Write 



10. Utilies 

    Analog-digital conversion    
    ADxx 
    ZADACQ

    Vector graphic output ( 4010 / Tera Term )
    TXINIT
    TXMOVE
    TXDRAW
    

11. Bugs, Foibles, Exasperations and cop-outs...

A1. Appendix 1  

    Error messages 
    Setting up
    Configuration 
    Limits

A2. Appendix 2 

    More examples



---------------------------------------------------------------


Prefaces, and acknowledgements

Version 2 update

To sum up, V2 has additions and enhancements.
 

-- IF THEN, ELSE IF, ELSE and DO WHILE commands
-- IF/WHILE logic clause recursion 
-- Character string-type datatypes
-- Input file line structure
-- Tektronix 4010 vector output

Version 1 

Originally this started as something in assembler, to experiment with writing math routines for pic microcontrollers. Along the way it was moved to C; as the initial project ended, the Microchip math libraries were switched in, and the instructions became more and more like a simple language. So the experiment became, to see how viable a small fortran interpreter for pic32mx was, and what level microcontroller would be needed.

Of course, an interpreted language offering double precision could be seen as over-done. And yet, there is a need for small amounts of precise calculation, a wish for grass-roots development, and concern that education is bypassing quantitive skills...So I hope it is useful.  It is not meant to be a finished work, but is at a reasonable stagepoint at least. 

I have cherry-picked quite a few good ideas, and certainly do not claim to be the originator
of them. The problem is, in an extensive and ill-defined industry, knowing where the ideas came from or where I saw them. Many articles (SC, EPE, Circuit Cellar) with dozens of authors, on using Microchip pics starting with the 16F84...The Microchip documentation...The C language and K&R of course...and the excellent books by Lucio di Jasio. Electride itself is written in C using the Microchip MPLABX and GNU software, with helpful assistance from Microchip support. The core algorithm used is of course van Djykstra's famous shunting-yard method, explained on Chris Jones website.

And from IT history, the visionary MONEC system in the mid seventies...running Fortran and Basic jobs for hundreds of students. I recently found out, it ran on a PDP11 with 32k memory. Amazing. 

Iconic examples are included as a traditional salute. This document is provisional at this stage, however the examples and outputs are cut-and-paste from actual sessions using the distributed build (with a few slightly abbreviated). A better write-up will have wait for eyesight and other issues.


Bibliography

Programming 16 bit microcontrollers in C (2007)
Di Jasio, L.

Programming 32 bit microcontrollers in C (2008)
Di Jasio, L.

The C Programming Language, (1978, 1988) second edition (ANSI). 
Kernighan, BW and Ritchie, DM.

and from time
An Introduction to Computer Programming in Fortran (Monecs Fortran) (1976)
Bellamy, CJ (dec) and Whitehouse, LG.

---------------------------------------------------------------

1. Overview

Overview

Electride is an embedded interpreter, that runs on PIC32MX chips.

It will load, run and store small programs very similar to Basic, written in a minor subset of Fortran 77.
The programs can easily use high level math and access the chip hardware, for example, to run A/D measurements and display results. Integer (32, 16 and 8 bit), single and double precision (32 and 64) floating point, and character based datatypes can be used as required. 

It can be connected to a serial terminal or run standalone. Typically a PC with something like Tera Term and a serial-usb pathway can be used, and/or hardware with a LCD display, button switches and so on. The Tektronix 4010 emulator in Tera Term can be used for simple vector graphics.

At startup a simple menu allows interaction with the user. If a program is already present and there is no serial connection during startup, the stored program will be run automatically.


The trial version is intended for entry-level use and has constraints. It runs on a PIC32MX170B 28-pin sdip ic. Other versions scale over the pic 32MX range. The appendix has more details.

---------------------------------------------------------------

2. Getting started : Hello World

To start, it is usual to load and run an (iconic) "helloworld" program.

Initially connect the board, switch it on, and run the PC terminal software.

Hitting <enter> on the keyboard will show the banner and simple menu list, something like :


    ELECTRIDE 2.0   S. Oliver 2014, 2015
    with content Microchip and GNU
    Trial PIC32MX170B version 1.9X


    (G) Get
    (S) Save
    (R) Run
    (L) List

>


To load a program it is sent from the PC to the board, after firstly setting the 
board to expect it. Hitting G (capital-G) does that, you will see a "Waiting.." prompt
as the board then waits for the program to be sent.

>G
Waiting..

Use the windows menu to send the program. It is the "Send File..." (not Transfer) item in Tera Term.
A file picker will let you navigate to and select the helloworld file.

"OK" is then displayed as feedback that the sending is complete.

>G
Waiting..
OK


The menu list then returns. It is a good idea to select S and save the program.
A "save.." confirmation will be displayed and the menu list returns.

>S
save..

Now select R to run the program.  The program is displayed first, followed by its output as it runs. After it finishes the pic32mx is reset and memory refreshed, and the menu and prompt return.

>R

      PROGRAM helloworld
C
      PRINT *, "Hello, world"
      END
\

Hello, world

rrefresh..


The first "r" is displayed as the reset starts, and the "refresh" displayed as the user program is reloaded from the saved content. 


As an exercise you can alter the output text string. Open the file with a text editor, add your initials inside the quotes, and save. After reloading you shoukd see your new message.


At the start the examples tend to use the PRINT command for output. This simply prints strings and variables in their default format. More specific formatting is detailed in a later section.





---------------------------------------------------------------

3. Summary of operation


As a first stage, the interpreter runs through the program in an initial pass. This does some simple input checking and sets up some structure, eg the subprogram entry points. The following main pass then steps through the program processing each line in depth.

Lines that are commands or program control statements have specific parsing and are described in the specific sections. In general commands are not recursive.

Lines with a leading assignment( "=" ) are assumed to be equations. These are processed as usual by evaluating the right hand side and assigning the result to the variable on the left hand side.
 
When processing the equation, the operands that are hard-coded digits, or ascii in single quotes, are pre-emptively converted to internal form using the most likely datatype. For a group of digits,
if no decimal point is present, the group is provisionally converted to a 32-bit signed integer. If a decimal point is present, double precision floating point is used instead. If the input group further contains the characters "e" or "d" it is assumed to be exponential format. For quote-contained ascii characters, a group is assumed to be concatenated characters as in a string, and a single character treated as a single byte character.

The tokens are then arranged into sequence and processed further.

The left hand side of the equation is then used to provide a datatype and memory location. The result is converted as necessary and the value stored at the memory location.

Eg 

      PROGRAM integer4
C
      INTEGER*4 i
      i = 1222333444
      PRINT *, i
      END
\

1222333444


When the end of the program is reached the focus returns to the console and prompt as described before.


The Input file

The program file itself is ordinary text, using a subset of ascii characters.

Keywords and commands in statements are in uppercase, with lowercase used for variables.

Lines are in the fortran layout. The first part of a line is set-column, so the first six column positions are reserved for specific use.

The first is reserved for a comment flag (C), which
allows the rest of the line to be used for comment text.
The second and sixth columns are reserved. 
The third, fourth, and fifth positions on a line can be used for
an optional identifying statement number (numerical label). 
The line content then usually starts at the seventh column. 

Tabs, control characters etc should not be used.

The main program optionally starts with a PROGRAM statement, 
and finishes with an END statement. Any subroutine and function 
definitions then follow, each starting with the
name declaration and finishing with an END statement. 

A backslash (\) is used to signal the end of the file. 
It is suggested that a file extension ".f7" be used to differentiate the file from other text files.

The examples used are included as files and are a good starting point. 

---------------------------------------------------------------

4. Variables, datatypes, arrays


   Integer (INTEGER*4, INTEGER*2,INTEGER*1)
   Floating point (REAL, DOUBLE)
   Character (CHARACTER*1, CHARACTER*x)

Variables must be declared before they can be used. The declaration specifies which datatype to use, followed by the variable name(s). A variable name is comprised of lowercase ascii characters, 
with the first six characters used as the unique identifier.  Variables are not automatic or implied, and are rejected if non-unique.

Local variables and arrays can be defined in each subprogram. 
Note that the name of a variable has to be 
interpreted every time it is used, so short names are more efficient. 

The datatype associated with a variable determines how that variable's data is 
processed and held in memory. The datatypes provided allow the use of integer, floating point, and character variables. A character datatype may consist of a single byte or alternatively sets a string length. 
 

Integer data is processed using the intrinsic 32-bit word size and integer arithmetic, and uses memory according to the specified byte count, eg an INTEGER*4 uses 4 bytes of memory. 


      PROGRAM integer4
C
      INTEGER*4 i
      i = 1222333444
      PRINT *, i
      END
\

1222333444

To conserve memory INTEGER*1 and INTEGER*2 can be used, which require 1 and 2 bytes respectively and hold smaller values. INTEGER*8 may be added in future.


Floating point
Floating point data is processed using either one word (datatype REAL: single precision) or two words (datatype DOUBLE: double precision). REAL provides precision of six significant figures and is held in 4 bytes of memory, DOUBLE gives twelve significant figures and uses 8 bytes.



      PROGRAM real
C
      REAL a
      a = 1.123456
      PRINT *, "a = ", a
      END
\

a = 1.123456


      PROGRAM double
C
      DOUBLE a
      a = 1.12345678
      PRINT *, "a = ", a
      END
\

a = 1.12345678

Exponential input format can also be used eg


      PROGRAM doubleexp
C
      DOUBLE a
      a = 1.12d3
      PRINT *, "a = ", a
      END
\

a = 1120.00000000


Character

If the datatype specifies one byte,
the data is processed and stored as ascii in a single byte.
If the datatype specifies more than one byte, multiple bytes are used in a contiguous sequence including an additional null byte bookend.

      PROGRAM charact
C
      CHARACTER*1 a
      a = 'G'
      PRINT *, "a is ", a
      END
\

a is G


      PROGRAM charactmult
C
      CHARACTER*16 txtstr(3)
      txtstr(1) = 'Hello, world! '
      txtstr(2) = 'live long '
      txtstr(3) = 'and prosper'
      PRINT *, txtstr(1), txtstr(2), txtstr(3)
      END
\

Hello, world! live long and prosper


The datatype also determines the default reporting format. Integers are reported with as many digits as required. Six (rounded) decimal places are presented by default for REALs, and eight for DOUBLEs.

This can be an inconvenient reminder of the precision limits eg

      PROGRAM realish
C
      REAL a
      a = 1000.20
      PRINT *, "a = ", a
      END
\

a = 1000.200012


Specific formatting can be used for reporting with suitable definition, for example,  a temperature reading may have resolution of 0.1 at best.

>L
      PROGRAM temperaturereal
C
      REAL celsius, fahr, step
      INTEGER*4 i
      FORMAT (2F6.1,/)
      step = 20.0
      fahr = 0.0
      DO 10 i = 1, 11
        fahr = fahr  + step
        celsius = 5.0 * ( fahr - 32.0 ) / 9.0
        WRITE (6,0) fahr, celsius
   10 CONTINUE
      END
\

  20.0  -6.7
  40.0   4.4
  60.0  15.6
  80.0  26.7
 100.0  37.8
 120.0  48.9
 140.0  60.0
 160.0  71.1
 180.0  82.2
 200.0  93.3
 220.0 104.4


For clarity the examples will often use the default reporting until specific formatting is covered later.


 

Arrays

Arrays are declared much the same way as single variables, with the declation also
specifying the dimension extents.  The total number of elements possible is set by 
the available memory. There is a maximum of three dimensions.

An array element is identified by an index of either an integer value or 
by a simple variable that has a valid integer value. Index numbering starts at 1.
Variables used as an index must be datatype integer*4.  
Index values outside the declared extent are trapped as errors at runtime.
Memory is reserved by each declaration line in four-byte chunks, so an array declaration 
is more efficient than multiple lines of variables.

      PROGRAM birdlife
C
      INTEGER*4 birds(3)
      birds(1) = 123456
      birds(2) = 314153
      birds(3) = 987654
      PRINT *, "There are ", birds(1), " buzzards"
      PRINT *, "There are ", birds(2), " eagles"
      PRINT *, "There are ", birds(3), " turkeys"
      END
\

There are 123456 buzzards
There are 314153 eagles
There are 987654 turkeys


Note that the array is used as one token , ie without spaces.


Using variables

Care should be taken to avoid incorrect techniques.  An example is when a large value is used as a baseline, and a much smaller value is added. The summation may not have the available range to utilise many significant figures of the smaller number. A similar example is subtracting two almost identical numbers. The result will have lost most of the significant digits, even if integers are being used to replace floating-point. 
  
In standard 32 bit IT systems, single-precision floating point values are accurate to about one part in 16 million - ie a little under seven significant figures for the positive values. In many cases this is not enough or is at least inconvenient. As an illustration it is interesting to try adding the fraction one ten-thousandth, 10000 times, to a starting point of 2500.0, on your favorite single-precision system...the returned answer will almost certainly be 2500.0, not 2501.0 as expected.

Double precision can help in some situations. It is accurate to twelve significant figures, and takes a little extra time to process. Here is "realish" upgraded :


      PROGRAM doubleish
C
      DOUBLE a
      a = 1000.20000000
      PRINT *, "a = ", a
      END
\

a = 1000.20000000


The following program simulates (not very well) float-charging a battery for three hours. The cell already has 10 amp-hours stored, and there is a milliamp charging. The summation fails with single precision but can be rescued with DOUBLE ( as a quick fix before a rethink.. ).


      PROGRAM battery
      INTEGER*4 sec
      DOUBLE start, stored, current, gain
C Initial state in amp-seconds
      start = 36000.0
      stored = start
C Three hours adding at one milliamp
      current = 0.001
      DO 10 sec = 1, 10800
      stored = stored + current
   10 CONTINUE
      gain = stored - start
      FORMAT (A,F5.3,/)
      WRITE (6,0) "amp-seconds gained : ", gain
      END
\

amp-seconds gained : 10.800


Often, as in this case, a need for double precision can be avoided by a suitable change in methodology, but sometimes it is vital.

* Do not over charge lithium cells !!


---------------------------------------------------------------

5. Operators, operands and intrinsic functions

The standard operators (+, -, *, / and **)  are used as normal. 
A "negate" ( - ) operator is included. Double precision math is used by default. The comparison operators ( <, <=, =, !=, >=, > amd & or | ) used for logic are covered in the flow section. 


Operands can be simple numbers, variable identifiers, array identifiers (with subscripts of either simple integers or integer variable identifiers), or the resultants of other operations in the normal math precedance. If required, brackets can be used to enforce evaluation sequence. Concatenated exponentiation should be made unambiguous with brackets.
Inadverdently mixing integer and floating point arithmetic is trapped as an error, unless the datatype is deliberately overridden.

In general the intrinsic functions SIN, COS, TAN, ASIN, ACOS, ATAN, SQRT, ABS, RAND, IFIX, FLOAT, DBLE, SNGL, ALOG, and EXP are used as normal, with the proviso that uppercase is used. They can be used as operators, ie, brackets are optional.
Complex formulae should be broken down into sections to fit.

Math functions and output

SIN 	Sin of input value (radians)
COS 	Cos of input value (radians)
TAN 	Tan of input value (radians)

ASIN	Arcsin in radians of input value (double)
ACOS	Arccos in radians of input value (double)
ATAN	Arctan in radians of input value (double)

SQRT	Square root of input value
ABS	Absolute value
RAND	Random integer, 0 - 65565. 

ALOG	Natural logarithm
EXP	e to the power x.

IFIX	Integer value of floatinpg point input
FLOAT	Floating point (single precision) equivalent of integer
DBLE	Double precision equivalent of input
SNGL	Single precision equivalent of double

ATOI    Converts character string to integer
ATODB   Converts character string to double precision float




The RAND function requires a dummy integer*4 argument. 

Intrinsic functions are also used for reading a digitized analog value via the A-D converter (ADxx) and reading input pin states (BRxx). They return integer*2 values and are covered in a later section.


Simple math expressions showing precedence

      PROGRAM mathexp
C
      INTEGER*4 a, b, c
      REAL x, y, z
      FORMAT (A,F4.2,A,/)
      a = 1
      WRITE "a = ", a
      b = 1 + 2
      WRITE "b = ", b
      c = b + b
      PRINT *, "c = ", c
      a = 1 * 2 + 3
      PRINT *, "a = ", a
      a = 1 + 2 * 3
      PRINT *, "a = ", a
      a = 1 + b * 3
      PRINT *, "a = ", a
      a = ( 1 + b ) * 3
      PRINT *, "a = ", a
      x = 0.500
      y = SIN ( x ) + COS ( x )
      PRINT *, "y = ", y
      z = FLOAT ( ADC5 )
      z = ( z * 3.260 ) / 1024.0
      PRINT *, "z = ", z , " volts"
      WRITE (6,0) "z = ", z , " volts"
      END
\

a = 1
b = 3
c = 6
a = 5
a = 7
a = 10
a = 12
y = 1.357008
z = 0.935977 volts
z = 0.94 volts

---------------------------------------------------------------

6. Subroutines and functions

User subroutines and functions can be defined and used as necessary. The definitions are placed after the main program. The interpreter sees the definitions in a pre-pass.

The definitions start with the SUBROUTINE or FUNCTION statement,
and finish with an END statement. A RETURN statement must be present. 
Functions must cite the required datatype. 

SUBROUTINE

A subroutine is instigated by a CALL statement in the main program.
In general variables are declared as normal and are local to the subroutine 
invocation.  Control returns to the calling program with the RETURN statement. 


      PROGRAM startup
C
      INTEGER*1 j
      j = 9
      PRINT *, "OK to start"
      CALL righto ( )
      PRINT *, "j = " , j
      END
C
      SUBROUTINE righto ( )
      INTEGER*1 j
      j = 42
      PRINT *, "Righto"
      PRINT *, "sub j = " , j
      RETURN
      END
\

OK to start
Righto
sub j = 42
j = 9

The subroutine definition can also include formal arguments, that is, parameters 
that are the variables used to pass data. Calls to invoke the subroutine must then also
include the matching actual arguments, to a maximum of eight. 

Parameters that are variable identifiers are passed as call-by-reference, that is, 
the memory locations used by the actual variables in the call are then 
also used by the correlating formal arguments set in the subroutine definition. When the subroutine finishes the actual variables retain the values. This uses memory efficiently.


      PROGRAM subaddten
C
      PRINT *, "Start"
      INTEGER*2 x
      x = 7
      PRINT *, "x = ", x
      CALL addten ( x )
      PRINT *, "x now = ", x
      END
C
      SUBROUTINE addten ( a )
      PRINT *, "start subroutine"
      a = a + 10
      PRINT *, "end subroutine"
      RETURN
      END
\

Start
x = 7
start subroutine
end subroutine
x now = 17


Note that technically it is a programming error for a call to a subroutine to cite a numerical value instead of a variable.

When an array is passed as a parameter, Electride will use the attributes of the array in the subroutine and so re-specifying the array dimensions is not necessary. However the array can be redeclared in the subroutine as a safeguard, in keeping with common practice. 

Within a subroutine, dimension extents can be dynamically specified at call time using simple integer variables from the argument list. This is useful as the subroutine can then be used again in other programs without having to edit it each time.

Subroutines can be nested four deep and called recursively. They must not have the same name as an array.

FUNCTION

Functions are a specialised form of subroutine and defined much the same way, with
the addition of specifying the datatype.
When executed, the function has the use of a variable of the same name and datatype, 
with the contents being returned to the calling statement.

Note that functions have been implemented with some concessions. 
Functions are evaluated left-to-right before the rest of the calling statement 
is processed, and a total of four can be called in one statement. 
Also, arguments for subroutines must be separated by spaces, but arguments 
in function calls are separated with commas only. 

Note that technically it is a common programming error for a function call to cite a numerical value instead of a variable. As a safeguard
in Electride the value will be passed as call-by-value. That is, the value will be passed to the function as the value of the corresponding formal variable, and the data discarded when the function finishes. 
 
Here the subroutine above is implemented as a function.


      PROGRAM funcaddten
C
      WRITE "Start"
      INTEGER*2 x, y
      x = 7
      y = 0
      PRINT *, "x = ", x, " y = ", y
      y = addten(x)
      PRINT *, "x = ", x, " y = ", y
      END
C
      INTEGER*2 FUNCTION addten ( a )
      PRINT *, "start function"
      addten = a + 10
      PRINT *, "end function"
      RETURN
      END
\

Start
x = 7 y = 0
start function
end function
x = 7 y = 17

---------------------------------------------------------------

7. Program Control

    CALL
    CONTINUE
    (DIMENSION)
    DO
    DO WHILE - END DO
    END
    GO TO
    IF
    IF THEN - ELSE IF - ELSE - END IF
    RETURN
    STOP


CALL

Calls a subroutine. 
This is covered in the subroutine section.

CONTINUE

Continues program processing. 

(DIMENSION)

Array datatype and dimensions are automatically carried through to subroutines and functions so a DIMENSION statement is not required.
Furthermore redimensioning arrays in memory is not in the project scope. So, for source compatability, programs can include a DIMENSION statement, but it is not active. 

DO

A DO statement initiates a repeated loop. The standard form has parameters detailing the loop iteration, and the alternative DO WHILE form repeats while a logical test evaluates to  true.
 
The standard DO statement specifies the loop end statement, the variable to use as a counter,  the start count, the end point count,
and optionally the increment value. The loop end statement is identified by a 
numerical label and must be within the program or subroutine. The count parameters 
can be numbers or integer variables (four byte), and the increment value 
defaults to 1 if not set.


      PROGRAM doloop
C
      INTEGER*4 count, start, finish
      PRINT *, "do loop"
      start = 4
      finish = 8
      DO 10 count = start, finish
      PRINT *, "count = ", count
   10 CONTINUE
      END
\

do loop
count = 4
count = 5
count = 6
count = 7
count = 8

 
Loops can be nested in multiple levels, with a limit set by the software version.
The same loop terminal statement can be used by multiple standard-form loop levels.  The loop end must not be a branching statement or a do-while end and it is strongly recommended that a CONTINUE is used as a convention.


      PROGRAM doloops
C
      INTEGER*4 i, j, k
      PRINT *, "Yo!  Loops! "
      DO 10 i = 1, 2
      DO 10 j = 1, 2
      DO 10 k = 1, 2
      PRINT *, "Like..  i=", i," j=", j," k=", k
   10 CONTINUE
      END
\

Yo!  Loops!
Like..  i=1 j=1 k=1
Like..  i=1 j=1 k=2
Like..  i=1 j=2 k=1
Like..  i=1 j=2 k=2
Like..  i=2 j=1 k=1
Like..  i=2 j=1 k=2
Like..  i=2 j=2 k=1
Like..  i=2 j=2 k=2


DO WHILE - END DO

A DO WHILE loop is similar to the standard DO form, however the statement includes a logical test. If the test returns true the loop is instigated, and then is repeated while the test remains true.
The loop range is to the associated END DO statement. 

>L
      PROGRAM dowhile
C
      INTEGER*4 count
      PRINT *, "Start.."
      count = 1
      DO WHILE ( count < 4 )
        PRINT *, "count ", count
        count = count + 1
      END DO
      PRINT *, "Finito"
      END
\

Start..
count 1
count 2
count 3
Finito

DO-WHILE loops can be nested in multiple levels, with a limit set by the software version. Each DO-WHILE loop must have a separate END-DO terminal statement.

To prevent ambiguity, END DO statements may not have numerical labels and so cannot be used to terminate standard-form loops.


END

Marks the end of the main program section or following subroutine or function.

GO TO

A GO TO command unconditionally transfers program flow to the destination statement, which must have a numerical label id. The destination must be within the local program / subroutine / function.

Note that, the original standard requires that a GO TO statement within a loop can transfer to a statement that is apparently outside the loop, (past the loop end point) and then jump back again with the loop state still remaining active.  So, existing loop ranges and states, tests etc remain in place even if a GO TO apparently exits the loop. It is strongly recommended that GO TOs be avoided if possible, or at least destinations kept very local and within any loop.


IF
IF THEN - ELSE IF

IF statements allow conditional branches and processing. 
An embedded logical test clause is evaluated and determines further action. For evaluation, the test is passed to the equation processor  and the values '0' used for false and '1' for true.

There are two forms, as the original IF single-line statement was extended to add a multiline IF .. THEN ... END IF form.

The single-line type has a IF keyword with a test (condition) before the rest of the line. If the test evaluates to true, the rest of the line is processed. 
The rest of the line is usually a simple assignment, a call to a subroutine 
or a return, a command to set a port pin state, or a GO TO. 

The tests are for conditions of 

	equal-to 			( = ),
	not-equal-to 			( != ),
	less-than 			( < ), 
	less-than-or-equal-to 		( <= ),
	greater-than 			( > ), 
	greater-than-or-equal-to 	( >= ). 




      PROGRAM liftoff
C
      INTEGER*4 altitude, stage
      PRINT *, "Ignition..."
      PRINT *, "Lift off !"
      stage = 1
      DO 10 altitude = 0, 100, 10
      IF ( altitude > 10 ) stage = 2
      IF ( altitude > 70 ) stage = 3
      PRINT *, "Stage ", stage, " and altitude ", altitude
   10 CONTINUE
      END
\

Ignition...
Lift off !
Stage 1 and altitude 0
Stage 1 and altitude 10
Stage 2 and altitude 20
Stage 2 and altitude 30
Stage 2 and altitude 40
Stage 2 and altitude 50
Stage 2 and altitude 60
Stage 2 and altitude 70
Stage 3 and altitude 80
Stage 3 and altitude 90
Stage 3 and altitude 100


Originally (V1) the statement had a preset layout, with one test and simple operands. In V2 the clause is evaluated to a result with 0 signifying false and not-zero signifying true. The evaluation can recurse and can include logical operators :

	and 	( & ) 
	or 	( | ).


      PROGRAM ifeqand
C
      INTEGER*4 i, j
      PRINT *, "start.."
      i = 5
      j = 28
      PRINT *, "j = ", j
      IF ( i = 5 & j = 28 ) PRINT *, "Ok"
      IF ( i = 5 & j != 28 ) PRINT *, "Bad"
      j = 24
      PRINT *, "j = ", j
      IF ( i = 5 & j = 28 ) PRINT *, "Ok"
      IF ( i = 5 & j != 28 ) PRINT *, "Bad"
      PRINT *, "FINISH "
      END
C
\

start..
j = 28
Ok
j = 24
Bad
FINISH


IF THEN - ELSE IF - ELSE - END IF

The multiline form has an initial IF ,, THEN statement and an associated END IF.
The IF.. THEN command includes the test, and conditionally runs through the following lines until the END IF statement is reached.

>L
      PROGRAM ifthen
C
      INTEGER*4 count
      PRINT *, "Start.."
      DO 10 count = 1, 2
      IF ( count = 1 ) THEN
        PRINT *, "Itsa one.."
      END IF
   10 CONTINUE
      PRINT *, "Finito"
      END
\

Start..
Itsa one..
Finito


Specific alternative conditions can optionally be included 
using ELSE IF's.  

>L
      PROGRAM ifthenelseif
C
      INTEGER*4 count
      PRINT *, "Start.."
      DO 10 count = 1, 3
      IF ( count = 1 ) THEN
        PRINT *, "Itsa one.."
      ELSE IF ( count = 2 ) THEN
        PRINT *, "Itsa two.."
      ELSE IF ( count = 3 ) THEN
        PRINT *, "Itsa three.."
      END IF
   10 CONTINUE
      PRINT *, "Finito"
      END
\

Start..
Itsa one..
Itsa two..
Itsa three..
Finito

An ELSE provides a generic alternative.

>L
      PROGRAM ifthenelse
C
      INTEGER*4 count
      PRINT *, "Start.."
      DO 10 count = 1, 2
      IF ( count = 1 ) THEN
        PRINT *, "Itsa one.."
      ELSE
        PRINT *, "whaat.."
      END IF
   10 CONTINUE
      PRINT *, "Finito"
      END
\

Start..
Itsa one..
whaat..
Finito

The full combo :

>L
      PROGRAM ifthenelseifelse
C
      INTEGER*4 count
      PRINT *, "Start.."
      DO 10 count = 1, 4
      IF ( count = 1 ) THEN
        PRINT *, "Itsa one.."
      ELSE IF ( count = 2 ) THEN
        PRINT *, "Itsa two.."
      ELSE IF ( count = 3 ) THEN
        PRINT *, "Itsa three.."
      ELSE
        PRINT *, "whaat.."
      END IF
   10 CONTINUE
      PRINT *, "Finito"
      END
\

Start..
Itsa one..
Itsa two..
Itsa three..
whaat..
Finito


RETURN

Returns from a subroutine.
This is covered in the subroutine section.

STOP

A historical command which prints STOP on the console and stops execution. The main use was for program development. Here this returns to the reset and menu sequence. 




---------------------------------------------------------------

8. Input, Output, Format

READ (input) and WRITE/PRINT (output) commands are used as a generic mechanism. A subset of Fortran is used as a template. Lower level access that uses bit setting and specific peripheral modules, and the defined commands used are covered in the next section.
  
At a entry level, the READ and WRITE commands use defaults for details and data formatting. For more specific control, optional information is used to set the required parameters.

The basic commands using the defaults are described first. The I/O is assumed to use the chip uart, connected to a serial terminal (console).


READ

A READ command reads input and ends on a carriage return. Commas can be used to separate multiple items. The text input is then converted to values, using the datatype of the variables specified. If a negative sign is required it must be the first character in each field. 

eg

      PROGRAM readmult
C
      REAL a, b
      INTEGER*2 c
      PRINT *, "Input for a, b, c ?"
      READ a, b, c
      PRINT *, a, " ", b, " ", c
      END
\

Input for a, b, c ?
3.141,2.345,66
3.141000 2.345000 66



PRINT *,
WRITE ...

A PRINT or WRITE command sends the values of variables to output. The datatype of each variable determines the format used. Quoted text strings can be included. 

The shorter versions can be used for convenience,

      PRINT "a = ", a ; 
      WRITE "a = ", a ;

and asterisks can be included to formally signify default values
 
      PRINT *, "a = ", a
      WRITE (*,*) "a = ", a  




FORMAT

FORMAT sets the descriptors used for specific formatting.

Formatted I/O requires a format descriptor to use for each variable. The format descriptors are stored as a sequential list using a FORMAT statement. When the WRITE command is processed, each variable is examined and output in turn, using the next format descriptor in the list. If the format list finishes, it is re-used as necessary.

The WRITE command then includes two extra parameters to identify in turn the hardware or file type (eg, a user terminal or disk), and the format list, before the variables to use. 

The first WRITE parameter, the number identifying the file/hardware type, can be set as '6' (user terminal) or left as '*' at this stage. 

The second WRITE parameter specifies which format list to use.
In larger systems multiple formats can be active, so an integer is cited which identifies which format statement to use. In this version the requirements are simpler, so a zero ( '0' ) is cited instead, which determines that the most recent format statement is used. 
 

Format descriptors are short strings citing I (integer), F (floating point), E (exponential) and A (alphanumeric). The letter is followed by numbers for the number of digits and decimal places. 

Eg

	I6	Integer field of six digits.
	F6.2	Real number with six digits and two decimal places.
        E20.4   Real number with four decimal places and exponent.
	A1	One ASCII character.
	A	Cited text string.
 

A number before the descriptor will repeat it. Other characters in a format descriptor are passed to the underlying C format command. If necessary the descriptors can be separated by simple actions to some extent, eg, an X will insert a space, and a forward slash (/) specifies an end-of-record which will output a carriage return/newline and rewind the list. The numeric output fields are right-justified with blanked leading zeros, text output fields ( A* format) are left justified and padded with spaces.

Cited text strings (to 32 characters) can be included in the variable list and must have a matching single A format.


The example has a few outputs.

      PROGRAM specformat
C
      INTEGER*4 a
      REAL b
      DOUBLE c
      CHARACTER*1 d, e, f, g
      CHARACTER*7 h
      a = 1222333444
      b = 3.12345678
      c = 45.12345678
      d = 'T'
      e = 'H'
      f = 'E'
      g = ' '
      h = 'Yo!'
      WRITE "start"
C
      WRITE h
C
      FORMAT (I10,/)
      WRITE (6,0) a
C
      a = 1234
      WRITE (6,0) a
      WRITE (6,0) a, a, a
C
      FORMAT (3I10,/)
      WRITE (6,0) a, a, a
C
      FORMAT (F8.6,/)
      WRITE (6,0) b
      FORMAT (F8.2,/)
      WRITE (6,0) b
      FORMAT (F10.8,/)
      WRITE (6,0) c
      FORMAT (A,F5.3,A,/)
      WRITE (6,0) "The value of c is ", c, " degrees. "
C
      FORMAT (E10.8,/)
      WRITE (6,0) c
      FORMAT (E20.4,/)
      WRITE (6,0) c
C
      FORMAT (A7,A7)
      WRITE (6,0) h, h
C
      FORMAT (A1)
      WRITE (6,0) d, e, f, g
      WRITE "finish"
      END
\

start
Yo!
1222333444
      1234
      1234
      1234
      1234
      1234      1234      1234
3.123457
    3.12
45.12345678
The value of c is 45.123 degrees.
4.51234568e+01
          4.5123e+01
Yo!    Yo!    THE finish


Repetition using an implied loop

A WRITE statement can acess array elements using an implied loop. This is useful with repeat descriptors.

Eg 

      FORMAT (64A1,/) ;
      WRITE (6,0) ( page(x,y), x = 1, 64 ) ;


Here the A1 descriptor is used 64 times before the next line, as the index variable x increments from 1 through 64. So, this will print 64 characters from the array and then start the next line.

Note that with an implied loop the list must be enclosed in brackets.  Currently there is a limit of one implied loop per write statement. It must follow non-loop variables.


For some 'retro' eighties lineprinter artwork, the example subroutine presents an offbeat pre-filled array row by row. 

...
...
C
      SUBROUTINE plott ( page )
      INTEGER*4 x, y
      FORMAT (64A1,/)
      DO 40 y = 1, 21
      WRITE (6,0) ( page(x,y), x = 1, 64 )
   40 CONTINUE
      RETURN
      END
\

start
!--------------------------------------------------------------!
!             ****                                             !
!          ***    ***                                          !
!        **          **                                        !
!      **              **                                      !
!     *                  *                                     !
!    *                    **                                   !
!  **                       *                                  !
! *                          *                                 !
!*                            *                                !
!--------------------------------------------------------------!
!                               **                            *!
!                                 *                         ** !
!                                  *                       *   !
!                                   *                     *    !
!                                    **                 **     !
!                                      *               *       !
!                                       **           **        !
!                                         ****    ***          !
!                                             ****             !
!--------------------------------------------------------------!
finish




---------------------------------------------------------------

9. Wired LCD and Port I/O 

LCD panel and Low level port access, and optionally keypad I/O 
is provided. Higher level access to peripherals, files etc will also use the READ/WRITE I/O already discussed. The crystal and SPI pins are provisionally reserved.

LCD

LCD output is set up for the standard Hitachi-compatible 16x2 LCD modules.


LCDSTRT
LCDPRNT

To use the module, firstly it is srarted and initialized with the LCDSTRT command, then command LCDPRNT will write to the display. The LCDPRNT is very similar to the PRINT or WRITE using default formats and is used the same way. 

      PROGRAM lcdhello
C
      LCDSTRT 
      LCDPRNT "Hello, world    "
      END
\

LCDNWLN
At the finish of the command the display cursor returns to the start of the first display line. To move to the next line, the command LCDNWLN is used, and the following LCDPRNT then writes to the next line.

      PROGRAM lcdhello2line
C
      LCDSTRT
      LCDPRNT "Hello, world    "
      LCDNWLN
      LCDPRNT "Yeah, baby !!   "
      END
\


It can be a good idea to pad with extra space characters, to ensure a refresh of the full line. The modules are fairly slow to visibly refresh so a delay is advisable.

As there is limited space, floating point numbers are displayed with a conservative format with two decimal places (REAL) and three decimal places (DOUBLE) respectively.

Port bit access.

Port pins (bits) are read or set with the Bxxx command keywords. 

To set a port pin state on or off the relevent bit is set up or down :

BDXY	Bit Down on port X pin Y
BUXY	Bit Up on port X pin Y

eg
 	BDB5 set port B bit 5 low.
and	BUB5 will set it high.


so to blip a pin

      PROGRAM pinblipd
C
   10 CONTINUE 
      BUB5 
      BDB5 
      GO TO 10 
      END 
\



Similarly a port pin state is read using R instead. The command acts as a function returning an integer value.

eg	
	n = BRB5 

will read port B pin 5 and return 1 or 0 as appropriate.


      PROGRAM pinled
C
      DO WHILE ( 1 = 1 )
        IF ( BRB8 = 1 ) BUB5 
        IF ( BRB8 = 0 ) BDB5 
      END DO 
      END 
\



In the '170 version the sixteen port B pins are accessable. The port 'B' identifier is automatically set so the B is ignored and a generic X can be used instead.


To read a 4x4 keypad, it is envisaged that a written function scans and reads port B lines and returns the key value.

---------------------------------------------------------------

10. Utilies

ADC

The chip 10-bit A-D converter can be used to take analog-digital readings. In this version it runs contiuously in the background, and measures the potential on pin 6 (AN4, RB2) and 7 (AN5, RB3) in alternation. 

The results are available as standard two-byte integers in the range 0 - 1023. Results can be accessed as single values or as a fast burst.

The ADc has a range of 1024 points so for a 3.2 volt ceiling the step size (quantum) will be a little over 3 millivolts. If nothing is connected to the input pin it is normal to see noise and the potential float around a bit. It is important to safeguard the analog inputs with overvoltage and noise filters.

The ADC minimum and maximum reference levels are set to the ADC power supply, which should be filtered to prevent noise. If filtering resistors are used, the current drawn by the ADC (a few milliamps) and consequent voltage drop will cause a small voltage offset from the main power levels.

ADxx 
 
A single result is accessed using the ADxx command which refers to the analog input #,

eg
      a = ADX4
      b = ADX5

reads the results of AN4 and AN5. The third character for larger analog input id's with more channels and is redundant here, so a generic C or X can be used.

Here the voltage rises as a fresh AA cell is connected.

      PROGRAM voltz
C
      INTEGER*4 i
      REAL x, y
      FORMAT (A,F5.3,A,/)
      DO 10 i = 1, 100
      CALL delay()
      x = FLOAT ( ADX5 )
      x = ( x * 3.260 ) / 1024.0
      WRITE (6,0) "Cell is at ", x, " volts"
   10 CONTINUE
      END
C
      SUBROUTINE delay ( )
      INTEGER*4 i
      DO 10 i = 1, 8000
   10 CONTINUE
      RETURN
      END
\

Cell is at 0.035 volts
Cell is at 0.025 volts
Cell is at 0.035 volts
Cell is at 0.035 volts
Cell is at 1.038 volts
Cell is at 1.592 volts
Cell is at 1.608 volts
Cell is at 1.608 volts
Cell is at 1.617 volts
Cell is at 1.617 volts
Cell is at 1.617 volts
Cell is at 1.617 volts
Cell is at 1.620 volts
Cell is at 1.620 volts
Cell is at 1.620 volts
...
...

ZADACQ

Results can also be accessed as a fast burst in an array. The command populates the array with 256 pairs of sequential AN4 and AN5 results.
The array is a standard array and must be declared as normal. 

eg
      INTEGER*2 acdat(256,2) 
      ...
      ZADACQ acdat 
      ...

See sdistoburst2.f7 in the more examples.

Shared pins may be in analog or digital mode.
In this version/ic the analog pins have initial precedence as ANxx.  
Note that using a digital port command (eg BDB2) on a pin used for analog input will then set that pin configuration to be digital and clobber the analog sampling.
 




Vector graphic output ( 4010 / Tera Term ).

To display vectors using the Tera Term terminal, the Tek window is opened and thereafter it interprets graphics commands sent in the ascii serial stream. The window can opened manually, or a Tera Term option can be set to open the window when the graphics screen sequence is detected.

An initialisation sequence is sent first, then the move and draw commands as required. The MOVE and DRAW parameters are two-byte integers either as values or variables. The first vector after initialisation is always invisible, ie taken to be a MOVE.

The visible screen is 1024 points wide and 512 points high, with another 256 addressable points off screen at the top. 


TXINIT
Sends Tektronix 4010 initialisation string to terminal.

TXMOVE x, y
Moves grahic cursor to new position x, y.

TXDRAW x, y
Draws a vector from current position to new position x, y.


The example here takes repeated AD measurements and plots a simple chart.
The image is a resullting screen shot of 100 Hz ripple. A faster burst-mode example is included later.


      PROGRAM sdisto
C
      INTEGER*2 dat(256)
      CALL tekinit ( )
      CALL tekrect ( )
      CALL acquiredat ( dat )
      CALL tekplot ( dat )
      PRINT *,
C
      END
C
      SUBROUTINE acquiredat ( acdat )
      INTEGER*4 i
      DO 20 i = 1, 256
   20 acdat(i) = ADX5
      RETURN
      END
C
C
      SUBROUTINE tekinit ( )
      TXINIT
      RETURN
      END
C
C
      SUBROUTINE tekrect ( )
      TXMOVE 32, 250
      TXDRAW 544, 250
      TXDRAW 544, 762
      TXDRAW 32, 762
      TXDRAW 32, 250
      RETURN
      END
C
      SUBROUTINE tekplot ( dat )
      INTEGER*4 i, j
      INTEGER*2 nn, mm
      nn = 32
      mm = dat(1) / 2 + 250
      IF ( mm > 762 ) mm = 762
      TXMOVE nn, mm
      DO 40 i = 2, 256
      nn = nn + 2
      mm = dat(i) / 2 + 250
      IF ( mm > 762 ) mm = 762
      TXDRAW nn, mm
   40 CONTINUE
      TXMOVE 32, 250
      RETURN
      END
\

plugpak 100Hz :
(see plugpak.png)


burst mode output showing 9600 rs232 : (examples)
(see rs2329600.jpg)


---------------------------------------------------------------

11. Bugs, Foibles, Exasperations so far and cop-outs ...

Bugs :

A01) "Variable not found"

If a variable name is one character and is at the end of others being declared, eg "d" in 

	INTEGER*4 ab, be, cg, d

there is an odd bug that sometimes skips the last variable name. It can be easily prevented by including an additional space (ie after the "d") before the line is ended.
 

A02) Three dimensional arrays

The third dimension index is not active in some I/O commands. Use 3-D arrays with caution. 



Documentation errors..

Citing arrays in subroutines / DIMENSION

The prior manual says an array can be redefined in a subroutine. This has been stopped, ie, arrays may not be redefined or dimensioned in a subroutine. If redefinition is tried an "already" error message is shown. A DIMENSION statement is included for compatibility but it has no action.

END IF / END DO

The parsing is a bit picky and so there must be exactly one space between the END and the IF or DO.

Some new user error codes are not in the prior manual and now have been included.

---------------------------------------------------------------

A1. Appendix

Error messages

Error #1 - incorrect datatype

	The variable type was not consistent with the action. Use FLOAT/DBLE/IFIX etc if needed.

Error #2 - array bounds error

	An array index value was zero or larger than the declared array range.
        
Error #3 - variable max exceeded

	Tha value was larger than the datatype maximum.
        
Error #4 - invalid hardware unit

	A formatted I/O has tried to use an illegal hardware type.
        
Error #5 - variable not found

	An expression has used a variable that has not been declared.
 
Error #%d - variable already specified

	A variable has been declared already.
        
Error #6 - statement not found

	An identified statement has been cited by id, but no statement with that id 	exists.    
  
Error #8 - variable datatype unknown

	A variable's datatype was not found. 
          
Error #9 - variable not defined  

        The variable is unknown.

Error #10 - expected array

	A variable that is not an array has been used instead of an array.
        
Error #11 - invalid option

	The option used is not available.
        
Error #12 - mismatched datatype

	An accidental attempt was made to mix integer and floating point math.
 
Error #13 - divide by zero

	A division by zero was attempted.
        
Error #14 - memory limit exceeded

	The variables declared use too much memory.
          
Error #15 - expected INTEGER*4

	Variables used as loop counters and array indexes must be INTEGER*4.
        
Error #16 - subroutine level exceeded

	Too many subroutines called.
         
Error #17 - subroutine definitions exceeded

	Too many subroutines defined.
        
Error #18 - loop nesting level exceeded

	Too many loops called.        

Error #19 - loop range past integer*4

	A loop variable will exceed the integer*4 limit.

Error #20 - illegal character detected near ...

	The input file has an illegal character eg tab.
        
Error #21 - syntax error 

	A misformed command.
       
Error #22 - line length exceeded

	The input line has too many characters.
      
Error #23 - file length exceeded  

	The input file (program) is too long.      

Error #24 - dimension error

	An array has been referenced with incorrect number of dimensions.
        
Error #26 - last line end/start space

	A space character was detected after the end of a line.
         
Error #27 - check input line

	The input line has a misformed sequence or typo.    

Error #28 - negative root     

	Attempt to find the square root of a negative number.   

Error #29 - numbr of variables exceeded

	A program/subroutine has tried to define too many variables.
        
Error #30 - subroutine not found  

	The subroutine called does not exist.
         
Error #34 - id'd lines exceeded

	A program/subroutine has tried to set too many lines with id number (labels).

Error #36 - missing quote

	A closing quotation mark was not found within range.

Error #37 - space expected 

	A space was expected, eg 'WRITE (...)' not 'WRITE(...)' .
          
Error #38 - not implemented in this  version

	Feature is not available.

Error #40 - eeprom not erased

	The eeprom was not cleared so a save is not possible. It usually means a power supply problem (likely), or that the eeprom is worn out (unlikely).
	
Error #44 - variable already in use   

	The variable has already been defined. 

Error #45 - brackets needed 

	Repeated ** (exponentiation) needs appropriate bracketing.

Error #50 - input overrun

	Expected shorter record/data.

Error #53 - IFs limit exceeded

	Too many IFs.

Error #54 - ELSE IFs limit exceeded

	Too many ELSE IF's.

Error #55 - IF nest limit exceeded

	IF nesting too deep.

Error #56 - Bad IF or WHILE structure

	Found an IF .. THEN or DO WHILE but not the corresponding END IF / END DO.
	
Error #59 - Line token limit

	The line has too many tokens.

Error - unspecified 

	Generic error message.



Setting up

The IC containing Electride will probably be on a circuit board or hardware 
with the required power supply and serial/usb connection. 

Pin 11	 RB4    Serial (TTL) output from pic to usb chip and usb
Pin 12	 RA4    Serial (TTL) input to pic from usb chip and usb

As well, a remote serial terminal will be needed, probably a PC running something like Tera Term. The PC usb/serial bridge may require setting up with the vendors usb .inf file. 
 
The serial connection then uses a PC COMx serial port, eg COM5, and the parameters should be set to 115 kbps, 8 bits, no parity, 1 stop bit, and no flow control/handshake. 

Configuration

Trial pic32mx170b SDIP version, configuration B :

IC pin		Used as		Connected to

01		/MCLR		Reset
02		nc
03		nc
04		RB0		Digital 0 / LCD D7
05		RB1		Digital 1 / LCD D6
06		RB2/AN4		Digital 2 / Analog ADC4
07		RB3/AN5		Digital 3 / Analog ADC5
08		Vss		Ground
09		nc		Reserved for crystal
10		nc		Reserved for crystal
11		RB4		Serial out to terminal / Digital 4
12		RA4		Serial in from terminal / Run mode
13		Vdd		Power 3.3v Tank+bypass capacitors
14		RB5		Digital 5
15		RB6		Digital 6 / LCD D5
16		RB7		Digital 7 / LCD D4
17		RB8		Digital 8 / LCD Enable
18		RB9		Digital 9 / LCD RegSelect
19		Vss		Ground
20		Vcap		Capacitor 10uF low esr
21		RB10		Digital A / LCD ReadWrite
22		RB11		Digital B 
23		RB12		Digital C
24		RB13		Digital D
25		RB14		Digital E
26		RB15		Digital F
27		AVss		ADC ground -
28		AVdd		ADC power +, filter+bypass capacitors


Version limits

Trial version :

program length			16k
memory for variables		16k
subroutine definitions		8
subroutine nest limit		4
variables / sub			32
array dimensions 		3
id'd lines / sub		20
loop nest depth			7


These are arbitrary values designed to allow small archetype programs to run. The scale-enabling algorithms are removed. 

The main version runs on a larger PIC32MX795/695 IC at nearly double the speed and has much larger limits. The software should also port to a PIC32MZ easily.



Differences from mainstream.

The scope is very much smaller than the traditional areas of fortran. So Electride is not meant to be a fast number cruncher, run economic or weather modelling, support Cape Canaveral, run a spreadsheet, pilot a UAV or run audio and video codecs!. The memory limits are small, and in particular it is an interpreted system which means the execution speed is much slower than compiled code. Only a minor subset of the language is intended.

Inevitably, for an interpreter to be shoehorned into a microcontroller there are some tradeoffs. As the scope is small several capabilities of larger systems are not particularly needed and so are not present or still pending. 
There are also arbitrary limits set for the intended use and version. On the positive side, several features of later software are included to replace deprecated or obsolete habits. There are also cosmetic differences left in place for differentiation.


The following are not present.

COMMON
EQUIVALENCE
Multiple (continuation) records
Complex numbers
Hollerith strings

To be included :

DATA 
FILE I/O


The following are features changed or updated from standard.

IMPLICIT NONE is permanently set.
Default-format reporting is included. (F77)
Quoted (double quotes) text string literals can be used in output. (F90)
Lower case is used for variable names.
Variable names can be longer than six characters (the first 
six still form the unique id). 
Standard comparison operators eg "<" instead of ".LT." (F77)
Format statements are used on a most-recent basis.
DIMENSION is not active as variable/array properties are automatically preset.


The cosmetic differences.

A WRITE command has a space separator before the first content (as in F90).


---------------------------------------------------------------

A2. Appendix 2

More examples

lineqform.f7

This example was originally on another system (MONECS) to show in-situ matrix inversion using single precision, and is used here with kind permission of the author LG Whitehouse.  The subroutine calculates the inverse of a 5x5 array (matrix), as used in solving simultaneous linear equations. The matrix-by-inverse product is calculated as a check, and subroutines are also used to load data and print the input, output and product matrices. There are some superficial changes to suit, the use here is as an example of using subroutines.

sdistoburst2.f7

This builds on the simple AD/Tektronix 4010 example. It gets AD measurements as a burst using ZADACQ. Then the two channels are plotted in the two last subroutines.


