[注意] 以下の内容は、DevTerm プリンタプログラム 2022/1/26バージョンに対して行っています。本家プリンタプログラムは、その後のバージョンアップで、標準でTTF フォント&UTF-8対応になっています。
いつの間にか DevTerm プリンタに UNICODE MODE が追加になってた。/ DevTerm/Code/thermal_printer at main · clockworkpi/DevTerm · GitHub https://t.co/DZaKEpRhiF
— Nochi (@shikarunochi) April 11, 2022
DevTerm の感熱プリンタプログラムにいくつかフォントを追加してみたのですが、フォント種類指定できるのは 0~7 までなので、そんなにたくさん追加できません。なので、外部からフォントファイルを送り込んで、自由に入れ替えする処理を作ってみました。
変更は、devterm_thermal_printer.c だけです。
https://github.com/shikarunochi/DevTerm/blob/main/Code/thermal_printer/devterm_thermal_printer.c
ファイルを入れ替えて、サイト説明にしたがってビルドし、プリンタプログラムを入れ替えてください。元の devterm_thermal_printer.elf はバックアップ取っておいたほうが良いです。
How to run it from source
・make
・sudo systemctl stop devterm-printer
・sudo cp -rf devterm_thermal_printer.elf /usr/local/bin
・sudo systemctl start devterm-printer
フォント入れ替えのコマンドは [DC2 (0x12)] [F (0x46)][WIDTH][HEIGHT] + [フォントファイル] にしました。WIDTHは8の倍数である必要があります。
256文字をASCIIコード順に並べたデータとなります。8×8フォントの場合、1文字データが1バイト(横8ドット)x 8行 =8バイトとなりますので、2048バイトのデータになります。
フォント入れ替え用ヘッダーを
echo -en "\x12\x46\x8\x8" > changeFontCommand8x8
のようにファイルで作っておいて、
cat changeFontCommand8x8 mz80font.dat > /tmp/DEVTERM_PRINTER_IN
のようにすれば、フォントが登録されて、自動的にフォント切り替えまで行います。
DevTerm、プリンタドライバに動的に8×8フォントを入れ替えられる機能を追加してみました。フォントだけ入れ換えて同じプログラム実行しています。
PC-8001 / FM-7 / X1 は微妙に違うw pic.twitter.com/ULbpvv2D3L— Nochi (@shikarunochi) February 26, 2022
(↑ Tweet の例は、8×8 フォント専用で作ってた時なので、引数が違ってます)
フォント番号 7番で登録してますので、他のフォントに変更した後に再度切り替える場合は、フォントデータ再読み込みしなくても、[ESC (0x1b)] [ ! (0x21)] [7]でフォントを 7番に切り替えればOKです。
echo -en "\x1b\x21\x7" > /tmp/DEVTERM_PRINTER_IN
エミュレータ用に公開されている、PC-6001用互換フォントを使ってみます。(公開されている方に感謝します!)
PC-6001mkII/6601用互換BASIC
http://000.la.coocan.jp/p6/basic66.html#cgrom
PC-6001は、フォントサイズが 8×12 で、ちょっと特殊な感じですね。フォント内容を表示させてみます。
import sys with open(sys.argv[1], "rb") as fontFile: while True: fontByte = fontFile.read(1) if len(fontByte) == 0: break fontData = int.from_bytes(fontByte, byteorder='big') print('{:02X}'.format(fontData) + ":", end="") for i in range(8): if fontData & (0x80 >> i) > 0: print("■", end = "") else: print(" ",end = "") print();
12バイトフォントデータがあり、その後4バイト空いて、次のフォントデータが入っているようです。フォントデータとして使うなら途中の4バイトを読み飛ばせば良さそう。
ということで、Pythonなら、こういう感じで変換。フォントデータは 12×256 = 3072バイトになります。
with open("cgrom.60", "rb") as fontfile: with open('pc6001font.dat', 'wb') as output: for i in range(256): #12バイト読み、4バイト飛ばす output.write(fontfile.read(12)) fontfile.read(4)
8×12ドット用のフォント入れ替えヘッダを作成して
echo -en "\x12\x46\x8\xc" > changeFontCommand8x12
フォント入れ替え!
cat changeFontCommand8x12 pc6001font.dat > /tmp/DEVTERM_PRINTER_IN
うまく出力できましたー。
ファイルサイズは、必ず WIDTH x HEIGHT / 8 になるようにしてください。プリンタ側のプログラムで余分なデータを読み捨てできればよかったのですが、うまい方法が思いつかなかったので…。フォントファイルのほうが指定より大きかった場合は、データが文字列としてプリンタから出力されてしまいますので、変な印刷が始まってヤバそうと思ったら感熱紙のムダを防ぐために、感熱紙を本体から外して印刷が収まるのを待つと良いです。
MZ-80K/C のフォント(8×8ドット)の場合、ディスプレイコード順をアスキーコード順に並べ替える必要があります。
ascii2disp = [ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6b,0x6a,0x2f,0x2a,0x2e,0x2d, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x4f,0x2c,0x51,0x2b,0x57,0x49, 0x55,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x52,0x59,0x54,0x50,0x40, 0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xdf,0xe7,0xe8,0xe9,0xea,0xec,0xed, 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xc0, 0x80,0xbd,0x9d,0xb1,0xb5,0xba,0xb4,0x9e,0xb2,0xb6,0xb9,0xbe,0x9f,0xb3,0xb7,0xbb, 0xbf,0xa3,0x85,0xa4,0xa5,0xa6,0x94,0x87,0x88,0x9c,0x82,0x98,0x84,0x92,0x90,0x83, 0x91,0x81,0x9a,0x97,0x93,0x95,0x89,0xa1,0xaf,0x8b,0x86,0x96,0xa2,0xab,0xaa,0x8a, 0x8e,0xb0,0xab,0x8d,0xa7,0xa8,0xa9,0x8f,0x8c,0xae,0xac,0x9b,0xa0,0x99,0xbc,0xb8, 0x40,0x3b,0x3a,0x70,0x3c,0x31,0x5a,0x3d,0x43,0x56,0x3f,0x1e,0x4a,0x1c,0x5d,0x3e, 0x5c,0x1f,0x5f,0x5e,0x37,0x7b,0x7f,0x36,0x7a,0x7e,0x33,0x4b,0x4c,0x1d,0x6c,0x5b, 0x34,0x41,0x35,0x34,0x74,0x30,0x7c,0x75,0x7d,0x4d,0x6f,0x6e,0x32,0x77,0x76,0x72, 0x73,0x47,0x7c,0x53,0x71,0x4e,0x6d,0x48,0x46,0x3d,0x44,0x1b,0x58,0x79,0x42,0x60 ] with open("FONT.ROM", "rb") as fontFile: with open('mz80font.dat', 'wb') as datFile: for asciiIndex in range(256): dispIndex = ascii2disp[asciiIndex] fontFile.seek(dispIndex * 8) datFile.write(fontFile.read(8))
FM-7(8×8ドット)は、SUBSYS_C.ROM イメージの先頭にフォントデータが入ってるので、8×256バイトだけ切り出しすればOKです。
with open("Subsys_c.rom", "rb") as fontFile with open('fm7font.dat', 'wb') as datFile: datFile.write(fontFile.read(256*8))