                     DF file structure (VERSION 21572 ('DT'))
                     ========================================


The .DF file structure is the following:
----------------------------------------

    The  FCB:  starting at byte 0 in the file. The first word is the
    version number.  Either version 21570 (ASCII character 'BT' for
    b*Tree) or version 21572 ('DT') is currently supported. Version 21572
    has view only passwords and memos. The  next word is a 16 bit  integer
    indicating the record size  in  bytes. The next word is the number of
    fields  in the file. The next word is the current number of indexed
    fields. The next word is  the size of the DCB in words. The next word
    is the beginning block (512  byte block, zero based) in the file of
    the DCB (the  first available  block after the end of the FCB). The
    next word is the  block offset  of the first record page (the first
    block after the end of  the DCB).  The next 5 words  should begin as
    all zeroes meaning the file is not password protected. That is the end
    of the fcb for version 'BT'.  For versions > 'BT', the next 5 words
    are the view only password and should also begin as all zeroes.
    Finishing off the fcb is one last word which is the number of memo
    fields in the file.
    
    The  field definition table begins immediately after the FCB and could
    be considered  as  part of it. This table is a simple array  of field
    definition  records, one for each field in the file. The first word
    in a  field  definition record is the size in bytes of the field.
    Boolean fields  are 2 bytes; Text fields are the display width + 1
    length byte + another byte  if necessary to make the size an even
    number;  Date fields are 4 bytes; Number fields are 4 bytes, Time,
    Scientific and Decimal  fields  are  10 bytes; and MEMO fields are 4
    bytes. The next word in the field  definition table  is the offset in
    the record of the field. The next word is a  0, 1,  or 2 depending on
    whether the field is a unique key, just  indexed, or  not indexed,
    respectively. The  next word  is  the  field  type. Presently defined
    field  types are: Text=0,  Number=1,  Scientific=2,
    Boolean(True/False)=3, reserved=4, Decimal=5, Date=6, Time = 7, Memo =
    8. The next word is a  repeat  of  the second word(the second word
    actually varies but only while the file is in use), the offset in the
    record in  bytes for this  field.  The next word varies for the type
    of the field: 1) if the field is allows precision (such as decimal
    fields) this word defines the decimal precision (2 means xxxxx.xx)
    2) for Memo fields, this word is the maximum size in bytes that a memo
    should be allowed to grow. The next 6 words contain the field  name,
    starting with  a length byte (the number of characters in the  name),
    followed by  the  upper case field name ('0':'9', '_', '#'  are  also
    allowed).  All field names must begin with a letter and must be unique
    for the file.

    The  DCB  (this data changes when file is used, FCB only  changes
    when the  Modify  command is used). The first two words in the DCB are
    a  32 bit integer  organized as high order word first, low second,
    but  the words themselves are Intel standard low byte first, high
    second.  This integer  is the  number  of records in the file.  The
    second  2  word integer  is  the maximum  number  of  records that
    has ever been used in the  file  (a  high water mark).  The next 2
    words are the beginning free space pointer,  which is a pointer  to  a
    linked list of available records (if no records have been deleted,
    this  is a 2 word zero).  The next word  is  the field number of the
    auto-increment field, if any (if not,  this  word  should  be  zero).
    The next 2 words are the current autoIncrement  value  (usually  the
    number of records ever added to the file + 1).  The next  2 word are
    the maximum index pages ever used. The next 2 words are the  index
    page  free list pointer (2 word zero means no  pages  ever deleted).
    The next two words, for versions > 'BT' only, are a pointer to the
    current free space linked list in the memo file. The memo page pointed
    to by these words has as its first two words a pointer to the next
    free page.  The free pages continue until a link in the free memo list
    is 0. Finally  the DCB ends with an array of index information for
    every field in the FCB. Each array element is made up of two parts:  a
    two  word  integer  indicating  the page number (zero based) of the
    root of the  b*tree  index  for the corresponding field (zero may mean
    field not indexed); and second, a single word indicating the depth  of
    the  tree (only a root => 0, more  levels, root  is  the highest
    level).

    After  the  DCB, at the beginning of the next block, the  record  pages
    begin.  A  record page is 4096 bytes. Dividing this number by the  size
    of  each  record determines how many records fit in a page. No  records
    span  a page  boundary: if  a record will not fit in a record page, the
    rest of the page is wasted  and the  record  begins on  the next page.
    
    A  record  begins  with  a 1 word version number.  If  this  number  is
    greater  than zero, then it is the number of updates done to the record
    modulo  32768. If it is negative or 0 then it means the record has been
    deleted,  and taken together with the next word is a freespace link ptr
    (the absolute value of it is the number of the next record in the list; 
    zero means that it is the last record in the list).

    Record  data  after the first word is as follows: Boolean
    (True/False) fields  should  be  either 0 or 1 (any non-zero number is
    true).  Date fields have  as the first word the year (e.g. 1990),
    followed by a byte which  is  the  day of the  month followed by
    another byte which is the month (e.g. 11=November).  Number fields are
    as  in the 32 bit integer explanation above.  Text fields begin with a
    length byte indicating how much of the  space  is in use, followed by
    the ASCII string. Scientific and Decimal fields are IEEE 80-bit
    floating point numbers.  The offsets defined  for each field assume
    the version word starts at byte 0.  Memo fields are two words which
    are a pointer to a memo in the .MF file. The page specified in the
    record should be multiplied by the number of bytes per memo page which
    is specified in the second word of the .MF file to find the starting
    byte.


The .IF STRUCTURE:
------------------

    The  .IF file is organized as a  B*-tree as described in Knuth vol  III
    with  the space optimization of not allocating space for page  pointers
    for  sons  in  leaf  pages. The structure of an index page  is  of  two
    types:  pages on levels>0 (fathers) have page pointers in between  each
    entry  (or,  if you prefer, in the front of each entry). Both kinds  of
    page  begin  with a word containing the number of entries in  the  page
    followed  by  a word which defines which level the page is on (level  0
    is  the  leaf page level, level 1 the level of direct fathers  of  leaf
    pages, etc.).  Leaf node pages have an array of record numbers followed 
    by index values.  Index values are identical  to  record  values except
    for text fields where the field values are Upper-cased versions  of the 
    record values.  Father (level > 0) node entries have page  pointers  in
    in  front of each of them, and one page pointer after the last of them,
    which  is the end of the data in the index page. Each page is 2K  words
    in length.

    It should  be  noted before attempting to work with the structure of an 
    .IF file that the Fix_File utility can make an .IF file if a proper .DF
    file already exists. This is done by making a junk file with the proper
    name and then running Fix_File on that file. 


The .MF STRUCTURE:
------------------

    The .MF file (memo files) begins with 512 bytes of header.  Currently
    most of the block is zeroed for future use.  The first word of the
    file is the version number (currently 0).  The second word of the file
    is the size of a single memo page (currently always 512 but it may
    possibly vary by the release of OA3.0).  The rest of the block should
    be zeroed.

    Each block following the first contains memo data.  Memos are divided
    into pages each containing the number of bytes specified in the second
    word of the MF file header.    The first two (2) words (32 bits) of
    each memo page is a pointer to the next memo page in that memo (ie
    memos are stored as linked lists of pages).  If a memo page's link is
    is zero (0), that page is the last page in that memo.   The rest of
    the memo page is straight text.  Note that if there is a database
    password on the .DF file, the memo file data (including the links but
    not including the header) is encrypted the same as the .DF file.

    The record values in the .DF file contain memo page numbers.  These
    are the first page of memos and memos are read until a NIL link is
    found. The .DF file also contains a free space pointer for the memo
    file.  This is a pointer to an unused memo.  This memo is expected to
    be linked to every memo page in the file that is not used.


.DF file structure in summary:
------------------------------

    File  Control  Block (FCB) - the first 24 bytes of a .DF  file  (block 0)
    contain general information about the database file:


      Byte Number        Byte Description
         0-1                Version Number (= 21570 ('BT') or 21571) 
         2-3                Size of a single record in bytes
         4-5                Number of fields in the file 
                                                (1 to 100 for version    'BT')
                                                (1 to 255 for versions > 'BT')
         6-7                Number of key fields (0 to the number of fields)
         8-9                Size in 2-byte words of Data Control Block
        10-11               Block offset of Data Control Block
        12-13               Block offset record data pages
        14-23               DF File Password ( zeroes if none )
  (versions >= 21571 only) 
        23-33               View only password (zeroes if none)
        34-35               Number of memo fields in the file. 


    Field Table
    Immediately  following  the File Control Block is a table description  of
    the  fields  in  the  database. The number of entries in  this  table  is
    variable  from 1 to 255 and is specified in bytes 4-5 of the File Control
    Block.  Each  entry in the table immediately follows the previous  entry.
    Each entry is structured as follows:

       Byte Number        Byte Description
         0-1                The size in bytes of the field.  This is a set
                            size and does not vary from record to record.
         2-3                Offset of current field in a record.  Note: the
                            first field in each record is at offset 2,
                            not zero, but after the offset of each
                            field is the offset of the previous field
                            plus the size of the previous field.
         4-5                Key type of the field.   0=unique key; 1=key;
                            2=non-key; 3=external;
         6-7                Data type of the field.  0=text; 1=number(integer)
                            2=scientific notation; 3=TRUE/FALSE;
                            4=untyped; 5=decimal; 6=date;
                            7=time,8=memo; 
         8-9                copy of  2-3 above
        10-11               Precision ( ie digits to right of the decimal
                            point ) of the field if it is numeric.
                            If field type is memo, then this is the max
                            size of a memo. 
        12-22               Name of the field.  The first byte is the
                            number of characters in the following
                            name (10 chars max in name).
        23                  Wasted byte to get fields on word boundaries.
        
    Data Control Block (DCB)
    The  next  structure  in  the  file is the  Data  Control  Block  which
    consists  of  up  to 1560 bytes and whose current size is  specified  in
    bytes  8-9  of  the  File Control Block. Note that  the  DCB  does  not
    necessarily  (nor usually) immediately follow the Field Table since the
    Field  Table is of variable size but rather the location of the DCB  is
    specified  in  bytes  10-11 of the FCB. The number found there  is  the
    number  of  512  byte blocks in the .DF file before the  DCB.  The  DCB
    format is as follows:

     Byte Number        Byte Description
       0-3              The number of records currently in the file.
       4-7              "high water mark" of number of records in file.
       8-11             record free space list head
      12-13             which field is auto-increment (0 means none)
      14-17             current Autoinc value (bumped when record added)
      18-21             index page "high water mark" for .IF allocation
      22-25             index page free list head (pointers 1 based numbers)
Version 'BT': 
      26-626            Index tree description table: 
                        Each entry in this table consists of 6 bytes:
                        Byte Number    Description
                         0-3           Root index page number (0 based)
                         4-5           level of root page in tree
Versions > 'BT': 
      26-29             Memo free page list head 
      30-1560           Index tree description table: 
                        Each entry in this table consists of 6 bytes:
                        Byte Number    Description
                         0-3           Root index page number (0 based)
                         4-5           level of root page in tree

    There  is one entry per field in the file whether or not that field  is
    indexed.  If the field is not indexed,  the entry should be filled with
    zeros.


***************************************************************************
***************************************************************************
***************************************************************************


                     SMK and PMK File Structures
                     ===========================


SMK File Structure:
-------------------

 Query text: The first two 512 byte blocks of the file are
   the query text attached to the screen mask. 
   
   Byte Number          Byte Description
      0-1023               Query text attached to the mask 

 Header: The first 31 words of the third block of the mask
   file (bytes 1024 to 1042) are the mask header and contain
   general information about the mask.
   
   Byte Number       Byte Description
      0-1               Version number(currently 2 if query is for a 
                            single file, 3 if there is a join) 
      2-3               Number of entries in mask
      4-5               Number of screen pages in mask
      6-7               Top formula spot used(1-based)
      8-9               Top must-match field(0-based)
     10-11              Number of external value fields
     12-13              Size in words of header section
     14-15              Size in words of mustmatch info
     16-17              Size in words of field format table
     18-19              Size in words of mustmatch value table
     20-21              Block to read field data from 
     22-23              Block to read mustmatch data from
     24-25              Block to read externals from
     26-27              Block to read mask text from
     28-29              Block to get field mapping from
     30-35              reserved for future use
     36-45              Use form password
     46-55              Change form password 
     56-61              Pointers used during execution of program only
     
Formula Table: Following the header information is a table of
   formulas.  The number of entries in this table is variable
   from 0 to 31 and is specified in bytes 6-7 of the header.
   Each entry immediately follows the previous entry. Each
   entry is structured as follows:
   
   If the field evaluated attribute is RANGE, then:
     Byte Number       Byte Description
         0                Length of high range string 
        1-31              High range string
        32                Length of low range string
        33-63             Low range string

   If the field evaluated attribute is DEPENDENT or the
   field kind is EXTERNAL, then:
     Byte Number       Byte Description
         0                Length of expression string 
        1-63              Expression string

 All the rest of the SMK structures are not necessarily contiguous
 nor guaranteed to be in any order, nor even guaranteed to exist
 (for example externals are not always present).  Their location is
 determined by the offset specified in the header. This offset is a
 0-based block offset where a block is defined as 512 bytes. Thus
 if a section begins at block 3, it begins at byte 3*512 = 1536.
 
Field Description Table: This table contains information on the
   formating and attributes of each entry.  It is located at the
   block specified in bytes 20-21 of the header.  It is packed,
   meaning that information is squeezed together by bits instead of
   bytes to save room.  This makes this table a little difficult to
   look at even with a tool such as the debugger or the Norton
   Utilities.  The number of entries in this table is specified by
   bytes 2-3 of the header. Each entry is structured as
   follows(note bit numbers are for each word are numbered 15 14 13
   12 11 10 9 8 7 6 5 4 3 2 1 0):
    
     Word Number   Bit Number       Bit Description
        1             0-6             x(horizontal) position on page
                      7-11            y(vertical) position of page
                      12-15           screen page number
        2              0              0=not mustfill 1=mustfill
                      1-5             Which formula table entry goes 
                                        with this entry
                       6              0=no uppercase 1=allow uppercase               
                       7              0=no decimal   1=allow decimal           
                       8              0=no blanks    1=allow blanks               
                       9              0=no lowercase 1=allow lowercase               
                       10             0=no digits    1=allow digits                  
                       11             0=no punctuation 1=allow punctuation               
                      12-14           0=normal entry 1=autoCalc 
                                      2=form 3=skip 4=dependent
                                      5=autoincrement 6=external
                       15             0=no duplicate 1=duplicate
        3              0-2            7 screen modes(bold etc)
                       3-9            width of entry
                      10-14           numeric precision
                       15             0=not mustmatch 1=mustmatch
        4              0-1            0=left justify 1=right
                                      2=center 3=repeat
                       2-9            Database field number
                      10-14           External table entry
                       15             unused

 Mustmatch Table: This table contains information used for
   mustmatch entries.  It is located at the block specified by
   bytes 22-23 of the header.  The number of entries is specified
   by bytes 8-9 of the header. Each entry is structured as follows:
   
     Byte Number       Byte Description
         0              Length of active file's field name
        1-10            Active file's field name
         11             Length of mustmatch file's field name
       12-21            Mustmatch file's field name
         22             Length of mustmatch file'a name
       23-45            Mustmatch file's name. Includes suffix,
                          may include prefix which is an SPI
                          nickname specified in searching order.
         
Externals Table: This table contains information used for
   external entries.  It is located at the block specified by
   bytes 24-25 of the header.  The number of entries is specified
   by bytes 10-11 of the header. Each entry is structured as follows:
   
     Byte Number       Byte Description
        0-1             Entry in Field Descriptiono table for the 
                          mustmatch field which this external is
                          attached to.
        2-3             Should equal 1 for now. 
        4-5             Entry in field description table describing
                          the attributes for this external.
       6-85             Used during execution of program only.
       
 Identifier Table: This table contains the name of each entry
   in the mask.  It is located at the block specified by
   bytes 28-29 of the header.  The number of entries is specified
   by bytes 2-3 of the header. Each entry is structured as follows:
         
     Byte Number       Byte Description
         0               Length of name
   If the version number in the header is even (ie currently = 2) then
        1-11             FIELDNAME 
   Else (if the version number is odd (ie currently = 3) 
        1-19             FILENAME.FIELDNAME 

 Mask Test: This is the actual text in the screen mask.
   It is located at the block specified by
   bytes 26-27 of the header.  It is simply the text 
   in the SMK each line immediately following the last
   with no wasted characters and 78 characters per line.
   

END SCREEN MASK DESCRIPTION



PMK File Structure:
-------------------

Query text: The first two 512 byte blocks of the file are
   the query text attached to the print mask. 
   
   Byte Number          Byte Description
      0-1023               Query text attached to the mask 

Header: The first 32 words of the third block of the mask
   is header information as follows: 

   Byte Number       Byte Description
      0-11              Used by program only 
     12-13              Printer width for PMK
     14-15              0=no line suppression 1=do line suppression
     16-17              Version number (= 1)
     18-19              Number of levelbreak fields
     20-21              True/False:New page before totals?
     22-23              True/False:New page each record? 
     24-25              True/False:Group header includes 1st rec?
     26-27              True/False:Line between records? 
     28-29              True/False:New page before group?
     30-31              Highest # entries which has been in PMK
     32-33              True/False:New page after totals?
     34-53              Level break table(see below)
     54-63              unused

Level Break Table: This is at byte 34 to 53 of the header. It's 
   structure is that of an array[1 .. 5 (5 is maximum number of
   level breaks allowed in a PMK)] of an array[1 .. 2 (1 is 
   information for printing  a group header section on a
   levelbreak, 2 is information for printing a subtotal section
   on a levelbreak)] of a set 0..15 (there can be up to 15 
   fields sorted at one time in the database).  Thus, each
   levelbreak can be specified as to which of the 15 sort fields
   it is (right now it must be one of the first 5) and whether
   it should cause a group header, subtotal, or both. 

Data: Following the header, the rest of the PMK is the data.
   Each entry in the PMK takes 64 bytes.  Each entry should
   follow immediately after the previous one.  They must be
   grouped according to PMK section (ie header,group header,
   record etc). Within a section, order matters only in that a
   virtual field should be defined before it is reference by
   another field. It is more efficient but not necessary that
   the fields go in a top to bottom/left to right.  Finally,
   each entry is bit packed which may make it hard to look at
   with such tools as the debugger or norton utilities.  Each
   entry is structured as follows(note bit numbers are for each
   word are numbered 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0):
   
     Word Number   Bit Number       Bit Description
        1             0-2             PMK section 0=header, 
                                      1=group header,2=record section
                                      3=subtotals,4=footer,5=totals
                      3               boolean:parenthesize neg numbers? 
                      4-7             y(vertical) coordinate   
                      8-15            width of entry
        2             0               boolean:print currency string?
                      1               boolean:commas every third digit?     
                      2-5             numeric precision
                      6-7             0=justify left,1=right
                                      2=center 3=repeat
                      8-15            x(horizontal) coordinate
        3-31          NA              Value of PMK entry. This is a
                                      string whose first byte is
                                      a length byte telling how many
                                      of the following byte are
                                      actually used.
        32            0               boolean:send superscript sequence? 
                      1               boolean:send subscript sequence?      
                      2               boolean:send normal sequence?      
                      3               boolean:send size 1 sequence?      
                      4               boolean:send size 2 sequence?      
                      5               boolean:send size 3 sequence?      
                      6               boolean:send color 1 sequence?      
                      7               boolean:send color 2 sequence?      
                      8               boolean:send color 3 sequence?      
                      9               boolean:send color 4 sequence?      
                      10              boolean:send bold sequence?      
                      11              boolean:send underline sequence?      
                      12              boolean:send italic sequence?      
                      13              boolean:send high quality sequence?      
                      14-15           unused
END PMK DESCRIPTION 


***************************************************************************
***************************************************************************
***************************************************************************


SUMMARY OF DIF FILE STRUCTURE
=============================

DIF is a trademark of Software Arts Products Corp. which is now
owned by Lotus Development Corp.

                    STRUCTURE OF A HEADER ITEM
================================================================
<TOPIC>                         Token describing header item.
<VECTOR NUMBER>,<NUMERIC VALUE> 0 if applies to header, 0 if no
                                number value.
<STRING VALUE>               null string ("") if no string value.
=================================================================


                      REQUIRED HEADER ITEMS
================================================================
TABLE
0, 1                            1 is the Version number
"<title describing data>"       Can be null string

VECTORS
0, <count>           <count> it the number of fields or columns.
""                              null string

TUPLES
0, <count>             <count> is the number of records or rows.
""                              null string

{optional header items appear here}
-----------------------------------

DATA                    Indicates that following entries are data
0,0
""                              null string

LABEL
<vector #>,<line #>      line # is for multi-line labels; 0 = 1.
"<label>"                     The label.

SIZE                      for db's to allocate fixed size fields
<vector #>,<bytes>              size in bytes.
""                              null string

TRUELENGTH       Portion of vector containing significant values.
<vector #>,<length>             length
""                              null string
================================================================


                        STRUCTURE OF A DATA ITEM
=================================================================
<TYPE INDICATOR>,<NUMERIC VALUE>see below.
<STRING VALUE>              depends on type indicator; see below.

TYPE INDICATOR
     -1           Special     Either BOT (Beginning of Tuple)
                              or EOD (End Of Data).  The Numeric
                              value is 0, and the string value is
                              BOT or EOD.

      0           Numeric     <Numeric Value> contains actual
                              value; this  may optionally contain
                              a leading + or -, a decimal point,
                              and an E cum signed/unsigned
                              exponent.

        STRING VALUES FOR CLASSIFYING NUMERIC (TYPE 0) DATA
----------------------------------------------------------------
<String Value>      meaning       special <numeric value> if any
----------------------------------------------------------------
       V            the default
       NA           not available                      0
       ERROR        invalid calculation                0
       TRUE         boolean value                      1
       FALSE        boolean value                      0
-----------------------------------------------------------------

      1           String      String value contains the string
                              value! Quotation marks optional
                              if value is a token.
=================================================================


***************************************************************************
***************************************************************************
***************************************************************************



                     Open Access Spreadsheet File Format
                     ===================================

OA2 FMD format:
---------------

                             Definition Blocks 
                             =================
                   

     FMDs are block structured files.  A block is 512 bytes.  The minimum 
size of a FMD file is 4 blocks.  These first four blocks of the file con-
tain file definition information and various indexes.  Following is a 
breakdown of the information in the first four blocks.

                                

-----------------------------------Block 0----------------------------------

     offset     name                  type 
     ------     ----                  ----     
                
                fpage0                      
       0          file revision       integer 
                                            
                  m_status                   
       2            high_col          integer 
       4            high_row          integer 
       6            empty_blocks      integer 
       8            groups_alloc      integer 
      10            num_names         integer 
      12            model_serial      integer 
                                       
      14          advance             boolean 
      16          order               boolean 
      18          appl_model          boolean 
      20          password            string[11] 
      
                  def_math
      32            filler            char 
      34            attr              packed array[1..8] of char 
      42            just              (left, center, right, padded) 
                                     
                  def_text           
      44            filler            char 
      46            attr              packed array[1..8] of char 
      54            just              (left, center, right, padded) 
                                     
      56          m_name              array[0..3] of string[23] 
     152          padding             string[57] 
     210          auto_recalc         boolean 
     212          cur_dec_char        char 
     214          need recalc         boolean 
     216          src_format          (f_fmd, f_cmp) 
     218          start_row           integer 
     220          start_col           integer 
     222          strart_window       integer 
     224          margins             array[0..2] of integer 
     230          template_mode       boolean 
     232          not_written_back    boolean 
     234          show_menu           boolean 
     236          definput            integer 
                                     
                  rstat (16 bytes)
     238            current_ok         boolean 
     240            rs_ec              integer
     242            rs_sc              integer
     244            rs_er              integer
     246            rs_sr              integer
     248            rs_g               integer
     250            rs_s               integer
     252            rs_p               integer
                                

     254            widths             array[1..200] of 0..255 
  
     454..511 (not used)
----------------------------------------------------------------------------    
      


------------------------------------Block 1---------------------------------

     offset     name                  type 
     ------     ----                  ----     
                w1                             
                  splits              array[1..5] of    (14 bytes ) 
       0            active            boolean 
       2            split_how         boolean 
       4            leaf_b            boolean 
       6            leaf_a            boolean 
       8            parent            integer 
      10            ch_b              integer 
      12            ch_a              integer 
      
      14          splits[2]...
      
                  window              array[1..6] of   (40 bytes) 
                  
                    w (8 bytes) 
      72              xpos            0..255
      73              ypos            0..255
      74              xmax            0..255
      75              ymax            0..255
      76              xcur            0..255
      77              attr            0..7 
                      curs            boolean 
                      fill            0..4095
                                    
      80            w_col             integer 
      82            w_row             integer 
      84            num_cos           integer 
      86            w_model           integer 
      88            was_model         integer 
      90            link_kind         (horiz, vert, both) 
      92            split             integer 
      94            linked            integer 
      96            lock_col          integer 
      98            lock_row          integer 
     100            unclean           integer 
     102            equat_view        integer 
     104            line_dirty        packed array [0..63] of boolean 
                                 
     112          window[2]... 

                query_record (104 bytes) 
     312          q_type              (q_none, q_extract, q_unique, q_find 
                                       q_hilite, q_delete, q_function, 
                                       q_j_extract, q_j_unique ) 
     
                  inp = var_record (34 bytes) 
     314            lry               integer 
     316            lrx               integer 
     318            uly               integer 
     320            ulx               integer 
     322            st                string[23] 
     346            model             integer 
                                 
     348          out                 var_record 
     382          que                 var_record 
     416          status              var_record
     418          status_on           boolean
     420          cur_data_rec        integer
     422          last_data_rec       integer
     424          cur_out_rec         integer
     426          last_out_rec        integer
                  

     428..511 (not used)
----------------------------------------------------------------------------    



Block 2--------------------------------------------------------------------- 

     offset     name                  type 
     ------     ----                  ----     
                                       
       0        master_index          array[0..199] of integer 
     
     400        name_idx              array[1..2] of integer 
     
     402..511 (not used)
----------------------------------------------------------------------------    



Block 3--------------------------------------------------------------------- 

     offset     record or variable name     
     ------     -----------------------     
  
       0        c_list                packed array [0..145] of char 
    
                graph_record (366 bytes) 
     146          chart_name          string[23] 
     170          column_recs         boolean 
     172          row_lab             var_record 
     206          col_lab             var_record 
     240          g_data              array[1..8] of var_record 
     
     (no extra space)
----------------------------------------------------------------------------    



Groups



     The remainder of the spreadsheet model file is comprised of 2 block
entities known as groups. These groups location in the file is stored in
various indexes.  







Index groups---------------------------------------------------------------- 
     
     offset     name                  type 
     ------     ----                  ----     
                                       
       0        src_block             integer 
       2        primary               integer 
       4        last_access           integer 
       6        g_type                integer 
        
                idx                   array[0..89] of (10 bytes) 
       8          used                packed array[0..35] of boolean
      14          disk_loc            integer 
      16          mem_loc             ^group 

      18        idx[1]... 
     
     908..1019 (not used)        
     
    1020        changed               boolean
    1022        g_model               integer
----------------------------------------------------------------------------    






Master Index: 
------------- 

     The master index array (see block 2) is an array of the block numbers
(always even) of the secondary indexes (aka index groups).  Each secondary
index corresponds to a 60 row by 54 column area of the spreadsheet, as 
shown below:

        1...    54 55...  108      163... 216 
       +----------+----------+... +----------+ 
     1 |          |          |    |          | 
     . |  0       |  50      |    | 150      | 
     : |          |          |    |          | 
       |          |          |    |          | 
    60 |          |          |    |          | 
       +----------+----------+... +----------+ 
    61 |          |          |    |          | 
     . |  1       |  51      |    | 151      | 
     : |          |          |    |          | 
       |          |          |    |          | 
  120  |          |          |    |          | 
       +----------+----------+... +----------+ 
       .          .          .    .          . 
       :          :          :    :          : 
        
       +----------+----------+... +----------+ 
  2941 |          |          |    |          | 
     . |  49      | 99       |    | 199      | 
     : |          |          |    |          | 
       |          |          |    |          | 
  3000 |          |          |    |          | 
       +----------+----------+... +----------+ 

     
     If no entries has been made in one of these areas, the corresponding
block value will be zero.



Index Groups:
------------- 

     Index groups have the following structure:
     
---------------------------------------------------------------------------- 
     
     offset     name                  type 
     ------     ----                  ----     
                                       
       0        src_block             integer 
       2        primary               integer 
       4        last_access           integer 
       6        g_type                integer   ( = 6 ) 
        
                idx                   array[0..89] of (10 bytes) 
       8          used                packed array[0..35] of boolean
      14          disk_loc            integer 
      16          mem_loc             ^group 

      18        idx[1]... 
     
     908..1019 (not used)        
     
    1020        changed               boolean
    1022        g_model               integer
----------------------------------------------------------------------------    


     Each secondary index contains the block numbers of the 90 node groups
associated with 60 by 54 cell spreadsheet area.  Zero values indicate that no
node group exists since no cells are used.  The node groups are indexed as
shown (for secondary #0) below:
  

         1...   6   7...  12       49...  54 
       +----------+----------+... +----------+... 
     1 |          |          |    |          | 
     . |  0       |  10      |    | 80       | 
     : |          |          |    |          | 
       |          |          |    |          | 
     6 |          |          |    |          | 
       +----------+----------+... +----------+... 
     7 |          |          |    |          | 
     . |  1       |  11      |    | 81       | 
     : |          |          |    |          | 
       |          |          |    |          | 
    12 |          |          |    |          | 
       +----------+----------+... +----------+... 
       .          .          .    .          . 
       :          :          :    :          : 
        
       +----------+----------+... +----------+... 
    55 |          |          |    |          | 
     . |  9       | 19       |    | 89       | 
     : |          |          |    |          | 
       |          |          |    |          | 
    60 |          |          |    |          | 
       +----------+----------+... +----------+... 
       :          :          :    :          : 


Node Groups: 
------------ 
     
     Node groups have the following structure: 

--------------------------------------------------------------------------- 
     
     offset     name                  type 
     ------     ----                  ----     
                                       
       0        src_block             integer 
       2        primary               integer 
       4        last_access           integer 
       6        g_type                integer   ( = 5 ) 
        
       8        nd_second             integer
      10        nd_disk_loc           integer
      12        nd_mem_loc            ^group
               
                gr                    array[0..35] of (26 bytes)
      14          chain               array[0..3] of 0..255 
      18          in_degree           integer
      20          value               10 byte floating point
      30          ntype      ..       (empty, text, constant, equation) 
                  njust      ..       (left, cnter, right, padded)
                  mtext      .        boolean 
                  merror     .        boolean 
                  filler_char........ char
      32          attributes          packed_array[1..8] of char  
      
      40        gr[1]... 

     950        num_used              integer 

     952..1019 (not used)                               
     
    1020        changed               boolean
    1022        g_model               integer
----------------------------------------------------------------------------    

     Each node group contains the actual data (fixed size) for  36
spreadsheet entries as shown below.



         1   2   3   4   5    6
       +---+---+---+---+---+----+ 
    1  | 0 | 1 | 2 | 3 | 4 | 5  | 
       +---+---+---+---+---+----+ 
    2  | 6 | 7 | 8 | 9 |10 | 11 | 
       +---+---+---+---+---+----+ 
    3  | 12| 13| 14| 15| 16| 17 | 
       +---+---+---+---+---+----+ 
    4  | 18| 19| 20| 21| 22| 23 | 
       +---+---+---+---+---+----+ 
    5  | 24| 25| 26| 27| 28| 29 | 
       +---+---+---+---+---+----+ 
    6  | 30| 31| 32| 33| 34| 35 | 
       +---+---+---+---+---+----+ 
    

     The nd_disk_loc variable is the block number of the first of
(of possibly 4) string groups associated with that node group.

     mtext and ntype = constant implies that the value field actually
contains a string of up to 9 characters.  mtext and ntype = text implies that
the node contains a text substitution expression ( eg: @a1....@ ).  In this
case, the input line string contains the actual display string and the
"numstring" contains information about the text substitution structured as
follows:
  
      (length byte) (relative_position) (display_length) (token_string)
                    (relative_position) (display_length) (token_string)
                    ...
                    (relative_position) (display_length) (token_string)
      

     For each substitution in a text entry there are threee components:
relative position is the number of characters from the beginning of the start
of the display string or from the last substitution, display_length is the
actual number of characters the substitution accounts for in the display
string, and token string is the token as typed in, for example "@a7.....@".

      merror denotes an invalid numeric expression.

     Equations are stored in a "packed" form with the following rules:
chr(1) is the key for a numeric function.  The byte following the chr(1)
is 32 + the ord of the function where the functions are as follows:

(ERROR, ABS, MIN, STDV, VAR, MEAN, SUM, COUNT, MAX, FV, DEPRY, DEPRD,
 IRR, TABLE, XTRN, PV, PWR, DATE, TIME, LIST, COS, MOD, EXP, TAN, ATAN,
 ASIN, ACOS, ROUND, RANDU, RANDN, VLIST, STAT, DAY, DOFWK, WEEK, MONTH
 YEAR, VPROD, XXXXX, QMIN, QMAX, QSTDV, QVAR, QSUM, QCNT, QMEAN )

     These two bytes replace the function name and the open parenthesis.
Coordinates are denoted by a chr(2) followed by a row word and a column 
word.  

     For example, +sum(1,a1,b2:c3) would be encoded as follows:
     
     (length byte)+(1)(38)1,(2)(01)(01),(2)(02)(02):(2)(03)(03)
     


String Groups:
--------------

     String groups contain the formula or label string entered at the input
line.  Numeric entries generally have a different display string stored in
the string goups.  This string may be empty, as their creation is sometimes
delayed until they are displayed.  st_disk_loc (note: same offset as the
nd_disk_loc variable in a node group) points to the next string group if it
exists.  Stat denotes the way in which the 1 to 4 string groups correspond to
the 36 nodes involved:


        0:     0..35 
        1:     0..17  18..35 
        2:     0..17  18..26  27..35 
        3:     0..8    9..17  18..35
        4:     0..8    9..17  18..26  27..35
        

     The data structure of all string groups is as follows:

---------------------------------------------------------------------------- 
     
     offset     name                  type 
     ------     ----                  ----     
                                       
       0        src_block             integer 
       2        primary               integer 
       4        last_access           integer 
       6        g_type                integer 
        
       8        back_ref              ^group 
      10        st_disk_loc           integer 
      12        st_mem_loc            ^group 
      14        stat                  integer 
      16        size                  integer 
      18        loc                   array[0..35] of integer 
      90        info                  packed array[0..890] of char 
     982        max_loc               integer 

     984..1019 (not used)        
     
    1020        changed               boolean
    1022        g_model               integer
----------------------------------------------------------------------------    





Name groups:

    The name groups disk location is stored in m_names.  Index goes from
1..fpage.num_names and is 0 if it has not been indexed.  Names are stored
in alphabetical order.  The structure of a name group is shown below: 

---------------------------------------------------------------------------- 
     
     offset     name                  type 
     ------     ----                  ----     
                                       
       0        src_block             integer 
       2        primary               integer 
       4        last_access           integer 
       6        g_type                integer 
        
                names                 array[1..50] of (20 bytes)
       8          name_str            string[9]
      18          necol               integer 
      20          nerow               integer 
      22          ns_col              integer 
      24          ns_row              integer 
      26          index               integer 
      
      28        names[2]... 
     
    1008..1019 (not used)        
     
    1020        changed               boolean
    1022        g_model               integer
----------------------------------------------------------------------------    


CMP file format: 

     Cmp file format is a condensed version of a .FMD file.  The first three
blocks of a .CMP file correspond to the block numbers 0, 1 and 3 of the .FMD
file.  Block number 2 of the .FMD file is the master indexa block and is not
saved in a .CMP file.

     Next comes the named areas.  The number of names is stored in the
fpage record (in block 0).  The names are saved in the loc_rec format
one after another alphabetically.  Unlike .FMD format there are no empty
loc_rec records.  

     The rest of the .CMP file corresponds to entries in the spreadsheet.
They are also stored sequentially.  First comes two integers denoting the row
and column of the upcoming node.  Then comes a condensed version of the node
type.  The size of this is is 19 bytes and contains all the information
starting with the value field.  The information before this is only used at
run-time.  Next comes the lit_string stored in normal string format. Finally,
if a text substitution exists, the num_string follows.
 
     The end of a cmp file is denoted by a 0 for the row number of the node. 


***************************************************************************
***************************************************************************
***************************************************************************


                     Open Access Spreadsheet File Format
                     ===================================


OA3 FMD format:
---------------
                             Definition Blocks 
                             =================

     FMDs are block structured files.  A block is 512 bytes.  The minimum 
size of a FMD file is 6 blocks.  These first six blocks of the file con-
tain file definition information and various indexes.  Following is a 
breakdown of the information in the first six blocks.

-----------------------------------Block 0----------------------------------

     offset     name                  type 
     ------     ----                  ----     
                fpage0                      
       0          file revision       integer 
                                            
                  m_status                   
       2            high_col          integer 
       4            high_row          integer 
       6            empty_blocks      integer 
       8            groups_alloc      integer 
      10            num_names         integer 

      12          unused_0            integer 
      14          advance             boolean 
      16          order               boolean 
      18          unused_1            boolean 
      20          password            string[11] 
      
                  def_math
      32            filler            char 
      34            attr              packed array[1..6] of char 
      40            modes             pu_modeset (printer modes) 
      44            just              (left, center, right, padded)
        
                  def_text           
      46            filler            char 
      48            attr              packed array[1..6] of char 
      54            modes             pu_modeset (printer modes) 
      58            just              (left, center, right, padded)       
                                     
      60          m_name              array[0..3] of string[23] 
     156          auto_recalc         boolean 
     158          cur_dec_char        char 
     160          need recalc         boolean 
     162          src_format          (f_fmd, f_cmp) 
     164          start_row           integer 
     166          start_col           integer 
     168          strart_window       integer 
     170          margins             array[0..2] of integer 
     176          template_mode       boolean 
     178          not_written_back    boolean 
     180          show_menu           boolean 
     182          definput            integer 
                                     
                  rstat (16 bytes)
     184            current_ok         boolean 
     186            rs_ec              integer
     188            rs_sc              integer
     190            rs_er              integer
     192            rs_sr              integer
     194            rs_g               integer
     196            rs_s               integer
     198            rs_p               integer
                                

     200          chartname            string[23]
     224
     
     224          widths               packed array [1..270] of 0..255;  

     494..511 (not used)
----------------------------------------------------------------------------
      

------------------------------------Block 1---------------------------------

     offset     name                  type 
     ------     ----                  ----     
       0        nm_idx                array [1..2] of integer 
                
                w1                             
                  splits              array[1..5] of    (14 bytes ) 
       4            active            boolean 
       6            split_how         boolean 
       8            leaf_b            boolean 
      10            leaf_a            boolean 
      12            parent            integer 
      14            ch_b              integer 
      16            ch_a              integer 
      
      18          splits[2]...
      
                  window              array[1..6] of   (40 bytes) 
                  
                    w (8 bytes) 
      76              xpos            0..255
      77              ypos            0..255
      78              xmax            0..255
      79              ymax            0..255
      80              xcur            0..255
      81              attr            0..7 
                      curs            boolean 
                      fill            0..4095
                                    
      84            w_col             integer 
      86            w_row             integer 
      88            num_cos           integer 
      90            w_model           integer 
      92            was_model         integer 
      94            link_kind         (horiz, vert, both) 
      96            split             integer 
      98            linked            integer 
     100            lock_col          integer 
     102            lock_row          integer 
     104            unclean           integer 
     106            equat_view        integer 
     108            line_dirty        packed array [0..63] of boolean 
                                 
     116          window[2]... 

                query_record (104 bytes) 
     316          q_type              (q_none, q_extract, q_unique, q_find 
                                       q_hilite, q_delete, q_function, 
                                       q_j_extract, q_j_unique ) 
     
                  inp = var_record (34 bytes) 
     318            lry               integer 
     320            lrx               integer 
     322            uly               integer 
     324            ulx               integer 
     326            st                string[23] 
     350            model             integer 
                                 
     352          out                 var_record 
     386          que                 var_record 
     420          status              var_record
     422          status_on           boolean
     424          cur_data_rec        integer
     426          last_data_rec       integer
     428          cur_out_rec         integer
     430          last_out_rec        integer
                  

     432..511 (not used)
----------------------------------------------------------------------------

Block 2 thru Block 5 ------------------------------------------------------- 

     offset     name                  type 
     ------     ----                  ----     
                                       
       0        master_index          array[0..829] of integer

  MASTER_INDEX spans all of blocks 2 and 3, and half of block 5 

Block 5 
     256        c_list                packed array [0..145] of char
     
     402 - 511 (not used) 

----------------------------------------------------------------------------

Master Index: 
------------- 

     The master index array (see block 2 - 5) is an array of the block 
numbers (always even) of the secondary indexes (aka index groups).  Each 
secondary index corresponds to a 60 row by 54 column area of the 
spreadsheet, as shown below:

        1...    54 55...  108      217... 270 
       +----------+----------+... +----------+ 
     1 |          |          |    |          | 
     . |  0       |  166     |    | 664      | 
     : |          |          |    |          | 
       |          |          |    |          | 
    60 |          |          |    |          | 
       +----------+----------+... +----------+ 
    61 |          |          |    |          | 
     . |  1       |  167     |    | 665      | 
     : |          |          |    |          | 
       |          |          |    |          | 
  120  |          |          |    |          | 
       +----------+----------+... +----------+ 
       .          .          .    .          . 
       :          :          :    :          : 
        
       +----------+----------+... +----------+ 
  9901 |          |          |    |          | 
     . |  165     | 331      |    | 829      | 
     : |          |          |    |          | 
       |          |          |    |          | 
  9960 |          |          |    |          | 
       +----------+----------+... +----------+ 

     
     If no entries has been made in one of these areas, the corresponding
block value will be zero.

----------------------------------------------------------------------------
Groups

     The remainder of the spreadsheet model file is comprised of 2 block
entities known as groups. These groups location in the file is stored in
various indexes.  


Index Groups:
------------- 

     Index groups have the following structure:
     
---------------------------------------------------------------------------- 
     
     offset     name                  type 
     ------     ----                  ----     
                                       
       0        src_block             integer 
       2        primary               integer 
       4        last_access           integer 
       6        g_type                integer   ( = 6 ) 
        
                idx                   array[0..89] of (10 bytes) 
       8          used                packed array[0..35] of boolean
      14          disk_loc            integer 
      16          mem_loc             ^group 

      18        idx[1]... 
     
     908..1023 (not used)        
     
    1023        g_model               0..127
                changed               boolean
    1024 
----------------------------------------------------------------------------

     Each secondary index contains the block numbers of the 90 node groups
associated with 60 by 54 cell spreadsheet area.  Zero values indicate that no
node group exists since no cells are used.  The node groups are indexed as
shown (for secondary #0) below:
  

         1...   6   7...  12       49...  54 
       +----------+----------+... +----------+... 
     1 |          |          |    |          | 
     . |  0       |  10      |    | 80       | 
     : |          |          |    |          | 
       |          |          |    |          | 
     6 |          |          |    |          | 
       +----------+----------+... +----------+... 
     7 |          |          |    |          | 
     . |  1       |  11      |    | 81       | 
     : |          |          |    |          | 
       |          |          |    |          | 
    12 |          |          |    |          | 
       +----------+----------+... +----------+... 
       .          .          .    .          . 
       :          :          :    :          : 
        
       +----------+----------+... +----------+... 
    55 |          |          |    |          | 
     . |  9       | 19       |    | 89       | 
     : |          |          |    |          | 
       |          |          |    |          | 
    60 |          |          |    |          | 
       +----------+----------+... +----------+... 
       :          :          :    :          : 


Node Groups: 
------------ 
     
     Node groups have the following structure: 

--------------------------------------------------------------------------- 
     
     offset     name                  type 
     ------     ----                  ----     
                                       
       0        src_block             integer 
       2        primary               integer 
       4        last_access           integer 
       6        g_type                integer   ( = 5 ) 
        
       8        nd_second             integer
      10        nd_disk_loc           integer
      12        nd_mem_loc            ^group
               
                gr                    array[0..35] of (26 bytes)
      14          chain0              integer
      16          chain               array[1..2] of 0..255 
      18          in_degree           integer
      20          value               10 byte floating point
      30          ntype      ..       (empty, text, constant, equation) 
                  njust      ..       (left, cnter, right, padded)
                  mtext      .        boolean 
                  merror     .        boolean 
      31          filler_char         char
      32          attributes          packed_array[1..6] of char  
      38          nmodes              pu_modeset (printer modes)
      
      42        gr[1]... 

    1022        num_used              0..127 {0..35}
    1023        g_model               0..127 {0..3}
                changed               boolean
    1024 
----------------------------------------------------------------------------

     Each node group contains the actual data (fixed size) for  36
spreadsheet entries as shown below.


         1   2   3   4   5    6
       +---+---+---+---+---+----+ 
    1  | 0 | 1 | 2 | 3 | 4 | 5  | 
       +---+---+---+---+---+----+ 
    2  | 6 | 7 | 8 | 9 |10 | 11 | 
       +---+---+---+---+---+----+ 
    3  | 12| 13| 14| 15| 16| 17 | 
       +---+---+---+---+---+----+ 
    4  | 18| 19| 20| 21| 22| 23 | 
       +---+---+---+---+---+----+ 
    5  | 24| 25| 26| 27| 28| 29 | 
       +---+---+---+---+---+----+ 
    6  | 30| 31| 32| 33| 34| 35 | 
       +---+---+---+---+---+----+ 
    

     The nd_disk_loc variable is the block number of the first of
(of possibly 4) string groups associated with that node group.

     mtext and ntype = constant implies that the value field actually
contains a string of up to 9 characters.  mtext and ntype = text implies that
the node contains a text substitution expression ( eg: @a1....@ ).  In this
case, the input line string contains the actual display string and the
"numstring" contains information about the text substitution structured as
follows:
  
      (length byte) (relative_position) (display_length) (token_string)
                    (relative_position) (display_length) (token_string)
                    ...
                    (relative_position) (display_length) (token_string)
      

     For each substitution in a text entry there are threee components:
relative position is the number of characters from the beginning of the start
of the display string or from the last substitution, display_length is the
actual number of characters the substitution accounts for in the display
string, and token string is the token as typed in, for example "@a7.....@".

      merror denotes an invalid numeric expression.

     Equations are stored in a "packed" form with the following rules:
chr(1) is the key for a numeric function.  The byte following the chr(1)
is 32 + the ord of the function where the functions are as follows:

(ERROR, ABS, MIN, STDV, VAR, MEAN, SUM, COUNT, MAX, FV, DEPRY, DEPRD,
 IRR, TABLE, XTRN, PV, PWR, DATE, TIME, LIST, COS, MOD, EXP, TAN, ATAN,
 ASIN, ACOS, ROUND, RANDU, RANDN, VLIST, STAT, DAY, DOFWK, WEEK, MONTH
 YEAR, VPROD, XXXXX, QMIN, QMAX, QSTDV, QVAR, QSUM, QCNT, QMEAN )

     These two bytes replace the function name and the open parenthesis.
Coordinates are denoted by a chr(2) followed by a row word and a column 
word.  

     For example, +sum(1,a1,b2:c3) would be encoded as follows:
     
     (length byte)+(1)(38)1,(2)(01)(01),(2)(02)(02):(2)(03)(03)


String Groups:
--------------

     String groups contain the formula or label string entered at the input
line.  Numeric entries generally have a different display string stored in
the string goups.  This string may be empty, as their creation is sometimes
delayed until they are displayed.  st_disk_loc (note: same offset as the
nd_disk_loc variable in a node group) points to the next string group if it
exists.  Stat denotes the way in which the 1 to 4 string groups correspond to
the 36 nodes involved:

        0:     0..35 
        1:     0..17  18..35 
        2:     0..17  18..26  27..35 
        3:     0..8    9..17  18..35
        4:     0..8    9..17  18..26  27..35
        

     The data structure of all string groups is as follows:

---------------------------------------------------------------------------- 
     
     offset     name                  type 
     ------     ----                  ----     
                                       
       0        src_block             integer 
       2        primary               integer 
       4        last_access           integer 
       6        g_type                integer 
        
       8        back_ref              ^group 
      10        st_disk_loc           integer 
      12        st_mem_loc            ^group 
      14        stat                  integer 
      16        size                  integer 
      18        loc                   array[0..35] of integer 
      90        info                  packed array[0..890] of char 
     982        max_loc               integer 

     984..1023 (not used)
     
    1023        g_model               0..127
                changed               boolean
    1024 
----------------------------------------------------------------------------


Name groups:

    The name groups disk location is stored in m_names.  Index goes from
1..fpage.num_names and is 0 if it has not been indexed.  Names are stored
in alphabetical order.  The structure of a name group is shown below: 

---------------------------------------------------------------------------- 
     offset     name                  type 
     ------     ----                  ----     
                                       
       0        src_block             integer 
       2        primary               integer 
       4        last_access           integer 
       6        g_type                integer 
        
                names                 array[1..50] of (20 bytes)
       8          name_str            string[9]
      18          necol               integer 
      20          nerow               integer 
      22          ns_col              integer 
      24          ns_row              integer 
      26          index               integer 
      
      28        names[2]... 
     
    1008..1023 (not used)        

    1023        g_model               0..127
                changed               boolean
    1024 
----------------------------------------------------------------------------

CMP file format: 

     Cmp file format is a condensed version of a .FMD file.  The first 
three blocks of a .CMP file correspond to the block numbers 0, 1 and 
half of 5 of the .FMD file.  Block number 2 - 5 of the .FMD file is the 
master index blocks and is not saved in a .CMP file.

     Next comes the named areas.  The number of names is stored in the
fpage record (in block 0).  The names are saved in the loc_rec format
one after another alphabetically.  Unlike .FMD format there are no empty
loc_rec records.  

     The rest of the .CMP file corresponds to entries in the spreadsheet.
They are also stored sequentially.  First comes two integers denoting the row
and column of the upcoming node.  Then comes a condensed version of the node
type.  The size of this is is 19 bytes and contains all the information
starting with the value field.  The information before this is only used at
run-time.  Next comes the lit_string stored in normal string format. Finally,
if a text substitution exists, the num_string follows.
 
     The end of a cmp file is denoted by a 0 for the row number of the node. 


***************************************************************************
***************************************************************************
***************************************************************************


MISCALLE.SPI FILE STRUCTURE
===========================
                                                
The miscalle is comprised of a one block list of screen
configurations followed by corresponding one block records.
The records are of type CRT0 as described in the MISCE.SPI
file structure definition. 


bytes           / data type
--------------------------------------------------------
0-511           / array [0-31] string[15]  
512-eof         / crt0 records
-------------------------------------------------------- 


***************************************************************************
***************************************************************************
***************************************************************************


     -------------------------------------------------------
      This is the definition of the contents of MISCE.SPI   
      MISCE.SPI is a 4 block file, each block corresponds   
      to a 'crtx' type below.                               
     -------------------------------------------------------
 

TYPE 
      trlrType    = packed array [0..5] of char;
      rngType     = packed array [0..6] of char;
      keyxtype    = packed array [0..63] of char;
      keyntype    = packed array [0..63] of char;
      scArray     = array [0..11] of String[9];
      funcArray   = array [0..7] of string[15];
      ssextype    = (dotfmd, dotcmp, dotwks);
     
     
     crt0 = packed record
            {  0} version    : INTEGER;
            {  2} screenID   : string[15];
            { 18} keyxlate   : keyxType;
            { 82} keyin      : keynType;
            {146} trailer    : trlrType;
            {152} range      : rngType;
            {160} height     : 0..255;
            {161} width      : 0..255;
            {162} printable  : set of char;
            {194} termshut   : string[15];
            {210} terminit   : string[15]; 
            {226} outlchars  : packed array [0..10] of char;
            {238} orthomodes : packed array [0..7] of char;
            {246} functstr   : funcArray;
            {374} sc_action  : scArray;
            {494} normatb    : integer;
            {496} curratb    : integer;
            {498} chosenatb  : integer;
            {500} {unused}
            {512} 
                END;


     crt1 = packed record
             {  0} howdate     : char;
             {  1} decchar     : char;
             {  2} collate_seq : packed array [char] OF char;
             {258} uppers      : packed array [0..53] of char;
             {312} lowers      : packed array [0..53] of char;
             {366} scratchname : string[23];
             {390} modemname   : string[23];
             {414} servename   : string[25];  {only use 23 of the 25}
             {440} ldevnum     : integer;
             {442} ldevname    : array [0..5] of string[7];
             {490} pdev        : string[15];
             {506} ldevunit    : packed array [0..5] of char;
             {512}
                END;
     
     crt2 = record
           {  0}  lvolnum    : integer;
           {  2}  lvolname   : array [0..7] of string[7];
           { 66}  linfotable : array [0..7] of integer;
           { 82}  freeoffset : integer;
           { 84}  pathnames  : packed array[0..427] of char;
           {512}
                END;
     crt3 = packed record
           {  0}  tmowner    : string[25];
           { 26}  lacardsc   : string[10];                
           { 38}  lasortsc   : string[11];                
           { 50}  tzone1     : string[15];                
           { 66}  tzone2     : string[15];
           { 82}  tzoff1     : integer;
           { 84}  tzoff2     : integer;
           { 86}  tmtmask    : boolean;
           { 86}  allhrz     : boolean;
           { 86}  tz1        : boolean;
           { 86}  tz2        : boolean;
           { 88}  defscrtxt  : string[23];
           {112}  defapptname: string[23];
           {136}  defrollname: string[23];
           {160}  defcvname  : string[23];
           {184}  defapint   : integer;
           {186}  defssext   : ssextype;
           {188}  wpdefsuf   : integer;
           {190}  wpdefdoc   : string[23];
           {214}  defadmdm   : string[23];
           {238}  defgd      : integer;{0=IBM,1=Herc,2=Colr+,3=ega4,4=ega16}
           {240}  defappmenu : string[23]; {default app.mnu file for network}
           {254}  defspchk   : integer;
           {256}  defsstime  : integer;
           {258}
                END;


***************************************************************************
***************************************************************************
***************************************************************************


OA2 MACRO (.MON) FILE STRUCTURE
===============================

byte 0-1 = # of bytes used in file. This is necessary because macros are always written to block boundarys.

The rest of the file contains the characters typed during the 
LEARN mode of the macro. Function keys are designated by a 
chr(0) followed by a character. Refer to this table for the
function key - character mappings:

<help>        = ?   <up>          = ^           
<menu>        = M   <down>        = v           
<print>       = H   <left>        = <           
<prt_scr>     = #   <right>       = >           
<scr_off>     = k   <word_fwd>    = W           
<search>      = /   <word_back>   = w           
<F5>          = G   <home>        = V           
<Alt-F5>      = g   <end>         = &           
<F6>          = ~   <jump_left>   = {           
<Alt-F6>      = U   <jump_right>  = }           
<F7>          = S   <pg_up>       = p           
<Alt-F7>      = s   <pg_down>     = P           
<F8>          = R   <tab>         = T           
<Alt-F8>      = "   <back_tab>    = t           
<F9>          = L   <ins>         = i           
<Alt-F9>      = l   <del>         = d           
<F10>         = !   <backspace>   = B           
<Alt-F10>     = %   <line_ins>    = I           
<ret>         = N   <line_del>    = D           
<undo>        = X   


Macro PAUSE and MESSAGE modes:
------------------------------

        macro PAUSE mode = 00 22  00 22 
                          <macro><macro> 
         
        macro MESSAGE mode = 00 22 [message chars] 00 22
                            <macro>               <macro>
                    
End Of File:
  At the end of the chars used is a macro character (00 22). 


***************************************************************************
***************************************************************************
***************************************************************************


INFOE.PRT FILE STRUCTURE
========================

INFOE.PRT files are divided into two areas, a directory
area and a data area. 

byte        / area 
-------------------------------------------------
   0-1023   / directory area - type: PRTINFO record
1024-EOF    / data area      - type: PU_INFO records 
-------------------------------------------------

----------------------------------------------------------------- 
DIRECTORY AREA DATA TYPES


  PRTINFO = RECORD
     NUMB  : INTEGER;
     NAMES : ARRAY[0..0] OF NAMEREC;
  END;                  

    NAMEREC = PACKED RECORD
       ID     : STRING[15]; { PASCAL strings have a length byte  } 
                            { at offset 0 so ID actually uses 16 } 
                            { bytes of storage.                  }
       STATUS : PU_STATUS;
       BLKOFF : 0..255;     { Block offset of PU_INFO record.    }
       BYTOFF : 0..255;     { Byte offset into above BLKOFF.     }
    END;            
         
    PU_STATUS = PACKED RECORD
       ISFILE       : boolean;   {is this a file?}
       ISCONS       : boolean;   {is this the console?}
       ISSERIAL     : boolean;
       ISPARALLEL   : boolean;
       ISGRAPHABLE  : boolean;   {is graphics possible}
       ISPLOTTER    : boolean;   {is this a plotter?}
       SINGLESHEET  : boolean;   {pause after every sheet}
       COLORCHG     : boolean;   {pause for color change}
       PRINTWHEEL   : boolean;   {pause for type change}
       PRTCLASS     : 0..127;
    END;         


DATA AREA TYPES
---------------

PU_Info = record
{00}  size         : integer;        {amount of memory used in words}
{02}  name         : string[15];     {name of printer}
{18}  comport      : PU_comrec;      {stores comport info}
{20}  hasmodes     : PU_modeset;     {modes of this printer}
{22}  hascommands  : PU_commset;     {commands of this printer}
{24}  status       : PU_status;      {current status}
{26}  paper        : PU_paper;       {current paper size}
{30}  plines       : PU_points;      {how far to print}
{32}  indentsize   : PU_points;      {how much to indent}
{34}  curmode      : PU_modeset;     {current mode of printer}
{36}  numwide      : integer;        {how many label columns}
{38}  sizes        : PU_sizes;       {sizes of diferent sizes}
{54}  grstuff      : PU_grinfo;
{76}  numbchars    : integer;      {number of chars to be translated.}
{78}  seqindex     : array[0..30] of integer;
{140} translation  : packed array[0..0] of char;
{???}                              {variable sized buffer area}
   end;
  
{ PU_modes are modes that can tell how a string is to be printed.
  The info record tells which modes are available.}
PU_modes = (PU_superscript, PU_subscript,
            PU_size1, PU_size2, PU_size3, PU_size4,
            PU_color1, PU_color2, PU_color3, PU_color4,
            PU_bold, PU_underline, PU_italic, PU_highquality);
            
PU_modeset = set of PU_modes;
          
{ These are commands available to operate on the printer.}
PU_comms = (PU_lineup, PU_linedown, PU_newpage, PU_halfline,
               PU_backspace, PU_return, PU_prtinit, PU_final,
{beginline =>} PU_res1, PU_res2, PU_res3, PU_endline,   
               PU_prepgraph, PU_shutgraph, PU_user1, PU_user2,
               PU_none);
               
PU_commset = set of PU_lineup..PU_user2;

PU_status = packed record
   isfile       : boolean;   {is this a file?}
   iscons       : boolean;   {is this the console?}
   isserial     : boolean;
   isparallel   : boolean;
   isgraphable  : boolean;   {is graphics possible}
   isplotter    : boolean;   {is this a plotter?}
   singlesheet  : boolean;   {pause after every sheet}
   colorchg     : boolean;   {pause for color change}
   printwheel   : boolean;   {pause for type change}
   prtclass     : 0..127;
end;
         
{ Points are used as the standard for measuring most types of print.
  Points are used to measure the size of fonts, the paper, and
  different sized prints. A point is defined as 1/72 of an inch.}
PU_points = integer;  

PU_paper = record         {how paper is sized}
   height  : PU_points;
   width   : PU_points;
end;

{stores print size for different types}
PU_sizes = array[PU_size1..PU_size4] of record
   xsize : PU_points;
   ysize : PU_points;
end;

{various integers needed for grphics}
PU_grinfo = packed record
   positbase   : integer;   {base of graphics beginline}
   pos         : 0..255;    {graphics beginline position}
   datalen     : 0..255;    {graphics beginline data length}
   groupsize   : integer;   {graphics number of pins}
   fontheight  : integer;   {graphics font pixel height}
   grfxint     : array[0..5] of integer;   {extra graphics integers}
   revpins     : boolean;   {graphics pins reversed?}
   positorder  : boolean;   {graphics beginline reversed?}
   grbool1     : boolean;   {extra graphics booleans}
   grbool2     : boolean;
   grbool3     : boolean;
   grbool4     : boolean;
   grbool5     : boolean;
   grbool6     : boolean;
   grxtra      : 0..255;
end;


PU_comrec = packed record
   port      : 0..15;    {set up by IOComm}
   baudrate  : 0..7;     {110,150,300,600,1200,2400,4800,9600}
   numDBits  : 0..3;     {5,6,7,8}
   numSBits  : 0..1;     {1,2}
   parity    : 0..3;     {none,odd,even}
   xonxoff   : boolean;
   etxack    : boolean;
   fill      : 0..3;
end;

