-
Notifications
You must be signed in to change notification settings - Fork 159
WGML COP Files
Table of Contents
The binary device file format is used for two distinct purposes:
- To encode :DEVICE, :DRIVER, and :FONT blocks.
- 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.
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.
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.
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.
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.
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.
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.
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:
- Character data, which can hold any byte value.
- String data, which cannot include null bytes.
- 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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
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:
- The CharacterDescriptionBlock, as discussed in Font File Blocks, encodes the :INTRANS blocks, the :OUTTRANS blocks, and the :WIDTH blocks.
- The attributes defined_name and member_name and the :INTRANS block and the :OUTRANS block are discussed in Common File Blocks.
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.
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.
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.
- Welcome
- Building
- Open Watcom Documentation
- Notes
- Relicensing effort
- Debugging
- OW tools usage Overview
- OW tools usage with CMake
- OW tools usage with Visual Studio Code
- Open Watcom 1.9 Wiki
OW Development
WGML Development
- WGML
- Augmented Devices
- Binary Device Files
- Common File Blocks
- COP Files
- Device File Blocks
- Device Function Language
- Device Function Notes
- Device Functions
- Directory File Format
- Drawing Boxes
- Driver File Blocks
- File and Directory Names
- Font File Blocks
- Fonts
- GML Tag Notes
- Keyword Statistics
- Macros and User Defined Tags
- Meta Data
- Page Layout Subsystem
- Search Paths
- Sequencing
- System Symbol Notes
- Tabs and Tabbing
- whpcvt Utility interaction