Skip to content
Jiri Malak edited this page Mar 7, 2021 · 8 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

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