Skip to content

WGML Binary Device Files

Jiri Malak edited this page Feb 20, 2021 · 5 revisions
Table of Contents

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.

The attributes that are used to build the entries in the directory file are discussed in 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 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 or the README file produceable from the WGML 3.33 Update 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 are different.
  • The directory files 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 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 are invoked at what points in creating the output file. This was used to determine, for those :INIT blocks 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 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 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 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.

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 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.

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 by the README file produceable from the WGML 3.33 Update. 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, 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 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 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 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, encodes the :VALUE blocks of both the :PAUSE blocks and the :FONTPAUSE blocks.
  • The PageGeometryBlock, as discussed in Device File Blocks, encodes both the :PAGESTART block and the :PAGEOFFSET block.
  • The TranslationBlock, as discussed in 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.

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:

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 by the README file produceable from the WGML 3.33 Update. 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, 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 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 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 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.
  • The attributes defined_name and member_name are discussed in the section 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:

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 by the README file produceable from the WGML 3.33 Update. 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, 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 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 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:

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, 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:

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.

Clone this wiki locally