Print a Unicode UTF-8 encoded textfile from a modern PC with an old-fashioned Commodore MPS 803 compatible printer.
This utility outputs raw bytes for printing Unicode texts (UTF-8 encoded) on a Commodore MPS 803 compatible printer. It should be used with opencbm package by Spiro Trikaliotis to redirect the output to the printer, connected through a XUM1541 cable, such as ZoomFloppy.
Commodore MPS 803 natively has a non-standard ASCII variant called PETSCII, missing a lot of symbols like letters with accents, and including a few of non-standard glyphs:
With cbmtext, the MPS 803 will be able to print modern Unicode text-files (UTF-8 encoded) including those with international characters, like letters with diacritics and cyrillic alphabet (look at the bottom of this README for some pictures).
- source/ - Source code in C
- cbmtext.cpp - Main program
- chardefs.h - Dot-matrix character definitions
- utf8.h - UTF8-CPP library, entry point
- utf8/ - UTF8-CPP library
- core.h - part of the library
- checked.h - part of the library
- unchecked.h - part of the library
- Makefile
- binaries/ - Precompiled executable files for different platforms
- windows/cbmtext.exe - for Windows
- macOS/cbmtext - for macOS, 64 bit
- linux/cbmtext - for Linux (x86_64)
- sample.txt - Sample Unicode text file, UTF-8 encoded
- macOS or Windows (32/64 bit) or Linux
- an MPS 803 printer or a compatible one
- XUM1541 / ZoomFloppy
- opencbm package installed (a.k.a. cbm4win)
- g++ if you want to compile from sources
To install opencbm you can use the installer from its website, or if you use a debian-based version of Linux, follow these instructions: https://debian.trikaliotis.net
On macOS you can use this command (with the help of Homebrew Package Manager):
brew install opencbm
Once you have g++ installed, just enter the "source" directory and launch:
make
An executable file named "cbmtext" will be generated: it's ready to use.
Synopsis:
cbmage <text file name>
cbmage -
This is the basic syntax: it will read the text file (first case), or from standard input (second case, giving "-" as parameter) writing on standard output (so, the terminal window) the raw bytes that should be interpreted by the MPS 803 printer.
The input stream (file on disk or standard input) must be UTF-8 encoded. The output must be redirected to the printer: let's see how.
The typical sequence of command you should use to do the task is:
cbmctrl reset
cbmctrl lock
cbmctrl listen 4 0
./cbmtext sample.txt | cbmctrl write
cbmctrl unlisten
cbmctrl unlock
In particular, the 4th line (./cbmtext sample.txt | cbmctrl write
) produces the raw bytes (launch it without "./" if you run it on Windows), which are redirected to the printer through the piped cbmctrl write
command.
Commodore MPS 803 is an 80 columns printer, so the text lines will be broken at the 80th character. Currently there is no word wrap function in cbmtext, so you have to word-wrap the text before sending it to the printer, i.e. with the fold Unix command:
$ cat sample.txt | fold -w 80 | ./cbmtext - | cbmctrl write
To print an international text on a CBM MPS 803, we have to mix text mode (for pre-defined PETSCII characters in printer's ROM) and graphics mode (for all the other symbols). Those new symbols have been implemented as dot-matrix definitions in the header file chardefs.h, in that way:
{L'á', {
0b001100, // ..██..
0b000000, // ......
0b011000, // .██...
0b000100, // ...█..
0b011100, // .███..
0b100100, // █..█..
0b011010 }}, // .██.█.
Literal binary constants are exactly the 6x7 human-readable bitmap representing the character (1 is for black, 0 for white). If for a particular glyph, a pre-defined character could be used, the syntax is the following:
{L'ρ', {'P'}},
It's the case of rho lowercase greek letter. It's similar to a latin lowercase p, so it can be inserted as a single-character replacement. But we replaced it apparently with an uppercase "P": that's because PETSCII charset, used by MPS 803, has swapped lowercase and uppercase letters.
So, by editing the header file chardefs.h you can add or modify the definitions the dot matrix related to each Unicode character. If a character is not yet coded, it will be printed as missing glyph symbol "□", also defined in the same file:
static list<char> missing_glyph = {
0b111110, // █████.
0b100010, // █...█.
0b100010, // █...█.
0b100010, // █...█.
0b100010, // █...█.
0b100010, // █...█.
0b111110 // █████.
};
Thanks to Spiro Trikaliotis for the opencbm package, to Till Harbaum for the initial case study of the XU1541 (and also for the fantastic MIST) and to ntrifunovic for the useful UTF8-CPP library library.