PIC Compiler

Lars Silen:s hemsida
Lars Silen's homepage in English
Johdatus suomeksi

Last change June 25 2003 at 0:15.

Coming soon!

The compiler is being ported to LINUX and completely re-written in the C-language. The source code will be available according to GNU copyright rules. The new version separates the compiler from the code generator. I hope some hackers would be interested in writing backend code generators for other processors. More information about the LINUX based compiler is available at the end of the document.

Please have patience, the work continues but work interferes with my hobby projects!

The compiler implements a simple BASIC/MODULA2/Pascal language here called SIL. The compiler translates the SIL program into PIC16C84 assembly language. The assembly language contains all high level language constructs as comments. In for example WHILE loops the body of the loop is clearly marked to allow the user to easily continue working with the assembly language code.

You can download a zipped version of the SIL language for DOS below. The program should thus work under DOS, OS/2, Win95, WinNT (and Linux using Linux dos emulator). The zipped package contains the compiler, example programs written in SIL and the resulting assembly output. An example of a SIL program is found here. The assembly program generated by the compiler is compiled into executable code (HEX) using the MPASMWIN program. Alternatively the MPASM (dos) program can be used. It is important that the assembler used understands Microchip instructions. You can thus _NOT_ use an assembler that _ONLY_ understands 8051 instructions. You can find additional program examples at the end of this text.

Sil version 0.813 is found here. This version supports 24 bit integers (range 0...16777215, I had to add large integers because driving my stepper motor one turn requires 4095 steps... ;) ). Only a small set of operations are so far supported. Supported CARDINAL operations are assignment, INC(), DEC() and IF xx = yy THEN ... . Please notice that fairly large internal changes have been made to comparisons, this means that new errors may have been introduced. Watch out and report all errors! Similar changes will later be made to WHILE ... DO ... ENDWHILE and REPEAT...UNTIL (when CARDINAL support is added to those constructs). Support will first be added to other types of comparisons and later for loop constructs. Observe that operations on CARDINAL values requires more RAM registers (3 bytes/CARDINAL) and also much more program memory. Use CARDINALS with wisdom...! CARDINAL numbers are declared

VAR Myvar, AnotherVar : CARDINAL

CARDINAL variables are used just like ordinary variables. Notice that elements of CARDINAL variables are accessible indirectly. The first (LSB) byte is accessible through IND(xxx) where xxx is ADR(Variable). The middle byte is xxx+1 and MSB is xxx+2.

Present version is SIL (version 0.813)

The most recent version 0.813 allows an alternative command line of the format:

sil -p c84 infile.sil outfile.asm

Observe that the re-direction to the outfile is unnecessary. The reason for the change is that Borland's Delphi seems to loose the re-direction information on the command line. The change allows one to write a graphical front end for the compiler. More information about new tools for the sil compiler is found at the end of the document and in the document about programming robots written by my son Sebastian. The version 0.809 adds support for extended (large) tables. A TABLE definition is extended in the following way:

TABLE BigTable 1 2 3 4 5 6 7 8 9 10
... 11 12 13 14 15 16 17 18 19 20

the new keyword '...' means that the previously defined table is extended.

The 0.8 series of the compiler also supports a simple string type intended to be used with LCD displays or serial communication. The syntax for a string is:

TABLE MyString STRING 'This is a string'

The alternative format (as in Modula-2) shown below is also allowed:

TABLE OtherString STRING "This contains the character ' "

Strings are accessed as ordinary tables.

Command line switches (New and Old)

Bugs reported/corrected

To conserve space :) the list has been shortened to errors reported for version 0.7 and higher. Notice that I may have forgot to mention the name of some of the debuggers/error reporters, if your name is left out it is purely unintentional - all error reports are very welcome.

Known but uncorrected bugs

There are presently no known bugs.

Description of the SIL language

A simple SIL tutorial is under construction. This text will contain example programs and some ideas on the the of the SIL language. The tutorial will be updated occasionally. If you have example code that you are willing to share please mail it to me but please include some explanations!

The SIL language consists of the following parts:

Declaration part

All variables are global and have to be declared before use. This is done as in Modula2 or in Pascal.

VAR PORTA[05h] , PORTB[06h] : BYTE
VAR TRISA[85h] , TRISB[86h] : BYTE

Numeric values in brackets [] force the compiler to generate the correct address definitions to fixed hardware registers.

VAR Avar,Bvar,Cvar,Dvar,Evar,Fvar : BYTE

The declaration statement declares the BYTE sisze variables Avar,Bvar,Cvar,Dvar,Evar,Fvar. The register addresses of the variables are generated automatically. Please notice that the use of single character variable names is discouraged. The SIL language as such does not restrict the use of variable names, but the assembler program assembling the final machine language program may use single character identifiers for internal purposes causing errors in the final assembly.

VAR Flags BITS Run, Reset, Clk : BYTE

The declaration above declares the bit size variables Run, Reset and Clk within the register Flags. In the program the bits are used as ordinary variables that kan take two values TRUE and FALSE. The value TRUE corresponds to the binary value "1" and FALSE to a binary "0". The declaration declares the bits starting from the least significant bit (bit 0) to the most significant bit (bit 7). If the position of the bit matters (processor flags and I/O bits) then un-used bits are declared n/a as in:

VAR Flags BITS Run, Reset, Clk, n/a, d0, n/a : BYTE

The physical addesses of RAM registers is generated automatically. Any number of VAR statements before the main program are allowed. Observe that the number of RAM register in a microcontroller is small because the program memory is ROM.

New in SIL v. 0.600

The new version 0.600 SIL compiler now accepts two different declaration types for BIT variables. The old version (used when the actual bit does not matter (for example when using single bits as Flags or boolean variables). The new version

VAR PORTA[05h] BITS Run[5], LED[0], Key[3] : BYTE

declares the bit variables Run, LED and Key within the byte size variable PORTA. Run is bit 5 (counted from zero), LED is bit zero and key is bit three. Mixing the both declaration types in the same statement is not allowed. It is OK to mix the declarations on different lines.

New in SIL v. 0.610

The SIL v. 0.610 allows declaration of BIT variables in several statements. Re-definition of bits will simply overwrite the old name and a warning will be generated. This new feature is introduced to give more flexibility when using include files. The old system caused problems when using several include *.h files. Assume for example:

First file:

VAR PORTA[05h] BITS Start[0];

Second file:

VAR PORTA[05h] BITS Sense1[1], Sense2[2], Sense3[3] : BYTE

In the old version the PORTA declaration in the second include file would have to be included in the *.h file where PORTA was declared making it difficult to write generic portable code. The new system allows new bit declarations to be added later meaning that for example some RS232 procedure through its own header file is able to re-define bits for serial input/output without any need for touching the standard header file like pic16c84.h .

Observe that ALIAS definitions with different variable names pointing to the same physical register is NOT allowed. It is dangerous to define absolute register addresses for user variables because the compiler automatically assigns the addresses.

Observe that redefining bits already defined in the main header file (for example pic16c84.h) may cause errors if standard variables are re-defined. For example re-defining the names of bits in the STATUS register may be risky.

New in SIL 0.701

The new version supports a new STRING type of table definitions. A string table ends in the character code '0'. A character string table is defined as follows (two different forms are available) :

TABLE AString STRING 'This is a string'

TABLE Another STRING "This is another string"

The two different forms allows the use of single or double quotes within a string just like in Modula2.

A new command DELAY(xxxx) where xxxx is is a BYTE bariable or a 8-bit constant is introduced. The command generates a very compact delay loop which allows very much improved timing compared to for example a WHILE loop.


The delay unit is 3 us if a 4MHz part is used. For example DELAY(10) would cause a 30 us delay. Remeber to take the actual processor clock frequency into account.

Setting the default number base

The number base is set to 16 (HEX) by default. This means that all numbers not specifically declared are interpreted as hexadecimal numbers. The default number base can be set to another value using the presudo command:


To set the default number base to 10 for example use


Please report possible errors when using number bases other than 16. There is a slight risk that the wrong code may be generated in some places due to the change. Errors in this area will be corrected if found.

Main program

The main program is declared as:


The main program has to end in ENDMAIN. Only one statement per line of text is presently allowed, this restriction is introduced to simplify parsing of the source program.


Procedures are declared after the main program. The only subprogram type is the PROCEDURE. Zero, one or two parameters can be passed and zer, one or two parameters are returned.

  ...body ...

The declared procedure is called as:

CALL Delay(Dly)

Parameters are passed to/from the procedure using the CallPar1 and CallPar2 variables that are declared in *.H (different header files for different processors). Procedures accept zero, one or two parameters. Inside a procedure the call parameters are accessed through the CallPar1 and CallPar2 variables. When doing nested procedure calls the same CallPar1 and CallPar2 varibles are used. In addition one should remember that the HW stack depth in a microcontroller is very limited. The PIC16C84 provides a 8-level deep hardware stack. The hardware stack is used by both interrupt procedures and ordinary procedures.

Parameter passing from the call parameter list to the actual variables within the procedure as follows:

...some code ...
A := CallPar1 ; Pass inparameter to some var.
... body of procedure ...
CallPar2 := C ; Return value is returned

Observe that the parameter passing used behaves like pass by reference in Modula-2 or Pascal (VAR parameters). Be aware of pissible side effects.

The procedure definitions:




Are used to define handlers specifically for the three different interrupt sources in the PIC16C84 processors (Timer0, INT and PortB interrupt). The interrupt service routines automatically handle generation of the correct IRET return code and reset the interrupt flags corresponding to the different interrupt sources.

Operations on variables

Variables are given values using ":=" (the same assignment operator as in Modula2 or Pascal) or the keyword LET.


A := 2
B := C
LET B = 0 

Observe that only simple left and right values are allowed presently. Assignments NOT ALLOWED ARE:

a := b + c 
b := c + 1

Both of the previous examples are illegal because the right hand sides of the assignments are too complex. The correct way of doing the assignment would be:

a := b

b := c

Indirect addressing (pointers to registers) are allowed using:

b := 15
a := IND(b)

After the substitution the variable a contains the contents of the register number 15 not the value 15. The present version SIL054 does not support indirect access to hardware registers in bank1. The address of a symbol can be substituted using the command:


After the substitution the variable a would contain the value 5 (the register address of PORTA).

Operations on single bits

Assume some bit variables are declared:

VAR PORTB[6] BITS Run, Alarm, LoWater;

Observe! To use bits for device control as described below the direction of the port has to be set beforehand. One is not able to use the same bit both for writing and reading without changing the direction (se the command DIRECTION_B(bitmask).

The bits Run, Alarm and LoWater correspond to bit0, bit1 and bit2 (counting from the least significant bit). If one for example wants to control external hardware then single outputs can be set/reset and single bits read. If the bit Run is connected to a high gain transistor (example TIP120) then fairly high loads can be switched directly. To start a motor connected to the TIP120 the command:

Run := TRUE

would be used. To switch the motor off again one would use the command:

Run := FALSE

It is equally easy to read single inputs. To read a switch connected to Alarm (assuming a high on alarm is the Alarm state) one would use something like:

IF Alarm THEN     (or IF Alarm = TRUE THEN )
   ... code for handling alarm ...
   ... things when situation is OK ...

Bit assignments are handled different (internally) for bit assignments between bits belonging to 'ordinary' RAM registers and bits belonging to a PORT register. The code generated to assign a bit a value that is used is very fast and compact but would cause occasional glitches on output pins if the same algorithm is used for PORTS. A slower but safe assignment is used for PORT IO operations.

Using EEPROM memory

Only some processors support EEPROM memory (PIC16C84). On other processors the commands below do not apply!

EEPROM memory (64 bytes of continous memory that is preserved even when the processor is switched off) is accessible through the special procedures:

EEPROM_WRITE(Address, Data)

Where Addess is the address of the EEPROM register to read (0..63). This parameter can be a variable, constant or plain number.


Address is the address of the EEPROM register to read and Data is a variable containing the result of the read.

The EEPROM_WRITE automatically disables interrupts. To minimize the code generated the user is in charge of re-enabling interrupts after the call. Automatic handling of re-enabling interrupts can be done as:

   EEPROM_WRITE(Address, Data)
   GIE := TRUE

Observe that the WRITE operation continues for 10 ms (10 000 machine cycles after the command started. It is thus a good idea to check the EEIF flag for command completion before trying to write another byte to EEPROM. Reading a EEPROM register is no problem because it needs a single cycle.

Arithmetic/Logical operations

Presently all arithmetic operations are done as function calls.


Means Add B to A and put result in A.
(A = A + B)


Means Subtract B from A and put result in A.
(A = A - B)


Means do bitwise A OR B and put the result in A.
(A = A OR B)


Means do bitwise A AND B and put the result in A.
(A = A AND B)


Means do bitwise A XOR B and put the result in A.
(A = A XOR B)


Increment A by one (A=A+1).


Decrement A by one (A=A-1).

Shift the contents of the register cyclically to the left through the carry bit. The number of bitpositions to shift is given by #pos.

Shift the contents of the register cyclically to the left. The number of bitpositions to shift is given by #pos.

Shift the contents of the register cyclically to the left through the carry bit.

Shift the contents of the register cyclically to the right through the carry bit.


A IF statement is of the form

IF _simple comparison_ THEN

The comparisons alloved are:

Less than "<"
Greater than ">"
Less or equal "<=" or "=<"
Greater or equal ">=" or "=>"
Equal "="
Unequal "#"

Observe that there should be spaces between the parameters and the operation for example:

   ... etc.


  C := D 
  E := 0 

  LET C = A 

The comparisons work on both byte size and bit size variables. The right hand side og the comparison may also be a litteral value.

Loop constructs

Loops of the types

WHILE comparison DO


UNTIL Comparison

FOR i := start value TO end value DO
  ... do something ...

FOR i := start value DOWNTO end value DO
  ... do something ...
are supported.

  LET C=A 


The DELAY(ByteVar) instruction creates a very compact and fast empty delay loop for timing purposes. The instruction generates to assembly instructions and consumes three (3) program instruction cycles per iteration. On a 4 MHz PIC16C84 the instruction DELAY(10) will generate a delay of ca. 30 us (see assembly source).


GOTO Label

Causes an immediate offset jump to a new location defined by Label.

  GOTO Dest0
  GOTO Dest1
  GOTO Dest2

This is a multiple branch instruction. Variable is a offset into the table och branches. If Variable = 2 then a branch to Dest2 will be done. The SAFE keyword indicates that code should be generated to check that the jump table does not cross a memory page boundary (a page is 256 bytes, we are using a 8 bit processor). If the SAFE keyword is left out then no checks are done but the code will be much faster. The user can actually easily check the location of the jump table from the assembly listing and use the assembler instruction ORG to force the table to a known valid address if necessary.

  GOTO Dest0
  GOTO Dest1
  GOTO Dest2

This instruction is identical to the previous one. When building state machines the alternative name provides better documentation.

Observe that it is perfectly possible to generate a jump table where the variable increases with steps grater than unity (example 0, 2, 4, 6, ...):


  State :=  1
    Data := 5
    GOTO State0
    Data := 7       <----------- This branch will be taken
    GOTO State1

It is also possible to do some simple housekeeping before the actual branch


  State :=  0
    CALL Setup0
    GOTO State0	<----------- This branch will be taken
    CALL Setup1      
    GOTO State1

Personally I feel that commands in a jump table should be kept well together because the code will otherwise become very diffycult to read. Of course it is a personal matter of taste.

Observe that CALL parameters are forbidden (but no checks done!) because the number of bytes generated for the CALL will othervise vary causing errors in the jump offsets. A simple CALL without passed parameters generates a single instruction. Generally complex instructions like comparisons etc should NOT be used in computed jumps due to the risk that the compiler will generate different numbers of instructions for different branches causing errors that are difficult to find.


Input and output is handled by setting bits on PORTA or PORTB (etc.) to binary 1 or binary 0. A binary 1 corresponds to a high voltage level on an output pin. The current sourcing provided by the PIC-processor is enough to burn out many LED:s that are without a current limiting resistor. The actual number of I/O bits/ports is device dependent. See the documentation for the device you are using.

Bits on the ports have to be defined as inputs or outputs using the commands:

DIRECTION_A( b'01111' )
DIRECTION_B( b'11110000' )

The first command sets bit4 of PORTA to output and all other bits to inputs. The second command sets bits 0...3 to outputs and bits 4...6 to inputs.

The state of different bits may be changed using normal substitution commands like:

PORTA := b'0011'

If DataClk is defined as a BIT type variable in PORTA then the bit can be manipulated directly using the statement:

DataClk := TRUE ; Sets the bit
DataClk := FALSE ; Clears the bit

The first command sets the bits 0 and 1 to one and the other bits to zero. If the direction was defined as b'10000' (see above) then the lowest two bits will be set to high state and the next two bits to lo-state. The fifth (highest) bit will not be influences (as seen from the outside) because the bit is defined as an input.

The AND(), OR() and XOR() commands may also be used to set the state of ports.


Data may be input in chunks or as bits from a port using normal substitution. I/O port bits can be tested immediately without any explicit reading if the port.


The command reads the state of PORTB into the var VarA.

Controlling the controller hardware flags

The new version SIL054 allows direct manipulation of many of the hardware flags that are used through function calls below. Both ways of manipulation can be used. Personally I think the function call approach is easier to read and thus preferable (a matter of taste).

The compiler supports the following hardware related flags:


User internal clock source (processor clock) or external clock source. The selections are mutually exclusive.


Enable/disable interrupt requests caused by timer (and counter).


Legal values: 1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128 or 1/256.

Legal values are: 1/1, 1/2, 1/4, 1/8, 1/16, 1/32, 1/64 or 1/128.

The single prescaler may be used either by the Counter/Timer or by the Watchdog timer but not by both.Don't change prescaler assignment without reading Microchip documentation. Changes may be needed in the compiler generated assembly code in that case.

Observe that the processor flags also may be manipulated directly using BIT size variables.

Using tables in program memory

Programming tasks on a simple controller may often be simplified by using data tables instead of doing complicated artihmetics on data. The PIC16C84 allowes a very fast and efficient way of defining data in the program ROM memory. Reading a table value will take only 3 instructions.

A table named "Test" with the data 1,2,3,4,5,6,7 is defined as:

TABLE Test 1 2 3 4 5 6 7

The data is read (counting from zero) using the command:

LOOKUP Test(Avar,2) [SAFE]

The command reads the third element and thus returns 3. After the call the variable Avar contains the value 3. The keyword SAFE is optional and forces the compiler to generate code that is independent of memory page boundaries but larger and slower. More efficient code is best generated by patching the assembly code.

Numeric tables can be extended over many lines using the new notation '...'. To define a large table containing 20 numbers extending over two lines but called through the same identifier 'BigTable' use:

TABLE BigTable 1 2 3 4 5 6 7 8 9 10
... 11 12 13 14 15 16 17 18 19 20

Please notice that a single table must have less than 256 elements due to the 8-bit PIC register size.

Character Strings

Because there are fairly cheap LCD modules availble that can easily be connected to a pic processor there is a need for character strings. Internally character strings are identical to TABLE definitions. The compiler handles translation of characters prom alphanumeric to numeric fomat.

The STRING extension will simplify storing string constants in program memory with no need to do conversion from ascii to hex for example (handled automatically by the compiler). The STRING extension is also needed when we have working (tested) serial communication procedures. Of course we want to talk to some dumb PC! A zero character is automatically be added at the end of the string just as in Modula-2 or in C to allow simple detection of the end of the string).

TABLE TableName STRING "This is a string"

TABLE OtherString STRING 'This is another string'

Using the alternative forms allows the inclusion of single or double quotes in the string. The table will be used exactly as before.

Handling Interrupts

The new version SIL054 allows direct manipulation of many of the interrupt related flags that are used through function calls below. Both ways of manipulation can be used. Personally I think the function call approach is easier to read and thus preferable (a matter of taste).

Three interrupt sources are supported:

The interrupt sources are selected with the commands:


Correspondingly they are disabled using the commands:


The commands enable/disable individual interrupts. If several interrupt sources are enabled then interrupts may be enabled/disabled globally using:


Using indents in the source file

Indents of essentially any depth are allowed in the source file as long as only single statements appear on lines. The compiler simply skips any white space at the beginning of lines.

Using comments in the source file

Comments start with the ";" character. Any comments are passed through the compiler without any changes and thus high level language comments will be seen in the assembly language output.

Inline assembly statements

Because any commands not recognized by the compiler are passed unprocessed through the compiler all kinds of assembly statements are allowed. Variables may be used freely but no checks are made that the variables actually are declared before use. Any non-declared variables will cause errors in the final assembly stage.

Test programs

There are som test programs supplied with the compiler. Test programs have the extension .SIL and assembled programs have the extension .ASM .

Tools needed

Microchip assembler program either for dos or for windows. The author does not know if the compiler output is compatible with other Microchip assemblers available on the net. The SIL compiler has only been tested with MPASWIN v.01.30.01. Please report problems and possible fixes.

Microchip PIC simulator program that allows one to single step a PIC machine code program is available on Internet. The program is useful to check that a new program works as intended before burning a working version of the chip.

Some program editor. The dos EDIT program may be used. The author likes the Pfe program a lot - test it.


The compiler is a executable DOS program (ca. 100 kB). The compiler is used as follows:

SIL -p PIC16C84 sourcefile >outputfile

Example programs and Procedure library

From v. 0.610 the SIL compiler allows additions to previous bit variable declarations. This makes it easy to create generic procedure libraries. Every procedure will consist of two files. The first file someproc.h declares variables that the procedure needs and adds necessary bit declarations either as extensions to existing bit declarations or as separate declarations. You can find some tested (and untested) SIL code here.

Source code

The compiler is written in TopSpeed Modula2. The source code will possibly be released later (needs some clean up!).

Future plans

The support for the PIC16C7X processors makes the implementation of I2C supported projects fairly simple. Ordinary asyncronous serial communication is also easy to implement. If somebody has tested code to share about serial communication, I2C etc I am interested in it. I think the correct way of developing the language is to collect tested procedures for different uses that can be included into any program. My view is that the library for a microcontroller should consist of a large set of separate/indipendent procedures (we are trying to save codespace and thus we do not need any runtime library).

For version 0.8 I have planned fairly large extensions for which all comments are very welcome before implementation starts:

A larger datatype will be introduced, something like CARDINAL or possibly some user definable type CARD[n] where n is some small integer 2 .. 4(?). Is it worthwhile to make it definable and also making all operations on the type more complex or is it better to make it fixed - what size then? The idea is to allowd access to the components of the CARDINAL type through something like a record syntax. Assume that we have a 3 byte CARDINAL named for example Counter. The components would then be accessible throug Counter.B0, Counter.B1 and Counter.B2 .

The variable declarations will change in version 0.7 to something like:

VAR VarName1, VarName2 ... : BYTE

VAR Flags BITS Flg, Run : BYTE

VAR Long, OtherLong : CARDINAL

On the long run the same operations as for BYTE and BIT will be supported but initially the following operations will be available:

INC() DEC() ADD() SUB() IF LongVar = xxxxx THEN

Robot programs written in SIL

The sil compiler can without changes be used to write PICBOT programs for a simulated robot. Several simulated robots can fight each other. Writing programs for a simulated robot could be a very good way of learning how to control an autonomous robot. A few programs for a simulated robot are found here. If you are interested in programming real robots using the SIL language Sebastian Silen (my son), Sebastian Ahlman and Joakim Nordling are building a small mobile robot using a PIC16C84 for a brain. The boys have written a program generator for the robot that implements a simple turtle graphics like language. The user clicks on buttons for FORWARD, REWERSE, LEFT, RIGHT etc. commands (fields for inputting the length of the move and size of the turn). The generator then allows compilation of the automatically generated *.rob program into a valid SIL program that is then compiled into assembly language. The beauty of the program generator is that the result always is a correct SIL program that always compiles without errors.

The robot is built from parts ordered over the Internet from HVW Technologies in Canada. The parts arrived within one week from the order (we live in Finland in the town of Esbo close to the capital Helsingfors/Helsinki). The robot consists presently of the following parts:

Presently the whole control chain from generating programs using ROBOTGEN to running the robot works. There are a few small problems with the robot not running exactly on a stright line (turns slightly to the left). Programs compile correctly though. In the near future the IRODS detector will be connected to another PIC processor and mechanically connected to a stepper motor salvaged from a floppy disk drive. The second PIC will use the stepper motor to scan the area in front of the robot (30 deg left, center and 30 deg right) and send the information to the controlling processor. When the IRODS scanner works then the command MOVE will be added to the ROBOTGEN program. The new command will run forward until an obstacle in front of the robot is detected. The robot will stop, turn in a direction dependent on the detected obstacle and then start to execute the next command. The stepper motor control will be implemented as in the example below.

When the IRODS system works the last step in the project will be to see if it is possible to teach the robot to find it's own docking/charging place without human help. The boys checked a possible solution where the docking station is marked with a clear plastic reflex plate (like the rear lights of a car) using 90 deg. prismas. They checked that a laser beam is returned along the incoming path for a large range of beam angles in relation to the reflex unit. The idea is to mount a low power laser indicator on the robot together with a light sensor. The robot would then turn around until the robot "sees" it's own laser. When the robot sees it's own laser it means it is pointing directly towards the docking station. Run forward (possibly with a few extra direction finding steps) until the robot docks.

The electrical connections are:

The planned automatic docking system is outlined below:

Stepper motor driver written in SIL

An example of a stepper motor driver program written in SIL is given here. A small ST28 stepper motor combined with a 1/64 reduction gear is used. The intention is to use a construction based on the example to build a simple astronomical clock using two stepper motors. One motor will turn one turn in 24 hours providing a normal clock using a 24 hour dial. The other motor will turn one turn in one year. The one year motor will drive several transparent plastic sheets generated using an ink-jet printer to give the month, day, the phases of the moon etc. How these sheets should be combined with transparent holes in the front-plate to show the data given above is left as an exercise for the reader ;).

LINUX, general portable SIL compiler

The SIL compiler is being ported to LINUX and implemented in C using a LEX fronted. The new version is a complete re-write of the present version of SIL and it is not yet usable. The following parts of the compiler are working (possibly causing some extra diagnostic output):

Changes compared to v. 0.80x for DOS

The new SIL version requires the BIT number to be specified at all times. The previous automatic version will be droppes because it is unnecessary and potentially dangerous. To declare the bits pa, pb and pc connected to PORTA bits 0, 1 and 2 one would use the declaration:

VAR PORTA[5] BITS pa[0], pb[1], pc[2] : BYTE

I have planned to introduce STATIC variables for PROCEDURES. Procedures would then have their own local variables but recursion would not be possible. The idea is to automatically generate variable names prefixed by the procedure name. Local static variables would then be accessible from the main level too using the correct prefix. This is not yet implemented, is this a good idea?

Remember that the code is very early alpha code and the compiler is not really useful even for simple work yet. The present version is really meant to show what is coming. I hope to have a partially useful version available within a week or two.

Building the SIL compiler under LINUX

Create a new directory for example called sil. Copy the tar file to the new directory and give the command

uncompress siltar.Z
mv siltar sil.tar
tar -xvf sil.tar

To compile the program give the command:


The executable program is sil.

Using the compiler under LINUX

To compile the supplied test1.sil program give the command:

silmain test1.sil test1.out

You can download the present LINUX version 0.1 of the SIL compiler here.

Existing problems:

Need some help with the LINUX version!

To create a working PIC programming environment under LINUX the following parts are needed:

Initially the most critical parts are the assembler and programmer. If you know any working assembler and programmer for LINUX that can be distributed fro free, then let me know (link to the SW).

If you would like to write code for the LINUX version of the SIL compiler you are very welcome to do that. A fairly large work for me is to write the code generator functions. If you know PIC assembly language you are very welcome to write the code generator parts for CARD values for IF, REPEAT and WHILE. I will supply the necessary information on request.


All kinds of feedback is welcome. The SIL compiler is presently so large that all aspects of it can't be tested very easily. Bug reports are taken seriously and I try to fix errors as fast as possible. New ideas on new features etc. are also welcome.

Other matters!

Copyright 1997 Lars Silen.

The new portable (LINUX) version of the SIL compiler is available under the GNU General Public License as published by the Free Software Foundation. Essentially this means that the program is distributed for free without any warranty. If the program is copied and passed on to a third party the new user of the program gets the same full rights to redistribute the program as the previous user. Source code must always be available to the new user either as a part of the package or on request. The use of the program is always free but the distributor may charge a reasonable fee for copying the package. Please read the full copyright text. Users are allowed to modify the program, but modifications should be clearly marked. A modified version of the program continues to fall under the GPL.
The DOS version of the SIL compiler and documentation is freely distributable either for free or for a reasonable copying fee as long as it is made clear to the purchaser that upgrades are available for free from the Internet.

If you like the compiler and want to pay for it then the procedure is:

If you are a bahá'í then please send the payment to the Arc fund (non bahá'ís are not allowed to support bahá'í activities - sorry folks!).

Send feedback to Lars . Silen @ kolumbus . fi

Direct mail link has been deleted because it generated too much spam. Leave out the spaces in the address.

Lars Silen's hemsida
Lars Silen's homepage in English
You are visitor number on this page since 26.4.97.