<details><summary>Table of Contents</summary>

- [Introduction](#Introduction)
- [Preliminary Notes](#Preliminary-Notes)
  - [Pseudo-Code Format](#Pseudo-Code-Format)
  - [Source Format](#Source-Format)
    - [Block Structure](#Block-Structure)
    - [Orthography](#Orthography)
  - [Differences Between Versions](#Differences-Between-Versions)
  - [Invariant Order](#Invariant-Order)
  - [Common Semantic Elements](#Common-Semantic-Elements)
  - [Analysis Technique](#Analysis-Technique)
- [Device Library File Formats](#Device-Library-File-Formats)
  - [The Header](#The-Header)
  - [The Directory File](#The-Directory-File)
  - [Device Library Member Files](#Device-Library-Member-Files)
    - [Discriminator](#Discriminator)
    - [Device File Format](#Device-File-Format)
      - [The Source Format](#The-Source-Format)
      - [The Binary Format](#The-Binary-Format)
      - [Sizing Data](#Sizing-Data)
    - [Driver File Format](#Driver-File-Format)
      - [The Source Format](#The-Source-Format-1)
      - [The Binary Format](#The-Binary-Format-1)
      - [Sizing Data](#Sizing-Data-1)
    - [Font File Format](#Font-File-Format)
      - [The Source Format](#The-Source-Format-2)
      - [The Binary Format](#The-Binary-Format-2)
      - [Sizing Data](#Sizing-Data-2)
  - [Padding](#Padding)
</details>

#
Introduction
------------

The binary device file format is used for two distinct purposes:

1.  To encode :DEVICE, :DRIVER, and :FONT blocks.
2.  To provide a directory file.

The directory file is used to allow device names of up to 78 characters to be used, even on file systems which restrict file name length (*i.e.*, FAT). The 78-character limit is documented in the [WGML 4 Reference](WGML-References#reference1).

The attributes that are used to build the entries in the directory file are discussed in [Common Attributes](WGML-Common-File-Blocks#Common-Attributes).

Preliminary Notes
-----------------

### Pseudo-Code Format

The decoded structures in the binary device files are expressed in a "sort-of C struct" form which should make the structure found clear to anyone reading this Wiki. They may or may not be valid "C" code.

These are not the structs that are used in the code. The binary device files contain many [count bytes and designators](WGML-Meta-Data#Designators) which simply are not needed by wgml after the binary device file has been parsed. Indeed, in many instances, their only role in parsing the binary device file is to be read and checked to be certain that they have the correct value.

Fields are referred to in these ways:

-   If the field is part of the struct under discussion, the field name is used by itself.
-   If the field is part of another struct, then the struct name is prepended with **.** as a separator.
-   If the field is part of an instance of another struct (that is, of a field in yet another struct) then the parent field's name is prepended with **.** as a separator.

The last two cases are distinguishable: struct names start with capital letters, field names start with lower case.

### Source Format

Many of the discussions of the specifics of the binary device file format include notes on the actual form of the source code accepted by gendev 3.33 and gendev 4.1. This section is intended to summarize common rules discovered governing that form, so that they need not be repeated in each section and sub-section.

All of the statements made here were confirmed by actual test. Many of them match statements made in the [WGML 4 Reference](WGML-References#reference1) or the README file produceable from the [WGML 3.33 Update](WGML-References#reference2) and should be taken as confirming the documentation, not as new discoveries. Those which contradict the documentation or which provide information not included in the documentation are new discoveries.

#### Block Structure

These statements apply unless otherwise noted in the discussion of a particular block:

-   Although the documentation and all available source files show each entry on its own line, this is not required and multiple elements can be placed on the same line.
-   The attributes which are present can appear in any order.
-   For blocks that include both attributes and sub-blocks, all of the attributes which are present must appear before any sub-block or this error message is seen:

<!-- -->

    AT--001: Required attribute not found.

-   Blocks which produce CodeBlocks (:VALUE, etc) must not be empty or this error message appears:

<!-- -->

    SN--034: Expecting text before termination tag.

#### Orthography

These statements apply unless otherwise noted in the discussion of a particular block:

-   Except for character and string values, each character may be upper or lower case individually. This applies to tags, attribute names, and predefined attribute values. NOTE: it is yet to be determined if character and string values match regardless of case.
-   Characters can be entered as such but must be delimited when used as an attribute value; if not delimited then either this message:

<!-- -->

    SN--001: Number is too large or contains invalid characters

or this message:

    AT--002: Missing attribute value

appears, apparently depending on whether or not the character entered can be interpreted by gendev as a "number". NOTE: if the character happens to be a decimal digit, then it will be indistinguishable from and so taken as a decimal number.

-   Characters used in :INTRANS, :OUTTRANS, and :WIDTH blocks are neither attributes nor attribute values, and should be entered without delimiters.
-   Characters can be entered as decimal numbers, with no delimiters or prefixes.
-   Characters can be entered as hexadecimal numbers, with no delimiters but with a **$** prefix.
-   Decimal or hexadecimal numbers (used to represent characters) which are delimited are treated as one or more characters.
-   If more than one character is entered, then this error message appears:

<!-- -->

    AT--007: The attribute value cannot have more than one character

-   Character strings can always use delimiters.
-   Character strings with no embedded spaces do not need to be delimited in most contexts; the known exception is that the value of attribute **font** of the :BOX or :UNDERSCORE block must be delimited if a character string is used, presumably to distinguish them from a font number, or this error message results:

<!-- -->

    SN--001: Number is too large or contains invalid characters

-   Undelimited character strings with embedded spaces produce this error message:

<!-- -->

    AT--001: Required attribute not found

Since more than one attribute can be placed on the same line, the first word after the space cannot be distinguished from the next attribute name.

These statements apply to both character and string delimiters:

-   Either single or double quotes may be used.
-   The quote on each end must be the same type (single or double), or this error message appears:

<!-- -->

    AT--005: Missing or invalid closing quote on attribute

Further experimentation with one attribute, **font\_out\_name1**, showed that

    $B5$C4'fred'$C3

was encoded by gendev as

    $B5$C4fred$C3

just as if the entire string were delimited or, since it does not have spaces, no delimiters were used at all. More intriguingly,

    'testfon_outname1'$C5

was encoded by gendev as

    testfon_outname1

suggesting that gendev treats a closing delimiter as the end of the string. These details will have to be further explored when gendev is being recreated.

### Differences Between Versions

There are some differences between version 3.33 and version 4.1. This section provides a summary. For more information, see the sections discussing the details of the binary device file format.

-   The [file headers](WGML-COP-Files#The-Header) are different.
-   The [directory files](WGML-COP-Files#The-Directory-File) are slightly different.
-   These numeric attributes are encoded as two-byte unsigned integers in version 3.33 and as four-byte unsigned integers in version 4.1:

<!-- -->

    For :DEVICE blocks:           3.33 upper limit  4.1 upper limit
        page_width                $CCCF             $7FFFFFFF
        page_depth                $CCCF             $7FFFFFFF
        horizontal_base_units     $CCCF             $7FFFFFFF
        vertical_base_units       $CCCF             $7FFFFFFF
    For :PAGESTART blocks:
        x_start                   $CCCF             $7FFFFFFF
        y_start                   $CCCF             $7FFFFFFF
    For :PAGEOFFSET blocks:
        x_start                   $CCCF             $7FFFFFFF
        y_start                   $CCCF             $7FFFFFFF
    For :FONT blocks:
        line_height               $CCCF             $7FFFFFFF
        line_space                $CCCF             $7FFFFFFF
        scale_basis               $7FFFFFFF         $7FFFFFFF
        scale_min                 $7FFFFFFF         $7FFFFFFF
        scale_max                 $7FFFFFFF         $7FFFFFFF
        char_width                $CCCF             $7FFFFFFF
    For :DBOX, :HLINE, and :VLINE blocks:
        thickness                 (not determined)

-   The [:WIDTH block](WGML-Font-File-Blocks#The-WIDTH-Block) comes in two sizes, and the larger size is different in version 3.33 than it is in version 4.1.

### Invariant Order

The order in which items appear in a binary device file does not depend on the order in which the various components of the encoded block appear in the source file. It does not matter if the order in the source file is fixed or if it can vary.

The order shown for all fields of all structs shown is the only order in which those fields appear. All of these fields are required in the sense that, if they are not present, the file contains a clear indicator that they are not present, which is to say that all fields are present, if only vistigially. This is the reason that a file error or premature end-of-file while reading a binary device file is the same as an error in the format: the format requires that all fields be present, if only vistigially, so their complete absence is a formatting error.

### Common Semantic Elements

Parsing a binary device file involves reducing it to semantically meaningful units, and the bulk of this page (and associated pages) deals with those units in detail. These units are composed of semantic elements, which can be classified into three groups:

1.  Character data, which can hold any byte value.
2.  String data, which cannot include null bytes.
3.  8-bit, 16-bit, and 32-bit unsigned integers.

Unless otherwise noted in the detailed discussions, character data has these properties:

-   Each character has its own unique significance, even when multiple characters appear in sets.

Unless otherwise noted in the detailed discussions, string data has these properties:

-   The significance of a string lies in the entire string taken as a unit, not in the individual characters.
-   Most strings are preceeded by a count byte; any "terminating null" in this case is part of the next semantic element.
-   Some strings are instead terminated by a null byte, which is part of the string considered as a semantic element in the binary device file.

Unless otherwise noted in the detailed discussions, integers have these properties:

-   The values are unsigned.
-   8-bit values are used to count the number of following bytes, which may be character or numeric data as well as strings or even sementic units containing several semantic elements.
-   Internal data, such as counts of repeated semantic units, are encoded by 16-bit values.
-   Attributes which are encoded as 16-bit values in version 3.33 are encoded as 32-bit values in version 4.1.

### Analysis Technique

The basic tool in analyzing the binary device file format was a small set of test source files. These files changed so rapidly that no attempt was made to preserve their various versions.

Attributes with character or string values were located in the binary device file by providing them with a known value in the source file and looking for it in the binary device file, and then changing it in the source file to confirm that the value found in the binary device file also changed.

Attributes with numeric values were located using the decimal equivalents of such values as "0x1111", "0x2222" and so on for 16-bit integers and "0x11111111", "0x22222222" and so on for 32-bit integers (note that each attribute was given a distinct value) and then looking for those values in the binary file. Once the location were found, since I am using a x86 processor which stores integers in "little-endian" format, values such as "0x1122" or "0x11223344" were used to confirm that they are, in fact, stored as integers and not just as arrays of bytes.

The remaining unsigned integers are produced by gendev all on its own, so it is not possible to be certain that they are, in fact, unsigned integers. It is, perhaps, a personal bias that I identify these as integers rather than as arrays of bytes. Unless a big-endian version of one or more binary device files appears, it will never be possible to be certain that these identifications are correct.

As each major type of binary device file was analyzed, the corresponding test file was reworked to form a set of test files which could be used with wgml to determine which [CodeBlocks](WGML-Device-Functions#The-CodeBlock-Structure) are invoked at what points in creating the output file. This was used to determine, for those [:INIT blocks](WGML-Driver-File-Blocks#The-INIT-Block) which produce multiple CodeBlocks, the order in which the CodeBlocks are invoked. This led to the interesting discovery that they are invoked by wgml 4.0 in the order given in the source, and that the CodeBlocks encoding :FONTVALUE blocks are invoked multiple times, which, insofar as the struct used for parsing is concerned, meant that each CodeBlock had to be identified as encoding a :VALUE block or a :FONTVALUE block as well as having their order preserved. I expect this sort of investigation to be very helpful when the time comes to produce the output side of wgml.

Device Library File Formats
---------------------------

### The Header

Here is what wdump -b produces when applied to the wgmlst.cop file in ow\\docs\\doc\\whelp:

    0000:  02 0C 00 0B 56 34 2E 31  20 50 43 2F 44 4F 53 04        V4.1 PC/DOS
    0010:  02 00 00 00 01 02 08 77  68 65 6C 70 64 72 76 08           whelpdrv
    0020:  57 48 45 4C 50 44 52 56  01 01 05 77 68 65 6C 70    WHELPDRV   whelp
    0030:  05 57 48 45 4C 50 00 00  00 00 00 00 00 00 00 00     WHELP
    0040:  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00

Examining other binary device files shows that every binary device file has a header with this structure:

    COPHeader {
        uint8_t   count = { 0x02 };
        uint16_t  version;
        uint8_t   text_version_length;
        char      text_version[ text_version_length ];
        uint8_t   type;
    };

The field **count** gives the number of bytes in the field **version**. It can, however, also be used as a "magic value", since any file starting with a different byte cannot be a binary device file.

The the field **version** differs between version 3.33 and version 4.1:

-   version 3.33: 0x000a
-   version 4.1: 0x000c

and so is taken to encode the file version. Testing shows that gendev and wgml from one version will not work with binary device files produced by gendev from the other version.

The field **length** contains the length of the field **text\_version**.

The field **text\_version** differs between version 3.33 and version 4.1:

-   version 3.33: V3.33 PC/DOS
-   version 4.1: V4.1 PC/DOS

and clearly contains human-readable text giving the version number.

The field **type** is also a count field, but the values it can contain can also be used to indicate the type of the file:

-   version 3.33: 0x02: directory file
-   either version: 0x03: device/driver/font file
-   version 4.1: 0x04: directory file

while the true significance of the value is:

-   0x02: a two-byte count of directory entries
-   0x03: a three-byte discriminator ("DEV", "DRV" or "FON")
-   0x04: a four-byte count of directory entries

Ending the header with what is, in fact, the count byte for the next field may appear strange. This does make sense when parsing the file is considered: if the function parsing the header simply indicated that it was working on a valid binary device file, each calling function (and there are four of them) would then have to determine for itself whether or not that file was a directory file. It is simpler and more efficient to make this determination in the function parsing the header.

The research program cfcheck.exe has verified that all available binary device files have either 0x02, 0x03, or 0x04 as the value of the count field **type**. Research programs cfparse.exe and copparse.exe have thoroughly exercised the header parsing code.

### The Directory File

Take another look at the contents of the wgmlst.cop file in ow\\docs\\doc\\whelp:

    0000:  02 0C 00 0B 56 34 2E 31  20 50 43 2F 44 4F 53 04        V4.1 PC/DOS
    0010:  02 00 00 00 01 02 08 77  68 65 6C 70 64 72 76 08           whelpdrv
    0020:  57 48 45 4C 50 44 52 56  01 01 05 77 68 65 6C 70    WHELPDRV   whelp
    0030:  05 57 48 45 4C 50 00 00  00 00 00 00 00 00 00 00     WHELP
    0040:  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00

At first glance, the file (after the header) is as simple as this:

    DirFile {
        uint32_t  count;
        DirEntry  entries[count];
    };

The file illustrated is a version 4.1 directory file. Comparison with a version 3.33 directory file gives this structure for the version 3.33 directory file:

    DirFile {
        uint16_t  count;
        DirEntry  entries[count];
    };

At this point, the page [Directory File Format](WGML-Directory-File-Format) might be worth examining. It explains the actual format currently found in the directory file ow\\docs\\gml\\syslib\\wgmlst.cop.

The value of the field **count** is the number of entries, at least, that is what it clearly contained in the directory files I produced with either version of gendev (the directory file discussed in [Directory File Format](WGML-Directory-File-Format) is, as in so much else, an exception to this).

The compact directory file entries are the defined name/member name pairs which it is the entire purpose of a directory file to provide. They have this structure:

    CompactDirEntry {
        uint16_t  type = < 0x0101 | 0x201 | 0x401 >;
        uint8_t   defined_name_length;
        char      defined_name[defined_name_length];
        uint8_t   member_name_length;
        char      member_name[member_name_length];
    };

The extended directory file entries have this structure:

    ExtendedDirEntry {
        uint16_t  metatype = 0x0001;
        uint16_t  type = < 0x0101 | 0x201 | 0x401 >;
        uint8_t   defined_name_length;
        char      defined_name[defined_name_length];
        uint16_t  marker = 0x0001;
        uint8_t   member_name_length;
        char      member_name[member_name_length];
        uint16_t  preview = < 0x0101 | 0x201 | 0x401 >;
    };

These fields are common to the two structures:

        uint16_t  type = < 0x0101 | 0x201 | 0x401 >;
        uint8_t   defined_name_length;
        char      defined_name[defined_name_length];
        uint8_t   member_name_length;
        char      member_name[member_name_length];

The values of the field **type** have these values:

-   0x101 for a binary device file encoding a :DEVICE block.
-   0x201 for a binary device file encoding a :DRIVER block.
-   0x401 for a binary device file encoding a :FONT block.

The program cfparse.exe has confirmed that, in each case where the binary device file exists, the **type** and the [Discriminator](#Discriminator) are consistent with the interpretations given above.

The fields **defined\_name\_length** and **member\_name\_length** provide the number of characters in the associated string.

The field **defined\_name** encodes the value of the attribute **defined\_name** and field **member\_name** encodes the value of the attribute **member\_name**. These attributes are discussed in the section [Common Attributes](WGML-Common-File-Blocks#Common-Attributes).

These fields are unique to the extended structure:

        uint16_t  metatype = 0x0001;
        uint16_t  marker = 0x0001;
        uint16_t  preview = < 0x0101 | 0x201 | 0x401 >;

-   The field **metatype** indicates that this is an extended rather than a compact DirEntry structure.
-   The field **marker** always has the same value, but it is not clear why it is needed.
-   The values of the field **preview** have the same meaning as the values of the field **type** but match the value of the field **type** field of the *following* DirEntry.

The page [Directory File Format](WGML-Directory-File-Format) should be consulted if more information on the extended structure is needed.

### Device Library Member Files

The entire point of a device library is to provide files encoding information used by wgml to format a document for a particular device. The term used for all such files up to this section has been "binary device file". However, now that the directory file has been examined, the term "binary member file" will be used to refer to any of the three remaining types of binary device file. Thus, up to this point, the terms "directory file" and "binary member file" refer to the two main varieties of binary device files.

The three types of binary member files, each corresponding to a particular source code block, are:

-   A **device** file describes the device.
-   A **driver** file provides code which, when executed, will produce the proper commands to control the device.
-   A **font** file describes a particular font, usually for use with a specific device or set of devices.

When these terms are used by themselves, they should be understood to refer to the *concepts* rather than any specific file. When **source** or **binary** is prepended, then they should be understood to refer to the source format or to the binary format (respectively). When **file** is appended, then the they should be understood to refer to an actual file containing either the source or the binary data, unless "source" or "binary" is prepended to indicate that the reference is specific. Thus, in this section, a "binary device file" is a binary member file which encodes a :DEVICE block describing the device.

Since both version 3.33 and version 4.1 headers use the same type byte (0x03) for these files, and the directory files use the same types (0x101, 0x201 and 0x401) to identify them, it should come as no surprise that there are very few differences between the two versions. A summary of those differences can be found [here](#Differences-Between-Versions).

#### Discriminator

The first item in each binary member file is a three-byte discriminator:

    char  discriminator[3] =
    <'D','E','V' for a device,
     'D','R','V' for a driver, or
     'F','O','N' for a font>

gendev does check to see that a source file whose defined name already exists in the directory file has the same member name as found for that defined name in the directory file, but whether it checks that the value in the field **DirEntry.type** is consistent with whether the member source file being processed is a device, driver, or font file is not known at this time -- and, even if it did, checking the descriminator of the existing file would appear to be pointless, since that file will be overwritten by a new one based on the block being processed.

wgml always knows what type of binary member file it is searching for: the only defined name that can correspond to a :DEVICE block is the defined name entered with the DEVICE command line option; the only defined name that can correspond to a :DRIVER block is the one given as the value of the attribute **driver\_name** (which is an attribute found only in a :DEVICE block); and the only defined names that can correspond to :FONT blocks are those given as the values of the various attributes **font** or **fontname** (which attributes are found only in a :DEVICE block).

The discriminator, then, can be treated as a final sanity check: if it is the value expected, the file is to be processed; if not, an error is to be reported.

#### Device File Format

##### The Source Format

The :DEVICE block was changed from the description in [WGML 4 Reference](WGML-References#reference1) by the README file produceable from the [WGML 3.33 Update](WGML-References#reference2). The result of this is rather disjointed, so I will be exploring the source file format as well as the binary file format.

All of the statements made describing the requirements imposed on the :DEVICE block by gendev were confirmed by actual test. Many of them match statements made in the documentation or the README and should be taken as confirming the documentation, not as new discoveries.

Due to the size and complexity of the device formats, a separate page, [Device File Blocks](WGML-Device-File-Blocks), will be used to explore the blocks included in the :DEVICE block.

Except as noted, the version 4.1 and version 3.33 source and binary formats for the device file are identical. And, as will be seen, the differences can be detected without having to know the version of the binary file being parsed.

This is the :DEVICE block:

    :DEVICE
       Attributes
       :PAUSE Block
       :DEVICEFONT Block
       :DEFAULTFONT Block
       :FONTPAUSE Block
       :BOX Block
       :UNDERSCORE Block
       :PAGESTART Block
       :PAGEOFFSET Block
       :INTRANS Block
       :OUTTRANS Block
    :eDEVICE.

[Device File Blocks](WGML-Device-File-Blocks) uses the tags (or "Attributes") to identify the blocks.

The README documents the removal of the :RULE block, which used the tags :RULE and :eRULE and which is no longer allowed, and the changes to the :BOX block (using the tag :DBOX instead of :BOX, which is confusing since :DBOX is a valid tag used in :DRIVER blocks), but the presence of the :PAGEOFFSET block, :INTRANS block, and :OUTTRANS block is not documented in either the [WGML 4 Reference](WGML-References#reference1) or in the wgml 3.33 README as possible blocks inside a :DEVICE block; instead, they were discovered by examining existing source files containing :DEVICE blocks. The structure of the :INTRANS block and of the :OUTTRANS block are documented as part of the :FONT block. The :PAGEOFFSET block is not documented at all (except for an error message for a missing :ePAGEOFFSET tag).

These included blocks are required (the error triggered by each if absent is also shown):

-   The Attributes:

<!-- -->

    AT--001: Required attribute not found.

-   The :BOX block:

<!-- -->

    SN-054: Expecting :box tag.

-   The :DEFAULTFONT block:

<!-- -->

    SN--021: Must have a :defaultfont with font=0.

-   The :DEVICEFONT block is required because the font names which are used by the :DEFAULTFONT block (at least one of which must be present) and which may be used by the :BOX block must also be used in a :DEVICEFONT block:

<!-- -->

    SN-019: Fontname not specified in :devicefont.

-   The :FONTPAUSE block is required for every :DEVICEFONT block which provides a name for the attribute **fontpause** (the same value must appear in the attribute **type** of the :FONTPAUSE block). Note that an empty string can be used for the attribute **fontpause** of the :DEVICEFONT block, in which case no :FONTPAUSE block is required.

<!-- -->

    SN--022: The fontpause in :devicefont has no match in :fontpause.

These included blocks are completely optional:

-   The :INTRANS block
-   The :OUTTRANS block
-   The :PAGEOFFSET block
-   The :PAGESTART block
-   The :PAUSE block
-   The :UNDERSCORE block

These included blocks can have multiple instances:

-   The :DEFAULTFONT block
-   The :DEVICEFONT block
-   The :FONTPAUSE block
-   The :INTRANS block
-   The :OUTTRANS block
-   The :PAUSE block

Extensive tests of block ordering revealed this fact:

    All blocks present must be in the order shown.

The details (potentially useful in creating gendev) are:

-   If the :PAUSE block follows the :DEVICEFONT block, this error message is produced:

<!-- -->

    SN-054: Expecting :box tag.

and, if it follows the :BOX block, this error message results:

    SN--043: Expecting :edevice tag

-   If the :DEVICEFONT block whose value for the attribute **fontname** matches the value for the attribute **fontname** used by a :DEFAULTFONT block follows that :DEFAULTFONT block, or if the :DEVICEFONT block whose value for the attribute **fontname** matches the value for the attribute **font** used by the :BOX block follows the :BOX block, then this error message results:

<!-- -->

    SN-019: Fontname not specified in :devicefont.

-   If a :DEVICEFONT block whose fontname is not used by a :DEFAULTFONT block is placed after all of the :DEFAULTFONT blocks but before the :BOX block, this error message is produced:

<!-- -->

    SN-054: Expecting :box tag.

-   A :DEVICEFONT block whose fontname is not used anywhere else which is placed after the :BOX block produces this error message:

<!-- -->

    SN--043: Expecting :edevice tag

-   A :DEFAULTFONT block which is placed after the :BOX block produces this error message:

<!-- -->

    SN--043: Expecting :edevice tag

-   A :FONTPAUSE block which is placed before all :DEVICEFONT blocks produces this error message:

<!-- -->

    SN-054: Expecting :box tag.

-   A :FONTPAUSE block which is placed after the :BOX block produces this error message:

<!-- -->

    SN--043: Expecting :edevice tag

-   A :RULE block placed before the :BOX block produces this error message:

<!-- -->

    SN-054: Expecting :box tag.

when placed after the :BOX block it produces this error message:

    SN--043: Expecting :edevice tag

this shows that a :RULE block is no longer allowed in a :DEVICE block.

-   If the :BOX block is placed in front of any :PAUSE block or the :DEVICEFONT block whose value for the attribute **fontname** matches the value for the attribute **font** value in the :BOX block, then this error message results:

<!-- -->

    SN-019: Fontname not specified in :devicefont.

-   If the :BOX block is placed after all :PAUSE block and after the :DEVICEFONT Block whose value for the attribute **fontname** matches the value for the attribute **font** value in the :BOX block, but before the required :DEFAULTFONT block,

this error message results on the :DEFAULTFONT line of the first :DEFAULTFONT block:

    SN--043: Expecting :edevice tag

-   If the :BOX block is placed after all :PAUSE blocks and after all :DEVICEFONT blocks and after all :DEFAULTFONT blocks, then this error message results on the :FONTPAUSE line of the first :FONTPAUSE block:

<!-- -->

    SN--043: Expecting :edevice tag

-   If the :BOX block is placed after the :UNDERSCORE block, the :PAGESTART block, the :PAGEOFFSET block, an :INTRANS block, or an :OUTTRANS block, then this error message appears:

<!-- -->

    SN-054: Expecting :box tag.

-   If the :UNDERSCORE block, the :PAGESTART block, the :PAGEOFFSET block, an :INTRANS block, or an :OUTTRANS block is placed anywhere before the :BOX block, then this error message appears:

<!-- -->

    SN-054: Expecting :box tag.

-   If the :UNDERSCORE block is placed after the :PAGESTART block, the :PAGEOFFSET block, an :INTRANS block, or an :OUTTRANS block then this error message appears:

<!-- -->

    SN--043: Expecting :edevice tag

-   If the :PAGESTART block is placed after the :PAGEOFFSET block, an :INTRANS block, or an :OUTTRANS block then this error message appears:

<!-- -->

    SN--043: Expecting :edevice tag

-   If the :PAGEOFFSET block is placed after an :INTRANS block or an :OUTTRANS Block, then error message appears:

<!-- -->

    SN--043: Expecting :edevice tag

-   If an :INTRANS Block is placed after an :OUTTRANS Block, then this error message appears.

<!-- -->

    SN--043: Expecting :edevice tag

Testing produced these additional results:

-   This error message:

<!-- -->

    SN--043: Expecting :edevice tag

appears if more than one instance of the Attributes, the :BOX block, the :UNDERSCORE block, the :PAGESTART block, or the :PAGEOFFSET block is placed in the source file.

##### The Binary Format

Now we come to the binary format used to encode the above structure. [Device File Blocks](WGML-Device-File-Blocks) contains the format of the blocks in the resulting binary device file, usually as part of the description of the corresponding source block. The exceptions are:

-   The FunctionsBlock, which is a Variant A FunctionsBlock as discussed in [Device Functions](WGML-Device-Functions), encodes the :VALUE blocks of both the :PAUSE blocks and the :FONTPAUSE blocks.
-   The PageGeometryBlock, as discussed in [Device File Blocks](WGML-Device-File-Blocks), encodes both the :PAGESTART block and the :PAGEOFFSET block.
-   The TranslationBlock, as discussed in [Device File Blocks](WGML-Device-File-Blocks), encodes both the :INTRANS blocks and the :OUTTRANS blocks.
-   The attributes **defined\_name** and **member\_name** and the :INTRANS block and the :OUTRANS block are discussed in [Common File Blocks](WGML-Common-File-Blocks).

Here is the overall format of the binary device file, starting with the first byte after the discriminator:

    DeviceFile {
        Attributes         attributes;
        uint16_t           next_codeblock;
        PagegeometryBlock  pagegeometry;
        BoxBlock           box;
        UnderscoreBlock    underscore;
        TranslationBlock   translation;
        DefaultfontBlock   defaultfonts;
        FunctionsBlock     functions;
        PauseBlock         pauses;
        DevicefontBlock    devicefonts;
    }

The field **next\_codeblock** requires some explanation. This is the same sort of value found in the fields **pauses.start\_pause**, **pauses.document\_pause**, **pauses.docpage\_pause**, **pauses.devpage\_pause**, and **devicefont.devicefonts\[\].font\_pause**: it is the sum of the values of all fields **functions.codeblocks\[\].count**.

Now that it is known that the compiled code in field **CodeBlock.function** is, on its highest level, a linked list with a termination indicator, so that the length of the field is not needed to interpret it, a possible use for the field **next\_codeblock** appears: perhaps wgml is using it to allocate a block of memory, copying the **CodeBlock.function** fields into it in order, and then using the values in the fields **pauses.start\_pause**, **pauses.document\_pause**, **pauses.docpage\_pause**, **pauses.devpage\_pause**, and **devicefont.devicefonts\[\].font\_pause** as offsets into this block.

This structure has these properties:

-   It is correct for both version 3.33 and version 4.1.
-   Every field is always present, whether the corresponding sub-block was present in the source file or not.
-   Every field is always present in the order shown.

##### Sizing Data

This table shows the number of bytes allocated for the cop\_device object, the number of bytes actually used, and the size of each binary device file in the Open Watcom repository development branch:

    Device File:   Allocated   Used    File Size
    HELP         2048             530    560
    PS       4096            3324   2480
    TASA         2048             530    560
    TERM         2048             686    720
    WHELP        2048             531    560

This table shows the number of bytes allocated for the cop\_device object, the number of bytes actually used, and the size of each binary device file produced by gendev 4.1 from the source files provided in the [WGML 3.33 Update](WGML-References#reference2):

    Device File:   Allocated   Used    File Size
    ASA             2048             529    560
    DIA630          2048             579    640
    ELQ850DR        2048             829    880
    ELQ805LQ        2048             808    800
    HPFAXSYS        2048            1798   1600
    HPLASER        11264           10333   8160
    HPLASRII       13312           12424   9760
    HPLASRPL       11264           10568   8320
    HPLPLEGL       11264           10566   8320
    MLT             2048             559    640
    MLTEXP          2048             576    640
    PCGRAPH         2048             609    640
    PCMATRIX        2048             571    640
    PROX24E         2048             732    800
    PS              4096            3268   2480
    QUME            2048             634    640
    TASA            2048             530    560
    TERM            2048             686    720
    TTY             2048             529    560
    X2700           2048             853    880

The code currently begins by allocating 2048 bytes and then increases the block, if necessary, by multiples of 1024. The above suggests that an initial value of 1024 and an increase of 3072 (for PS) would work as well (or better, since PS would then require only one reallocation) for the devices actually in use. However, it appears that realloc() could be used to shrink each the cop\_device instance to the actual size needed, freeing the additional space, in which case starting at 4096 would be fastest for the devices used by Open Watcom since, for those devices, no expansion would be needed.

#### Driver File Format

##### The Source Format

The :DRIVER block was changed from the description in [WGML 4 Reference](WGML-References#reference1) by the README file produceable from the [WGML 3.33 Update](WGML-References#reference2). The result of this is rather disjointed, so I will be exploring the source file format as well as the binary file format.

All of the statements made describing the requirements imposed on the :DRIVER block by gendev were confirmed by actual test. Many of them match statements made in the documentation or the README and should be taken as confirming the documentation, not as new discoveries.

Due to the size and complexity of the driver formats, a separate page, [Driver File Blocks](WGML-Driver-File-Blocks), will be used to explore the blocks included in the :DRIVER block.

Except as noted, the version 4.1 and version 3.33 source and binary formats for the driver file are identical. And, as will be seen, the differences can be detected without having to know the version of the binary file being parsed.

This is the :DRIVER block:

    :DRIVER
      Attributes
      :INIT Block
      :FINISH Block
      :NEWLINE Block
      :NEWPAGE Block
      :HTAB Block
      :FONTSTYLE Block
      :FONTSWITCH Block
      :PAGEADDRESS Block
      :ABSOLUTEADDRSS Block
      :HLINE Block
      :VLINE Block
      :DBOX Block
    :eDRIVER

[Driver File Blocks](WGML-Driver-File-Blocks) uses the tags (or "Attributes") to identify the blocks.

The README documents the removal of the :BOLDSTART, :BOLDEND, :UNDERSTART, and :UNDEREND blocks, their replacement with the :FONTSTYLE block, and that a :NEWLINE block is no longer required "if :ABSOLUTE is specified". The :FONTSTYLE Block is not documented at all (except for two error messages: SN-084 and SN-088).

These included blocks are required (the error triggered by each if absent is also shown):

-   The Attributes:

<!-- -->

    AT--001: Required attribute not found

-   The :NEWPAGE block:

<!-- -->

    SN--033: Expecting :newpage tag

-   Either an :ABSOLUTEADDRESS block or a :NEWLINE block with an attribute **advance** value of "1" is required. If there is no :ABSOLUTEADDRESS block and no :NEWLINE block, then this error message results:

<!-- -->

    DF--011: Need a newline with an advance of 1

These included blocks are completely optional:

-   The :DBOX block
-   The :FINISH block
-   The :FONTSTYLE block
-   The :FONTSWITCH block
-   The :HLINE block
-   The :HTAB block
-   The :INIT block
-   The :PAGEADDRESS block
-   The :VLINE block

These included blocks can have multiple instances:

-   The :FINISH block
-   The :FONTSTYLE block
-   The :FONTSWITCH block
-   The :INIT block
-   The :NEWLINE block

The :FINISH block and the :INIT block can have at most two instances; the others which can have multiple instances can have as many as needed.

Extensive tests of block ordering show these results:

-   Although the [WGML 4 Reference](WGML-References#reference1) states that "\[w\]hen \[the blocks\] are specified, they must be in the order shown in \[the figure showing the structure\]", exhaustive (and exhausting) testing shows that the blocks can, in fact, occur in any order whatsoever, so long as they are all placed after the Attributes.

The phrase "any order whatsoever" means exactly what it says:

-   If two :INIT blocks are present, it does not matter whether the block with the value START for the attribute **place** comes before or after the block with the value DOCUMENT for the attribute **place**.
-   If two :FINISH blocks are present, it does not matter whether the block with the value END for the attribute **place** comes before or after the block with the value DOCUMENT for the attribute **place**.
-   If more than one :NEWLINE block is present, they can be in any order by the value of the attribute **advance**.
-   Whenever more than one instance of the same included block is present, the instances do not have to be grouped in any fashion: each instance can be placed anywhere in the file, before or after any instance of any included block, provided only that the Attributes come first.

Testing produced these additional results:

-   Including any of the :BOLDSTART, :BOLDEND, :UNDERSTART, or :UNDEREND blocks produces this error message at the start of the first which is encountered:

<!-- -->

    SN--036: Expecting :edriver tag

this shows that these blocks are no longer allowed in a :DRIVER block.

-   Using a value other than START or DOCUMENT for the attribute **place** in an :INIT block produces this error:

<!-- -->

    AT--003: Invalid attribute value

-   A second :INIT block with the value START or DOCUMENT for the attribute **place** produces this statement:

<!-- -->

    Place value was already used.

and this error message:

    AT--004: Attribute already found

-   Using a value other than END or DOCUMENT for the attribute **place** in a :FINISH block produces this error:

<!-- -->

    AT--003: Invalid attribute value

-   A second :FINISH block with the value END or DOCUMENT for the attribute **place** produces this statement:

<!-- -->

    Place value was already used.

and this error:

    AT--004: Attribute already found

-   The values for the attribute **advance** of the :NEWLINE block, when more than one block is present, need not be contiguous.
-   Multiple :FONTSWITCH blocks may be placed in the source file; however, if more than one :FONTSWITCH block has the same value for the attribute **type**, this error message results:

<!-- -->

    SN--030: Duplicate :fontswitch type

-   Multiple :FONTSTYLE blocks may be placed in the source file; however, if more than one :FONTSTYLE block has the same value for the attribute **type**, this error message results:

<!-- -->

    SN--084: Duplicate :fontstyle type

-   There can be at most one :PAGEADDRESS block; if a second :PAGEADDRESS block is encountered, this error results:

<!-- -->

    SN--066: More than one :pageaddress specified

-   There can be at most one :ABSOLUTEADDRESS block; if a second :ABSOLUTEADDRESS block is found, this error message appears:

<!-- -->

    SN--067: More than one :absoluteaddress specified

-   There can be at most one :HLINE block; if a second :HLINE block is found, this error message appears:

<!-- -->

    SN--075: More than one :hline specified

-   There can be at most one :VLINE block; if a second :HLINE block is found, this error message appears:

<!-- -->

    SN--076: More than one :vline specified

-   There can be at most one :DBOX block; if a second :DBOX block is found, this error message appears:

<!-- -->

    SN--077: More than one :dbox specified

##### The Binary Format

Now we come to the binary format used to encode the above structure. [Driver File Blocks](WGML-Driver-File-Blocks) contains the format of the blocks in the resulting binary driver file, usually as part of the description of the corresponding source block. The exceptions are:

-   The various FunctionsBlock variants, and the CodeBlock structure, are discussed in [Device Functions](WGML-Device-Functions).
-   The attributes **defined\_name** and **member\_name** are discussed in the section [Common Attributes](WGML-Common-File-Blocks#Common-Attributes).

Here is the overall format of the binary driver file, starting with the first byte after the discriminator:

    DriverFile {
        Attributes       attributes;
        PageAddressBlock pageaddress;
        InitFuncs        inits;
        FinishFuncs      finishes;
        NewlineFuncs     newlines;
        FunctionsBlock   unknown;
        FunctionsBlock   newpage;
        FunctionsBlock   htab;
        FontswitchFuncs  fontswitches;
        FontstyleGroup   fontstyles;
        FunctionsBlock   absoluteaddress;
        HlineBlock       hline;
        VlineBlock       vline;
        DboxBlock        dbox;
    };

Fields of type **FunctionsBlock** are all Variant A FunctionsBlocks.

The field **unknown** is a blank P-buffer. While other possibilities doubtless exist, I suspect one of these is the correct explanation:

-   There may be an unknown block that can occur in a :DRIVER but for which we have neither documentation nor example.
-   This may have been where the :BOLDSTART, :BOLDEND, :UNDERSTART, and :UNDEREND blocks were encoded, when they were allowed in a :DRIVER block, if they were encoded in a single FunctionsBlock of some sort.

This structure has these properties:

-   It is correct for both version 3.33 and version 4.1.
-   Every field is always present, whether the corresponding sub-block was present in the source file or not.
-   Every field is always present in the order shown.

##### Sizing Data

This table shows the number of bytes allocated for the cop\_driver object, the number of bytes actually used, and the size of each binary driver file in the Open Watcom repository development branch:

    Device File:   Allocated   Used    File Size
    HELPDRV        2048             710    1520
    PSDRV          8192            8074    9120
    TASADRV        2048             874    1920
    TERMDRV        2048             325    1600
    WHELPDRV       3072            2586    3920

This table shows the number of bytes allocated for the cop\_driver object, the number of bytes actually used, and the size of each binary driver file produced by gendev 4.1 from the source files provided in the [WGML 3.33 Update](WGML-References#reference2):

    Device File:   Allocated   Used    File Size
    ASADRV         2048             856    1840
    D630DRV        2048            1352    2560
    DR850DRV       2048            1556    2560
    HPLDRV         2048            1377    2240
    HPLPDRV        3072            2976    4000
    HPLPLDRV       3072            2976    4000
    LQ850DRV       2048            1881    3120
    MLTDRV         2048            1535    2400
    MLTEDRV        2048            1942    2800
    PCMADRV        2048            1083    2000
    PSDRV          8192            7368    8320
    QUMEDRV        2048            1633    2800
    TASADRV        2048             874    1920
    TERMDRV        2048             313    1520
    TTYDRV         2048             844    1920
    X24EDRV        2048            1478    2560
    X2700DRV       2048            1963    2640

The code currently begins by allocating 2048 bytes and then increases the block, if necessary, by multiples of 1024. The above suggests that an initial value of 3072 (for WHLPDRV) and an increase of 5120 (for PS) would work well for the drivers actually in use. However, it appears that realloc() could be used to shrink each the cop\_driver instance to the actual size needed, freeing the additional space, in which case starting at 8192 would be fastest for all of the drivers listed above, whether used by Open Watcom or not, since no expansion would be needed.

#### Font File Format

##### The Source Format

The :FONT block was changed from the description in [WGML 4 Reference](WGML-References#reference1) by the README file produceable from the [WGML 3.33 Update](WGML-References#reference2). Although the :FONT block is so simple that the result of this can not really be called "disjointed", I will still be exploring the source file format as well as the binary file format.

All of the statements made describing the requirements imposed on the :FONT block by gendev were confirmed by actual test. Many of them match statements made in the documentation or the README and should be taken as confirming the documentation, not as new discoveries.

Although the :FONT block is not nearly as complicated as either the :DEVICE or the :DRIVER block, a separate page, [Font File Blocks](WGML-Font-File-Blocks), will nevertheless be used to explore the blocks included in the :FONT block.

Except as noted, the version 4.1 and version 3.33 source and binary formats for the font file are identical. And, as will be seen, the differences can be detected without having to know the version of the binary file being parsed.

This is the :FONT block:

    :FONT
       Attributes
       :WIDTH Block
       :INTRANS Block
       :OUTTRANS Block
    :eFONT.

[Font File Blocks](WGML-Font-File-Blocks) uses the tags (or "Attributes") to identify the blocks.

The README documents the removal of the attribute **mono\_space\_width** from the Attributes.

The manual gives this info (in reference to the :WIDTH, :INTRANS and :OUTTRANS Blocks):

    Each of the character definition blocks are optional, and may be
    specified more tha[n] once and in any order. If specified, they
    must follow the font attributes.

Which aptly describes the situation, when emended as shown.

##### The Binary Format

Now we come to the binary format used to encode the above structure. [Font File Blocks](WGML-Font-File-Blocks) contains the format of the blocks in the resulting binary device file, usually as part of the description of the corresponding source block. The exceptions are:

-   The [CharacterDescriptionBlock](WGML-Font-File-Blocks#The-CharacterDescriptionBlock-Structure), as discussed in [Font File Blocks](WGML-Font-File-Blocks), encodes the :INTRANS blocks, the :OUTTRANS blocks, and the :WIDTH blocks.
-   The attributes **defined\_name** and **member\_name** and the :INTRANS block and the :OUTRANS block are discussed in [Common File Blocks](WGML-Common-File-Blocks).

Here is the overall format of the binary font file, starting with the first byte after the discriminator:

    FontBlock {
        Attributes                 attributes;
        CharacterDescriptionBlock  characterBlock;
    }

At this level of abstraction, this format is not very complicated at all. The CharacterDescriptionBlock, as discussed in [Font File Blocks](WGML-Font-File-Blocks), compensates for this by being rather intricate.

##### Sizing Data

This table shows the number of bytes allocated for the cop\_font object, the number of bytes actually used, and the size of each binary font file in the Open Watcom repository development branch:

    Font File:  Allocated   Used   File Size
    MONO01          2048              52     80
    PSAB            2048            1092   1120
    PSABO           2048            1099   1120
    PSAD            2048            1092   1120
    PSADO           2048            1099   1120
    PSBD            2048            1089   1120
    PSBDI           2048            1095   1120
    PSBL            2048            1090   1120
    PSBLI           2048            1096   1120
    PSCB            2048              65     80
    PSCO            2048              60     80
    PSCOB           2048              68     80
    PSCOBO          2048              72     80
    PSHN            2048            1093   1120
    PSHNB           2048            1098   1120
    PSHNBO          2048            1105   1120
    PSHNO           2048            1101   1120
    PSHV            2048            1086   1120
    PSHVB           2048            1091   1120
    PSHVBO          2048            1098   1120
    PSHVO           2048            1094   1120
    PSNB            2048            1098   1120
    PSNBI           2048            1104   1120
    PSNI            2048            1100   1120
    PSNR            2048            1099   1120
    PSPB            2048            1090   1120
    PSPBI           2048            1096   1120
    PSPI            2048            1092   1120
    PSPR            2048            1091   1120
    PSSHADE         2048              52     80
    PSSYM           3072            2519   2000
    PSTR            2048            1088   1120
    PSTRB           2048            1087   1120
    PSTRBI          2048            1093   1120
    PSTRI           2048            1089   1120
    PSZAP           2048            1089   1120

This table shows the number of bytes allocated for the cop\_font object, the number of bytes actually used, and the size of each binary font file produced by gendev 4.1 from the source files provided in the [WGML 3.33 Update](WGML-References#reference2):

    Font File:  Allocated   Used   File Size
    DIAPROP         2048            1076    320
    HP1C10B8        2048              73     80
    HP1C10BC        2048              74     80
    HP1C10BE        2048              73     80
    HP1C10BN        2048              74     80
    HP1C10I8        2048              73     80
    HP1C10IC        2048              74     80
    HP1C10IE        2048              73     80
    HP1C10IN        2048              74     80
    HP1C10M8        2048              73     80
    HP1C10MC        2048              74     80
    HP1C10ME        2048              73     80
    HP1C10MN        2048              74     80
    HP1C12I8        2048              73     80
    HP1C12IC        2048              74     80
    HP1C12IE        2048              73     80
    HP1C12IN        2048              74     80
    HP2H14B8        2048            1097    400
    HP2H14BC        2048            1098    400
    HP2H14BE        2048            1097    400
    HP2H14BN        2048            1098    400
    HP2T08M8        2048            1095    400
    HP2T08MC        2048            1096    400
    HP2T08ME        2048            1095    400
    HP2T08MN        2048            1096    400
    HP2T12B8        2048            1097    400
    HP2T12BC        2048            1098    400
    HP2T12BE        2048            1097    400
    HP2T12BN        2048            1098    400
    HP2T12I8        2048            1097    400
    HP2T12IC        2048            1098    400
    HP2T12IE        2048            1097    400
    HP2T12IN        2048            1098    400
    HP2T12M8        2048            1097    400
    HP2T12MC        2048            1098    400
    HP2T12ME        2048            1097    400
    HP2T12MN        2048            1098    400
    HPAC12B8        2048              73     80
    HPAC12I8        2048              73     80
    HPBH14BA        2048            1101    400
    HPBT08MA        2048            1095    400
    HPBT10BA        2048            1097    400
    HPBT10IA        2048            1097    400
    HPBT10MA        2048            1097    400
    HPCC12B8        2048              73     80
    HPCC12BA        2048              73     80
    HPCC12BF        2048              73     80
    HPCC12BG        2048              73     80
    HPCC12BH        2048              73     80
    HPCC12BI        2048              73     80
    HPCC12BK        2048              73     80
    HPCC12BS        2048              73     80
    HPCC12BW        2048              73     80
    HPCC12I8        2048              73     80
    HPCC12IA        2048              73     80
    HPCC12IF        2048              73     80
    HPCC12IG        2048              73     80
    HPCC12IH        2048              73     80
    HPCC12II        2048              73     80
    HPCC12IK        2048              73     80
    HPCC12IS        2048              73     80
    HPCC12IW        2048              73     80
    HPCC12M8        2048              73     80
    HPCC12MA        2048              73     80
    HPCC12MF        2048              73     80
    HPCC12MG        2048              73     80
    HPCC12MH        2048              73     80
    HPCC12MI        2048              73     80
    HPCC12MK        2048              73     80
    HPCC12MS        2048              73     80
    HPCC12MW        2048              73     80
    HPCN09M8        2048              77     80
    HPCN09MA        2048              77     80
    HPCN09MF        2048              77     80
    HPCN09MG        2048              77     80
    HPCN09MH        2048              77     80
    HPCN09MI        2048              77     80
    HPCN09MK        2048              77     80
    HPCN09MS        2048              77     80
    HPCN09MW        2048              77     80
    HPDP10B8        2048              73     80
    HPDP10BA        2048              73     80
    HPDP10I8        2048              73     80
    HPDP10IA        2048              73     80
    HPDP10M8        2048              73     80
    HPDP10MA        2048              73     80
    HPEG12B8        2048              73     80
    HPEG12BA        2048              73     80
    HPEG12I8        2048              73     80
    HPEG12IA        2048              73     80
    HPEG12M8        2048              73     80
    HPEG12MA        2048              73     80
    HPFH14B8        2048            1101    400
    HPFH14BA        2048            1101    400
    HPFN09M8        2048              77     80
    HPFN09MA        2048              77     80
    HPFT08M8        2048            1095    400
    HPFT08MA        2048            1095    400
    HPFT10B8        2048            1097    400
    HPFT10BA        2048            1097    400
    HPFT10I8        2048            1097    400
    HPFT10IA        2048            1097    400
    HPFT10M8        2048            1097    400
    HPFT10MA        2048            1097    400
    HPFXC12B        2048              88    160
    HPFXC12M        2048              88    160
    HPFXH08M        2048            1096    400
    HPFXH10B        2048            1096    400
    HPFXH10I        2048            1096    400
    HPFXH10M        2048            1096    400
    HPFXH12B        2048            1096    400
    HPFXH12I        2048            1096    400
    HPFXH12M        2048            1096    400
    HPFXH14B        2048            1096    400
    HPFXH14I        2048            1096    400
    HPFXH14M        2048            1096    400
    HPFXH18B        2048            1096    400
    HPFXH24B        2048            1096    400
    HPFXT08M        2048            1096    400
    HPFXT10B        2048            1096    400
    HPFXT10I        2048            1096    400
    HPFXT10M        2048            1096    400
    HPFXT12B        2048            1096    400
    HPFXT12I        2048            1096    400
    HPFXT12M        2048            1096    400
    HPFXT14B        2048            1096    400
    HPFXT14I        2048            1096    400
    HPFXT14M        2048            1096    400
    HPFXT18M        2048            1096    400
    HPFXT24M        2048            1096    400
    HPGL12MD        2048              73     80
    HPGP07MA        2048              75     80
    HPGP07ML        2048              75     80
    HPGP10BA        2048              73     80
    HPGP10BL        2048              73     80
    HPGP10IA        2048              73     80
    HPGP10IL        2048              73     80
    HPGP10MA        2048              73     80
    HPGP10ML        2048              73     80
    HPHC12BA        2048              73     80
    HPHC12BL        2048              73     80
    HPHC12IA        2048              73     80
    HPHC12IL        2048              73     80
    HPHC12MA        2048              73     80
    HPHC12ML        2048              73     80
    HPHL12MD        2048              73     80
    HPHP07MA        2048              75     80
    HPHP07ML        2048              75     80
    HPIC12B8        2048              73     80
    HPIC12BC        2048              74     80
    HPIC12BE        2048              73     80
    HPIC12BN        2048              74     80
    HPIC12M8        2048              73     80
    HPIC12MA        2048              73     80
    HPIC12MC        2048              74     80
    HPIC12ME        2048              73     80
    HPIC12MN        2048              74     80
    HPIC12MX        2048              73     80
    HPIN09M8        2048              77     80
    HPIN09MA        2048              77     80
    HPIN09MC        2048              78     80
    HPIN09ME        2048              77     80
    HPIN09MN        2048              78     80
    HPIN09MX        2048              77     80
    HPJP07M8        2048              75     80
    HPJP07MA        2048              75     80
    HPJP07MM        2048              75     80
    HPJP10B8        2048              73     80
    HPJP10BA        2048              73     80
    HPJP10I8        2048              73     80
    HPJP10IA        2048              73     80
    HPJP10M7        2048              73     80
    HPJP10M8        2048              73     80
    HPJP10MA        2048              73     80
    HPJP10MM        2048              73     80
    HPJP10MO        2048              74     80
    HPKT08M8        2048            1095    400
    HPKT08MA        2048            1095    400
    HPKT08MM        2048            1095    400
    HPKT10B8        2048            1097    400
    HPKT10BA        2048            1097    400
    HPKT10I8        2048            1097    400
    HPKT10IA        2048            1097    400
    HPKT10M7        2048            1097    400
    HPKT10M8        2048            1097    400
    HPKT10MA        2048            1097    400
    HPKT10MM        2048            1097    400
    HPKT10MO        2048            1098    400
    HPLC12B8        2048              73     80
    HPLC12I8        2048              73     80
    HPLN09M8        2048              77     80
    HPMP10B8        2048              73     80
    HPMP10I8        2048              73     80
    HPMP10M8        2048              73     80
    HPNG12B8        2048              73     80
    HPNG12I8        2048              73     80
    HPNG12M8        2048              73     80
    HPPT10B8        2048            1097    400
    HPPT10I8        2048            1097    400
    HPPT10M8        2048            1097    400
    HPQC12B8        2048              73     80
    HPQC12I8        2048              73     80
    HPQG12B8        2048              73     80
    HPQG12M8        2048              73     80
    HPRG14MA        2048              73     80
    HPRG14ML        2048              73     80
    HPRL14MD        2048              73     80
    HPRR14BA        2048              74     80
    HPRR14BL        2048              74     80
    HPRR16BA        2048              75     80
    HPRR16BL        2048              75     80
    HPRR18BA        2048              75     80
    HPRR18BL        2048              75     80
    HPTH06MA        2048            1095    400
    HPTH08BA        2048            1095    400
    HPTH08MA        2048            1095    400
    HPTH10BA        2048            1097    400
    HPTH12BA        2048            1097    400
    HPTH14BA        2048            1097    400
    HPUG10M8        2048              77     80
    HPUH06M8        2048            1095    400
    HPUH08M8        2048            1095    400
    HPUH10B8        2048            1097    400
    HPUH12B8        2048            1097    400
    HPUH14B8        2048            1097    400
    HPUL12MD        2048              73     80
    HPVG10M8        2048              77     80
    HPVH06M8        2048            1095    400
    HPVH08M8        2048            1095    400
    HPVH10B8        2048            1097    400
    HPVH12B8        2048            1097    400
    HPVH14B8        2048            1097    400
    HPVL12MD        2048              73     80
    HPW346M8        2048              74     80
    HPW381M8        2048              74     80
    HPWG10M8        2048              77     80
    HPWG10MA        2048              77     80
    HPWG14M8        2048              73     80
    HPWG14MA        2048              73     80
    HPWL12MD        2048              73     80
    HPWO12MR        2048              73     80
    HPXB12MB        2048              73     80
    HPXG10M8        2048              77     80
    HPXG10MA        2048              77     80
    HPXG14M8        2048              73     80
    HPXG14MA        2048              73     80
    HPXL12MD        2048              73     80
    HPYC12B8        2048              73     80
    HPYC12I8        2048              73     80
    HPYC12M8        2048              73     80
    HPYN09M8        2048              77     80
    HPZH08M8        2048            1095    400
    HPZH08MA        2048            1095    400
    HPZH08ME        2048            1095    400
    HPZH10B8        2048            1097    400
    HPZH10BA        2048            1097    400
    HPZH10BE        2048            1097    400
    HPZH10I8        2048            1097    400
    HPZH10IA        2048            1097    400
    HPZH10IE        2048            1097    400
    HPZH10M8        2048            1097    400
    HPZH10MA        2048            1097    400
    HPZH10ME        2048            1097    400
    HPZH12B8        2048            1097    400
    HPZH12BA        2048            1097    400
    HPZH12BE        2048            1097    400
    HPZH12I8        2048            1097    400
    HPZH12IA        2048            1097    400
    HPZH12IE        2048            1097    400
    HPZH12M8        2048            1097    400
    HPZH12MA        2048            1097    400
    HPZH12ME        2048            1097    400
    HPZH14B8        2048            1097    400
    HPZH14BA        2048            1097    400
    HPZH14BE        2048            1097    400
    HPZN09M8        2048              77     80
    HPZN09MA        2048              77     80
    HPZN09ME        2048              77     80
    HPZT08M8        2048            1095    400
    HPZT08MA        2048            1095    400
    HPZT08ME        2048            1095    400
    HPZT10B8        2048            1097    400
    HPZT10BA        2048            1097    400
    HPZT10BE        2048            1097    400
    HPZT10I8        2048            1097    400
    HPZT10IA        2048            1097    400
    HPZT10IE        2048            1097    400
    HPZT10M8        2048            1097    400
    HPZT10MA        2048            1097    400
    HPZT10ME        2048            1097    400
    HPZT12B8        2048            1097    400
    HPZT12BA        2048            1097    400
    HPZT12BE        2048            1097    400
    HPZT12I8        2048            1097    400
    HPZT12IA        2048            1097    400
    HPZT12IE        2048            1097    400
    HPZT12M8        2048            1097    400
    HPZT12MA        2048            1097    400
    HPZT12ME        2048            1097    400
    HPZT14B8        2048            1097    400
    HPZT14BA        2048            1097    400
    HPZT14BE        2048            1097    400
    LQ850C17        2048              52     80
    LQ850D10        2048              54     80
    LQ850D12        2048              54     80
    LQ850D15        2048              54     80
    LQ850D17        2048              52     80
    LQ850D20        2048              52     80
    LQ850E12        2048              54     80
    LQ850E20        2048              52     80
    LQ850M15        2048              54     80
    LQ850P10        2048              54     80
    LQ850PRO        2048            1076    320
    MLTRES          2048              52     80
    MONO01          2048              52     80
    MONO07          2048              52     80
    MONO12          2048              52     80
    MONO12H8        2048              52     80
    MONO24          2048              52     80
    PSAB            2048            1092   1120
    PSABO           2048            1099   1120
    PSAD            2048            1092   1120
    PSADO           2048            1099   1120
    PSBD            2048            1089   1120
    PSBDI           2048            1095   1120
    PSBL            2048            1090   1120
    PSBLI           2048            1096   1120
    PSCB            2048              65     80
    PSCO            2048              60     80
    PSCOB           2048              68     80
    PSCOBO          2048              72     80
    PSHN            2048            1093   1120
    PSHNB           2048            1098   1120
    PSHNBO          2048            1105   1120
    PSHNO           2048            1101   1120
    PSHV            2048            1096   1120
    PSHVB           2048            1091   1120
    PSHVBO          2048            1098   1120
    PSHVO           2048            1094   1120
    PSNB            2048            1098   1120
    PSNBI           2048            1104   1120
    PSNI            2048            1100   1120
    PSNR            2048            1099   1120
    PSPB            2048            1090   1120
    PSPBI           2048            1096   1120
    PSPI            2048            1092   1120
    PSPR            2048            1091   1120
    PSSYM           3072            2519   2000
    PSTR            2048            1088   1120
    PSTRB           2048            1087   1120
    PSTRBI          2048            1093   1120
    PSTRI           2048            1089   1120
    PSZAP           2048            1089   1120
    QUME10          2048              52     80
    QUME12          2048              52     80
    QUMEPROP        2048            1076    320
    X24EC10         2048              52     80
    X24EC17         2048              52     80
    X24EE12         2048              52     80
    X24EPRO         2048            1076    320
    XBOPS           2048            1094    400
    XBOPSBIO        3072            2150    640
    XBOPSBO         3072            2149    640
    XBOPSIO         3072            2149    640
    XBOPSO          3072            2148    640
    XCP125O         2048            1125    400
    XCP14           2048            1093    400
    XEL12           2048            1095    400
    XEL12BO         3072            2150    640
    XEL12O          3072            2149    640
    XKO10           2048            1096    400
    XKO10B          2048            1097    400
    XKO12           2048            1096    400
    XKO12B          2048            1097    400
    XKO14           2048            1096    400
    XKO6            2048            1095    400
    XKO8            2048            1095    400
    XKO8B           2048            1096    400
    XLG10BO         3072            2157    640
    XLG10O          3072            2156    640
    XLG12           2048            1102    400
    XLG12BO         3072            2157    640
    XLG12O          3072            2156    640
    XLG15BO         3072            2157    640
    XLG15O          3072            2156    640
    XMA12BO         3072            2151    640
    XMA12O          3072            2150    640
    XOA10           2048            1094    400
    XOB10           2048            1094    400
    XSC10           2048            1097    400
    XSP10           2048            1099    400
    XSP10BO         3072            2154    640
    XSP10O          3072            2153    640
    XTI10           2048            1095    400
    XTI10B          2048            1096    400
    XTI10BIO        3072            2151    640
    XTI10BO         3072            2150    640
    XTI10I          2048            1096    400
    XTI10IO         3072            2150    640
    XTI10O          3072            2149    640
    XTI12BO         3072            2150    640
    XTI12IO         3072            2150    640
    XTI12O          3072            2149    640
    XTJ10BO         3072            2151    640
    XTJ10O          3072            2150    640
    XTRPS           2048            1095    400
    XTRPSBO         3072            2150    640
    XTRPSO          3072            2149    640
    XVI10BO         3072            2152    640
    XVI10O          3072            2151    640
    XVI12           2048            1097    400
    XVI12BO         3072            2152    640
    XVI12O          3072            2151    640

The code currently begins by allocating 2048 bytes and then increases the block, if necessary, by multiples of 1024. The above suggests that this should work all right in almost all cases. It appears that realloc() could be used to shrink each the cop\_font instance to the actual size needed, freeing the additional space, in which case starting at 3072 would be fastest for all of the fonts listed above, whether used by Open Watcom or not, since no expansion would be needed.

### Padding

All available binary device files (in general, that is, including both directory files and binary member files) have been checked by the research program cfcheck.exe and have a length which is a multiple of 16. This is true for both version 3.33 and version 4.1 files. Whether this is necessary (that is, whether wgml requires it) is not yet known.
