美咲フォントROMを作ってみた
メモリーに限りのあるArduinoで日本語を表示すべく、美咲フォントをEEPROMに書き込んで、美咲フォントROMを作ってみました。EEPROMは 24FC1025 を使用します。 使用方法は 『I2C接続:1MBit EEPROM 24FC1025』 を参照。
表示デバイスにはSSD1306を使用しています。
※SSD1315でもそのまま使えます (多分:スクロール関係の命令が若干違うだけでホボ互換なので)
 美咲フォント
 美咲フォントArduno用 美咲フォントデータを作る
FONTX ビットマップフォントデータからArduinoで使えるテキスト形式の定義情報に変換します。FONTXはMS-DOS時代のフォントデータで、現在では、ほぼ使われていないようです。
FONTXからテキスト形式に変換するコンバータは存在しますが、MS-DOS(16Bit-OS)用でWidnows(32Bit/64Bit-OS)では動作しません。
FONTXのファイルフォーマットは▼のようになっています。
半角フォント
| Offset | Size | フィールド内容 | 
|---|---|---|
| 0 | 6 | ファイル・シグネチャ("FONTX2") | 
| 6 | 8 | フォント名 | 
| 14 | 1 | フォント幅 WF(ドット) | 
| 15 | 1 | フォント高さ HF(ドット) | 
| 16 | 1 | 文字コード・フラグ(0:ANK) | 
| 17 | ※1 | フォントイメージ (※1:フォントサイズ×256) | 
全角フォント
| Offset | Size | フィールド内容 | 
|---|---|---|
| 0 | 6 | ファイル・シグネチャ("FONTX2") | 
| 6 | 8 | フォント名 | 
| 14 | 1 | フォント幅 WF?(ドット) | 
| 15 | 1 | フォント高さ HF?(ドット) | 
| 16 | 1 | 文字コード・フラグ (1:シフトJIS) | 
| 17 | 1 | コード・ブロック数 NB | 
| 18 | 2 | ブロック1開始コード コード・ブロック・テーブル | 
| 20 | 2 | ブロック1終了コード (リトル・エンディアン) | 
| … | … | … | 
| 14+4*NB | 2 | ブロックNB開始コード | 
| 16+4*NB | 2 | ブロックNB終了コード | 
| 18+4*NB | ※2 | フォントイメージ (※2:フォントサイズ×各ブロックのコード数の総和) | 
これを読み出して ▼の書式で書き出すツールをVC++で作成
| フォントイメージのアドレス | UTF16コード | フォントイメージ | 
|---|---|---|
| 0x0000~0xFFFF | 0x0020~0xFFE5 | 未使用部分を削って7Byteに圧縮 | 
美咲フォントはMS-DOSなどのCRT表示を前提としたフォントなので、SSD1306とは表示の向きが違います。
なので、SSD1306で使いやすいように読み出し時に90度回転しておきます。
|  | Windows等のディプレイと SSD1306等のOLEDでは 表示の向きが違うので SSD1306に合わせて ビットデータを変換 |  | 
 FONTX2TEXT.zip ソースコード(VisualStudio2019)と実行モジュール(x86用)
 FONTX2TEXT.zip ソースコード(VisualStudio2019)と実行モジュール(x86用)※SJIS->UTF16コード変換にWinAPIを使用しているため、Windowsでしか動きません。
フォントデータをEEPROMに書き込む
UTF16文字コードの1バイト目をINDEXテーブルのテーブル番号のキーとし2バイト目でFONTイメージのアドレスのINDEXテーブルのキーとします。
美咲フォントファイルの構造を▼のようにします。
ROM1(64KByteブロック)
| 0x0000 ~ 0x00FF | INDEXテーブルのテーブル番号 | 256バイト | 1~255の番号が入る。 実際には美咲フォントで使用されるUTF16の1バイト目は96種類しかないので 1~96の値が入る。 0は該当するINDEXが存在しない事を示す。※未対応文字になります | 
| 0x0100 ~ 0x01FF | 未使用 | ||
| 0x0200 ~ 0x03FF | INDEXテーブル1 (UTF16コード1バイト目が0x00) FONTイメージのアドレス | 512Byte | フォントイメージのアドレスが入る | 
| INDEテーブル2 ・・・ INDEXテーブル95(表記省略) | |||
| 0xC000 ~ 0xC1FF | INDEXテーブル96 (UTF16コード1バイト目が0xFF) FONTイメージのアドレス | 512Byte | フォントイメージのアドレスが入る | 
| 0xC200 ~ 0xCFFF | 未使用 | ||
| 0xD000 ~ 0xD03F | 半角カナ全角変換テーブル | 64Byte | 半角カナ全角変換テーブル ※容量あまったから入れてみた | 
ROM2(64KByteブロック)
| 0x0000 ~ 0x0006 | フォントイメージ | 7Byte | 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // | 
| フォントイメージ 6929文字 x 7Byte | |||
| 0xBD86 ~ 0xBD8D | フォントイメージ | 7Byte | 0x00,0x2B,0x2C,0x78,0x2C,0x2B,0x00, // ¥ | 

FONTデータの全部はArduinoに乗らないので、分割して書き込みます。
MISAKI.hの #define FONTxx のコメントを順番に外してコンパイル/実行
 MakeKanjiROM-01.zip
 MakeKanjiROM-01.zip日本語フォント表示
フォントの読み出し手順 例:'あ' UTF16コード 0x3042 の場合1バイト目の0x30 をキーにして INDEXテーブルのテーブル番号 を取得します。
(1) ROM1のアドレス 0x0030 から1バイトを読み出し。 ※256バイトのテーブルなのでメモリー上に保持した方が良いです。
-> 11が得られます
(2) INDEXテーブルのアドレスを求めます。
-> 512 × 11 = 5632 = 0x1600 が得られます。
(3) FONTデータのINDEXアドレスを求めます
-> 0x1600 + UTF16コードの2バイト目 × 2 = 0x1600 + 0x42 × 2 = 0x1684
(4) ROM1のアドレス 0x1684 から2バイト読み出し。 ※FONTデータのアドレスです。
-> 0x074D が得られます。
(5) ROM2のアドレス 0x074D から7バイトを読み出し。
-> 'あ' のフォントイメージが得られます。
得られたフォントイメージをSSD1306に書き出し。
※ SPI接続のSSD1306を使用しています。

 KanjiFontDEMO-EEPROM3.zip
 KanjiFontDEMO-EEPROM3.zip