 

-----------------------B E T A   I N F O R M A T I O N --------------------
     This file describes the BETA version of a Small C compiler for
the Motorola 68HC11.  This 'manual' is vague in places and
incomplete in others.  A proper, more complete manual is in the works
and will by available when the compiler is released.

MOST IMPORTANT---
  THERE ARE INCLUDED EXAMPLES (ESPECIALLY CLOCK.C AND CLOCK2.C) THAT SHOULD BE
STUDIED _EXTENSIVELY_ TO GET A FEEL OF WHAT IS GOING ON!!!!!


PRINT THIS DOCUMENT - IT IS ONLY A FEW PAGES!!!!

I AM ASSUMING YOU KNOW A FAIR AMOUNT ABOUT C, 68HC11 ASSEMBLY,
DOWNLOADING TO EVALUATION BOARDS, BURNING ROMS, ETC.  IF YOU ARE
EXPECTING SOMETHING LIKE TURBO C, WITH THE SLICK ENVIRONMENT,
EXTENSIVE DEBUGGING FACILITIES, ETC., THEN YOU DOWNLOADED THE WRONG
PROGRAM!!!


                               ORGANIZATION

   I.    Introduction
   II.   Compiling an example
   III.  The two types of generated programs
   IV.   Added Keywords
   V.    Using and Writing Drivers
   VI.   Small C's Library
   VII.  Troubleshooting




I.  Introduction

    The 68HC11 Small C compiler (CC.EXE) is a command line compiler that
generates 68HC11 assembly language from C source code.  This assembly language
can then be assembled with a standard 'HC11 assembler such as AS11 (included
with this ZIP file).
    The reference for the Small C language is James Hendrix' Small C Compiler
V2.2 and is available at most computer bookstores.
    James Hendrix' original compiler was re-written in parts to facilitate
code generation for the 'HC11, and could be re-written to generate code for
other micros.  The work done in modifying the compiler, and how to modify the
compiler for other micros in detailed in a article to be published (maybe,
anyway) in 'Circuit Cellar Ink: The Embedded Systems Journal'.
    Since the target systems using the HC11 can vary to a great degree, there
are two different and distinct types of programs this compiler will generate.
    The first type is a runtime version, and it is designed to run under the
control of a monitor (such as BUFFALO).  A runtime version, as generated by
the compiler, does not set up interrupt vectors and assumes a stack is already
set up for it when it is invoked.  Thus, a runtime version is most useful when
debugging code on an existing system running a monitor program.
    The second type of program generated is a ROM version.  This version DOES
set up the stack and initializes all the interrupt vectors (via a table in
ROM).  Once a runtime version is running on the target system, a ROM version
is generated by invoking the compiler with a   -R   on the command line.


II. Compiling An Example

    Since you are probably interested in looking at the code generated by the
compiler, we will step through a quick example to familiarize you with the
process.
    The compiler, CC.EXE, does not do any 'linking' by itself, it simply
generates two files- CODEOUT.ASM and DATAOUT.ASM.  The first holds all of the
code, and the second holds all of the data declarations.  These two files,
when merged, can then be assembled like any assembly program.  I have included
a .BAT file to do all the linking, compiling, and assembling with only one
command-  hopefully this will be your primary way of doing things.
    There is an example included with this .ZIP file called EXAMPLE1.C
consisting of the short program

#code 0xD000
#data 0xC000
#include <lib\startup.c>

int i;

main(){
 i+=2;
}

    By typing

     SC EXAMPLE1

    at the DOS prompt, will will do the following:

     1) Link in the system library, 6811_LIB.C
     2) Compile the program and #included files
     3) Merge the compiler output files, DATAOUT.ASM and CODEOUT.ASM
     4) Assemble the merged .ASM file
     5) Generate EXAMPLE1.LST and EXAMPLE.S19

    EXAMPLE1.LST is a listing of the assembled file from the assembler, and
EXAMPLE.S19 is the file for you ROM or for downloading to the monitor.

Notice in the EXAMPLE1.LST file that the system library has been appended by
the .BAT file automatically, and that the original C source is included in the
output as comments.





III.  The Two Types of Generated Programs

    As was mentioned earlier, two types of programs are generated by the
compiler: a runtime version, and a ROM version.

The runtime version would be invoked by

    SC MYPROG

while the ROM version would be invoked with the -R switch, such as

    SC MYPROG -R


    A C program differs slightly for each model.  For a runtime version, a
typical shell would look like:

#code (insert starting address of code here)
#data (insert starting address of data here)
#include <lib\startup.c>

/* The previous line 'links' in a very small startup library */


main(){
 /* Your code here */
}

Notice, we didn't have to specify a stack address.  A monitor typically takes
control of this for you.  In fact, BUFFALO will often times crash if you try
to muscle the user stack away from it!
    After downloading to your evaluation board, the program can be started
by typing a 'G' followed by the starting address of the code.


The typical shell for a ROM bound program should look like this:

#code  (Staring address...)
#data  (ditto...)
#stack (ditto...)

main(){
}

The S19 file generated from a ROM compile will make sure all the proper
vectors are initialized, and automatically set the stack register before
calling main.

IV.  ADDED KEYWORDS
    The Small C compiler has had several additions made to it to help with the
support of the 68HC11.  The added words are:

  #code
  #data
  #stack
  rom
  interrupt

   The first three compiler directives were included to allow a way to specify
where the various components of a program were to live.  All during the
development of this compiler, I've used the following parameters

  #code 0xC0F0
  #data 0xC000

   RAM on the Moto EVB begins at 0xC000.

    The 'rom' keyword provides a way for the user to set up a permanent array.
Normally, if the following is typed
    char buf[]="This is a test";

the buffer will be created in RAM.  Obviously, after a system power up, the
string won't be there (as it would wThis means the initialization will also
exist in RAM.  Obviously, when a system is first powered up, this
initialization won't be there. The solution to this is to force the string to
be stuck into ROM.  This can be accomplished by typing

    rom char buf[]="This is a test";

This will force the string to exist in the code segment of the assemblers
.S19 file.

    Additionally, I have added the 'interrupt' keyword.  Declaring a function
to be of type 'interrupt' causes the compiler to generate the proper entrance
and exit codes so that the function is really an Interrupt Service Routine.

    Looking at the CLOCK.C demo, you'll see the following

    interrupt toi(){ /* Timer Overflow Interrupt Service Routine */
     sys_clk++;   /* increment the system clock */
     bit_set(0x1025,0x80) /* Clear the overflow interrupt flag */
    }

Thus, the above function is called whenever this interrupts occurs.  Note that
additional interrupts are inhibited during an ISR.  If desired, you can enable
interrupts ( by calling e_int() ), although nesting of interrupts isn't
recommended.
    In order to be recognized by the compiler, all interrupts must have a
specific name.  The names are as follows:

 int. Name---------Function----------------
   sci             SCI system
   spi             SPI system
   pac_in          Pulse Accum. Input Edge
   pac_of          Pulse Accum. Overflow
   toi             Timer overflow interrupt
   tme_oc5         Timer output Compare 5
   tme_oc4
   tme_oc3
   tme_oc2
   tme_oc1
   tme_ic3         Timer Input Capture 3
   tme_ic2
   tme_ic1
   rti             Real Time Interrupt
   irq             External pin Service Routine
   xirq            Pseudo NMI
   swi             software interrupt
   illegal         Illegal opcode trap
   cop             Compuer Operating Properly Failure
   clk_mon         Clock Failure

    So let's say you needed to trap an illegal opcode.  In C, this would be
coded as

interrupt illegal(){
 fputs("An illegal op code was encountered",stdout);
}

NOTE: YOU MUST ENABLE THIS INTERRUPT AND GLOBAL INTERRUPTS FOR THIS TO WORK!!

Also note that if you are using an EVB, you must re-vector the interrupt
manually.
  See the examples CLOCK.C and CLOCK2.C for examples of how things are
done for a monitor and ROM situations.


V.  Writing device drivers

  Essentially, a device driver must either ouput or input a character.  The
driver is responsible for all timing and error handling.  There are two
drivers included with the BETA version, EVB_out and SER_out.  Both drivers
are very short, and very simple.  Essentially, they both take the character
passed to them and output it to the device they're writing to.



VI. SMALL C's LIBRARY

  Linked into every Small C program (compiled via the SC.BAT program) is the
standard 6811_LIB.C file.  This file is the low level libary, and handles such
things as the 16 bit math, shifting, etc.
  It also includes several small functions such as

   peek()
   peekb()
   poke()
   pokeb()

   and non-standard functions such as

   e_int()     (enable interrupts)
   d_int()     (disable interrupts)
   bit_set(int address; char val)  (set the bits @ address that are set in
                                    val)
   bit_clr(int address; char val)  (clear the bits @ address that are clear
                                    in val)


Also included are the standard functions:


   atoi()
   fopen()
   fprintf()
   fputc()
   fputs()
   itoa()
   strlen()

Obviously, there are many more functions not included   in this beta version.




THIS CONCLUDES THE BETA DOCUMENTATION...