LocoScript 2, LocoChar and LocoFont
Within LocoScript 2, the dot-matrix printer font is defined either by the printer file MATRIX.PRI (LocoScript 2.00-2.19) or a font file such as MATRIX.#ST (LocoScript 2.12 onward).
Similar font files are also used to store other types of printer font (such as daisywheel layouts, bitmaps for 24-pin printers, or other character mappings). This document only covers files of type 1, fonts for the PCW dot-matrix printer.
Fonts
Standard fonts | |
---|---|
The original font is called Standard, and is a derivative of the printer font used in LocoScript 1 (though with detail differences to many of the character shapes). | ![]() |
From LocoScript 2.16, a second font, Sans-Serif, was also supplied. | ![]() |
LocoFont | |
The LocoFont add-on font pack provides nine additional fonts: | |
Capitals (small caps) | ![]() |
Copper Plate (no draft version) | ![]() |
Definite (no draft version) | ![]() |
Deco (no draft version) | ![]() |
Finesse (no draft version) | ![]() |
Modern | ![]() |
Roman (no draft version) | ![]() |
Standard 2 (a version of the Standard font similar to the old LocoScript 1 outline) | ![]() |
Script (no draft version) | ![]() |
LocoChar
From version 2.12, LocoScript allows up to 16 characters in a font to be replaced by user-defined characters. The characters available for replacement are the circled digits and the six curly quote characters that follow them.
The program LocoChar performs the redefinition. Starting with one of the standard font files, it allows a custom version of that file to be created, containing replacement screen and printer bitmaps for the 16 user-defined characters. The original LocoChar is written in BASIC; later versions are machine-code programs that run under CP/M.
Font-file format
Conventions
LocoScript saves its files on CP/M-formatted discs, and therefore uses CP/M conventions such as 8.3 filenames and 128-byte records.
A byte is 8 bits. A word is 16 bits, in little-endian format.
Versions
There are three versions of the file format:
- Version 1
- Used in LocoScript 2.00-2.11. Supports up to 480 characters. User-defined characters not supported.
- Version 2
- Used in LocoScript 2.12-2.19. Supports up to 480 characters. User-defined characters supported.
- Version 3
- Used in LocoScript 2.20+. Supports up to 512
characters. User-defined characters supported. The characters are
rearranged:
- In version 2, characters 0-15 are the top halves of double-height characters (tall Sigma, tall Pi etc) and characters 16-31 are combining accents. In version 3, characters 0-31 are combining accents and the double-height characters move to the 272-287 range.
- Characters 256 and up have their numbers increased by 32.
- Some character outlines have been redesigned.
- The PS widths table retains 480 entries, skipping over characters 256-287.
File header
Like nearly all LocoScript files, a font begins with a 128-byte header:
Offset Value Notes ============================================================================== 00h 'CHR' or 'PRI' File type ('CHR' for a font, 'PRI' for the printer driver itself) 03h Major version 1-3, as above 04h Minor version Always appears to be 1 05h Identity File identity, 3 lines each of 30 ASCII bytes 5Fh Word: Link number Purpose unknown, not used by LocoChar 61h Word: Checksum 16-bit checksum of file (excluding header) 63h Word: Length Length of file in 128-byte records (excluding header) 65h Style name 12 ASCII bytes 71h Byte: Style pitch? LocoChar calls this STYPITCH but does not access it. 72h Byte: Type flags Bits 0-2: Font type. Possible values include: 1 => PCW8000 dot-matrix 2 => PCW9000 daisywheel 3 => External printer driven using text (eg 9-pin matrix or daisywheel) 4 => External 24-pin dot-matrix Bit 3: Set for a font, clear for the printer driver itself. Bit 4: Set for a dot-matrix character set 73h 8 bytes: Driver LocoChar calls this DRIVER but does not access it. 7Bh Word: Font offset Offset to the font within this file 7Dh Word LocoChar calls this OPTIONS but does not access it. 7Fh Byte: Checksum 8-bit checksum of the preceding 127 bytes ==============================================================================
For a font file, the offset to the font is 0x80 (ie, the font immediately follows the header). For a printer driver file, the driver comes first and the font further on.
Font data
Taking 0 as the start of the font, it has this format:
Offset Value Notes ============================================================================== 0000h 12 bytes: Char set Character set name 000Ch 2 bytes Unknown 000Eh 1 byte Bit 7 set if all bitmaps are uncompressed? 000Fh 1 byte Flags. Bit 6 is set if the screen characters have been redesigned. ------------------------------------------------------------------------------ 0010h 240 bytes PS widths table: Widths for 480 characters. For character n, the width is at entry (n/2), with the low nibble giving the width of the even-numbered character and the high nibble giving the width of the odd-numbered character. Add 9 to the value to get the actual PS width. ------------------------------------------------------------------------------ 0100h 128 bytes (v2/v3 only) 16 8x8 bitmaps giving the screen appearance of the user-defined characters. ------------------------------------------------------------------------------ 1922 bytes (v1/v2) Index table; four bytes per character, plus 2050 bytes (v3) one extra word for end of file. Index entries are defined below. ------------------------------------------------------------------------------ 124 bytes NLQ character bitmaps (second pass) 124 bytes NLQ character bitmaps (first pass) 124 bytes Draft character bitmaps ------------------------------------------------------------------------------ varies Character pattern data ==============================================================================
Each index entry is formed:
DW offset DB flags DB extra
The top three bits of the offset indicate how the rest of the offset is to be treated:
- Offset 0E000h-0FFFFh
- This is an accented character. Bits 13-0 of the offset give the base character number. Bits 4-0 of the flags give the accent character number. For example, character 200 (รข) might be stored as 61 E0 03 42. Offset 0E061h means the base character is 61h ('a'). Flags 03h mean the accent number is 3 (circumflex — character 13h in v1/v2 files, character 03h in v3 files).
- Offset 0C000h-0DFFFh
- This is a duplicate character. Bits 13-0 of the offset give the duplicate character. For example, character 352 (capital Alpha) might be stored as 41 C0 FF 57. Offset 0C041h means the shape from character 41h ('A') is used.
- Offset 08000h-0BFFFh
- This is an uncompressed character (normally this would apply only to user-defined characters). Bits 13-0 of the offset give the address of its bitmaps relative to the start of the index table. The bitmaps are a standard size: 11 bytes for draft, 48 for NLQ.
- Offset 00000h-03FFFh
- This is a standard character. Bits 13-0 of the offset give the address of its bitmaps relative to the start of the index table. The low 4 bits of byte 3 ('extra') give length of the 'draft' bitmap, and the remainder is the 'NLQ' bitmap.
- 00h-7Bh
- Bitmap reference. The bitmaps begin immediately after the index
table; I have called this address index_end.
- NLQ (v1)
- There is a table of bitmaps at index_end, containing 124 words. Within each word, the high byte is for the first pass and the low byte is for the second pass.
- NLQ (v2/v3)
- There are two tables of bitmaps, each containing 124 bytes. The bitmaps for the first pass are at index_end + 7Ch and the bitmaps for the second pass are at index_end.
- Draft
- There is a single set of bitmaps, at index_end + 0F8h.
- 7Ch
- Literal (only found in NLQ patterns). Followed by two bytes giving the pin bitmaps for the second and first passes.
- 7Dh-7Fh
- Repeat. The following column is repeated value-79h times.
For characters with offset above 0C000h, byte 3 (extra) is used to calculate the length of the previous character. This is normally calculated as (offset of next character & 0x7FFF) - (offset of this character & 07FFF). However if the next character is an accent or other cross-reference, the offset needs to be calculated from byte 3:
if (char[n].offset & 0x4000) { return 0; /* This character is a reference */ } else if (char[n+1].offset & 0x4000) { /* Next character is a reference */ unsigned offset2 = (char[n].offset & 0x1F00) | char[n+1].extra; if (offset2 < (char[n].offset & 0x1FFF)) offset2 += 0x100; length = offset2 - (char[n].offset & 0x1FFF); } else { /* Next character is not a reference */ length = (char[n+1].offset & 0x1FFF) - (char[n].offset & 0x1FFF); }
For a character that isn't a reference, the flags byte has the following meaning:
Bit 7: Character shifted down. Shifted-down characters are printed on the bottom 8 printer pins, rather than the top 8; intended for characters with descenders. Bit 6: Character is shifted down when an accent is superimposed on it. Bit 5: Character cannot be copied in LocoChar. Set on the large mathematical symbols (large Pi, large Sigma etc.) because they are drawn in two halves, top and bottom. Bit 4: Accent replaces a dot (eg, on 'i' or 'j'). Any non-blank line from the accent will completely replace the corresponding line from the character. Bits 3-0: Proportional spacing columns minus 11
For a character that isn't a reference, the 'extra' byte has the following meaning:
Bits 7-5: Blank columns at left (NLQ) Bit 4: Blank column at left (draft) Bits 3-0: Number of bytes in draft character shape (compressed characters)
For compressed characters, following the offset in the index table leads you to the draft-mode pattern. 'extra' gives the length of the draft-mode pattern in bytes; add it to the offset to get the address of the NLQ pattern.
In the pattern, bit 7 of a byte is set if it should be preceded by a blank column. Bits 6-0 give a pattern number:
For uncompressed characters, following the offset in the index table leads you to 11 bytes giving the character bitmap for draft mode, followed by 48 defining it in NLQ mode.
The draft mode shape is 11 bytes. In each byte, bits 0-7 give the pin bitmap (bit 0 is the top pin, bit 7 the bottom).
The NLQ mode shape is 24 words. In each word, the high 8 bits give the pin bitmap on the first pass, and the low 8 bits the pin bitmap on the second pass.