,ll 6.6
,cs 10
,pl 66
,lm 0.2,0.5
,pn 1
,ju
,hd
,ce
OmegaSoft 6809 Cross Pascal Language Handbook (V1.0)
,,
,ft

,ce 1
7-##
,,
,ce
OmegaSoft 6809 Cross Pascal Language Handbook (V1.0)

,ce
MODULAR COMPILATION
 
When a program becomes very large it will tend to delay development of the program. This results from longer editor load and save sequences, longer compilation time, and longer assembly times. If instead your program is broken up into one main program, and a number of modules, then only the portion being changed need be recompiled and reassembled. A typical method of modular programming would be to have one file be the main program with procedures and functions declared as external and only the main global block in the file. The actual procedures and functions would be declared as entry in the various modules.

To set up a modular system, first segment procedures and functions into modules, compile and assemble those modules, compile and assemble the main program, and then set up a linker control file to load first the setup code (from the linkage creator), then the main program, then the modules (any order), and then of course the runtime library. The modules can also be assembly language routines. Now when a module needs changing just compile it, assemble it and then link it, this will be much faster than a non-modularized system.

,ce
MODULE HEADER FORMAT

The module header is very similar to a program heading with the word "program" changed to "module". After the last procedure in a module there is the word "modend" and then the period. This replaces the main program's begin end pair.

module heading = module identifier [( identifier
                 {, identifier} ) ] ; sub-block modend .


   module     identifier       (        identifier      )       ;

                                            ,


             sub-block      modend       .


The sub-block is identical to a block except it lacks the begin..statement..end syntax.
,pg
,ce
MODULE FORMAT


sub-block = {(label-declaration | constant-declaration |
            type-declaration | variable-declaration)}
            {(procedure-declaration | function-declaration)}


 
                          label declaration


 
                         constant declaration


 
                           type declaration


 
                         variable declaration


 
                        procedure declaration


 
                         function declaration



,ce
GLOBAL STACK VARIABLES
 
If the modules require the use of global stack variables then these must be defined in the modules. Since global variables are assigned stack offsets in the order in which they are compiled, care must be taken to insure that the variable declarations in the modules exactly match the variable declaration in the main program. Failure to observe this precaution will result in execution errors, and possibly the end of life as we now know it. 

One of the easiest methods of doing this is to put all of the global variable declarations in an include file and using it in each file. In this manner if a change is made to a global variable it will be changed in each module the next time they are compiled. 

Global stack variables are not accessible by assembly language routines directly.

STANDARD I/O DEVICE VARIABLES

When these devices are listed in the program parameter list they are allocated on the stack. When they are initialized at the start of the main program, their addresses are also put into the global stack frame, where they are accessed from thereafter, and by any module that needs them.
,pg

To access the standard I/O devices from assembly language, you need to use an include file "xpasequ" in your assembly source code. The symbols required out of this file are r$inp, r$out, r$aux, and r$key. For instance to get the address of the output device.

            ldx -6,y           {only needed for non-global access}
            ldx r$out,x

,ce
EXTERNAL AND ENTRY VARIABLES

Another way to access global variables is to declare variables as entry in the main program and to declare variables as external in the modules that need to reference them.

This method is supported for compatibility with the old 6809 resident compiler, it is not recommended for new designs (use varib entry & varib external instead). Note that when using this method that any variables declared as entry or external must be unique within the first 8 characters, as they must pass through the assembler and linker.

To access an entry variable from assembly language, just use it's name (truncated to 8 characters) as an offset from the global stack mark :

                  ldx -6,y       {for non global access if needed}
                  leax name,x

,ce
VARIABLES LOCATED IN VARIABLE SECTION

If you wish to have variables that are not accessible by the main program then they can be defined with the varib option. If you have global variables that need to be known a few modules (but not the main program) then they can be defined as varib entry in one module, and varib external in all other modules. Their names must be unique in the first 8 characters, as they must pass through the assembler and linker. Variables declared as "varib entry" may be accessed by assembly language routines by :

                 ldx -6,y      {for non global access only}
                 leax name,x   {variable name truncated to 8 char}

You may also allocate a symbol in assembly language routine in varib section and then reference it in a pascal module by defining the variable as "varib external" in the pascal module. The assembly language declaration :

                 xdef     name
                 varib
           name  rmb      <size>

,ce
EXAMPLE

The example program and 3 modules below show all useful combinations of variable declarations in the global section. Only the declarations are shown
,pg

INCLUDE FILE :

   type
     abc = array [1 .. 10] of integer ;
   var
     def : abc ;
     ghi : integer ;
     klm : longhex ;
     nop : string ;

PROGRAM :

  program test (input, output, auxout) ;
    { if any standard devices are needed, they must be declared
      in the main program }
  {$Iinclude} {global to program and all modules}
    var
      prg1 : real ;
      prg2 : integer entry ; {global to main program and selected
                              modules}
      prg3 : set of 'A' .. 'Z' entry ; {same as above}
      prg4 : byte varib ; {used only in main program}

MODULE 1 :

  module test1 (output) ; {only output used here}
 {$Iinclude}              {get global to all file}
    var
      mod1a : char varib ; {used only in this file}
      mod1b : char varib entry ; {defined here, used here and
                                  in other module}
      mod2a : char varib external ;{defined in another module
                                    used here also}
      prg2 : integer external ; {defined in main program, used
                                 here also}

MODULE 2 :

  module test2 (input, output) ; {both input and output needed}
 {$Iinclude}
    var
      mod2a : char varib entry ; {defined here and used in other
                                  module}
      mod2b : real varib ; {used only here}

MODULE 3 :

  module test3 (auxout) ; {only auxout needed}
 {$Iinclude}
    var
      mod3a : abc varib ; {used only here}
      mod1b : char varib external ; {defined in another module,
                                     used here also}
      prg2 : integer external ; {defined in main program, used
                                 here also}
,pg

,ce
EXTERNAL AND ENTRY PROCEDURES AND FUNCTIONS

To be used in a modular system some procedures and functions will be declared as entry or external. Only those procedures and functions who must be called from other modules need be declared entry, all others can remain local to their module. Note that any procedures or functions that are declared as entry or external must be unique within the first 8 characters, as they must pass through the assembler and linker.

