2 TBL_routines

This set of routines allows you to write a data from memory to an object
file. In situations where a system needs to reference a data structure that
is small enough to be kept entirely in memory and that changes infrequently,
it is often useful to write one program that builds the data structure
and writes it out to an object file, which is then linked into the program
that references the structure.

3 Summary
The simplest use of the routines is to write a single data structure to
a single psect. For example, you could write the variable Table to the file 
TABLE.OBJ by:

   TBL_open_table(context,'TABLE');
   TBL_define_symbol(context,'TABLE');
   TBL_store_data(context,Table,size(Table));
   TBL_close_table(context);
                                                 
You can, however:

   supply additional information to TBL_open_table, such as
      a version number, a creator name, and a filename different from the
      module name;

   switch psects with TBL_set_psect (psects are identified by numbers, from 0 to
      255); 

   put more than one variable in a psect with repeated calls to
      TBL_define_symbol and TBL_store_data; 

   make sure that variables are properly aligned with TBL_align_counter; 

   set a psect to be readonly, writeable, FORTRAN COMMON, or
      some unorthodox combination of flags, and set a psect's name with
      tbl_set_psect_info.

3 Contexts_and_psects

The TBL routines operate on contexts, which are pointers to object files
variables and a collection of information about the file. TBL keeps track
of the current psect, and for each psect, its current relocation counter,
the maximum alignment requested for it, its flags, and its name.

The current psect after you call TBL_open_table is psect 0; it (and any
other psect you reference) has the following values:

   Relocation counter:	0;
			The relocation counter starts at zero, and is
			incremented when you call TBL_store_data. A separate
			relocation counter is kept for each psect. The current
			value of the relocation counter is used as the value 
			of the symbol defined when you call TBL_define_symbol.

   Maximum alignment:	no alignment requested 
			If you never call TBL_align_counter for that psect,
			the linker will be asked to align the psect itself
			on a longword boundary; otherwise it will be aligned 
			on the largest boundary requested.

   Flags:		TBL_readonly
			This is a combination of flags which compilers use
			for code and constant data. You can also specify
			flag values of TBL_writable for static writeable
			data and TBL_common for data in FORTRAN COMMON.
			You can also roll your own flag values by using
			the GPS$M_xxx constant definitions in STARLET.
			
   Name:		No name specified.
			If you do not explicitly set a name, TBL will pick
			a name based on the value of the flags: $CODE for
			TBL_readonly, $LOCAL for TBL_writeable, and $BLANK
			for TBL_common. If you roll your own flags, you
			will be much better off if you make up your own
			name; otherwise TBL will make up a name which is
			unintelligible, dependant on the value of the flags
			and the psect's alignment. 



3 TBL_set_psect

[global]
procedure TBL_set_psect(
   context: TBL_context;
   ps: integer);

{Sets the relocation counter to the current location in psect ps}

3 TBL_open_table

[hidden]
const
   defaultVersion = '01';
   defaultCreator = 'Table Writer V1.1, MCV/VCU';
   defaultRecSize = 512;
[global] 
procedure TBL_open_table(
    var context:    TBL_context;
           {pointer to context information}
        moduleName: [class_s] packed array[m1..mN: integer] of char;
           {module name string for object file header record}
        version:    [class_s,truncate] packed array[v1..vN: integer] of char;
           {Version string for object file header record}
           {default: defaultVersion}
        creator:    [class_s,truncate] packed array[c1..cN: integer] of char;
           {Creator name string for object file header record}
           {default: defaultCreator}
        fileName:   [class_s,truncate] packed array[f1..fN: integer] of char;
           {Name of object file}
           {default: moduleName+'OBJ'}
        inRecSize:  [truncate] integer);
           {Maximum object file reocrd size}
           {default: defaultRecSize}

{Opens an object file and writes the header records;
 Sets the relocation counter to psect 0, byte 0}

3 TBL_align_counter

[hidden]
const
   minAlign = 0;
   maxAlign = 9;

[global]
procedure TBL_align_counter(
   context: TBL_context;
   align: integer);

{Sets the relocation counter to the least number greater than or equal to
 its present value that is evenly divisible by 2**align.
 Saves the maximum requested alignment for each psect. The alignment
 specified for the psect as whole will be this maximum alignment; if
 no alignment adjustment is requested for a psect, the alignment specified
 will be 2 (i.e. the psect will begin on an address divisible by 4}

3 TBL_define_symbol

[global]
procedure TBL_define_symbol(
   context:   TBL_context;
   gloSym:     [class_s] packed array[s0..sN: integer] of char);

{Defines the global symbol gloSym as a relocatable symobl with a
 value corresonding to the relocation counter for the current psect}

[external]                                      
procedure TBL_store_data(
        context: TBL_context;
   %ref data:     [unsafe,readonly] packed array[lo..hi: integer] of char;
        dataSize: integer);

{Writes dataSize bytes from data to the object file, breaking data up
 into as many TIR records as necessary. The data will start at the point
 of the current relocation counter, and the relocation counter will be
 increased by dataSize}

3 TBL_set_psect_info

[global]
procedure TBL_set_psect_info(
   context:   TBL_context;
   flags:     uword;
   name:      [class_s,truncate] packed array[n0..nN: integer] of char);

{Sets the psect flags (and psect name, if supplied) for the current psect}

{The most common flags combinations are supplied as the constants
 TBL_readOnly, TBL_writeable, and TBL_common.
 The default name for a psect depends on its flags. If the flags are equal
 to TBL_readOnly then the default pname is '$CODE'; if TBL_writeable then 
 '$LOCAL'; and if TBL_common then '$BLANK'. If an unorthodox flag combination
 is used and a psect name is not supplied, then an arbitrary name dependant
 on the flags and the psect alignment will be used.}

3 TBL_close_table

const
   TBL_success = 0;
   TBL_warning = 1;
   TBL_error = 2;
   TBL_abort = 3;

[global]
procedure TBL_close_table(
   context: TBL_context;
   error: [truncate] integer);

{Closes the object file.
 If error is not supplied it defaults to TBL_success; the values
 TBL_warning, TBL_error, and TBL_abort can be used to indicate a
 'compile' time error to the linker, which will issue an appropriate
 message and in the case of TBL_error will refuse to create the executable
 file, and in the case of TBL_abort, will abort the link operation
 without reading any other object files}
