
INTRODUCTION
------------

Starting with version gpsim-0.20.0, support for external modules has
been added. This allows gpsim to create a full simulation environment
that extends beyond just a PIC. It also provides for users to create
their own simulation modules without having to be aware of the
detailed internals of gpsim.

The module approach attempts to leverage off the gpsim
infrastructure. The definition of a pic processor is now derived from
a `module'. A module can have pins just like a PIC. The node
infrastructure for connecting stimuli to gpsim I/O pins has been
extended to now include the module I/O pins. Break points and internal
module events can be traced just like they are in a real pic. A
stimulus can be connected to a module. In fact, although I haven't
tried it, gpsim can almost simulate a module with no PIC present!

Several example modules have been created and serve as example
templates. These are found in the ./modules/ subdirectory. In
addition, examples may also be found in the ./examples/14bit/
subdirectory that illustrate how the modules can be used.


HOW DO I LOAD A MODULE?
-----------------------
A new command called 'module' has been added to gpsim.

Straight from gpsim:

gpsim> help module
module [ [load module_type [module_name]] | [lib lib_name] | [list] | 
[[dump | pins] module_name] ]
        If no options are specified, then the currently defined module(s)
        will be displayed. This is the same as the `module list' command.
        The `module load lib_name' tells gpsim to search for the module
        library called `lib_name' and to load it. (Note that the format of
        module libraries is exactly the same as a Linux shared library. This
        means that the module library should reside in a path available to
        dlopen(). Please see the README.MODULES in the gpsim distribution.
        To instantiate a new module, then type
          module module_type module_name
        where module_type refers to a specific module in a module library
        and module_name is the user name assigned to it.
        Information about a module can be displayed by the commad
          module module_name [dump | pins]

        where module_name is the name that you assigned when the module
        was instantiated. The optional dump and pins identifiers specify
        the information you wish to display (dump is the default).

        examples:


        module                      // Display the modules you've already defined.
        module lib my_mods.so       // Load the module library called my_mods.
        module list                 // Display the list of modules supported.
        module load lcd my_lcd      // Create an instance of an 'lcd'
        module pins my_lcd          // Display the pin states of an instantiated module
        module load lcd lcd2x20     // Create a new module.
        module load led start_light // and another.


As you can see, there's a whole lot of stuff packed into this new command.


HOW DO I CREATE MY OWN MODULE?
------------------------------

Probably the best place to begin is to find a pre-existing module that
is close to the one you wish to create and then make copy it and make
changes.

(basic structure of modules)

HOW DO I CREATE A LIBRARY FOR MY MODULES?
-----------------------------------------
Without a doubt, the best thing to do is copy the way gpsim does it. 

The distributions for the LED and the Logic modules is probably the
best place to begin. There are many details that I can't satisfactory
cover in the scope of this document.

In the example module libraries you'll find two major sections. First
there's something I've called the `module manager'. This is a
necessary managerial layer that provides the dynamic interface. Second
is the module section that defines a module's behavior.

Module Manager
--------------
The module manager provides the dynamic link support. 

There are several mandatory functions:


get_mod_list()
------------

This function returns a pointer to the list of modules that are supported in the library. 

/*********************************************************
 * mod_list - Display all of the modules in this library.
 *
 * This is a required function for gpsim compliant libraries.
 */

  Module_Types * get_mod_list(void)
  {

    return available_modules;

  }

For this to work of course, a list called `available_modules' of type
Module_Types must be declared. From the Led library, the list is only
one deep and looks like so:

/*
class Module_Types
{
public:

  char *names[2];
  Module * (*module_constructor) (void);
};
*/
Module_Types available_modules[] =
{
  { "led_7Segments", "led", Led_7Segments::construct},
  { 0,0,0}  // indicates there are no more modules
};

The first two parameters are names that the module may be called. The
last parameter is a pointer to a static member function of the
module. gpsim will call this function to create a new module.

Note the all 0's module. This marks the end of the list.

more...

Shared Libraries
----------------

The link between modules and gpsim is `dynamic'. Which is to say, when
gpsim is compiled it knows nothing about a specific module. Similarly,
when a module is compiled it is done so indepently of gpsim. The
module compilation depends on gpsim only to the degree of using the
include files provided. The module compilation however does not
include a step at which it is linked with gpsim. Is that clear? I
guess the point to understand, is that gpsim and the modules are built
separately.

Now, when gpsim loads a module, it will open the `shared library' in
which it is contained. The infrastructure of shared libraries is
defined by the OS and not by gpsim. Consequently, there are a few
details that have to be managed before the shared libraries will work
properly.

(ldconfig)


$ more /etc/ld.so.conf
/usr/X11R6/lib
/usr/i486-linux-libc5/lib
/usr/local/lib
/usr/lib
